diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 192e2b6cb..e6119cd6c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -956,7 +956,7 @@ static int lib_pPlayerCanDamage(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - //HUDSAFE + NOHUD // was hud safe but then i added a lua hook INLEVEL if (!player) return LUA_ErrInvalid(L, "player_t"); diff --git a/src/lua_hook.h b/src/lua_hook.h index 9fcc36594..45e116c34 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -48,6 +48,7 @@ enum hook { hook_MobjMoveBlocked, hook_MapThingSpawn, hook_FollowMobj, + hook_PlayerCanDamage, hook_PlayerQuit, hook_MAX // last hook @@ -87,7 +88,8 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 #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 -boolean LUAh_FollowMobj(player_t *player, mobj_t *mo); // Hook for P_PlayerAfterThink Smiles mobj-following +boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following +UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index de8d29be4..7f7e8adc6 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -59,6 +59,7 @@ const char *const hookNames[hook_MAX+1] = { "MobjMoveBlocked", "MapThingSpawn", "FollowMobj", + "PlayerCanDamage", "PlayerQuit", NULL }; @@ -200,6 +201,7 @@ static int lib_addHook(lua_State *L) case hook_JumpSpinSpecial: case hook_PlayerSpawn: case hook_FollowMobj: + case hook_PlayerCanDamage: case hook_ShieldSpawn: case hook_ShieldSpecial: lastp = &playerhooks; @@ -1247,6 +1249,51 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj) return hooked; } +// Hook for P_PlayerCanDamage +UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj) +{ + hook_p hookp; + UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_PlayerCanDamage/8] & (1<<(hook_PlayerCanDamage%8)))) + return 0; + + lua_settop(gL, 0); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerCanDamage) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, mobj, META_MOBJ); + } + 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; +} + void LUAh_PlayerQuit(player_t *plr, int reason) { hook_p hookp; diff --git a/src/p_user.c b/src/p_user.c index b1b755204..9a5d315a3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -987,6 +987,18 @@ boolean P_PlayerCanDamage(player_t *player, mobj_t *thing) if (!player->mo || player->spectator || !thing || P_MobjWasRemoved(thing)) return false; +#ifdef HAVE_BLUA + { + UINT8 shouldCollide = LUAh_PlayerCanDamage(player, thing); + if (P_MobjWasRemoved(thing)) + return false; // removed??? + if (shouldCollide == 1) + return true; // force yes + else if (shouldCollide == 2) + return false; // force no + } +#endif + if ((player->powers[pw_carry] == CR_NIGHTSMODE) && (player->pflags & PF_DRILLING)) return true;