diff --git a/src/lua_baselib.c b/src/lua_baselib.c index c6b87193c..577549f5a 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -377,7 +377,9 @@ static int lib_pSpawnMobj(lua_State *L) NOHUD if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SpawnMobj(x, y, z, type), META_MOBJ); + mobj_t *th = P_SpawnMobj(x, y, z, type); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } @@ -403,7 +405,9 @@ static int lib_pSpawnMissile(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SpawnMissile(source, dest, type), META_MOBJ); + mobj_t *th = P_SpawnMissile(source, dest, type); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } @@ -420,7 +424,9 @@ static int lib_pSpawnXYZMissile(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SpawnXYZMissile(source, dest, type, x, y, z), META_MOBJ); + mobj_t *th = P_SpawnXYZMissile(source, dest, type, x, y, z); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } @@ -439,7 +445,9 @@ static int lib_pSpawnPointMissile(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SpawnPointMissile(source, xa, ya, za, type, x, y, z), META_MOBJ); + mobj_t *th = P_SpawnPointMissile(source, xa, ya, za, type, x, y, z); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } @@ -456,7 +464,9 @@ static int lib_pSpawnAlteredDirectionMissile(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle), META_MOBJ); + mobj_t *th = P_SpawnAlteredDirectionMissile(source, type, x, y, z, shiftingAngle); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } @@ -485,7 +495,9 @@ static int lib_pSPMAngle(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SPMAngle(source, type, angle, allowaim, flags2), META_MOBJ); + mobj_t *th = P_SPMAngle(source, type, angle, allowaim, flags2); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } @@ -499,7 +511,9 @@ static int lib_pSpawnPlayerMissile(lua_State *L) return LUA_ErrInvalid(L, "mobj_t"); if (type >= NUMMOBJTYPES) return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1); - LUA_PushUserdata(L, P_SpawnPlayerMissile(source, type, flags2), META_MOBJ); + mobj_t *th = P_SpawnPlayerMissile(source, type, flags2); + th->islocal = !hook_important; + LUA_PushUserdata(L, th, META_MOBJ); return 1; } diff --git a/src/lua_hook.h b/src/lua_hook.h index 14437c26f..3072f2775 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -109,6 +109,7 @@ ENUM (STRING_HOOK); extern boolean hook_cmd_running; // This is used by PlayerCmd and lua_playerlib to prevent anything from being wirtten to player while we run PlayerCmd. extern int hook_defrosting; +extern bool hook_important; void LUA_HookVoid(int hook); void LUA_HookHUD(int hook, huddrawlist_h drawlist); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 6d04b6154..c2016b771 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -19,6 +19,7 @@ #include "b_bot.h" #include "z_zone.h" #include "m_perfstats.h" +#include "w_wad.h" #include "lua_script.h" #include "lua_libs.h" @@ -39,14 +40,20 @@ LIST (stringHookNames, STRING_HOOK_LIST); #undef LIST +typedef struct { + int id; + bool important; +} hookinfo_t; + typedef struct { int numHooks; - int *ids; + hookinfo_t *ids; } hook_t; typedef struct { int numGeneric; int ref; + bool important; } stringhook_t; static hook_t hookIds[HOOK(MAX)]; @@ -56,6 +63,8 @@ static hook_t mobjHookIds[NUMMOBJTYPES][MOBJ_HOOK(MAX)]; // Lua tables are used to lookup string hook ids. static stringhook_t stringHooks[STRING_HOOK(MAX)]; +bool hook_important = true; + // This will be indexed by hook id, the value of which fetches the registry. static int * hookRefs; static int nextid; @@ -109,7 +118,11 @@ static void get_table(lua_State *L) FUNCINLINE static ATTRINLINE void add_hook_to_table(lua_State *L, int n) { + lua_newtable(L); lua_pushnumber(L, nextid); + lua_rawseti(L, -2, 1); + lua_pushboolean(L, wadfiles[numwadfiles-1]->important); + lua_rawseti(L, -2, 2); lua_rawseti(L, -2, n); } @@ -180,7 +193,8 @@ FUNCINLINE static ATTRINLINE void add_hook(hook_t *map) { Z_Realloc(map->ids, (map->numHooks + 1) * sizeof *map->ids, PU_STATIC, &map->ids); - map->ids[map->numHooks++] = nextid; + map->ids[map->numHooks].important = wadfiles[numwadfiles-1]->important; + map->ids[map->numHooks++].id = nextid; } FUNCINLINE static ATTRINLINE void add_mobj_hook(lua_State *L, int hook_type) @@ -287,6 +301,7 @@ struct Hook_State { const char * string;/* used to fetch table, ran first if set */ int top;/* index of last argument passed to hook */ int id;/* id to fetch ref */ + boolean important;/* is this hook from local addon */ int values;/* num arguments passed to hook */ int results;/* num values returned by hook */ Hook_Callback results_handler;/* callback when hook successfully returns */ @@ -416,22 +431,29 @@ FUNCINLINE static ATTRINLINE void init_hook_call hook->results_handler = results_handler; } -FUNCINLINE static ATTRINLINE void get_hook(Hook_State *hook, const int *ids, int n) +FUNCINLINE static ATTRINLINE void get_hook(Hook_State *hook, const hookinfo_t *ids, int n) { - hook->id = ids[n]; + hook->id = ids[n].id; + hook->important = ids[n].important; lua_getref(gL, hookRefs[hook->id]); } FUNCINLINE static ATTRINLINE void get_hook_from_table(Hook_State *hook, int n) { lua_rawgeti(gL, -1, n); + lua_rawgeti(gL, -1, 1); hook->id = lua_tonumber(gL, -1); lua_pop(gL, 1); + lua_rawgeti(gL, -2, 2); + hook->important = lua_toboolean(gL, -1); + lua_pop(gL, 2); lua_getref(gL, hookRefs[hook->id]); } static int call_single_hook_no_copy(Hook_State *hook) { + hook_important = hook->important; + if (lua_pcall(gL, hook->values, hook->results, EINDEX) == 0) { if (hook->results > 0)