31#include "nlua_audio.h"
33#include "nlua_camera.h"
36#include "nlua_music.h"
46#define XML_EVENT_ID "Events"
47#define XML_EVENT_TAG "event"
49#define EVENT_FLAG_UNIQUE (1<<0)
54typedef struct EventData_ {
88static int event_cmp(
const void* a,
const void* b );
105 if (ev->
id == eventid)
130 if ((ret == 0) && (
id != NULL))
194 memset( ev, 0,
sizeof(
Event_t) );
195 if ((
id != NULL) && (*
id != 0))
205 ev->
env = nlua_newEnv();
217 nlua_setenv(naevL, ev->
env,
"mem");
220 if (nlua_dobufenv(ev->
env, data->lua, strlen(data->lua), data->sourcefile) != 0) {
221 WARN(_(
"Error loading event file: %s\n"
223 "Most likely Lua file has improper syntax, please check"),
224 data->sourcefile, lua_tostring(naevL,-1));
229 if ((
id==NULL) || (*
id==0))
245 nlua_freeEnv(ev->
env);
268 if (ev->
id == eventid) {
278 WARN(_(
"Event ID '%u' not valid."), eventid);
302 if (ev->
data == data)
328 if ((trigger==EVENT_TRIGGER_LAND || trigger==EVENT_TRIGGER_LOAD) && (ed->
spob != NULL) && (strcmp(ed->
spob,
land_spob->
name)!=0))
347 if (trigger==EVENT_TRIGGER_ENTER)
349 else if (trigger==EVENT_TRIGGER_LOAD || trigger==EVENT_TRIGGER_LAND)
368 pcre2_match_data *match_data = pcre2_match_data_create_from_pattern( ed->
chapter_re, NULL );
370 pcre2_match_data_free( match_data );
373 case PCRE2_ERROR_NOMATCH:
376 WARN(_(
"Matching error %d"), rc );
386 if (ed->
cond != NULL) {
389 WARN(_(
"Conditional for event '%s' failed to run."), ed->
name);
420 temp->
trigger = EVENT_TRIGGER_NULL;
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);
427 node = parent->xmlChildrenNode;
432 xmlr_strd(node,
"spob",temp->
spob);
433 xmlr_strd(node,
"system",temp->
system);
434 xmlr_strd(node,
"chapter",temp->
chapter);
436 xmlr_strd(node,
"cond",temp->
cond);
437 xmlr_float(node,
"chance",temp->
chance);
438 xmlr_int(node,
"priority",temp->
priority);
440 if (xml_isNode(node,
"faction")) {
448 if (xml_isNode(node,
"location")) {
449 char *buf = xml_get(node);
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;
461 WARN(_(
"Event '%s' has invalid 'trigger' parameter: %s"), temp->
name, buf);
467 else if (xml_isNode(node,
"unique")) {
473 else if (xml_isNode(node,
"notes"))
476 WARN(_(
"Unknown node '%s' in event '%s'"), node->name, temp->
name);
477 }
while (xml_nextNode(node));
484 PCRE2_SIZE erroroffset;
485 temp->
chapter_re = pcre2_compile( (PCRE2_SPTR)temp->
chapter, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, 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 );
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");
502static int event_cmp(
const void* a,
const void* b )
511 return strcmp( ea->
name, eb->
name );
522 Uint32 time = SDL_GetTicks();
526 for (
int i=0; i <
array_size( event_files ); i++) {
528 free( event_files[ i ] );
538 WARN(_(
"Duplicate event '%s'!"), ed->
name);
546 time = SDL_GetTicks() - time;
567 const char *pos, *start_pos;
576 if (filebuf == NULL) {
577 WARN(_(
"Unable to read data from '%s'"), file);
586 pos =
strnstr( filebuf,
"</event>", bufsize );
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);
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);
604 doc = xmlParseMemory( start_pos, pos-start_pos );
606 WARN(_(
"Unable to parse document XML header for Event '%s'"), file);
611 node = doc->xmlChildrenNode;
613 WARN(_(
"Malformed '%s' file: missing root element '%s'"), file,
XML_EVENT_TAG);
620 temp->
lua = strdup(filebuf);
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) );
700 WARN(_(
"No event data found matching name '%s'."), evdata);
733 WARN(_(
"Trying to test claims of unknown event with id '%d'!"), eventid);
753 WARN(_(
"Detected event '%s' without any hooks and is therefore invalid. Removing event."),
768 xmlw_startElem(writer,
"events");
775 xmlw_startElem(writer,
"event");
778 xmlw_attr(writer,
"id",
"%u",ev->
id);
781 xmlw_startElem(writer,
"claims");
783 xmlw_endElem(writer);
786 xmlw_startElem(writer,
"lua");
788 xmlw_endElem(writer);
790 xmlw_endElem(writer);
793 xmlw_endElem(writer);
806 xmlNodePtr node = parent->xmlChildrenNode;
812 if (xml_isNode(node,
"events"))
814 }
while (xml_nextNode(node));
827 xmlNodePtr node = parent->xmlChildrenNode;
835 if (!xml_isNode(node,
"event"))
838 xmlr_attr_strd(node,
"name",buf);
840 WARN(_(
"Event has missing 'name' attribute, skipping."));
845 WARN(_(
"Event in save has name '%s' but event data not found matching name. Skipping."), buf);
850 xmlr_attr_uint(node,
"id",
id);
852 WARN(_(
"Event with data '%s' has invalid 'id' attribute, skipping."),
event_dataName(data));
860 WARN(_(
"Event with data '%s' was not created, skipping."),
event_dataName(data));
866 cur = node->xmlChildrenNode;
868 if (xml_isNode(cur,
"lua"))
870 }
while (xml_nextNode(cur));
873 if (xml_isNode(node,
"claims"))
875 }
while (xml_nextNode(node));
880int event_reload(
const char *name )
Provides macros to work with dynamic arrays.
#define array_free(ptr_array)
Frees memory allocated and sets array to NULL.
#define array_create_size(basic_type, capacity)
Creates a new dynamic array of ‘basic_type’ with an initial capacity.
#define array_erase(ptr_array, first, last)
Erases elements in interval [first, last).
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
#define array_grow(ptr_array)
Increases the number of elements by one and returns the last element.
#define array_shrink(ptr_array)
Shrinks memory to fit only ‘size’ elements.
#define array_push_back(ptr_array, element)
Adds a new element at the end of the array.
#define array_create(basic_type)
Creates a new dynamic array of ‘basic_type’.
void claim_destroy(Claim_t *claim)
Destroys a system claim.
void claim_activate(Claim_t *claim)
Activates a claim on a system.
int claim_testSys(const Claim_t *claim, int sys)
Tests to see if a system is claimed by a system claim.
Claim_t * claim_xmlLoad(xmlNodePtr parent)
Loads a claim.
int claim_xmlSave(xmlTextWriterPtr writer, const Claim_t *claim)
Saves all the systems in a claim in XML.
void claim_activateAll(void)
Activates all the claims.
int cond_check(const char *cond)
Checks to see if a condition is true.
static unsigned int event_genid
int event_start(const char *name, unsigned int *id)
Starts an event.
const char * event_dataName(int dataid)
Gets the event data name from id.
void events_exit(void)
Exits the event subsystem.
int event_alreadyRunning(int data)
Check to see if an event is already running.
static int event_parseFile(const char *file, EventData *temp)
Parses an event file.
const char * event_getData(unsigned int eventid)
Gets the name of the event data.
int events_loadActive(xmlNodePtr parent)
Loads the player's active events from a save.
void event_remove(unsigned int eventid)
Removes an event by ID.
Event_t * event_get(unsigned int eventid)
Gets an event.
static Event_t * event_active
void events_cleanup(void)
Cleans up and removes active events.
int event_dataID(const char *evdata)
Gets the event data id from name.
static void event_cleanup(Event_t *ev)
Cleans up an event.
static void event_freeData(EventData *event)
Frees an EventData structure.
int event_save(unsigned int eventid)
Checks to see if an event should be saved.
static int events_parseActive(xmlNodePtr parent)
Parses the actual individual event nodes.
int event_isUnique(unsigned int eventid)
Checks to see if an event is unique.
int events_load(void)
Loads all the events.
void event_activateClaims(void)
Activates all the active event claims.
void event_checkValidity(void)
Checks the event validity and cleans up after them.
void events_trigger(EventTrigger_t trigger)
Runs all the events matching a trigger.
int events_saveActive(xmlTextWriterPtr writer)
Saves the player's active events.
static int event_parseXML(EventData *temp, const xmlNodePtr parent)
Loads up an event from an XML node.
static unsigned int event_genID(void)
Generates a new event ID.
int event_testClaims(unsigned int eventid, int sys)
Tests to see if an event has claimed a system.
static EventData * event_data
#define EVENT_FLAG_UNIQUE
static int event_create(int dataid, unsigned int *id)
Creates an event.
int faction_get(const char *name)
Gets a faction ID by name.
int hook_hasEventParent(unsigned int parent)
Checks to see how many hooks there are with the same event parent.
void hook_rmEventParent(unsigned int parent)
Removes all hooks belonging to parent event.
int naev_isQuit(void)
Get if Naev is trying to quit.
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).
char ** ndata_listRecursive(const char *path)
Lists all the visible files in a directory, at any depth.
static char buf[NEWS_MAX_LENGTH]
int nlua_loadStandard(nlua_env env)
Loads the standard Naev Lua API.
int nlua_loadBackground(nlua_env env)
Loads the graphics library.
int nlua_loadCamera(nlua_env env)
Loads the camera library.
int event_run(unsigned int eventid, const char *func)
Runs the event function.
int nlua_loadEvt(nlua_env env)
Loads the event Lua library.
int nlua_loadHook(nlua_env env)
Loads the hook Lua library.
int nlua_loadMusic(nlua_env env)
Music Lua module.
int nlua_loadTex(nlua_env env)
Loads the texture library.
int nlua_loadTk(nlua_env env)
Loads the Toolkit Lua library.
int npc_rm_parentEvent(unsigned int id)
Removes all the npc belonging to an event.
char * strnstr(const char *haystack, const char *needle, size_t size)
A bounded version of strstr. Conforms to BSD semantics.
int nxml_persistLua(nlua_env env, xmlTextWriterPtr writer)
Persists all the nxml Lua data.
int nxml_unpersistLua(nlua_env env, xmlNodePtr parent)
Unpersists Lua data into a table named "mem".
int player_eventAlreadyDone(int id)
Checks to see if player has already completed a event.
Activated event structure.