naev 0.10.4
event.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
14#include "nstring.h"
15#include <stdint.h>
16#include <stdlib.h>
17
18#include "naev.h"
21#include "event.h"
22
23#include "conf.h"
24#include "array.h"
25#include "cond.h"
26#include "hook.h"
27#include "log.h"
28#include "land.h"
29#include "ndata.h"
30#include "nlua.h"
31#include "nlua_audio.h"
32#include "nlua_bkg.h"
33#include "nlua_camera.h"
34#include "nlua_evt.h"
35#include "nlua_hook.h"
36#include "nlua_music.h"
37#include "nlua_tex.h"
38#include "nlua_tk.h"
39#include "nluadef.h"
40#include "npc.h"
41#include "nxml.h"
42#include "nxml_lua.h"
43#include "player.h"
44#include "rng.h"
45
46#define XML_EVENT_ID "Events"
47#define XML_EVENT_TAG "event"
49#define EVENT_FLAG_UNIQUE (1<<0)
54typedef struct EventData_ {
55 char *name;
56 char *sourcefile;
57 char *lua;
58 unsigned int flags;
60 /* For specific cases. */
61 char *spob;
62 char *system;
63 char *chapter;
64 int *factions;
65 pcre2_code *chapter_re;
67 EventTrigger_t trigger;
68 char *cond;
69 double chance;
71} EventData;
72
73/*
74 * Event data.
75 */
76static EventData *event_data = NULL;
78/*
79 * Active events.
80 */
81static unsigned int event_genid = 0;
82static Event_t *event_active = NULL;
84/*
85 * Prototypes.
86 */
87static unsigned int event_genID (void);
88static int event_cmp( const void* a, const void* b );
89static int event_parseFile( const char* file, EventData *temp );
90static int event_parseXML( EventData *temp, const xmlNodePtr parent );
91static void event_freeData( EventData *event );
92static int event_create( int dataid, unsigned int *id );
93int events_saveActive( xmlTextWriterPtr writer );
94int events_loadActive( xmlNodePtr parent );
95static int events_parseActive( xmlNodePtr parent );
96
100Event_t *event_get( unsigned int eventid )
101{
102 /* Iterate. */
103 for (int i=0; i<array_size(event_active); i++) {
104 Event_t *ev = &event_active[i];
105 if (ev->id == eventid)
106 return ev;
107 }
108
109 return NULL;
110}
111
119int event_start( const char *name, unsigned int *id )
120{
121 int ret, edat;
122 unsigned int eid;
123
124 edat = event_dataID( name );
125 if (edat < 0)
126 return -1;
127 eid = 0;
128 ret = event_create( edat, &eid );
129
130 if ((ret == 0) && (id != NULL))
131 *id = eid;
132 return ret;
133}
134
141const char *event_getData( unsigned int eventid )
142{
143 Event_t *ev = event_get( eventid );
144 if (ev == NULL)
145 return NULL;
146
147 return event_data[ ev->data ].name;
148}
149
156int event_isUnique( unsigned int eventid )
157{
158 Event_t *ev = event_get( eventid );
159 if (ev == NULL)
160 return -1;
161
162 return !!(event_data[ ev->data ].flags & EVENT_FLAG_UNIQUE);
163}
164
168static unsigned int event_genID (void)
169{
170 unsigned int id;
171 do {
172 id = ++event_genid; /* Create unique ID. */
173 } while (event_get(id) != NULL);
174 return id;
175}
176
184static int event_create( int dataid, unsigned int *id )
185{
186 Event_t *ev;
187 EventData *data;
188
189 if (event_active==NULL)
191
192 /* Create the event. */
193 ev = &array_grow( &event_active );
194 memset( ev, 0, sizeof(Event_t) );
195 if ((id != NULL) && (*id != 0))
196 ev->id = *id;
197 else
198 ev->id = event_genID();
199
200 /* Add the data. */
201 ev->data = dataid;
202 data = &event_data[dataid];
203
204 /* Open the new state. */
205 ev->env = nlua_newEnv();
207 nlua_loadEvt(ev->env);
208 nlua_loadHook(ev->env);
209 nlua_loadCamera(ev->env);
210 nlua_loadTex(ev->env);
212 nlua_loadMusic(ev->env);
213 nlua_loadTk(ev->env);
214
215 /* Create the "mem" table for persistence. */
216 lua_newtable(naevL);
217 nlua_setenv(naevL, ev->env, "mem");
218
219 /* Load file. */
220 if (nlua_dobufenv(ev->env, data->lua, strlen(data->lua), data->sourcefile) != 0) {
221 WARN(_("Error loading event file: %s\n"
222 "%s\n"
223 "Most likely Lua file has improper syntax, please check"),
224 data->sourcefile, lua_tostring(naevL,-1));
225 return -1;
226 }
227
228 /* Run Lua. */
229 if ((id==NULL) || (*id==0))
230 event_run( ev->id, "create" );
231 if (id != NULL)
232 *id = ev->id;
233
234 return 0;
235}
236
242static void event_cleanup( Event_t *ev )
243{
244 /* Free lua env. */
245 nlua_freeEnv(ev->env);
246
247 /* Free hooks. */
249
250 /* Free NPC. */
252
253 /* Free claims. */
254 if (ev->claims != NULL)
255 claim_destroy( ev->claims );
256}
257
263void event_remove( unsigned int eventid )
264{
265 /* Find the event. */
266 for (int i=0; i<array_size(event_active); i++) {
267 Event_t *ev = &event_active[i];
268 if (ev->id == eventid) {
269 /* Clean up event. */
270 event_cleanup(ev);
271
272 /* Move memory. */
274 return;
275 }
276 }
277
278 WARN(_("Event ID '%u' not valid."), eventid);
279}
280
284int event_save( unsigned int eventid )
285{
286 Event_t *ev = event_get(eventid);
287 if (ev == NULL)
288 return 0;
289 return ev->save;
290}
291
297int event_alreadyRunning( int data )
298{
299 /* Find events. */
300 for (int i=0; i<array_size(event_active); i++) {
301 Event_t *ev = &event_active[i];
302 if (ev->data == data)
303 return 1;
304 }
305
306 return 0;
307}
308
314void events_trigger( EventTrigger_t trigger )
315{
316 int created = 0;
317 for (int i=0; i<array_size(event_data); i++) {
318 EventData *ed = &event_data[i];
319
320 if (naev_isQuit())
321 return;
322
323 /* Make sure trigger matches. */
324 if (ed->trigger != trigger)
325 continue;
326
327 /* Spob. */
328 if ((trigger==EVENT_TRIGGER_LAND || trigger==EVENT_TRIGGER_LOAD) && (ed->spob != NULL) && (strcmp(ed->spob,land_spob->name)!=0))
329 continue;
330
331 /* System. */
332 if ((ed->system != NULL) && (strcmp(ed->system,cur_system->name)!=0))
333 continue;
334
335 /* Make sure chance is succeeded. */
336 if (RNGF() > ed->chance)
337 continue;
338
339 /* Test uniqueness. */
340 if ((ed->flags & EVENT_FLAG_UNIQUE) &&
342 continue;
343
344 /* Test factions. */
345 if (ed->factions != NULL) {
346 int fct, match = 0;
347 if (trigger==EVENT_TRIGGER_ENTER)
348 fct = cur_system->faction;
349 else if (trigger==EVENT_TRIGGER_LOAD || trigger==EVENT_TRIGGER_LAND)
351 else
352 match = -1; /* Don't hae to check factions. */
353
354 if (match==0) {
355 for (int j=0; j<array_size(ed->factions); j++) {
356 if (fct == ed->factions[j]) {
357 match = 1;
358 break;
359 }
360 }
361 if (!match)
362 continue;
363 }
364 }
365
366 /* If chapter, must match chapter regex. */
367 if (ed->chapter_re != NULL) {
368 pcre2_match_data *match_data = pcre2_match_data_create_from_pattern( ed->chapter_re, NULL );
369 int rc = pcre2_match( ed->chapter_re, (PCRE2_SPTR)player.chapter, strlen(player.chapter), 0, 0, match_data, NULL );
370 pcre2_match_data_free( match_data );
371 if (rc < 0) {
372 switch (rc) {
373 case PCRE2_ERROR_NOMATCH:
374 continue;
375 default:
376 WARN(_("Matching error %d"), rc );
377 break;
378 }
379 continue;
380 }
381 else if (rc == 0)
382 continue;
383 }
384
385 /* Test conditional. */
386 if (ed->cond != NULL) {
387 int c = cond_check(ed->cond);
388 if (c<0) {
389 WARN(_("Conditional for event '%s' failed to run."), ed->name);
390 continue;
391 }
392 else if (!c)
393 continue;
394 }
395
396 /* Create the event. */
397 event_create( i, NULL );
398 created++;
399 }
400
401 /* Run claims if necessary. */
402 if (created)
404}
405
413static int event_parseXML( EventData *temp, const xmlNodePtr parent )
414{
415 xmlNodePtr node;
416
417 memset( temp, 0, sizeof(EventData) );
418
419 /* Defaults. */
420 temp->trigger = EVENT_TRIGGER_NULL;
421
422 /* get the name */
423 xmlr_attr_strd(parent, "name", temp->name);
424 if (temp->name == NULL)
425 WARN(_("Event in %s has invalid or no name"), EVENT_DATA_PATH);
426
427 node = parent->xmlChildrenNode;
428 do { /* load all the data */
429 /* Only check nodes. */
430 xml_onlyNodes(node);
431
432 xmlr_strd(node,"spob",temp->spob);
433 xmlr_strd(node,"system",temp->system);
434 xmlr_strd(node,"chapter",temp->chapter);
435
436 xmlr_strd(node,"cond",temp->cond);
437 xmlr_float(node,"chance",temp->chance);
438 xmlr_int(node,"priority",temp->priority);
439
440 if (xml_isNode(node,"faction")) {
441 if (temp->factions == NULL)
442 temp->factions = array_create( int );
443 array_push_back( &temp->factions, faction_get( xml_get(node) ) );
444 continue;
445 }
446
447 /* Trigger. */
448 if (xml_isNode(node,"location")) {
449 char *buf = xml_get(node);
450 if (buf == NULL)
451 WARN(_("Event '%s': Null trigger type."), temp->name);
452 else if (strcmp(buf,"enter")==0)
453 temp->trigger = EVENT_TRIGGER_ENTER;
454 else if (strcmp(buf,"land")==0)
455 temp->trigger = EVENT_TRIGGER_LAND;
456 else if (strcmp(buf,"load")==0)
457 temp->trigger = EVENT_TRIGGER_LOAD;
458 else if (strcmp(buf,"none")==0)
459 temp->trigger = EVENT_TRIGGER_NONE;
460 else
461 WARN(_("Event '%s' has invalid 'trigger' parameter: %s"), temp->name, buf);
462
463 continue;
464 }
465
466 /* Flags. */
467 else if (xml_isNode(node,"unique")) { /* unique event. */
468 temp->flags |= EVENT_FLAG_UNIQUE;
469 continue;
470 }
471
472 /* Notes for the python mission mapping script. */
473 else if (xml_isNode(node,"notes"))
474 continue;
475
476 WARN(_("Unknown node '%s' in event '%s'"), node->name, temp->name);
477 } while (xml_nextNode(node));
478
479 /* Process. */
480 temp->chance /= 100.;
481
482 if (temp->chapter != NULL) {
483 int errornumber;
484 PCRE2_SIZE erroroffset;
485 temp->chapter_re = pcre2_compile( (PCRE2_SPTR)temp->chapter, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL );
486 if (temp->chapter_re == NULL){
487 PCRE2_UCHAR buffer[256];
488 pcre2_get_error_message( errornumber, buffer, sizeof(buffer) );
489 WARN(_("Mission '%s' chapter PCRE2 compilation failed at offset %d: %s"), temp->name, (int)erroroffset, buffer );
490 }
491 }
492
493#define MELEMENT(o,s) \
494 if (o) WARN(_("Event '%s' missing/invalid '%s' element"), temp->name, s)
495 MELEMENT(temp->trigger==EVENT_TRIGGER_NULL,"location");
496 MELEMENT((temp->trigger!=EVENT_TRIGGER_NONE) && (temp->chance==0.),"chance");
497#undef MELEMENT
498
499 return 0;
500}
501
502static int event_cmp( const void* a, const void* b )
503{
504 const EventData *ea, *eb;
505 ea = (const EventData*) a;
506 eb = (const EventData*) b;
507 if (ea->priority < eb->priority)
508 return -1;
509 else if (ea->priority > eb->priority)
510 return +1;
511 return strcmp( ea->name, eb->name );
512}
513
519int events_load (void)
520{
521 char **event_files = ndata_listRecursive( EVENT_DATA_PATH );
522 Uint32 time = SDL_GetTicks();
523
524 /* Run over events. */
526 for (int i=0; i < array_size( event_files ); i++) {
527 event_parseFile( event_files[i], NULL );
528 free( event_files[ i ] );
529 }
530 array_free( event_files );
532
533#ifdef DEBUGGING
534 for (int i=0; i<array_size(event_data); i++) {
535 EventData *ed = &event_data[i];
536 for (int j=i+1; j<array_size(event_data); j++)
537 if (strcmp( ed->name, event_data[j].name )==0)
538 WARN(_("Duplicate event '%s'!"), ed->name);
539 }
540#endif /* DEBUGGING */
541
542 /* Sort based on priority so higher priority missions can establish claims first. */
543 qsort( event_data, array_size(event_data), sizeof(EventData), event_cmp );
544
545 if (conf.devmode) {
546 time = SDL_GetTicks() - time;
547 DEBUG( n_("Loaded %d Event in %.3f s", "Loaded %d Events in %.3f s", array_size(event_data) ), array_size(event_data), time/1000. );
548 }
549 else
550 DEBUG( n_("Loaded %d Event", "Loaded %d Events", array_size(event_data) ), array_size(event_data) );
551
552 return 0;
553}
554
561static int event_parseFile( const char* file, EventData *temp )
562{
563 size_t bufsize;
564 xmlNodePtr node;
565 xmlDocPtr doc;
566 char *filebuf;
567 const char *pos, *start_pos;
568
569#ifdef DEBUGGING
570 /* To check if event is valid. */
571 int ret;
572#endif /* DEBUGGING */
573
574 /* Load string. */
575 filebuf = ndata_read( file, &bufsize );
576 if (filebuf == NULL) {
577 WARN(_("Unable to read data from '%s'"), file);
578 return -1;
579 }
580 if (bufsize == 0) {
581 free( filebuf );
582 return -1;
583 }
584
585 /* Skip if no XML. */
586 pos = strnstr( filebuf, "</event>", bufsize );
587 if (pos==NULL) {
588 pos = strnstr( filebuf, "function create", bufsize );
589 if ((pos != NULL) && !strncmp(pos,"--common",bufsize))
590 WARN(_("Event '%s' has create function but no XML header!"), file);
591 free(filebuf);
592 return 0;
593 }
594
595 /* Separate XML header and Lua. */
596 start_pos = strnstr( filebuf, "<?xml ", bufsize );
597 pos = strnstr( filebuf, "--]]", bufsize );
598 if (pos == NULL || start_pos == NULL) {
599 WARN(_("Event file '%s' has missing XML header!"), file);
600 return -1;
601 }
602
603 /* Parse the header. */
604 doc = xmlParseMemory( start_pos, pos-start_pos );
605 if (doc == NULL) {
606 WARN(_("Unable to parse document XML header for Event '%s'"), file);
607 return -1;
608 }
609
610 /* Get the root node. */
611 node = doc->xmlChildrenNode;
612 if (!xml_isNode(node,XML_EVENT_TAG)) {
613 WARN(_("Malformed '%s' file: missing root element '%s'"), file, XML_EVENT_TAG);
614 return -1;
615 }
616
617 if (temp == NULL)
618 temp = &array_grow(&event_data);
619 event_parseXML( temp, node );
620 temp->lua = strdup(filebuf);
621 temp->sourcefile = strdup(file);
622
623#ifdef DEBUGGING
624 /* Check to see if syntax is valid. */
625 ret = luaL_loadbuffer(naevL, temp->lua, strlen(temp->lua), temp->name );
626 if (ret == LUA_ERRSYNTAX) {
627 WARN(_("Event Lua '%s' syntax error: %s"),
628 file, lua_tostring(naevL,-1) );
629 } else {
630 lua_pop(naevL, 1);
631 }
632#endif /* DEBUGGING */
633
634 /* Clean up. */
635 xmlFreeDoc(doc);
636 free(filebuf);
637
638 return 0;
639}
640
646static void event_freeData( EventData *event )
647{
648 free( event->name );
649 free( event->sourcefile );
650 free( event->lua );
651
652 free( event->spob );
653 free( event->system );
654 free( event->chapter );
655 pcre2_code_free( event->chapter_re );
656
657 free( event->cond );
658#if DEBUGGING
659 memset( event, 0, sizeof(EventData) );
660#endif /* DEBUGGING */
661}
662
666void events_cleanup (void)
667{
668 /* Free active events. */
669 for (int i=0; i<array_size(event_active); i++)
672 event_active = NULL;
673}
674
678void events_exit (void)
679{
681
682 /* Free data. */
683 for (int i=0; i<array_size(event_data); i++)
686 event_data = NULL;
687}
688
695int event_dataID( const char *evdata )
696{
697 for (int i=0; i<array_size(event_data); i++)
698 if (strcmp(event_data[i].name, evdata)==0)
699 return i;
700 WARN(_("No event data found matching name '%s'."), evdata);
701 return -1;
702}
703
710const char *event_dataName( int dataid )
711{
712 return event_data[dataid].name;
713}
714
719{
720 /* Free active events. */
721 for (int i=0; i<array_size(event_active); i++)
722 if (event_active[i].claims != NULL)
723 claim_activate( event_active[i].claims );
724}
725
729int event_testClaims( unsigned int eventid, int sys )
730{
731 Event_t *ev = event_get( eventid );
732 if (ev==NULL) {
733 WARN(_("Trying to test claims of unknown event with id '%d'!"), eventid);
734 return 0;
735 }
736 return claim_testSys( ev->claims, sys );
737}
738
743{
744 /* Iterate. */
745 for (int i=0; i<array_size(event_active); i++) {
746 Event_t *ev = &event_active[i];
747
748 /* Check if has children. */
749 if (hook_hasEventParent( ev->id ) > 0)
750 continue;
751
752 /* Must delete. */
753 WARN(_("Detected event '%s' without any hooks and is therefore invalid. Removing event."),
754 event_dataName( ev->data ));
755 event_remove( ev->id );
756 i--; /* Keep iteration safe. */
757 }
758}
759
766int events_saveActive( xmlTextWriterPtr writer )
767{
768 xmlw_startElem(writer,"events");
769
770 for (int i=0; i<array_size(event_active); i++) {
771 Event_t *ev = &event_active[i];
772 if (!ev->save) /* Only save events that want to be saved. */
773 continue;
774
775 xmlw_startElem(writer,"event");
776
777 xmlw_attr(writer,"name","%s",event_dataName(ev->data));
778 xmlw_attr(writer,"id","%u",ev->id);
779
780 /* Claims. */
781 xmlw_startElem(writer,"claims");
782 claim_xmlSave( writer, ev->claims );
783 xmlw_endElem(writer); /* "claims" */
784
785 /* Write Lua magic */
786 xmlw_startElem(writer,"lua");
787 nxml_persistLua( ev->env, writer );
788 xmlw_endElem(writer); /* "lua" */
789
790 xmlw_endElem(writer); /* "event" */
791 }
792
793 xmlw_endElem(writer); /* "events" */
794
795 return 0;
796}
797
804int events_loadActive( xmlNodePtr parent )
805{
806 xmlNodePtr node = parent->xmlChildrenNode;
807
808 /* cleanup old events */
810
811 do {
812 if (xml_isNode(node,"events"))
813 if (events_parseActive( node ) < 0) return -1;
814 } while (xml_nextNode(node));
815
816 return 0;
817}
818
825static int events_parseActive( xmlNodePtr parent )
826{
827 xmlNodePtr node = parent->xmlChildrenNode;
828 do {
829 char *buf;
830 unsigned int id;
831 int data;
832 xmlNodePtr cur;
833 Event_t *ev;
834
835 if (!xml_isNode(node,"event"))
836 continue;
837
838 xmlr_attr_strd(node,"name",buf);
839 if (buf==NULL) {
840 WARN(_("Event has missing 'name' attribute, skipping."));
841 continue;
842 }
843 data = event_dataID( buf );
844 if (data < 0) {
845 WARN(_("Event in save has name '%s' but event data not found matching name. Skipping."), buf);
846 free(buf);
847 continue;
848 }
849 free(buf);
850 xmlr_attr_uint(node,"id",id);
851 if (id==0) {
852 WARN(_("Event with data '%s' has invalid 'id' attribute, skipping."), event_dataName(data));
853 continue;
854 }
855
856 /* Create the event. */
857 event_create( data, &id );
858 ev = event_get( id );
859 if (ev == NULL) {
860 WARN(_("Event with data '%s' was not created, skipping."), event_dataName(data));
861 continue;
862 }
863 ev->save = 1; /* Should save by default again. */
864
865 /* Get the data. */
866 cur = node->xmlChildrenNode;
867 do {
868 if (xml_isNode(cur,"lua"))
869 nxml_unpersistLua( ev->env, cur );
870 } while (xml_nextNode(cur));
871
872 /* Claims. */
873 if (xml_isNode(node,"claims"))
874 ev->claims = claim_xmlLoad( node );
875 } while (xml_nextNode(node));
876
877 return 0;
878}
879
880int event_reload( const char *name )
881{
882 int res, edat = event_dataID( name );
883 EventData save, *temp = edat<0 ? NULL : &event_data[edat];
884 if (temp == NULL)
885 return -1;
886 save = *temp;
887 res = event_parseFile( save.sourcefile, temp );
888 if (res == 0)
889 event_freeData( &save );
890 else
891 *temp = save;
892 return res;
893}
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
Definition: array.h:158
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
Definition: array.h:102
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
Definition: array.h:140
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
Definition: array.h:119
#define array_shrink(ptr_array)
Shrinks memory to fit only ‘size’ elements.
Definition: array.h:149
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
Definition: array.h:129
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
Definition: array.h:93
void claim_destroy(Claim_t *claim)
Destroys a system claim.
Definition: claim.c:189
void claim_activate(Claim_t *claim)
Activates a claim on a system.
Definition: claim.c:251
int claim_testSys(const Claim_t *claim, int sys)
Tests to see if a system is claimed by a system claim.
Definition: claim.c:170
Claim_t * claim_xmlLoad(xmlNodePtr parent)
Loads a claim.
Definition: claim.c:305
int claim_xmlSave(xmlTextWriterPtr writer, const Claim_t *claim)
Saves all the systems in a claim in XML.
Definition: claim.c:278
void claim_activateAll(void)
Activates all the claims.
Definition: claim.c:239
int cond_check(const char *cond)
Checks to see if a condition is true.
Definition: cond.c:53
static unsigned int event_genid
Definition: event.c:81
int event_start(const char *name, unsigned int *id)
Starts an event.
Definition: event.c:119
const char * event_dataName(int dataid)
Gets the event data name from id.
Definition: event.c:710
void events_exit(void)
Exits the event subsystem.
Definition: event.c:678
int event_alreadyRunning(int data)
Check to see if an event is already running.
Definition: event.c:297
static int event_parseFile(const char *file, EventData *temp)
Parses an event file.
Definition: event.c:561
const char * event_getData(unsigned int eventid)
Gets the name of the event data.
Definition: event.c:141
int events_loadActive(xmlNodePtr parent)
Loads the player's active events from a save.
Definition: event.c:804
void event_remove(unsigned int eventid)
Removes an event by ID.
Definition: event.c:263
Event_t * event_get(unsigned int eventid)
Gets an event.
Definition: event.c:100
static Event_t * event_active
Definition: event.c:82
void events_cleanup(void)
Cleans up and removes active events.
Definition: event.c:666
int event_dataID(const char *evdata)
Gets the event data id from name.
Definition: event.c:695
static void event_cleanup(Event_t *ev)
Cleans up an event.
Definition: event.c:242
static void event_freeData(EventData *event)
Frees an EventData structure.
Definition: event.c:646
int event_save(unsigned int eventid)
Checks to see if an event should be saved.
Definition: event.c:284
static int events_parseActive(xmlNodePtr parent)
Parses the actual individual event nodes.
Definition: event.c:825
#define XML_EVENT_TAG
Definition: event.c:47
int event_isUnique(unsigned int eventid)
Checks to see if an event is unique.
Definition: event.c:156
int events_load(void)
Loads all the events.
Definition: event.c:519
void event_activateClaims(void)
Activates all the active event claims.
Definition: event.c:718
void event_checkValidity(void)
Checks the event validity and cleans up after them.
Definition: event.c:742
void events_trigger(EventTrigger_t trigger)
Runs all the events matching a trigger.
Definition: event.c:314
int events_saveActive(xmlTextWriterPtr writer)
Saves the player's active events.
Definition: event.c:766
static int event_parseXML(EventData *temp, const xmlNodePtr parent)
Loads up an event from an XML node.
Definition: event.c:413
static unsigned int event_genID(void)
Generates a new event ID.
Definition: event.c:168
int event_testClaims(unsigned int eventid, int sys)
Tests to see if an event has claimed a system.
Definition: event.c:729
static EventData * event_data
Definition: event.c:76
#define EVENT_FLAG_UNIQUE
Definition: event.c:49
static int event_create(int dataid, unsigned int *id)
Creates an event.
Definition: event.c:184
int faction_get(const char *name)
Gets a faction ID by name.
Definition: faction.c:182
int hook_hasEventParent(unsigned int parent)
Checks to see how many hooks there are with the same event parent.
Definition: hook.c:850
void hook_rmEventParent(unsigned int parent)
Removes all hooks belonging to parent event.
Definition: hook.c:821
Spob * land_spob
Definition: land.c:82
int naev_isQuit(void)
Get if Naev is trying to quit.
Definition: naev.c:155
Header file with generic functions and naev-specifics.
void * ndata_read(const char *path, size_t *filesize)
Reads a file from the ndata (will be NUL terminated).
Definition: ndata.c:154
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
Definition: ndata.c:232
static char buf[NEWS_MAX_LENGTH]
Definition: news.c:45
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
Definition: nlua.c:760
int nlua_loadBackground(nlua_env env)
Loads the graphics library.
Definition: nlua_bkg.c:38
int nlua_loadCamera(nlua_env env)
Loads the camera library.
Definition: nlua_camera.c:47
int event_run(unsigned int eventid, const char *func)
Runs the event function.
Definition: nlua_evt.c:101
int nlua_loadEvt(nlua_env env)
Loads the event Lua library.
Definition: nlua_evt.c:69
int nlua_loadHook(nlua_env env)
Loads the hook Lua library.
Definition: nlua_hook.c:121
int nlua_loadMusic(nlua_env env)
Music Lua module.
Definition: nlua_music.c:58
int nlua_loadTex(nlua_env env)
Loads the texture library.
Definition: nlua_tex.c:62
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
Definition: nlua_tk.c:90
int npc_rm_parentEvent(unsigned int id)
Removes all the npc belonging to an event.
Definition: npc.c:277
char * strnstr(const char *haystack, const char *needle, size_t size)
A bounded version of strstr. Conforms to BSD semantics.
Definition: nstring.c:26
int nxml_persistLua(nlua_env env, xmlTextWriterPtr writer)
Persists all the nxml Lua data.
Definition: nxml_lua.c:368
int nxml_unpersistLua(nlua_env env, xmlNodePtr parent)
Unpersists Lua data into a table named "mem".
Definition: nxml_lua.c:521
int player_eventAlreadyDone(int id)
Checks to see if player has already completed a event.
Definition: player.c:2971
Player_t player
Definition: player.c:73
static const double c[]
Definition: rng.c:264
StarSystem * cur_system
Definition: space.c:105
Event data structure.
Definition: event.c:54
char * chapter
Definition: event.c:63
char * name
Definition: event.c:55
char * cond
Definition: event.c:68
double chance
Definition: event.c:69
char * lua
Definition: event.c:57
int * factions
Definition: event.c:64
int priority
Definition: event.c:70
EventTrigger_t trigger
Definition: event.c:67
pcre2_code * chapter_re
Definition: event.c:65
unsigned int flags
Definition: event.c:58
char * spob
Definition: event.c:61
char * system
Definition: event.c:62
char * sourcefile
Definition: event.c:56
Activated event structure.
Definition: event.h:12
unsigned int id
Definition: event.h:13
int save
Definition: event.h:16
int data
Definition: event.h:14
nlua_env env
Definition: event.h:15
Claim_t * claims
Definition: event.h:17
int devmode
Definition: conf.h:158
char * chapter
Definition: player.h:116
int faction
Definition: space.h:66
char * name
Definition: space.h:90
SpobPresence presence
Definition: space.h:102