38#include "nlua_commodity.h"
41#include "nlua_outfit.h"
42#include "nlua_pilot.h"
50typedef struct HookQueue_s {
63typedef enum HookType_e {
106 int ( *func )(
void * );
124static int hooks_executeParam(
const char *stack,
const HookParam *param );
249 while ( param[n].type != HOOK_PARAM_SENTINEL ) {
250 switch ( param[n].type ) {
252 lua_pushnil(
naevL );
254 case HOOK_PARAM_NUMBER:
255 lua_pushnumber(
naevL, param[n].u.num );
257 case HOOK_PARAM_STRING:
258 lua_pushstring(
naevL, param[n].u.str );
260 case HOOK_PARAM_BOOL:
261 lua_pushboolean(
naevL, param[n].u.b );
263 case HOOK_PARAM_PILOT:
266 case HOOK_PARAM_SHIP:
269 case HOOK_PARAM_OUTFIT:
272 case HOOK_PARAM_COMMODITY:
275 case HOOK_PARAM_FACTION:
278 case HOOK_PARAM_SSYS:
281 case HOOK_PARAM_SPOB:
284 case HOOK_PARAM_JUMP:
288 lua_rawgeti(
naevL, LUA_REGISTRYINDEX, param[n].u.ref );
292 WARN( _(
"Unknown Lua parameter type." ) );
293 lua_pushnil(
naevL );
322 WARN( _(
"Trying to run hook with nonexistent parent: deleting" ) );
329 if ( misn == NULL ) {
330 WARN( _(
"Trying to run hook with parent not in player mission stack: "
337 if ( ( claims > 0 ) &&
346 misn_runStart( misn, hook->
u.
misn.
func );
354 if ( misn_runFunc( misn, hook->
u.
misn.
func, n ) <
356 WARN( _(
"Hook [%s] '%d' -> '%s' failed" ), hook->
stack, hook->
id,
383 if ( ( claims > 0 ) &&
393 WARN( _(
"Hook [%s] '%d' -> '%s' failed, event does not exist. Deleting "
410 WARN( _(
"Hook [%s] '%d' -> '%s' failed" ), hook->
stack, hook->
id,
441 switch ( hook->
type ) {
460 WARN( _(
"Invalid hook type '%d', deleting." ), hook->
type );
499 Hook *new_hook = calloc( 1,
sizeof(
Hook ) );
509 new_hook->
type = type;
511 new_hook->
stack = strdup( stack );
515 if ( strcmp( stack,
"safe" ) == 0 )
621 new_hook->
u.
func.func = func;
622 new_hook->
u.
func.data = data;
640 new_hook->
u.
func.func = func;
641 new_hook->
u.
func.data = data;
660 while ( h != NULL ) {
700 if ( (
player.p == NULL ) || player_isFlag( PLAYER_CREATING ) )
711 for (
int j = 1; j >= 0; j-- ) {
717 if ( h->is_date == 0 )
720 if ( h->created != 0 )
726 if ( h->acc < h->res )
746unsigned int hook_addDateMisn(
unsigned int parent,
const char *func,
758 new_hook->
res = resolution;
764unsigned int hook_addDateEvt(
unsigned int parent,
const char *func,
776 new_hook->
res = resolution;
790 if ( (
player.p == NULL ) || player_isFlag( PLAYER_CREATING ) ||
791 player_isFlag( PLAYER_DESTROYED ) )
799 for (
int j = 1; j >= 0; j-- ) {
872 if ( ( h->type ==
HOOK_TYPE_MISN ) && ( parent == h->u.misn.parent ) )
884 if ( ( h->type ==
HOOK_TYPE_EVENT ) && ( parent == h->u.event.parent ) )
898 if ( ( h->type ==
HOOK_TYPE_MISN ) && ( parent == h->u.misn.parent ) )
914 if ( ( h->type ==
HOOK_TYPE_EVENT ) && ( parent == h->u.event.parent ) )
920static int hooks_executeParam(
const char *stack,
const HookParam *param )
925 if ( (
player.p == NULL ) || player_isFlag( PLAYER_DESTROYED ) )
930 if ( strcmp( stack, h->stack ) == 0 ) {
937 for (
int j = 1; j >= 0; j-- ) {
946 if ( h->created != 0 )
949 if ( strcmp( stack, h->stack ) != 0 )
966 if ( param != NULL ) {
968 while ( param[n].type != HOOK_PARAM_SENTINEL ) {
969 switch ( param[n].type ) {
971 luaL_unref(
naevL, LUA_REGISTRYINDEX, param[n].u.ref );
1002 if ( (
player.p == NULL ) || player_isFlag( PLAYER_DESTROYED ) )
1006 hq->
stack = strdup( stack );
1008 if ( param != NULL ) {
1009 for ( ; param[i].type != HOOK_PARAM_SENTINEL; i++ )
1010 hq->
hparam[i] = param[i];
1013 if ( i >= HOOK_MAX_PARAM )
1014 WARN( _(
"HOOK_MAX_PARAM is set too low (%d), need at least %d!" ),
1015 HOOK_MAX_PARAM, i );
1032 if ( (
player.p == NULL ) || player_isFlag( PLAYER_DESTROYED ) )
1040 return hooks_executeParam( stack, param );
1078 switch ( h->
type ) {
1108 if ( (
player.p == NULL ) || player_isFlag( PLAYER_DESTROYED ) )
1114 WARN( _(
"Attempting to run hook of id '%d' which is not in the stack" ),
1148 switch ( h->
type ) {
1175 while ( h != NULL ) {
1204 if ( ( h->type ==
HOOK_TYPE_MISN ) && ( parent == h->u.misn.parent ) )
1217 if ( ( h->type ==
HOOK_TYPE_EVENT ) && ( parent == h->u.event.parent ) )
1230 const char *nosave[] = {
"p_death",
"p_board",
"p_disable",
1231 "p_jump",
"p_attacked",
"p_idle",
1248 for (
int i = 0; strcmp( nosave[i],
"end" ) != 0; i++ )
1249 if ( strcmp( nosave[i], h->
stack ) == 0 )
1263 xmlw_startElem( writer,
"hooks" );
1269 xmlw_startElem( writer,
"hook" );
1271 switch ( h->type ) {
1273 xmlw_attr( writer,
"type",
"misn" );
1274 xmlw_elem( writer,
"parent",
"%u", h->u.misn.parent );
1275 xmlw_elem( writer,
"func",
"%s", h->u.misn.func );
1279 xmlw_attr( writer,
"type",
"event" );
1280 xmlw_elem( writer,
"parent",
"%u", h->u.event.parent );
1281 xmlw_elem( writer,
"func",
"%s", h->u.event.func );
1285 WARN( _(
"Something has gone screwy here..." ) );
1290 xmlw_elem( writer,
"id",
"%u", h->id );
1291 xmlw_elem( writer,
"stack",
"%s", h->stack );
1295 xmlw_elem( writer,
"resolution",
"%" PRId64, h->res );
1297 xmlw_endElem( writer );
1299 xmlw_endElem( writer );
1317 node = parent->xmlChildrenNode;
1319 if ( xml_isNode( node,
"hooks" ) )
1321 }
while ( xml_nextNode( node ) );
1341 xmlNodePtr node, cur;
1342 char *func, *stack, *stype;
1343 unsigned int parent, id, new_id;
1349 node = base->xmlChildrenNode;
1351 if ( xml_isNode( node,
"hook" ) ) {
1359 xmlr_attr_strd( node,
"type", stype );
1361 if ( stype == NULL )
1364 else if ( strcmp( stype,
"misn" ) == 0 ) {
1369 else if ( strcmp( stype,
"event" ) == 0 ) {
1375 WARN( _(
"Hook of unknown type '%s' found, skipping." ), stype );
1381 cur = node->xmlChildrenNode;
1383 xml_onlyNodes( cur );
1386 xmlr_long( cur,
"id",
id );
1389 xmlr_str( cur,
"stack", stack );
1393 xmlr_uint( cur,
"parent", parent );
1394 xmlr_str( cur,
"func", func );
1398 if ( xml_isNode( cur,
"resolution" ) ) {
1400 res = xml_getLong( cur );
1405 WARN( _(
"Save has unknown hook node '%s'." ), cur->name );
1406 }
while ( xml_nextNode( cur ) );
1409 if ( ( parent == 0 ) || ( func == NULL ) || ( stack == NULL ) ) {
1410 WARN( _(
"Invalid hook." ) );
1423 WARN( _(
"Save has unsupported hook type." ) );
1439 }
while ( xml_nextNode( node ) );
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
int claim_testSys(const Claim_t *claim, int sys)
Tests to see if a system is claimed by a system claim.
void claim_activateAll(void)
Activates all the claims.
Event_t * event_get(unsigned int eventid)
Gets an event.
int event_save(unsigned int eventid)
Checks to see if an event should be saved.
int event_testClaims(unsigned int eventid, int sys)
Tests to see if an event has claimed a system.
static unsigned int hook_id
static int hook_runningstack
static ntime_t hook_time_accum
unsigned int hook_addTimerEvt(unsigned int parent, const char *func, double ms)
Adds a new event type hook timer.
int hook_runIDparam(unsigned int id, const HookParam *param)
Runs a single hook by id.
static int hook_parseParam(const HookParam *param)
Parses hook parameters.
static Hook * hook_new(HookType_t type, const char *stack)
Generates and allocates a new hook.
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
static int hook_runMisn(Hook *hook, const HookParam *param, int claims)
Runs a mission hook.
void hook_rmMisnParent(unsigned int parent)
Removes all hooks belonging to parent mission.
static void hq_free(HookQueue_t *hq)
Frees a queued hook.
static int hook_loadingstack
static void hq_clear(void)
Clears the queued hooks.
int hook_load(xmlNodePtr parent)
Loads hooks for a player.
static Hook * hook_get(unsigned int id)
Gets a hook by ID.
void hooks_update(double dt)
Updates all the hook timer related stuff.
int hook_runID(unsigned int id)
Runs a single hook by id.
unsigned int hook_addTimerFunc(int(*func)(void *), void *data, double ms)
Adds a function hook to be run.
int hook_hasEventParent(unsigned int parent)
Checks to see how many hooks there are with the same event parent.
static void hooks_updateDateExecute(ntime_t change)
Updates date hooks and runs them if necessary.
static void hooks_purgeList(void)
Purges the list of deletable hooks.
static int hq_add(HookQueue_t *hq)
void hook_clear(void)
Clears the hooks.
static HookQueue_t * hook_queue
void hook_cleanup(void)
Gets rid of all current hooks.
int hooks_runParamDeferred(const char *stack, const HookParam *param)
Runs all the hooks of stack in the next frame. Does not trigger right away.
static int hook_runEvent(Hook *hook, const HookParam *param, int claims)
Runs a Event function hook.
nlua_env hook_env(unsigned int hook)
Gets the lua env for a hook.
void hooks_updateDate(ntime_t change)
Updates the time to see if it should be updated.
static int hook_run(Hook *hook, const HookParam *param, int claims)
Runs a hook.
static Mission * hook_getMission(Hook *hook)
Gets the mission of a hook.
unsigned int hook_addEvent(unsigned int parent, const char *func, const char *stack)
Adds a new event type hook.
static void hook_free(Hook *h)
Frees a hook.
void hook_rm(unsigned int id)
Removes a hook.
void hook_clearEventTimers(unsigned int parent)
Clears the timer hooks for an event.
static int hook_needSave(Hook *h)
Checks if a hook needs to be saved.
void hook_exclusionEnd(double dt)
Ends exclusion zone and runs all the queued hooks.
int hooks_run(const char *stack)
Runs all the hooks of stack.
void hook_rmEventParent(unsigned int parent)
Removes all hooks belonging to parent event.
unsigned int hook_addFunc(int(*func)(void *), void *data, const char *stack)
Adds a function hook to be run.
static unsigned int hook_genID(void)
Generates a new hook id.
int hook_hasMisnParent(unsigned int parent)
Checks to see how many hooks there are with the same mission parent.
void hook_exclusionStart(void)
Starts the hook exclusion zone, this makes hooks queue until exclusion is done.
unsigned int hook_addTimerMisn(unsigned int parent, const char *func, double ms)
Adds a new mission type hook timer hook.
static int hook_parse(xmlNodePtr base)
Parses an individual hook.
unsigned int hook_addMisn(unsigned int parent, const char *func, const char *stack)
Adds a new mission type hook.
static void hook_rmRaw(Hook *h)
Removes a hook.
void hook_clearMissionTimers(unsigned int parent)
Clears the timer hooks for a mission.
int hook_save(xmlTextWriterPtr writer)
Saves all the hooks.
Mission ** player_missions
Header file with generic functions and naev-specifics.
Commodity ** lua_pushcommodity(lua_State *L, Commodity *commodity)
Pushes a commodity on the stack.
void event_runStart(unsigned int eventid, const char *func)
Starts running a function, allows programmer to set up arguments.
int event_runFunc(unsigned int eventid, const char *func, int nargs)
Runs a function previously set up with event_runStart.
LuaFaction * lua_pushfaction(lua_State *L, LuaFaction faction)
Pushes a faction on the stack.
void hookL_unsetarg(unsigned int hook)
Unsets a Lua argument.
int hookL_getarg(unsigned int hook)
Gets a Lua argument for a hook.
LuaJump * lua_pushjump(lua_State *L, LuaJump jump)
Pushes a jump on the stack.
const Outfit ** lua_pushoutfit(lua_State *L, const Outfit *outfit)
Pushes a outfit on the stack.
LuaPilot * lua_pushpilot(lua_State *L, LuaPilot pilot)
Pushes a pilot on the stack.
const Ship ** lua_pushship(lua_State *L, const Ship *ship)
Pushes a ship on the stack.
LuaSpob * lua_pushspob(lua_State *L, LuaSpob spob)
Pushes a spob on the stack.
LuaSystem * lua_pushsystem(lua_State *L, LuaSystem sys)
Pushes a system on the stack.
void pilots_rmHook(unsigned int hook)
Removes a hook from all the pilots.
void player_runHooks(void)
Runs hooks for the player.
Activated event structure.
The actual hook parameter.
Hook queue to delay execution.
struct HookQueue_s * next
HookParam hparam[HOOK_MAX_PARAM]
Internal representation of a hook.
struct Hook::@264345225004242262323027051365150246323230242044::@070036032215365024117244330054177130317351256353 event
union Hook::@264345225004242262323027051365150246323230242044 u
struct Hook::@264345225004242262323027051365150246323230242044::@140054251303342262042302245035216014375144270033 misn
Represents an active mission.