diff --git a/src/lua_hook.h b/src/lua_hook.h index 88867db2b..fe5706f56 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -46,6 +46,7 @@ enum hook { hook_ShieldSpawn, hook_ShieldSpecial, hook_MobjMoveBlocked, + hook_MapThingSpawn, hook_MAX // last hook }; @@ -83,5 +84,6 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 #define LUAh_ShieldSpawn(player) LUAh_PlayerHook(player, hook_ShieldSpawn) // Hook for P_SpawnShieldOrb #define LUAh_ShieldSpecial(player) LUAh_PlayerHook(player, hook_ShieldSpecial) // Hook for shield abilities #define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) +boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index dadc1861a..04efac070 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -57,6 +57,7 @@ const char *const hookNames[hook_MAX+1] = { "ShieldSpawn", "ShieldSpecial", "MobjMoveBlocked", + "MapThingSpawn", NULL }; @@ -128,6 +129,7 @@ static int lib_addHook(lua_State *L) case hook_MobjRemoved: case hook_HurtMsg: case hook_MobjMoveBlocked: + case hook_MapThingSpawn: hook.s.mt = MT_NULL; if (lua_isnumber(L, 2)) hook.s.mt = lua_tonumber(L, 2); @@ -187,6 +189,7 @@ static int lib_addHook(lua_State *L) case hook_BossDeath: case hook_MobjRemoved: case hook_MobjMoveBlocked: + case hook_MapThingSpawn: lastp = &mobjhooks[hook.s.mt]; break; case hook_JumpSpecial: @@ -1073,4 +1076,66 @@ void LUAh_NetArchiveHook(lua_CFunction archFunc) // stack: tables } +boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_MapThingSpawn/8] & (1<<(hook_MapThingSpawn%8)))) + return false; + + lua_settop(gL, 0); + + // Look for all generic mobj map thing spawn hooks + for (hookp = mobjhooks[MT_NULL]; hookp; hookp = hookp->next) + if (hookp->type == hook_MapThingSpawn) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, mthing, META_MAPTHING); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + for (hookp = mobjhooks[mo->type]; hookp; hookp = hookp->next) + if (hookp->type == hook_MapThingSpawn) + { + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, mo, META_MOBJ); + LUA_PushUserdata(gL, mthing, META_MAPTHING); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (lua_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + #endif diff --git a/src/p_mobj.c b/src/p_mobj.c index 520f9ad07..e38551548 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9698,6 +9698,16 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; +#ifdef HAVE_BLUA + if (LUAh_MapThingSpawn(mobj, mthing)) + { + if (P_MobjWasRemoved(mobj)) + return; + } + else if (P_MobjWasRemoved(mobj)) + return; + else +#endif switch(mobj->type) { case MT_SKYBOX: