UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
cp_event.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include "../../cl_shared.h"
27 #include "../../../shared/parse.h"
28 #include "../../../common/binaryexpressionparser.h"
29 #include "cp_campaign.h"
30 #include "cp_time.h"
31 #include "cp_xvi.h"
32 #include "cp_event_callbacks.h"
34 
35 static linkedList_t* eventMails = nullptr;
36 
44 eventMail_t* CL_GetEventMail (const char* id)
45 {
46  int i;
47 
48  for (i = 0; i < ccs.numEventMails; i++) {
49  eventMail_t* mail = &ccs.eventMails[i];
50  if (Q_streq(mail->id, id))
51  return mail;
52  }
53 
54  LIST_Foreach(eventMails, eventMail_t, listMail) {
55  if (Q_streq(listMail->id, id))
56  return listMail;
57  }
58 
59  return nullptr;
60 }
61 
67 {
68  /* the pointers are not freed, this is done with the
69  * pool clear in CP_ResetCampaignData */
70  cgi->LIST_Delete(&eventMails);
71 }
72 
74 static const value_t eventMail_vals[] = {
75  {"subject", V_TRANSLATION_STRING, offsetof(eventMail_t, subject), 0},
76  {"from", V_TRANSLATION_STRING, offsetof(eventMail_t, from), 0},
77  {"to", V_TRANSLATION_STRING, offsetof(eventMail_t, to), 0},
78  {"cc", V_TRANSLATION_STRING, offsetof(eventMail_t, cc), 0},
79  {"date", V_TRANSLATION_STRING, offsetof(eventMail_t, date), 0},
80  {"body", V_TRANSLATION_STRING, offsetof(eventMail_t, body), 0},
81  {"icon", V_HUNK_STRING, offsetof(eventMail_t, icon), 0},
82  {"model", V_HUNK_STRING, offsetof(eventMail_t, model), 0},
83  {"skipmessage", V_BOOL, offsetof(eventMail_t, skipMessage), MEMBER_SIZEOF(eventMail_t, skipMessage)},
84 
85  {nullptr, V_NULL, 0, 0}
86 };
87 
92 void CL_ParseEventMails (const char* name, const char** text)
93 {
94  eventMail_t* eventMail;
95 
97  cgi->Com_Printf("CL_ParseEventMails: mail def \"%s\" with same name found, second ignored\n", name);
98  return;
99  }
100 
101  /* initialize the eventMail */
102  eventMail = &ccs.eventMails[ccs.numEventMails++];
103  OBJZERO(*eventMail);
104 
105  cgi->Com_DPrintf(DEBUG_CLIENT, "...found eventMail %s\n", name);
106 
107  eventMail->id = cgi->PoolStrDup(name, cp_campaignPool, 0);
108 
109  cgi->Com_ParseBlock(name, text, eventMail, eventMail_vals, cp_campaignPool);
110 }
111 
113 {
114  const campaignEvents_t* events = campaign->events;
115  int i;
116 
117  /* no events for the current campaign */
118  if (!events)
119  return;
120 
121  /* no events in that definition */
122  if (!events->numCampaignEvents)
123  return;
124 
125  for (i = 0; i < events->numCampaignEvents; i++) {
126  const campaignEvent_t* event = &events->campaignEvents[i];
127  if (event->interest <= ccs.overallInterest) {
128  RS_MarkStoryLineEventResearched(event->tech);
129  }
130  }
131 }
132 
139 {
140  for (int i = 0; i < ccs.numCampaignEventDefinitions; i++) {
142  if (Q_streq(events->id, name)) {
143  for (int j = 0; j < events->numCampaignEvents; j++) {
144  const campaignEvent_t* event = &events->campaignEvents[j];
145  if (!RS_GetTechByID(event->tech))
146  Sys_Error("Illegal tech '%s' given in events '%s'", event->tech, events->id);
147  }
148  return events;
149  }
150  }
151 
152  return nullptr;
153 }
154 
155 static int CP_CheckTriggerEvent (const char* expression, const void* userdata)
156 {
157  if (Q_strnull(expression))
158  return -1;
159 
160  const char* type;
161 
162  /* check that a particular installation type is built already */
163  type = Q_strstart(expression, "installation");
164  if (type != nullptr) {
165  if (strlen(type) <= 1)
166  return -1;
167  char value[MAX_VAR];
168  Q_strncpyz(value, type + 1, sizeof(value));
169  value[strlen(value) - 1] = '\0';
170  const installationType_t insType = INS_GetType(value);
171  if (INS_HasType(insType, INSTALLATION_NOT_USED))
172  return 1;
173  return 0;
174  }
175 
176  /* check whether a particular ufo was detected */
177  type = Q_strstart(expression, "ufo");
178  if (type != nullptr) {
179  if (strlen(type) <= 1)
180  return -1;
181  char value[MAX_VAR];
182  Q_strncpyz(value, type + 1, sizeof(value));
183  value[strlen(value) - 1] = '\0';
184  const char* detectedUFO = static_cast<const char*>(userdata);
185  if (Q_strnull(detectedUFO))
186  return -1;
187  return Q_streq(detectedUFO, value);
188  }
189 
190  /* check that the given xvi level is reached in any nation */
191  type = Q_strstart(expression, "xvi");
192  if (type != nullptr) {
193  int xvi;
194  if (sscanf(type, "[%i]", &xvi) != 1)
195  return -1;
196  /* check for XVI infection rate */
197  NAT_Foreach(nation) {
198  const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
199  if (stats->xviInfection >= xvi)
200  return 1;
201  }
202  return 0;
203  }
204 
205  /* check that the given tech is already researched */
206  type = Q_strstart(expression, "researched");
207  if (type != nullptr) {
208  if (strlen(type) <= 1)
209  return -1;
210  char value[MAX_VAR];
211  Q_strncpyz(value, type + 1, sizeof(value));
212  value[strlen(value) - 1] = '\0';
213  technology_t* tech = RS_GetTechByID(value);
214  if (tech == nullptr)
215  return -1;
216  if (RS_IsResearched_ptr(tech))
217  return 1;
218  return 0;
219  }
220 
221  /* check for nation happiness - also see the lost conditions in the campaign */
222  type = Q_strstart(expression, "nationhappiness");
223  if (type != nullptr) {
224  int nationAmount;
225 
226  if (sscanf(type, "[%i]", &nationAmount) != 1)
227  return -1;
228 
229  int nationBelowLimit = 0;
230  NAT_Foreach(nation) {
231  const nationInfo_t* stats = NAT_GetCurrentMonthInfo(nation);
232  if (stats->happiness < ccs.curCampaign->minhappiness) {
233  nationBelowLimit++;
234  if (nationBelowLimit >= nationAmount)
235  return 1;
236  }
237  }
238  return 0;
239  }
240 
241  /* check that the given average xvi level is reached */
242  type = Q_strstart(expression, "averagexvi");
243  if (type != nullptr) {
244  int xvipercent;
245  if (sscanf(type, "[%i]", &xvipercent) != 1)
246  return -1;
247  if (xvipercent < 0 || xvipercent > 100)
248  return -1;
249  const int xvi = CP_GetAverageXVIRate();
250  if (xvi > ccs.curCampaign->maxAllowedXVIRateUntilLost * xvipercent / 100)
251  return 1;
252  return 0;
253  }
254 
255  type = Q_strstart(expression, "difficulty");
256  if (type != nullptr) {
257  int difficulty;
258  if (sscanf(type, "[%i]", &difficulty) != 1)
259  return -1;
260  return ccs.curCampaign->difficulty == difficulty;
261  }
262 
263  /* check that these days have passed in the campaign */
264  type = Q_strstart(expression, "days");
265  if (type != nullptr) {
266  int days;
267  if (sscanf(type, "[%i]", &days) != 1)
268  return -1;
269  date_t d = ccs.curCampaign->date;
270  d.day += days;
271  if (Date_IsDue(&d))
272  return 1;
273  return 0;
274  }
275 
276  type = Q_strstart(expression, "alienscaptured");
277  if (type != nullptr) {
279  return 1;
280  return 0;
281  }
282 
283  type = Q_strstart(expression, "samsitearmed");
284  if (type != nullptr) {
286  return 1;
287 
288  INS_ForeachOfType(installation, INSTALLATION_DEFENCE) {
289  if (installation->installationStatus == INSTALLATION_WORKING) {
290  for (int i = 0; i < installation->installationTemplate->maxBatteries; i++) {
291  const aircraftSlot_t* slot = &installation->batteries[i].slot;
292  if (slot->ammoLeft > 0)
293  return 1;
294  }
295  }
296  }
297 
298  return 0;
299  }
300 
301  cgi->Com_Printf("unknown expression given: '%s'\n", expression);
302 
303  return -1;
304 }
305 
311 void CP_TriggerEvent (campaignTriggerEventType_t type, const void* userdata)
312 {
313  int i;
314 
315  for (i = 0; i < ccs.numCampaignTriggerEvents; i++) {
317  if (event->type != type || (!event->active && event->reactivate == nullptr))
318  continue;
319 
320  if (event->active) {
321  if (!cgi->BEP_Evaluate(event->require, CP_CheckTriggerEvent, userdata))
322  continue;
323  if (Q_strvalid(event->command)) {
325  cgi->Cmd_ExecuteString("%s", event->command);
327  }
328 
329  if (event->once) {
330  event->active = false;
331  }
332  } else {
333  event->active = cgi->BEP_Evaluate(event->reactivate, CP_CheckTriggerEvent, userdata);
334  }
335  }
336 }
337 
339 static const value_t event_vals[] = {
341  {"require", V_HUNK_STRING, offsetof(campaignTriggerEvent_t, require), 0},
342  {"reactivate", V_HUNK_STRING, offsetof(campaignTriggerEvent_t, reactivate), 0},
343  {"command", V_HUNK_STRING, offsetof(campaignTriggerEvent_t, command), 0},
344  {"once", V_BOOL, offsetof(campaignTriggerEvent_t, once), MEMBER_SIZEOF(campaignTriggerEvent_t, once)},
345 
346  {nullptr, V_NULL, 0, 0}
347 };
348 
349 #define EVENTCONSTANTS_NAMESPACE "eventTrigger::"
351  {EVENTCONSTANTS_NAMESPACE "new_day", NEW_DAY},
352  {EVENTCONSTANTS_NAMESPACE "ufo_detection", UFO_DETECTION},
353  {EVENTCONSTANTS_NAMESPACE "captured_aliens_died", CAPTURED_ALIENS_DIED},
354  {EVENTCONSTANTS_NAMESPACE "captured_aliens", CAPTURED_ALIENS},
355  {EVENTCONSTANTS_NAMESPACE "alienbase_discovered", ALIENBASE_DISCOVERED},
356 
357  {nullptr, -1}
358 };
359 
360 void CP_ParseEventTrigger (const char* name, const char** text)
361 {
362  const char* errhead = "CP_ParseEventTrigger: unexpected end of file (event ";
363  const char* token;
364 
366  cgi->Com_Printf("CP_ParseEventTrigger: max event def limit hit\n");
367  return;
368  }
369 
370  token = cgi->Com_EParse(text, errhead, name);
371  if (!*text)
372  return;
373 
374  if (!*text || token[0] != '{') {
375  cgi->Com_Printf("CP_ParseEventTrigger: event def '%s' without body ignored\n", name);
376  return;
377  }
378 
379  cgi->Com_RegisterConstList(eventConstants);
380 
382  OBJZERO(*event);
383  cgi->Com_DPrintf(DEBUG_CLIENT, "...found event %s\n", name);
385  event->active = true;
386  event->id = cgi->PoolStrDup(name, cp_campaignPool, 0);
387 
388  do {
389  token = cgi->Com_EParse(text, errhead, name);
390  if (!*text)
391  break;
392  if (*token == '}')
393  break;
394  if (!cgi->Com_ParseBlockToken(name, text, event, event_vals, cp_campaignPool, token)) {
395  cgi->Com_Printf("CP_ParseEventTrigger: Ignoring unknown event value '%s'\n", token);
396  }
397  } while (*text);
398 
399  cgi->Com_UnregisterConstList(eventConstants);
400 }
401 
403 {
405  int i;
406 
407  for (i = 0; i < ccs.numCampaignTriggerEvents; i++) {
409  if (event->active)
410  continue;
412 
413  cgi->XML_AddString(s, SAVE_TRIGGEREVENTS_NAME, event->id);
414  cgi->XML_AddBool(s, SAVE_TRIGGEREVENTS_STATE, event->active);
415  }
416 
417  return true;
418 }
419 
421 {
422  xmlNode_t* n, *s;
423 
425  if (!n)
426  return true;
427 
429  const char* id = cgi->XML_GetString(s, SAVE_TRIGGEREVENTS_NAME);
430  const bool state = cgi->XML_GetBool(s, SAVE_TRIGGEREVENTS_STATE, true);
431 
432  int i;
433  for (i = 0; i < ccs.numCampaignTriggerEvents; i++) {
435  if (Q_streq(event->id, id)) {
436  event->active = state;
437  break;
438  }
439  }
440  }
441 
442  return true;
443 }
444 
449 void CL_ParseCampaignEvents (const char* name, const char** text)
450 {
451  const char* errhead = "CL_ParseCampaignEvents: unexpected end of file (events ";
452  const char* token;
454 
456  cgi->Com_Printf("CL_ParseCampaignEvents: max events def limit hit\n");
457  return;
458  }
459 
460  token = cgi->Com_EParse(text, errhead, name);
461  if (!*text)
462  return;
463 
464  if (!*text || token[0] != '{') {
465  cgi->Com_Printf("CL_ParseCampaignEvents: events def '%s' without body ignored\n", name);
466  return;
467  }
468 
470  OBJZERO(*events);
471  cgi->Com_DPrintf(DEBUG_CLIENT, "...found events %s\n", name);
472  events->id = cgi->PoolStrDup(name, cp_campaignPool, 0);
474 
475  do {
476  campaignEvent_t* event;
477  token = cgi->Com_EParse(text, errhead, name);
478  if (!*text)
479  break;
480  if (*token == '}')
481  break;
482 
483  if (events->numCampaignEvents >= MAX_CAMPAIGNEVENTS) {
484  cgi->Com_Printf("CL_ParseCampaignEvents: max events per event definition limit hit\n");
485  return;
486  }
487 
488  /* initialize the eventMail */
489  event = &events->campaignEvents[events->numCampaignEvents++];
490  OBJZERO(*event);
491 
492  event->tech = cgi->PoolStrDup(token, cp_campaignPool, 0);
493 
494  token = cgi->Com_EParse(text, errhead, name);
495  if (!*text)
496  return;
497 
498  cgi->Com_EParseValue(event, token, V_INT, offsetof(campaignEvent_t, interest), sizeof(int));
499 
500  if (event->interest < 0)
501  Sys_Error("Illegal interest value in events definition '%s' for tech '%s'", events->id, event->tech);
502  } while (*text);
503 }
504 
508 void CL_EventAddMail (const char* eventMailId)
509 {
510  eventMail_t* eventMail = CL_GetEventMail(eventMailId);
511  if (!eventMail) {
512  cgi->Com_Printf("CL_EventAddMail: Could not find eventmail with id '%s'\n", eventMailId);
513  return;
514  }
515 
516  if (eventMail->sent) {
517  return;
518  }
519 
520  if (!eventMail->from || !eventMail->to || !eventMail->subject || !eventMail->body) {
521  cgi->Com_Printf("CL_EventAddMail: mail with id '%s' has incomplete data\n", eventMailId);
522  return;
523  }
524 
525  if (!eventMail->date) {
526  dateLong_t date;
527  char dateBuf[MAX_VAR] = "";
528 
529  CP_DateConvertLong(&ccs.date, &date);
530  Com_sprintf(dateBuf, sizeof(dateBuf), _("%i %s %02i"),
531  date.year, Date_GetMonthName(date.month - 1), date.day);
532  eventMail->date = cgi->PoolStrDup(dateBuf, cp_campaignPool, 0);
533  }
534 
535  eventMail->sent = true;
536 
537  if (!eventMail->skipMessage) {
538  uiMessageListNodeMessage_t* m = MS_AddNewMessage("", va(_("You've got a new mail: %s"), _(eventMail->subject)), MSG_EVENT);
539  if (m)
540  m->eventMail = eventMail;
541  else
542  cgi->Com_Printf("CL_EventAddMail: Could not add message with id: %s\n", eventMailId);
543  }
544 
545  UP_OpenEventMail(eventMailId);
546 }
547 
554 void CL_EventAddMail_f (void)
555 {
556  if (cgi->Cmd_Argc() < 2) {
557  cgi->Com_Printf("Usage: %s <event_mail_id>\n", cgi->Cmd_Argv(0));
558  return;
559  }
560 
562 }
list of script aliases to register
Definition: scripts.h:232
bool Q_strnull(const char *string)
Definition: shared.h:138
int capturedAliens
Definition: cp_statistics.h:39
int numCampaignEventDefinitions
Definition: cp_campaign.h:331
int CP_GetAverageXVIRate(void)
Return the average XVI rate.
Definition: cp_xvi.cpp:163
const nationInfo_t * NAT_GetCurrentMonthInfo(const nation_t *const nation)
Get the current month nation stats.
Definition: cp_nation.cpp:132
installationType_t INS_GetType(const char *type)
XML tag constants for savegame.
bool Date_IsDue(const date_t *date)
Checks whether a given date is equal or earlier than the current campaign date.
Definition: cp_time.cpp:255
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
int numCampaignTriggerEvents
Definition: cp_campaign.h:334
#define MAX_CAMPAIGNS
Definition: cp_campaign.h:31
bool RS_IsResearched_ptr(const technology_t *tech)
Checks whether an item is already researched.
QGL_EXTERN GLint GLenum type
Definition: r_gl.h:94
char * id
Definition: cp_event.h:39
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
Definition: shared.cpp:410
#define SAVE_TRIGGEREVENTS_TRIGGEREVENT
char * subject
Definition: cp_event.h:43
void UP_OpenEventMail(const char *eventMailID)
void CL_EventAddMail(const char *eventMailId)
Adds the event mail to the message stack. This message is going to be added to the savegame...
Definition: cp_event.cpp:508
bool INS_HasType(installationType_t type, installationStatus_t status)
Checks whether the given installation type is available.
#define _(String)
Definition: cl_shared.h:43
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
int xviInfection
Definition: cp_nation.h:38
#define EVENTCONSTANTS_NAMESPACE
Definition: cp_event.cpp:349
int day
Definition: common.h:291
date_t date
Definition: cp_campaign.h:245
#define SAVE_TRIGGEREVENTS_NAME
#define INS_ForeachOfType(var, installationType)
byte day
Definition: cp_time.h:37
char * to
Definition: cp_event.h:41
char * date
Definition: cp_event.h:46
#define MAX_CAMPAIGNEVENTS
Definition: cp_event.h:29
bool CP_TriggerEventSaveXML(xmlNode_t *p)
Definition: cp_event.cpp:402
uiMessageListNodeMessage_t * MS_AddNewMessage(const char *title, const char *text, messageType_t type, technology_t *pedia, bool popup, bool playSound)
Adds a new message to message stack.
Definition: cp_messages.cpp:61
memPool_t * cp_campaignPool
Definition: cp_campaign.cpp:61
float happiness
Definition: cp_nation.h:37
Defines campaign events when story related technologies should be researched.
Definition: cp_event.h:64
const char * Date_GetMonthName(int month)
Returns the short monthame to the given month index.
Definition: cp_time.cpp:317
#define Q_strvalid(string)
Definition: shared.h:141
#define xmlNode_t
Definition: xml.h:24
void CL_ParseCampaignEvents(const char *name, const char **text)
Definition: cp_event.cpp:449
void CP_CampaignTriggerFunctions(bool add)
Add/Remove temporary mission trigger functions.
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
static const constListEntry_t eventConstants[]
Definition: cp_event.cpp:350
Campaign XVI header.
installationType_t
#define DEBUG_CLIENT
Definition: defines.h:59
#define NAT_Foreach(var)
iterates trough nations
Definition: cp_nation.h:80
bool RS_MarkStoryLineEventResearched(const char *techID)
#define OBJZERO(obj)
Definition: shared.h:178
void CP_ParseEventTrigger(const char *name, const char **text)
Definition: cp_event.cpp:360
#define MAX_VAR
Definition: shared.h:36
static int CP_CheckTriggerEvent(const char *expression, const void *userdata)
Definition: cp_event.cpp:155
char * tech
Definition: cp_event.h:65
#define SAVE_TRIGGEREVENTS_TRIGGEREVENTS
int numCampaignEvents
Definition: cp_event.h:71
void CL_EventAddMail_f(void)
Definition: cp_event.cpp:554
const cgame_import_t * cgi
short year
Definition: cp_time.h:35
This is the technology parsed from research.ufo.
Definition: cp_research.h:137
char const * Q_strstart(char const *str, char const *start)
Matches the start of a string.
Definition: shared.cpp:587
ccs_t ccs
Definition: cp_campaign.cpp:62
stats_t campaignStats
Definition: cp_campaign.h:378
int maxAllowedXVIRateUntilLost
Definition: cp_campaign.h:188
Engine-side time information in the game.
Definition: common.h:290
campaignEvent_t campaignEvents[MAX_CAMPAIGNEVENTS]
Definition: cp_event.h:70
byte month
Definition: cp_time.h:36
void CP_TriggerEvent(campaignTriggerEventType_t type, const void *userdata)
Triggers a campaign event with a special type.
Definition: cp_event.cpp:311
const campaignEvents_t * CP_GetEventsByID(const char *name)
Definition: cp_event.cpp:138
Campaign geoscape time header.
static const value_t event_vals[]
Valid event mail parameters.
Definition: cp_event.cpp:339
technology_t * RS_GetTechByID(const char *id)
return a pointer to the technology identified by given id string
struct eventMail_s * eventMail
Definition: cp_messages.h:68
slot of aircraft
Definition: cp_aircraft.h:77
void CP_FreeDynamicEventMail(void)
Make sure, that the linked list is freed with every new game.
Definition: cp_event.cpp:66
date_t date
Definition: cp_campaign.h:190
available mails for a tech - mail and mail_pre in script files
Definition: cp_event.h:38
campaignEvents_t campaignEvents[MAX_CAMPAIGNS]
Definition: cp_campaign.h:330
eventMail_t eventMails[MAX_EVENTMAILS]
Definition: cp_campaign.h:327
#define MAX_EVENTMAILS
Definition: cp_event.h:28
Definition: scripts.h:49
const eventRegister_t events[]
List of functions to register nodes.
Definition: e_main.cpp:92
Human readable time information in the game.
Definition: cp_time.h:34
char * body
Definition: cp_event.h:47
QGL_EXTERN GLint i
Definition: r_gl.h:113
void CP_CheckCampaignEvents(campaign_t *campaign)
Definition: cp_event.cpp:112
Definition: scripts.h:50
signed int difficulty
Definition: cp_campaign.h:185
#define MAX_CAMPAIGN_TRIGGER_EVENTS
Definition: cp_event.h:96
xmlNode_t *IMPORT * XML_GetNextNode(xmlNode_t *current, xmlNode_t *parent, const char *name)
int overallInterest
Definition: cp_campaign.h:238
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
campaignTriggerEvent_t campaignTriggerEvents[MAX_CAMPAIGN_TRIGGER_EVENTS]
Definition: cp_campaign.h:333
void CP_DateConvertLong(const date_t *date, dateLong_t *dateLong)
Converts a date from the engine in a (longer) human-readable format.
Definition: cp_time.cpp:72
char * from
Definition: cp_event.h:40
#define MEMBER_SIZEOF(TYPE, MEMBER)
Definition: scripts.h:34
#define LIST_Foreach(list, type, var)
Iterates over a linked list, it's safe to delete the returned entry from the list while looping over ...
Definition: list.h:41
static linkedList_t * eventMails
Definition: cp_event.cpp:35
Header file for single player campaign control.
Definition: scripts.h:52
xmlNode_t *IMPORT * XML_AddNode(xmlNode_t *parent, const char *name)
#define SAVE_TRIGGEREVENTS_STATE
const char *IMPORT * Com_EParse(const char **text, const char *errhead, const char *errinfo)
int numEventMails
Definition: cp_campaign.h:328
#define Q_streq(a, b)
Definition: shared.h:136
char *IMPORT * PoolStrDup(const char *in, memPool_t *pool, const int tagNum)
bool skipMessage
Definition: cp_event.h:52
const campaignEvents_t * events
Definition: cp_campaign.h:194
eventMail_t * CL_GetEventMail(const char *id)
Searches all event mails for a given id.
Definition: cp_event.cpp:44
bool CP_TriggerEventLoadXML(xmlNode_t *p)
Definition: cp_event.cpp:420
campaign_t * curCampaign
Definition: cp_campaign.h:377
campaignTriggerEventType_t
events that are triggered by the campaign
Definition: cp_event.h:78
void CL_ParseEventMails(const char *name, const char **text)
Definition: cp_event.cpp:92
float minhappiness
Definition: cp_campaign.h:186
static struct mdfour * m
Definition: md4.cpp:35
const char *IMPORT * Cmd_Argv(int n)
static const value_t eventMail_vals[]
Valid event mail parameters.
Definition: cp_event.cpp:74
const char *IMPORT * XML_GetString(xmlNode_t *parent, const char *name)
xmlNode_t *IMPORT * XML_GetNode(xmlNode_t *parent, const char *name)
Detailed information about the nation relationship (currently per month, but could be used elsewhere)...
Definition: cp_nation.h:33
bool sent
Definition: cp_event.h:51