diff --git a/src/hook.c b/src/hook.c index 6497853..c9ca63b 100644 --- a/src/hook.c +++ b/src/hook.c @@ -24,8 +24,10 @@ static int hook_runningstack = 0; // Check if stack is running. // Extern. extern int misn_run(Mission* misn, char* func); +// Intern. +static int hook_run(Hook* hook); -int hook_run(Hook* hook) { +static int hook_run(Hook* hook) { int i; Mission* misn; @@ -129,6 +131,18 @@ int hooks_run(char* stack) { return 0; } +// Run a single hook by id. +void hook_runID(int id) { + int i; + + for(i = 0; i < hook_nstack; i++) + if(hook_stack[i].id == id) { + hook_run(&hook_stack[i]); + return; + } + DEBUG("Attempting to run hook of id '%d' which is not in the stack", id); +} + // Clean upi after ourselves. void hook_cleanup(void) { free(hook_stack); diff --git a/src/hook.h b/src/hook.h index a0bf51b..ebd89d1 100644 --- a/src/hook.h +++ b/src/hook.h @@ -18,6 +18,7 @@ void hook_rmParent(unsigned int parent); // ======================================================== int hooks_run(char* stack); +void hook_runID(int id); // Runs hook of specific id. // Destroy hook. void hook_cleanup(void); diff --git a/src/misn_lua.c b/src/misn_lua.c index 13151cb..3d9f1bd 100644 --- a/src/misn_lua.c +++ b/src/misn_lua.c @@ -10,6 +10,7 @@ #include "space.h" #include "toolkit.h" #include "land.h" +#include "pilot.h" #include "player.h" #include "ltime.h" #include "misn_lua.h" @@ -148,10 +149,12 @@ static const luaL_Reg tk_methods[] = { static int hook_land(lua_State* L); static int hook_takeoff(lua_State* L); static int hook_time(lua_State* L); +static int hook_pilotDeath(lua_State* L); static const luaL_Reg hook_methods[] = { - { "land", hook_land }, - { "takeoff", hook_takeoff }, - { "time", hook_time }, + { "land", hook_land }, + { "takeoff", hook_takeoff }, + { "time", hook_time }, + { "pilotDeath", hook_pilotDeath }, { 0, 0 } }; @@ -730,8 +733,8 @@ static int hook_generic(lua_State* L, char* stack) { cur_mission->data->name); return 0; } - hook_add(cur_mission->id, func, stack); - return 0; + i = hook_add(cur_mission->id, func, stack); + return i; } static int hook_land(lua_State* L) { @@ -749,3 +752,20 @@ static int hook_time(lua_State* L) { return 0; } +static int hook_pilotDeath(lua_State* L) { + MIN_ARGS(2); + int h; + unsigned int p; + + if(lua_isnumber(L, -2)) p = (unsigned int) lua_tonumber(L, -2); + else { + MISN_DEBUG("Invalid first param"); + return 0; + } + + h = hook_generic(L, "death"); // We won't actually call the death stack directly. + pilot_addHook(pilot_get(p), PILOT_HOOK_DEATH, h); + + return 0; +} + diff --git a/src/pilot.c b/src/pilot.c index 4609ad3..86e098d 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -9,6 +9,7 @@ #include "xml.h" #include "spfx.h" #include "rng.h" +#include "hook.h" #include "pilot.h" #define XML_ID "Fleets" // XML section identifier. @@ -274,6 +275,10 @@ void pilot_dead(Pilot* p) { // Our pilot is now deadz. pilot_setFlag(p, PILOT_DEAD); + + // Run hook if pilot has a death hook. + if(p->hook_type == PILOT_HOOK_DEATH) + hook_runID(p->hook); } void pilot_setSecondary(Pilot* p, const char* secondary) { @@ -712,6 +717,12 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) { return 0; } +// Add a hook to the pilot. +void pilot_addHook(Pilot* pilot, int type, int hook) { + pilot->hook_type = type; + pilot->hook = hook; +} + // ==Init pilot.=========================================== // ship : Ship pilot is flying. // name : Pilot's name, if NULL, ships name will be used. @@ -778,6 +789,10 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, int faction, pilot->ncommodities = 0; pilot->cargo_free = pilot->ship->cap_cargo; + // Hooks. + pilot->hook_type = PILOT_HOOK_NONE; + pilot->hook = 0; + // Set flags and functions. if(flags & PILOT_PLAYER) { pilot->think = player_think; // Players don't need to thing! :P diff --git a/src/pilot.h b/src/pilot.h index 80cd1cb..05f6276 100644 --- a/src/pilot.h +++ b/src/pilot.h @@ -17,8 +17,12 @@ #define HYPERSPACE_FADEOUT 1000 // Time fadeout. // Aproximation for pilot size. -#define PILOT_SIZE_APROX 0.8 -#define PILOT_DISABLED_ARMOUR 0.3 // Based on armour percentage. +#define PILOT_SIZE_APROX 0.8 +#define PILOT_DISABLED_ARMOUR 0.3 // Based on armour percentage. + +// Hooks. +#define PILOT_HOOK_NONE 0 // No hook. +#define PILOT_HOOK_DEATH 1 // Pilot died. // Flags. #define pilot_isFlag(p,f) (p->flags & (f)) @@ -98,6 +102,10 @@ typedef struct Pilot_ { uint32_t flags; // Used for AI etc. unsigned int ptimer; // Generic timer for internal pilot use. + // Hook attached to the pilot. + int hook_type; + int hook; + // AI. AI_Profile* ai; // Ai personality profile. unsigned int tcontrol; // Timer for control tick. @@ -174,3 +182,5 @@ void fleet_free(void); void pilots_update(double dt); void pilots_render(void); +void pilot_addHook(Pilot* pilot, int type, int hook); +