From ef4840555e2c52a781e69ade5c56a88f70963af9 Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Tue, 31 Dec 2019 15:17:02 -0800 Subject: [PATCH] Add MobjLineCollide hook --- src/lua_hook.h | 3 ++ src/lua_hooklib.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_map.c | 11 +++++++ 3 files changed, 95 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index d035be097..6f8805708 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -25,6 +25,7 @@ enum hook { hook_PostThinkFrame, hook_MobjSpawn, hook_MobjCollide, + hook_MobjLineCollide, hook_MobjMoveCollide, hook_TouchSpecial, hook_MobjFuse, @@ -70,7 +71,9 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which); +UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which); #define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type +#define LUAh_MobjLineCollide(thing, line) LUAh_MobjLineCollideHook(thing, line, hook_MobjLineCollide) // Hook for PIT_CheckThing by (thing) mobj type #define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d548f6a65..2d9a98c4b 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -36,6 +36,7 @@ const char *const hookNames[hook_MAX+1] = { "PostThinkFrame", "MobjSpawn", "MobjCollide", + "MobjLineCollide", "MobjMoveCollide", "TouchSpecial", "MobjFuse", @@ -125,6 +126,7 @@ static int lib_addHook(lua_State *L) // Take a mobjtype enum which this hook is specifically for. case hook_MobjSpawn: case hook_MobjCollide: + case hook_MobjLineCollide: case hook_MobjMoveCollide: case hook_TouchSpecial: case hook_MobjFuse: @@ -184,6 +186,7 @@ static int lib_addHook(lua_State *L) lastp = &mobjthinkerhooks[hook.s.mt]; break; case hook_MobjCollide: + case hook_MobjLineCollide: case hook_MobjMoveCollide: lastp = &mobjcollidehooks[hook.s.mt]; break; @@ -562,6 +565,84 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) return shouldCollide; } +UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) +{ + hook_p hookp; + UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) + return 0; + + I_Assert(thing->type < NUMMOBJTYPES); + + lua_settop(gL, 0); + + // Look for all generic mobj collision hooks + for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) + { + if (hookp->type != which) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, thing, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + } + 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_isnil(gL, -1)) + { // if nil, leave shouldCollide = 0. + if (lua_toboolean(gL, -1)) + shouldCollide = 1; // Force yes + else + shouldCollide = 2; // Force no + } + lua_pop(gL, 1); + } + + for (hookp = mobjcollidehooks[thing->type]; hookp; hookp = hookp->next) + { + if (hookp->type != which) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, thing, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + } + 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_isnil(gL, -1)) + { // if nil, leave shouldCollide = 0. + if (lua_toboolean(gL, -1)) + shouldCollide = 1; // Force yes + else + shouldCollide = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldCollide; +} + // Hook for mobj thinkers boolean LUAh_MobjThinker(mobj_t *mo) { diff --git a/src/p_map.c b/src/p_map.c index 1b6f23cde..628268bff 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1988,6 +1988,17 @@ static boolean PIT_CheckLine(line_t *ld) if (lowfloor < tmdropoffz) tmdropoffz = lowfloor; +#ifdef HAVE_BLUA + { + UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, ld); // checks hook for thing's type + if (P_MobjWasRemoved(tmthing)) + return true; // one of them was removed??? + if (shouldCollide == 1) + return false; // force collide + else if (shouldCollide == 2) + return true; // force no collide + } +#endif return true; }