diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index a1ea4fdaf..d7f89bffd 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -86,8 +86,6 @@ struct hook_s }; typedef struct hook_s* hook_p; -#define FMT_HOOKID "hook_%d" - // For each mobj type, a linked list to its thinker and collision hooks. // That way, we don't have to iterate through all the hooks. // We could do that with all other mobj hooks, but it would probably just be @@ -237,9 +235,9 @@ static int lib_addHook(lua_State *L) *lastp = hookp; // set the hook function in the registry. - lua_pushfstring(L, FMT_HOOKID, hook.id); + lua_getfield(L, LUA_REGISTRYINDEX, "hooks"); lua_pushvalue(L, 1); - lua_settable(L, LUA_REGISTRYINDEX); + lua_rawseti(L, -2, hook.id); return 0; } @@ -248,6 +246,10 @@ int LUA_HookLib(lua_State *L) memset(hooksAvailable,0,sizeof(UINT8[(hook_MAX/8)+1])); roothook = NULL; lua_register(L, "addHook", lib_addHook); + + lua_newtable(L); + lua_setfield(L, LUA_REGISTRYINDEX, "hooks"); + return 0; } @@ -255,26 +257,30 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return false; I_Assert(mo->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[mo->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -292,10 +298,9 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -317,20 +322,24 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = playerhooks; hookp; hookp = hookp->next) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, plr, META_PLAYER); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -352,25 +361,30 @@ boolean LUAh_PlayerHook(player_t *plr, enum hook which) void LUAh_MapChange(INT16 mapnumber) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MapChange/8] & (1<<(hook_MapChange%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + lua_pushinteger(gL, mapnumber); for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_MapChange) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } - + lua_settop(gL, 0); } @@ -378,22 +392,27 @@ void LUAh_MapChange(INT16 mapnumber) void LUAh_MapLoad(void) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MapLoad/8] & (1<<(hook_MapLoad%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + lua_pushinteger(gL, gamemap); for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_MapLoad) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } lua_settop(gL, 0); @@ -403,25 +422,30 @@ void LUAh_MapLoad(void) void LUAh_PlayerJoin(int playernum) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerJoin/8] & (1<<(hook_PlayerJoin%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + lua_pushinteger(gL, playernum); for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerJoin) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } - + lua_settop(gL, 0); } @@ -429,22 +453,26 @@ void LUAh_PlayerJoin(int playernum) void LUAh_PreThinkFrame(void) { hook_p hookp; + int HOOKSINDEX; // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) return; - + lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_PreThinkFrame) - { + { if (cv_perfstats.value == 4) time_taken = I_GetPreciseTime(); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -456,22 +484,22 @@ void LUAh_PreThinkFrame(void) lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_getinfo(gL, ">S", &ar); PS_SetPreThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; } } - + } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for frame (after mobj and player thinkers) void LUAh_ThinkFrame(void) { hook_p hookp; + int HOOKSINDEX; // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; @@ -481,14 +509,17 @@ void LUAh_ThinkFrame(void) lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_ThinkFrame) { if (cv_perfstats.value == 3) time_taken = I_GetPreciseTime(); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -500,8 +531,7 @@ void LUAh_ThinkFrame(void) lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_getinfo(gL, ">S", &ar); PS_SetThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; @@ -509,13 +539,14 @@ void LUAh_ThinkFrame(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for frame (at end of tick, ie after overlays, precipitation, specials) void LUAh_PostThinkFrame(void) { hook_p hookp; + int HOOKSINDEX; // variables used by perf stats int hook_index = 0; precise_t time_taken = 0; @@ -524,14 +555,17 @@ void LUAh_PostThinkFrame(void) lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_PostThinkFrame) { if (cv_perfstats.value == 5) time_taken = I_GetPreciseTime(); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -543,8 +577,7 @@ void LUAh_PostThinkFrame(void) lua_Debug ar; time_taken = I_GetPreciseTime() - time_taken; // we need the function, let's just retrieve it again - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_getinfo(gL, ">S", &ar); PS_SetPostThinkFrameHookInfo(hook_index, time_taken, ar.short_src); hook_index++; @@ -552,25 +585,29 @@ void LUAh_PostThinkFrame(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for Y_Ticker void LUAh_IntermissionThinker(void) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8)))) return; - lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_pushcfunction(gL, LUA_GetErrorMessage);; + + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_IntermissionThinker) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -580,25 +617,29 @@ void LUAh_IntermissionThinker(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } // Hook for Y_VoteTicker void LUAh_VoteThinker(void) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_VoteThinker/8] & (1<<(hook_VoteThinker%8)))) return; lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) { if (hookp->type == hook_VoteThinker) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); if (lua_pcall(gL, 0, 0, 1)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); @@ -608,7 +649,7 @@ void LUAh_VoteThinker(void) } } - lua_pop(gL, 1); // Pop error handler + lua_pop(gL, 2); // Pop error handler and hooks table } @@ -617,29 +658,33 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) { hook_p hookp; UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) return 0; I_Assert(thing1->type < NUMMOBJTYPES); - + if (!(mobjcollidehooks[MT_NULL] || mobjcollidehooks[thing1->type])) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj collision hooks for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, thing1, META_MOBJ); LUA_PushUserdata(gL, thing2, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -663,13 +708,12 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) if (hookp->type == which) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, thing1, META_MOBJ); LUA_PushUserdata(gL, thing2, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -698,25 +742,29 @@ boolean LUAh_MobjThinker(mobj_t *mo) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MobjThinker/8] & (1<<(hook_MobjThinker%8)))) return false; I_Assert(mo->type < NUMMOBJTYPES); - + if (!(mobjthinkerhooks[MT_NULL] || mobjthinkerhooks[mo->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj thinker hooks for (hookp = mobjthinkerhooks[MT_NULL]; hookp; hookp = hookp->next) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -733,10 +781,9 @@ boolean LUAh_MobjThinker(mobj_t *mo) for (hookp = mobjthinkerhooks[mo->type]; hookp; hookp = hookp->next) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) LUA_PushUserdata(gL, mo, META_MOBJ); - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); if (lua_pcall(gL, 1, 1, 1)) { if (!hookp->error || cv_debug & DBG_LUA) @@ -759,29 +806,33 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_TouchSpecial/8] & (1<<(hook_TouchSpecial%8)))) return false; I_Assert(special->type < NUMMOBJTYPES); - - if (!(mobjhooks[MT_NULL] || mobjhooks[special->type])) + + if (!(mobjhooks[MT_NULL] || mobjhooks[special->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic touch special hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_TouchSpecial) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -800,13 +851,12 @@ boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher) if (hookp->type == hook_TouchSpecial) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, special, META_MOBJ); LUA_PushUserdata(gL, toucher, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -830,31 +880,35 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldDamage/8] & (1<<(hook_ShouldDamage%8)))) return 0; I_Assert(target->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic should damage hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -880,15 +934,14 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type == hook_ShouldDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -919,31 +972,35 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MobjDamage/8] & (1<<(hook_MobjDamage%8)))) return false; I_Assert(target->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj damage hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_MobjDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -964,15 +1021,14 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 if (hookp->type == hook_MobjDamage) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); lua_pushvalue(gL, -5); @@ -998,29 +1054,33 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MobjDeath/8] & (1<<(hook_MobjDeath%8)))) return false; I_Assert(target->type < NUMMOBJTYPES); - + if (!(mobjhooks[MT_NULL] || mobjhooks[target->type])) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // Look for all generic mobj death hooks for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) if (hookp->type == hook_MobjDeath) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1040,14 +1100,13 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (hookp->type == hook_MobjDeath) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1072,22 +1131,26 @@ boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_BotTiccmd/8] & (1<<(hook_BotTiccmd%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_BotTiccmd) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, bot, META_PLAYER); LUA_PushUserdata(gL, cmd, META_TICCMD); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -1112,23 +1175,27 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerCmd/8] & (1<<(hook_PlayerCmd%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + hook_cmd_running = true; for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerCmd) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, cmd, META_TICCMD); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 1, 1)) { @@ -1153,23 +1220,27 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_BotAI && (hookp->s.skinname == NULL || !strcmp(hookp->s.skinname, ((skin_t*)tails->skin)->name))) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, sonic, META_MOBJ); LUA_PushUserdata(gL, tails, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 8, 1)) { @@ -1181,10 +1252,10 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) } // This turns forward, backward, left, right, jump, and spin into a proper ticcmd for tails. - if (lua_istable(gL, 2+1)) { + if (lua_istable(gL, -8)) { boolean forward=false, backward=false, left=false, right=false, strafeleft=false, straferight=false, jump=false, spin=false; #define CHECKFIELD(field) \ - lua_getfield(gL, 2+1, #field);\ + lua_getfield(gL, -8, #field);\ if (lua_toboolean(gL, -1))\ field = true;\ lua_pop(gL, 1); @@ -1200,7 +1271,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) #undef CHECKFIELD B_KeysToTiccmd(tails, cmd, forward, backward, left, right, strafeleft, straferight, jump, spin); } else - B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, 2+1), lua_toboolean(gL, 2+2), lua_toboolean(gL, 2+3), lua_toboolean(gL, 2+4), lua_toboolean(gL, 2+5), lua_toboolean(gL, 2+6), lua_toboolean(gL, 2+7), lua_toboolean(gL, 2+8)); + B_KeysToTiccmd(tails, cmd, lua_toboolean(gL, -8), lua_toboolean(gL, -7), lua_toboolean(gL, -6), lua_toboolean(gL, -5), lua_toboolean(gL, -4), lua_toboolean(gL, -3), lua_toboolean(gL, -2), lua_toboolean(gL, -1)); lua_pop(gL, 8); hooked = true; @@ -1215,30 +1286,34 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_LinedefExecute/8] & (1<<(hook_LinedefExecute%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = linedefexecutorhooks; hookp; hookp = hookp->next) if (!strcmp(hookp->s.funcname, line->text)) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, line, META_LINE); LUA_PushUserdata(gL, mo, META_MOBJ); LUA_PushUserdata(gL, sector, META_SECTOR); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); if (lua_pcall(gL, 3, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } hooked = true; } @@ -1254,16 +1329,21 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerMsg/8] & (1<<(hook_PlayerMsg%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerMsg) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, &players[source], META_PLAYER); // Source player if (flags & 2 /*HU_CSAY*/) { // csay TODO: make HU_CSAY accessible outside hu_stuff.c @@ -1285,8 +1365,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) else lua_pushboolean(gL, false); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); lua_pushvalue(gL, -6); @@ -1313,24 +1392,28 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_HurtMsg/8] & (1<<(hook_HurtMsg%8)))) return false; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_HurtMsg && (hookp->s.mt == MT_NULL || (inflictor && hookp->s.mt == inflictor->type))) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1354,61 +1437,69 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) { hook_p hookp; int errorhandlerindex; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8)))) return; // stack: tables I_Assert(lua_gettop(gL) > 0); I_Assert(lua_istable(gL, -1)); - + lua_pushcfunction(gL, LUA_GetErrorMessage); errorhandlerindex = lua_gettop(gL); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // tables becomes an upvalue of archFunc - lua_pushvalue(gL, -2); + lua_pushvalue(gL, -3); lua_pushcclosure(gL, archFunc, 1); // stack: tables, archFunc for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_NetVars) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -2); // archFunc if (lua_pcall(gL, 1, 0, errorhandlerindex)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } - lua_pop(gL, 2); // Pop archFunc and error handler + lua_pop(gL, 3); // Pop archFunc, error handler and hooks table // stack: tables } void LUAh_PlayerQuit(player_t *plr, int reason) { hook_p hookp; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerQuit/8] & (1<<(hook_PlayerQuit%8)))) return; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerQuit) { - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, plr, META_PLAYER); // Player that quit lua_pushinteger(gL, reason); // Reason for quitting } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -3); lua_pushvalue(gL, -3); if (lua_pcall(gL, 2, 0, 1)) { - CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); - lua_pop(gL, 1); + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); } } @@ -1421,6 +1512,7 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_MusicChange/8] & (1<<(hook_MusicChange%8)))) return false; @@ -1428,11 +1520,14 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_MusicChange) { - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushstring(gL, oldname); lua_pushstring(gL, newname); lua_pushinteger(gL, *mflags); @@ -1480,26 +1575,30 @@ UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldSpin/8] & (1<<(hook_ShouldSpin%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to check for mobj type because it will always be MT_PLAYER in this case. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldSpin) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1529,26 +1628,30 @@ UINT8 LUAh_ShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldExplode/8] & (1<<(hook_ShouldExplode%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to check for mobj type because it will always be MT_PLAYER in this case. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldExplode) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1578,26 +1681,30 @@ UINT8 LUAh_ShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; UINT8 shouldDamage = 0; // 0 = default, 1 = force yes, 2 = force no. + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_ShouldSquish/8] & (1<<(hook_ShouldSquish%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to check for mobj type because it will always be MT_PLAYER in this case. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_ShouldSquish) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1627,26 +1734,30 @@ boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerSpin/8] & (1<<(hook_PlayerSpin%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to look for target->type because it will always be MT_PLAYER. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerSpin) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1670,26 +1781,30 @@ boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerSquish/8] & (1<<(hook_PlayerSquish%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to look for target->type because it will always be MT_PLAYER. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerSquish) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1713,26 +1828,30 @@ boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source) { hook_p hookp; boolean hooked = false; + int HOOKSINDEX; if (!gL || !(hooksAvailable[hook_PlayerExplode/8] & (1<<(hook_PlayerExplode%8)))) return 0; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage); + lua_getfield(gL, LUA_REGISTRYINDEX, "hooks"); + HOOKSINDEX = lua_gettop(gL); + I_Assert(lua_istable(L, HOOKSINDEX)); + // We can afford not to look for target->type because it will always be MT_PLAYER. for (hookp = roothook; hookp; hookp = hookp->next) if (hookp->type == hook_PlayerExplode) { ps_lua_mobjhooks.value.i++; - if (lua_gettop(gL) == 1) + if (lua_gettop(gL) == 2) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); } - lua_pushfstring(gL, FMT_HOOKID, hookp->id); - lua_gettable(gL, LUA_REGISTRYINDEX); + lua_rawgeti(gL, HOOKSINDEX, hookp->id); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); lua_pushvalue(gL, -4); @@ -1749,4 +1868,4 @@ boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source) } lua_settop(gL, 0); return hooked; -} \ No newline at end of file +}