diff --git a/src/k_kart.c b/src/k_kart.c index e56e7c96..a40d4838 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -21,6 +21,7 @@ #include "k_kart.h" #include "f_finale.h" #include "lua_hud.h" // For Lua hud checks +#include "lua_hook.h" // For MobjDamage and ShouldDamage // SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H: // gamespeed is cc (0 for easy, 1 for normal, 2 for hard) @@ -1860,9 +1861,25 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount) pt->color = source->skincolor; } -void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem) +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflictor, boolean trapitem) { UINT8 scoremultiply = 1; + // PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too. +#ifdef HAVE_BLUA + boolean force = false; // Used to check if Lua ShouldSpin should get us damaged reguardless of flashtics or heck knows what. + UINT8 shouldForce = LUAh_ShouldSpin(player, inflictor, source); + if (P_MobjWasRemoved(player->mo)) + return; // mobj was removed (in theory that shouldn't happen) + if (shouldForce == 1) + force = true; + else if (shouldForce == 2) + return; +#else + static const boolean force = false; + (void)inflictor; // in case some weirdo doesn't want Lua. +#endif + + if (!trapitem && G_BattleGametype()) { if (K_IsPlayerWanted(player)) @@ -1878,10 +1895,16 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem || player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) { - K_DoInstashield(player); - return; + if (!force) // if shoulddamage force, we go THROUGH that. + { + K_DoInstashield(player); + return; + } } + if (LUAh_PlayerSpin(player, inflictor, source)) // Let Lua do its thing or overwrite if it wants to. Make sure to let any possible instashield happen because we didn't get "damaged" in this case. + return; + if (source && source != player->mo && source->player) K_PlayHitEmSound(source); @@ -1958,9 +1981,24 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem return; } -void K_SquishPlayer(player_t *player, mobj_t *source) +void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) { UINT8 scoremultiply = 1; + // PS: Inflictor is unused for all purposes here and is actually only ever relevant to Lua. It may be nil too. +#ifdef HAVE_BLUA + boolean force = false; // Used to check if Lua ShouldSquish should get us damaged reguardless of flashtics or heck knows what. + UINT8 shouldForce = LUAh_ShouldSquish(player, inflictor, source); + if (P_MobjWasRemoved(player->mo)) + return; // mobj was removed (in theory that shouldn't happen) + if (shouldForce == 1) + force = true; + else if (shouldForce == 2) + return; +#else + static const boolean force = false; + (void)inflictor; // Please stop forgetting to put inflictor in yer functions thank -Lat' +#endif + if (G_BattleGametype()) { if (K_IsPlayerWanted(player)) @@ -1976,10 +2014,16 @@ void K_SquishPlayer(player_t *player, mobj_t *source) || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) { - K_DoInstashield(player); - return; + if (!force) // You know the drill by now. + { + K_DoInstashield(player); + return; + } } + if (LUAh_PlayerSquish(player, inflictor, source)) // Let Lua do its thing or overwrite if it wants to. Make sure to let any possible instashield happen because we didn't get "damaged" in this case. + return; + player->kartstuff[k_sneakertimer] = 0; player->kartstuff[k_driftboost] = 0; @@ -2056,6 +2100,19 @@ void K_SquishPlayer(player_t *player, mobj_t *source) void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A bit of a hack, we just throw the player up higher here and extend their spinout timer { UINT8 scoremultiply = 1; +#ifdef HAVE_BLUA + boolean force = false; // Used to check if Lua ShouldExplode should get us damaged reguardless of flashtics or heck knows what. + UINT8 shouldForce = LUAh_ShouldExplode(player, inflictor, source); + if (P_MobjWasRemoved(player->mo)) + return; // mobj was removed (in theory that shouldn't happen) + if (shouldForce == 1) + force = true; + else if (shouldForce == 2) + return; + +#else + static const boolean force = false; +#endif if (G_BattleGametype()) { if (K_IsPlayerWanted(player)) @@ -2071,10 +2128,16 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b ||*/player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_hyudorotimer] > 0 || (G_BattleGametype() && ((player->kartstuff[k_bumper] <= 0 && player->kartstuff[k_comebacktimer]) || player->kartstuff[k_comebackmode] == 1))) { - K_DoInstashield(player); - return; + if (!force) // ShouldDamage can bypass that, again. + { + K_DoInstashield(player); + return; + } } + if (LUAh_PlayerExplode(player, inflictor, source)) // Same thing. Also make sure to let Instashield happen blah blah + return; + if (source && source != player->mo && source->player) K_PlayHitEmSound(source); @@ -3215,6 +3278,7 @@ static void K_DoShrink(player_t *user) } } + void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) { const fixed_t vscale = mapheaderinfo[gamemap-1]->mobj_scale + (mo->scale - mapheaderinfo[gamemap-1]->mobj_scale); diff --git a/src/k_kart.h b/src/k_kart.h index 864a8609..fed490db 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -29,8 +29,8 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); void K_DoInstashield(player_t *player); void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); -void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem); -void K_SquishPlayer(player_t *player, mobj_t *source); +void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflictor, boolean trapitem); +void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor); void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor); void K_StealBumper(player_t *player, player_t *victim, boolean force); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index bc41183f..79de02a5 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2190,13 +2190,16 @@ static int lib_kSpinPlayer(lua_State *L) player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *source = NULL; INT32 type = (INT32)luaL_optinteger(L, 3, 0); - boolean trapitem = lua_optboolean(L, 4); + mobj_t *inflictor = NULL; + boolean trapitem = lua_optboolean(L, 5); NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - K_SpinPlayer(player, source, type, trapitem); + if (!lua_isnone(L, 4) && lua_isuserdata(L, 4)) + inflictor = *((mobj_t **)luaL_checkudata(L, 4, META_MOBJ)); + K_SpinPlayer(player, source, type, inflictor, trapitem); return 0; } @@ -2204,12 +2207,15 @@ static int lib_kSquishPlayer(lua_State *L) { player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); mobj_t *source = NULL; + mobj_t *inflictor = NULL; NOHUD if (!player) return LUA_ErrInvalid(L, "player_t"); if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) source = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); - K_SquishPlayer(player, source); + if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) + inflictor = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); + K_SquishPlayer(player, source, inflictor); return 0; } @@ -2248,7 +2254,7 @@ static int lib_kSpawnKartExplosion(lua_State *L) fixed_t x = luaL_checkfixed(L, 1); fixed_t y = luaL_checkfixed(L, 2); fixed_t z = luaL_checkfixed(L, 3); - fixed_t radius = (fixed_t)luaL_optinteger(L, 4, 32*FRACUNIT); + fixed_t radius = (fixed_t)luaL_optinteger(L, 4, 32*FRACUNIT); INT32 number = (INT32)luaL_optinteger(L, 5, 32); mobjtype_t type = luaL_optinteger(L, 6, MT_MINEEXPLOSION); angle_t rotangle = luaL_optinteger(L, 7, 0); diff --git a/src/lua_hook.h b/src/lua_hook.h index 26b70570..485db43f 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -44,6 +44,12 @@ enum hook { hook_HurtMsg, hook_PlayerSpawn, hook_PlayerQuit, + hook_ShouldSpin, //SRB2KART + hook_ShouldExplode, //SRB2KART + hook_ShouldSquish, //SRB2KART + hook_PlayerSpin, //SRB2KART + hook_PlayerExplode, //SRB2KART + hook_PlayerSquish, //SRB2KART hook_MAX // last hook }; @@ -80,4 +86,11 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Ho #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting +UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be spun out? +UINT8 LUAh_ShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be exploded? +UINT8 LUAh_ShouldSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be squished? + +boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SpinPlayer. Allows Lua to execute code and/or overwrite its behavior. +boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_ExplodePlayer. Allows Lua to execute code and/or overwrite its behavior. +boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Hook for K_SquishPlayer. Allows Lua to execute code and/or overwrite its behavior. #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index f06e28cd..89a6db20 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -55,6 +55,12 @@ const char *const hookNames[hook_MAX+1] = { "HurtMsg", "PlayerSpawn", "PlayerQuit", + "ShouldSpin", + "ShouldExplode", + "ShouldSquish", + "PlayerSpin", + "PlayerExplode", + "PlayerSquish", NULL }; @@ -154,6 +160,12 @@ static int lib_addHook(lua_State *L) *p = 0; } break; + case hook_ShouldSpin: + case hook_ShouldExplode: + case hook_ShouldSquish: + case hook_PlayerSpin: + case hook_PlayerExplode: + case hook_PlayerSquish: default: break; } @@ -195,6 +207,12 @@ static int lib_addHook(lua_State *L) case hook_LinedefExecute: lastp = &linedefexecutorhooks; break; + case hook_ShouldSpin: + case hook_ShouldExplode: + case hook_ShouldSquish: + case hook_PlayerSpin: + case hook_PlayerExplode: + case hook_PlayerSquish: default: lastp = &roothook; break; @@ -953,7 +971,7 @@ boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector) } // Hook for player chat -// Added the "mute" field. It's set to true if the message was supposed to be eaten by spam protection. +// Added the "mute" field. It's set to true if the message was supposed to be eaten by spam protection. // But for netgame consistency purposes, this hook is ran first reguardless, so this boolean allows for modders to adapt if they so desire. boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) { @@ -987,7 +1005,7 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute) if (mute) lua_pushboolean(gL, true); // the message was supposed to be eaten by spamprotecc. else - lua_pushboolean(gL, false); + lua_pushboolean(gL, false); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); @@ -1108,4 +1126,268 @@ void LUAh_PlayerQuit(player_t *plr, int reason) lua_settop(gL, 0); } +// Hook for K_SpinPlayer. Determines if yes or no we should get damaged reguardless of circumstances. +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. + if (!gL || !(hooksAvailable[hook_ShouldSpin/8] & (1<<(hook_ShouldSpin%8)))) + return 0; + + lua_settop(gL, 0); + + // 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) + { + if (lua_gettop(gL) == 0) + { + 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_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 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 (lua_toboolean(gL, -1)) + shouldDamage = 1; // Force yes + else + shouldDamage = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldDamage; +} + +// Hook for K_ExplodePlayer. Determines if yes or no we should get damaged reguardless of circumstances. +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. + if (!gL || !(hooksAvailable[hook_ShouldExplode/8] & (1<<(hook_ShouldExplode%8)))) + return 0; + + lua_settop(gL, 0); + + // 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) + { + if (lua_gettop(gL) == 0) + { + 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_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 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 (lua_toboolean(gL, -1)) + shouldDamage = 1; // Force yes + else + shouldDamage = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldDamage; +} + +// Hook for K_SquishPlayer. Determines if yes or no we should get damaged reguardless of circumstances. +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. + if (!gL || !(hooksAvailable[hook_ShouldSquish/8] & (1<<(hook_ShouldSquish%8)))) + return 0; + + lua_settop(gL, 0); + + // 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) + { + if (lua_gettop(gL) == 0) + { + 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_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 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 (lua_toboolean(gL, -1)) + shouldDamage = 1; // Force yes + else + shouldDamage = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldDamage; +} + +// Hook for K_SpinPlayer. This is used when the player has actually been spun out, but before anything has actually been done. This allows Lua to overwrite the behavior or to just perform actions. +boolean LUAh_PlayerSpin(player_t *player, mobj_t *inflictor, mobj_t *source) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_PlayerSpin/8] & (1<<(hook_PlayerSpin%8)))) + return 0; + + lua_settop(gL, 0); + + // 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) + { + if (lua_gettop(gL) == 0) + { + 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_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 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; +} + +// Hook for K_SquishPlayer. This is used when the player has actually been spun out, but before anything has actually been done. This allows Lua to overwrite the behavior or to just perform actions. +boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_PlayerSquish/8] & (1<<(hook_PlayerSquish%8)))) + return 0; + + lua_settop(gL, 0); + + // 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) + { + if (lua_gettop(gL) == 0) + { + 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_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 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; +} + +// Hook for K_ExplodePlayer. This is used when the player has actually been spun out, but before anything has actually been done. This allows Lua to overwrite the behavior or to just perform actions. +boolean LUAh_PlayerExplode(player_t *player, mobj_t *inflictor, mobj_t *source) +{ + hook_p hookp; + boolean hooked = false; + if (!gL || !(hooksAvailable[hook_PlayerExplode/8] & (1<<(hook_PlayerExplode%8)))) + return 0; + + lua_settop(gL, 0); + + // 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) + { + if (lua_gettop(gL) == 0) + { + 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_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 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_inter.c b/src/p_inter.c index 28ce0d96..9c66df17 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -599,7 +599,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_RemoveMobj(special); } else - K_SpinPlayer(player, special, 0, false); + K_SpinPlayer(player, NULL, 0, special, false); return; /*case MT_EERIEFOG: special->frame &= ~FF_TRANS80; @@ -3259,6 +3259,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } +#ifdef HAVE_BLUA // Add this back here for ACTUAL NORMAL DAMAGE. The funny shit is that the player is barely ever "actually" damaged. + if (LUAh_MobjDamage(target, inflictor, source, damage)) + return true; +#endif + if (!force && inflictor && (inflictor->flags & MF_FIRE)) { if ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL) @@ -3291,8 +3296,11 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_KillPlayer(player, source, damage); else if (player->kartstuff[k_invincibilitytimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->powers[pw_flashing]) { - K_DoInstashield(player); - return false; + if (!force) // shoulddamage bypasses all of that. + { + K_DoInstashield(player); + return false; + } } else { @@ -3301,7 +3309,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da || inflictor->type == MT_SMK_THWOMP || inflictor->player)) { player->kartstuff[k_sneakertimer] = 0; - K_SpinPlayer(player, source, 1, false); + K_SpinPlayer(player, source, 1, inflictor, false); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); @@ -3313,7 +3321,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else { - K_SpinPlayer(player, source, 0, false); + K_SpinPlayer(player, source, 0, inflictor, false); } return true; } diff --git a/src/p_map.c b/src/p_map.c index 97d062fd..e3ce18c9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -882,7 +882,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(thing->player, tmthing->target, tmthing); else - K_SpinPlayer(thing->player, tmthing->target, 0, false); + K_SpinPlayer(thing->player, tmthing->target, 0, tmthing, false); } return true; // This doesn't collide with anything, but we want it to effect the player anyway. @@ -915,7 +915,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_PLAYER) { // Player Damage - K_SpinPlayer(thing->player, tmthing->target, 0, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD)); + K_SpinPlayer(thing->player, tmthing->target, 0, tmthing, (tmthing->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD)); // This Item Damage if (tmthing->eflags & MFE_VERTICALFLIP) @@ -1061,7 +1061,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // Player Damage - K_SpinPlayer(tmthing->player, thing->target, 0, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD)); + K_SpinPlayer(tmthing->player, thing->target, 0, tmthing, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD)); // Other Item Damage if (thing->eflags & MFE_VERTICALFLIP) @@ -1091,7 +1091,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->state == &states[S_MINEEXPLOSION1]) K_ExplodePlayer(tmthing->player, thing->target, thing); else - K_SpinPlayer(tmthing->player, thing->target, 0, false); + K_SpinPlayer(tmthing->player, thing->target, 0, tmthing, false); return true; } @@ -1425,9 +1425,9 @@ static boolean PIT_CheckThing(mobj_t *thing) { if (tmthing->scale > thing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) // SRB2kart - Handle squishes first! - K_SquishPlayer(thing->player, tmthing); + K_SquishPlayer(thing->player, tmthing, tmthing); else if (thing->scale > tmthing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) - K_SquishPlayer(tmthing->player, thing); + K_SquishPlayer(tmthing->player, thing, tmthing); else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility! P_DamageMobj(thing, tmthing, tmthing, 1); else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) @@ -1543,7 +1543,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype() && tmthing->player->kartstuff[k_pogospring]) { K_StealBumper(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing, 0, false); + K_SpinPlayer(thing->player, tmthing, 0, tmthing, false); } } else if (P_IsObjectOnGround(tmthing) && thing->momz < 0) @@ -1552,7 +1552,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (G_BattleGametype() && thing->player->kartstuff[k_pogospring]) { K_StealBumper(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing, 0, false); + K_SpinPlayer(tmthing->player, thing, 0, thing, false); } } else @@ -1563,12 +1563,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer])) { K_StealBumper(thing->player, tmthing->player, false); - K_SpinPlayer(tmthing->player, thing, 0, false); + K_SpinPlayer(tmthing->player, thing, 0, tmthing, false); } else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer])) { K_StealBumper(tmthing->player, thing->player, false); - K_SpinPlayer(thing->player, tmthing, 0, false); + K_SpinPlayer(thing->player, tmthing, 0, thing, false); } } @@ -1664,7 +1664,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // collide if (tmthing->z < thing->z && thing->momz < 0) - K_SquishPlayer(tmthing->player, thing); + K_SquishPlayer(tmthing->player, thing, thing); else { if (thing->flags2 & MF2_AMBUSH) @@ -4270,7 +4270,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (!thing->player) P_DamageMobj(thing, killer, killer, 10000); else - K_SquishPlayer(thing->player, killer); // SRB2kart - Squish instead of kill + K_SquishPlayer(thing->player, killer, killer); // SRB2kart - Squish instead of kill } } } diff --git a/src/p_spec.c b/src/p_spec.c index 7ac637d4..3aa74f52 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4033,7 +4033,7 @@ DoneSection2: case 7: // SRB2kart 190117 - Oil Slick (deprecated) if (roversector || P_MobjReadyToTrigger(player->mo, sector)) { - K_SpinPlayer(player, NULL, 0, false); + K_SpinPlayer(player, NULL, 0, NULL, false); } break; diff --git a/src/p_user.c b/src/p_user.c index 79e0cad7..488b8e7c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7243,7 +7243,7 @@ static void P_MovePlayer(player_t *player) P_DamageMobj(player->mo, NULL, NULL, 42000); // Respawn crushed spectators else { - K_SquishPlayer(player, NULL); // SRB2kart - we don't kill when squished, we squish when squished. + K_SquishPlayer(player, NULL, NULL); // SRB2kart - we don't kill when squished, we squish when squished. /* mobj_t *killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL); killer->threshold = 44; // Special flag that it was crushing which killed you. @@ -7768,7 +7768,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) continue; if (mo->type == MT_PLAYER) // Players wipe out in Kart - K_SpinPlayer(mo->player, source, 0, false); + K_SpinPlayer(mo->player, source, 0, inflictor, false); //} else P_DamageMobj(mo, inflictor, source, 1000);