From 0175e5b6a5787f791e3555461c8b5e79edf9821e Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 26 Nov 2018 21:23:41 +0100 Subject: [PATCH 1/4] Possible fix for lack of mobjdamage and shoulddamage lua functionalities on players. --- src/k_kart.c | 59 ++++++++++++++++++++++++++++++++++++++++------- src/k_kart.h | 2 +- src/lua_baselib.c | 5 +++- src/p_inter.c | 18 +++++++++++---- src/p_map.c | 18 +++++++-------- src/p_spec.c | 2 +- src/p_user.c | 2 +- 7 files changed, 80 insertions(+), 26 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 4403dd4a..946aeacd 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) @@ -1842,8 +1843,24 @@ 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, boolean trapitem, mobj_t *inflictor) { + + // 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 ShouldDamage should get us damaged reguardless of flashtics or heck knows what. + UINT8 shouldForce = LUAh_ShouldDamage(player->mo, inflictor, source, 1); + 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 + + UINT8 scoremultiply = 1; if (!trapitem && G_BattleGametype()) { @@ -1860,10 +1877,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_MobjDamage(player->mo, inflictor, source, 1)) + return; + if (source && source != player->mo && source->player) K_PlayHitEmSound(source); @@ -2029,6 +2052,20 @@ 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 { + +#ifdef HAVE_BLUA + boolean force = false; // Used to check if Lua ShouldDamage should get us damaged reguardless of flashtics or heck knows what. + UINT8 shouldForce = LUAh_ShouldDamage(player->mo, inflictor, source, 1); + 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 UINT8 scoremultiply = 1; if (G_BattleGametype()) { @@ -2045,10 +2082,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_MobjDamage(player->mo, inflictor, source, 1)) + return; + if (source && source != player->mo && source->player) K_PlayHitEmSound(source); @@ -3181,7 +3224,7 @@ static void K_DoShrink(player_t *user) // Wipeout K_DropItems(&players[i]); - K_SpinPlayer(&players[i], user->mo, 1, false); + K_SpinPlayer(&players[i], user->mo, 1, false, NULL); // P_RingDamage P_DoPlayerPain(&players[i], user->mo, user->mo); diff --git a/src/k_kart.h b/src/k_kart.h index 8f8cd100..72a03e97 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -28,7 +28,7 @@ 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_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem, mobj_t *inflictor); void K_SquishPlayer(player_t *player, mobj_t *source); void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor); void K_StealBumper(player_t *player, player_t *victim, boolean force); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 1c14093c..6eb998f7 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2191,12 +2191,15 @@ static int lib_kSpinPlayer(lua_State *L) mobj_t *source = NULL; INT32 type = (INT32)luaL_optinteger(L, 3, 0); boolean trapitem = lua_optboolean(L, 4); + 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_SpinPlayer(player, source, type, trapitem); + if (!lua_isnone(L, 5) && lua_isuserdata(L, 5)) + inflictor = *((mobj_t **)luaL_checkudata(L, 5, META_MOBJ)); + K_SpinPlayer(player, source, type, trapitem, inflictor); return 0; } diff --git a/src/p_inter.c b/src/p_inter.c index baae2701..7838db2c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -590,7 +590,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, special, 0, false, NULL); return; /*case MT_EERIEFOG: special->frame &= ~FF_TRANS80; @@ -3243,6 +3243,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) @@ -3275,8 +3280,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 { @@ -3285,7 +3293,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, false, inflictor); damage = player->mo->health - 1; P_RingDamage(player, inflictor, source, damage); P_PlayerRingBurst(player, 5); @@ -3297,7 +3305,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, false, inflictor); } return true; } diff --git a/src/p_map.c b/src/p_map.c index ba6e6454..c33a2dd5 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, false, tmthing); } 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->type == MT_BANANA || tmthing->type == MT_BANANA_SHIELD), tmthing); // 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, (thing->type == MT_BANANA || thing->type == MT_BANANA_SHIELD), tmthing); // 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, false, tmthing); return true; } @@ -1423,7 +1423,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person. && !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height)) { - + if (tmthing->scale > thing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) // SRB2kart - Handle squishes first! K_SquishPlayer(thing->player, tmthing); else if (thing->scale > tmthing->scale + (mapheaderinfo[gamemap-1]->mobj_scale/8)) @@ -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, false, tmthing); } } 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, false, thing); } } 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, false, tmthing); } 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, false, thing); } } diff --git a/src/p_spec.c b/src/p_spec.c index 6ac325cd..27345fe5 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, false, NULL); } break; diff --git a/src/p_user.c b/src/p_user.c index b2849c85..b0caec59 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7764,7 +7764,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, false, inflictor); //} else P_DamageMobj(mo, inflictor, source, 1000); From ec279da272c39ff9c2d621c338570b806748d441 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Mon, 26 Nov 2018 21:24:57 +0100 Subject: [PATCH 2/4] classic lat forgot whitespaces meme --- src/k_kart.c | 8 ++++---- src/lua_baselib.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 946aeacd..dec6b0d2 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1883,10 +1883,10 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem return; } } - + if (LUAh_MobjDamage(player->mo, inflictor, source, 1)) return; - + if (source && source != player->mo && source->player) K_PlayHitEmSound(source); @@ -2088,10 +2088,10 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b return; } } - + if (LUAh_MobjDamage(player->mo, inflictor, source, 1)) return; - + if (source && source != player->mo && source->player) K_PlayHitEmSound(source); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 6eb998f7..c6d810c8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2251,7 +2251,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); From ed4477705d7e3610d4168a54ad60b834834ba1a4 Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Tue, 27 Nov 2018 18:27:43 +0100 Subject: [PATCH 3/4] Separated the damage hooks into multiple more precise hooks for players. --- src/k_kart.c | 42 +++++-- src/k_kart.h | 2 +- src/lua_baselib.c | 5 +- src/lua_hook.h | 13 +++ src/lua_hooklib.c | 286 +++++++++++++++++++++++++++++++++++++++++++++- src/p_inter.c | 2 +- src/p_map.c | 8 +- src/p_user.c | 2 +- 8 files changed, 340 insertions(+), 20 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index dec6b0d2..8c2e8916 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1845,11 +1845,11 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount) void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem, mobj_t *inflictor) { - + (void)inflictor; // in case some weirdo doesn't want Lua. // 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 ShouldDamage should get us damaged reguardless of flashtics or heck knows what. - UINT8 shouldForce = LUAh_ShouldDamage(player->mo, inflictor, source, 1); + 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) @@ -1884,7 +1884,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem } } - if (LUAh_MobjDamage(player->mo, inflictor, source, 1)) + 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) @@ -1963,8 +1963,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) { + (void)inflictor; // Please stop forgetting to put inflictor in yer functions thank -Lat' + + // 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; +#endif + UINT8 scoremultiply = 1; if (G_BattleGametype()) { @@ -1981,10 +1997,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; @@ -2054,8 +2076,8 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b { #ifdef HAVE_BLUA - boolean force = false; // Used to check if Lua ShouldDamage should get us damaged reguardless of flashtics or heck knows what. - UINT8 shouldForce = LUAh_ShouldDamage(player->mo, inflictor, source, 1); + 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) @@ -2089,7 +2111,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b } } - if (LUAh_MobjDamage(player->mo, inflictor, source, 1)) + 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) diff --git a/src/k_kart.h b/src/k_kart.h index 72a03e97..d191af97 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -29,7 +29,7 @@ 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, mobj_t *inflictor); -void K_SquishPlayer(player_t *player, mobj_t *source); +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 c6d810c8..97eb5cf1 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2207,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; } 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 7838db2c..717e8139 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -590,7 +590,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_RemoveMobj(special); } else - K_SpinPlayer(player, special, 0, false, NULL); + K_SpinPlayer(player, NULL, 0, false, special); return; /*case MT_EERIEFOG: special->frame &= ~FF_TRANS80; diff --git a/src/p_map.c b/src/p_map.c index c33a2dd5..6d8579df 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -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]) @@ -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) @@ -4262,7 +4262,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_user.c b/src/p_user.c index b0caec59..296f3b0c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7242,7 +7242,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. From 54a7e65ff615b5cbd3845faa00fb8caa1a04378e Mon Sep 17 00:00:00 2001 From: Latapostrophe Date: Wed, 28 Nov 2018 19:50:30 +0100 Subject: [PATCH 4/4] Moved (void)inflictor;s below and put scoremultiply at the top of all the damage funcs --- src/k_kart.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index e806defa..a40d4838 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1863,6 +1863,7 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount) 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. @@ -1874,12 +1875,11 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto else if (shouldForce == 2) return; #else - (void)inflictor; // in case some weirdo doesn't want Lua. static const boolean force = false; + (void)inflictor; // in case some weirdo doesn't want Lua. #endif - UINT8 scoremultiply = 1; if (!trapitem && G_BattleGametype()) { if (K_IsPlayerWanted(player)) @@ -1983,6 +1983,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto 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. @@ -1994,11 +1995,10 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) else if (shouldForce == 2) return; #else - (void)inflictor; // Please stop forgetting to put inflictor in yer functions thank -Lat' static const boolean force = false; + (void)inflictor; // Please stop forgetting to put inflictor in yer functions thank -Lat' #endif - UINT8 scoremultiply = 1; if (G_BattleGametype()) { if (K_IsPlayerWanted(player)) @@ -2099,7 +2099,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source, mobj_t *inflictor) 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); @@ -2113,7 +2113,6 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b #else static const boolean force = false; #endif - UINT8 scoremultiply = 1; if (G_BattleGametype()) { if (K_IsPlayerWanted(player))