From 35cecad868b5c54b7938395d6f313deb63d2bfc5 Mon Sep 17 00:00:00 2001 From: lachablock Date: Tue, 23 Mar 2021 14:49:22 +1100 Subject: [PATCH 1/6] Do not let nonspin characters enter sectors they could not enter if standing at full height --- src/lua_baselib.c | 22 ++++++++++++++++++++++ src/p_local.h | 2 ++ src/p_map.c | 11 +++++++++++ src/p_user.c | 24 ++++++++++++++++++------ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 916fa9254..a59ba546e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1671,6 +1671,26 @@ static int lib_pSwitchShield(lua_State *L) return 0; } +static int lib_pPlayerCanEnterSpinGaps(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + lua_pushboolean(L, P_PlayerCanEnterSpinGaps(player)); + return 1; +} + +static int lib_pPlayerShouldUseSpinHeight(lua_State *L) +{ + player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + INLEVEL + if (!player) + return LUA_ErrInvalid(L, "player_t"); + lua_pushboolean(L, P_PlayerShouldUseSpinHeight(player)); + return 1; +} + // P_MAP /////////// @@ -3872,6 +3892,8 @@ static luaL_Reg lib[] = { {"P_SpawnSpinMobj",lib_pSpawnSpinMobj}, {"P_Telekinesis",lib_pTelekinesis}, {"P_SwitchShield",lib_pSwitchShield}, + {"P_PlayerCanEnterSpinGaps",lib_pPlayerCanEnterSpinGaps}, + {"P_PlayerShouldUseSpinHeight",lib_pPlayerShouldUseSpinHeight}, // p_map {"P_CheckPosition",lib_pCheckPosition}, diff --git a/src/p_local.h b/src/p_local.h index 8caab0d27..8568dd4f8 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -143,6 +143,8 @@ angle_t P_GetLocalAngle(player_t *player); void P_SetLocalAngle(player_t *player, angle_t angle); void P_ForceLocalAngle(player_t *player, angle_t angle); boolean P_PlayerFullbright(player_t *player); +boolean P_PlayerCanEnterSpinGaps(player_t *player); +boolean P_PlayerShouldUseSpinHeight(player_t *player); boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); diff --git a/src/p_map.c b/src/p_map.c index a1cad524e..7eec0937c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1955,6 +1955,12 @@ static boolean PIT_CheckLine(line_t *ld) // set openrange, opentop, openbottom P_LineOpening(ld, tmthing); + // players should not always cross into sectors that they could not at full height + if (tmthing->player + && openrange < P_GetPlayerHeight(tmthing->player) + && !P_PlayerCanEnterSpinGaps(tmthing->player)) + return false; + // adjust floor / ceiling heights if (opentop < tmceilingz) { @@ -3331,6 +3337,11 @@ static boolean PTR_LineIsBlocking(line_t *li) if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, slidemo->scale)) return true; // too big a step up + if (slidemo->player + && openrange < P_GetPlayerHeight(slidemo->player) + && !P_PlayerCanEnterSpinGaps(slidemo->player)) + return true; // nonspin character should not take this path + return false; } diff --git a/src/p_user.c b/src/p_user.c index 02592053d..38f13f8fd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8653,12 +8653,7 @@ void P_MovePlayer(player_t *player) fixed_t oldheight = player->mo->height; // Less height while spinning. Good for spinning under things...? - if ((player->mo->state == &states[player->mo->info->painstate]) - || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) - || (player->pflags & PF_SPINNING) - || player->powers[pw_tailsfly] || player->pflags & PF_GLIDING - || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) - || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + if (P_PlayerShouldUseSpinHeight(player)) { player->mo->height = P_GetPlayerSpinHeight(player); atspinheight = true; @@ -12953,3 +12948,20 @@ boolean P_PlayerFullbright(player_t *player) || !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6])))); // Note the < instead of <= } + +// returns true if the player can enter a sector that they could not if standing at their skin's full height +boolean P_PlayerCanEnterSpinGaps(player_t *player) +{ + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)); +} + +// returns true if the player should use their skin's spinheight instead of their skin's height +boolean P_PlayerShouldUseSpinHeight(player_t *player) +{ + return (P_PlayerCanEnterSpinGaps(player) + || (player->mo->state == &states[player->mo->info->painstate]) + || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) + || player->powers[pw_tailsfly] + || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)); +} From cd72594d0eceee0e8dd6efd382763c894e51e2b2 Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 15:09:04 +1100 Subject: [PATCH 2/6] Revise conditions under which players use spinheight and enter gaps: - players with SF_NOJUMPDAMAGE but *not* SF_NOJUMPSPIN now always use spinheight while jumping (i.e. even with PF_NOJUMPDAMAGE), as long as their panim is PA_JUMP or PA_ROLL - players with SF_NOJUMPSPIN no longer use spinheight while jumping (but,) - PA_ROLL is now an acceptable condition for using spinheight (but not for entering gaps, e.g. S3K shields will shrink the hitbox but not allow gap entry on their own) - flying players now only use spinheight if they do not have SF_NOJUMPSPIN (you're welcome, EggpackRE) - players with neither SF_NOJUMPSPIN nor SF_NOJUMPDAMAGE use the same conditions as in 2.2.9 prerelease, i.e. use spinheight and can enter gaps unless they have PF_NOJUMPDAMAGE --- src/p_user.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 38f13f8fd..63942e0be 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12949,11 +12949,18 @@ boolean P_PlayerFullbright(player_t *player) && player->mo->state < &states[S_PLAY_NIGHTS_TRANS6])))); // Note the < instead of <= } +#define JUMPCURLED(player) ((player->pflags & PF_JUMPED)\ + && (!(player->charflags & SF_NOJUMPSPIN))\ + && (!(player->pflags & PF_NOJUMPDAMAGE)\ + || ((player->charflags & SF_NOJUMPDAMAGE)\ + && (player->panim == PA_JUMP || player->panim == PA_ROLL))))\ + // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) { - return ((player->pflags & (PF_SPINNING|PF_GLIDING)) - || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)); + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide + || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way } // returns true if the player should use their skin's spinheight instead of their skin's height @@ -12961,7 +12968,7 @@ boolean P_PlayerShouldUseSpinHeight(player_t *player) { return (P_PlayerCanEnterSpinGaps(player) || (player->mo->state == &states[player->mo->info->painstate]) - || ((player->pflags & PF_JUMPED) && !(player->pflags & PF_NOJUMPDAMAGE)) - || player->powers[pw_tailsfly] - || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)); + || (player->panim == PA_ROLL) + || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) + && !(player->charflags & SF_NOJUMPSPIN))); } From fdd02e35c8afc739916d3fbbc2fcf7deb465d7e1 Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 15:25:35 +1100 Subject: [PATCH 3/6] Fix P_PlayerCanEnterGaps issues with polyobject collision --- src/p_map.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 7eec0937c..bf668ba3e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1955,12 +1955,6 @@ static boolean PIT_CheckLine(line_t *ld) // set openrange, opentop, openbottom P_LineOpening(ld, tmthing); - // players should not always cross into sectors that they could not at full height - if (tmthing->player - && openrange < P_GetPlayerHeight(tmthing->player) - && !P_PlayerCanEnterSpinGaps(tmthing->player)) - return false; - // adjust floor / ceiling heights if (opentop < tmceilingz) { @@ -2729,7 +2723,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (thing->type == MT_SKIM) maxstep = 0; - if (tmceilingz - tmfloorz < thing->height) + if (tmceilingz - tmfloorz < thing->height + || (thing->player + && tmceilingz - tmfloorz < P_GetPlayerHeight(thing->player) + && !P_PlayerCanEnterSpinGaps(thing->player))) { if (tmfloorthing) tmhitthing = tmfloorthing; From b5c61a8a2afc2c042e4153e8f5091d509c1aa65d Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 21:41:09 +1100 Subject: [PATCH 4/6] Add PlayerHeight and PlayerCanEnterSpinGaps Lua hooks --- src/lua_hook.h | 4 +++ src/lua_hooklib.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 21 +++++++++-- 3 files changed, 112 insertions(+), 3 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 5cfcb8360..0d631aa4e 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -61,6 +61,8 @@ enum hook { hook_GameQuit, hook_PlayerCmd, hook_MusicChange, + hook_PlayerHeight, + hook_PlayerCanEnterSpinGaps, hook_MAX // last hook }; @@ -118,3 +120,5 @@ boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hoo void LUAh_GameQuit(boolean quitting); // Hook for game quitting boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Hook for building player's ticcmd struct (Ported from SRB2Kart) boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping, UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes +fixed_t LUAh_PlayerHeight(player_t *player); +UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player); diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 29c15a4de..6e9b9d65c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -77,6 +77,8 @@ const char *const hookNames[hook_MAX+1] = { "GameQuit", "PlayerCmd", "MusicChange", + "PlayerHeight", + "PlayerCanEnterSpinGaps", NULL }; @@ -221,6 +223,8 @@ static int lib_addHook(lua_State *L) case hook_ShieldSpawn: case hook_ShieldSpecial: case hook_PlayerThink: + case hook_PlayerHeight: + case hook_PlayerCanEnterSpinGaps: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -1971,3 +1975,89 @@ boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boo newname[6] = 0; return hooked; } + +// Hook for determining player height +fixed_t LUAh_PlayerHeight(player_t *player) +{ + hook_p hookp; + fixed_t newheight = -1; + if (!gL || !(hooksAvailable[hook_PlayerHeight/8] & (1<<(hook_PlayerHeight%8)))) + return 0; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerHeight) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + LUA_PushUserdata(gL, player, META_PLAYER); + PushHook(gL, hookp); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 1)) { + 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)) + { + fixed_t returnedheight = lua_tonumber(gL, -1); + // 0 height has... strange results, but it's not problematic like negative heights are. + // when an object's height is set to a negative number directly with lua, it's forced to 0 instead. + // here, I think it's better to ignore negatives so that they don't replace any results of previous hooks! + if (returnedheight >= 0) + newheight = returnedheight; + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return newheight; +} + +// Hook for determining whether players are allowed passage through spin gaps +UINT8 LUAh_PlayerCanEnterSpinGaps(player_t *player) +{ + hook_p hookp; + UINT8 canEnter = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_PlayerCanEnterSpinGaps/8] & (1<<(hook_PlayerCanEnterSpinGaps%8)))) + return 0; + + lua_settop(gL, 0); + lua_pushcfunction(gL, LUA_GetErrorMessage); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PlayerCanEnterSpinGaps) + continue; + + ps_lua_mobjhooks++; + if (lua_gettop(gL) == 1) + LUA_PushUserdata(gL, player, META_PLAYER); + PushHook(gL, hookp); + lua_pushvalue(gL, -2); + if (lua_pcall(gL, 1, 1, 1)) { + 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 canEnter = 0. + if (lua_toboolean(gL, -1)) + canEnter = 1; // Force yes + else + canEnter = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return canEnter; +} diff --git a/src/p_user.c b/src/p_user.c index 63942e0be..56767f433 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8651,9 +8651,16 @@ void P_MovePlayer(player_t *player) { boolean atspinheight = false; fixed_t oldheight = player->mo->height; + fixed_t luaheight = LUAh_PlayerHeight(player); + if (luaheight != -1) + { + player->mo->height = luaheight; + if (luaheight <= P_GetPlayerSpinHeight(player)) + atspinheight = true; // spinning will not save you from being crushed + } // Less height while spinning. Good for spinning under things...? - if (P_PlayerShouldUseSpinHeight(player)) + else if (P_PlayerShouldUseSpinHeight(player)) { player->mo->height = P_GetPlayerSpinHeight(player); atspinheight = true; @@ -12958,6 +12965,12 @@ boolean P_PlayerFullbright(player_t *player) // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) { + UINT8 canEnter = LUAh_PlayerCanEnterSpinGaps(player); + if (canEnter == 1) + return true; + else if (canEnter == 2) + return false; + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) // players who are spinning or gliding || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) // players who are landing from a glide || JUMPCURLED(player)); // players who are jumpcurled, but only if they would normally jump that way @@ -12966,9 +12979,11 @@ boolean P_PlayerCanEnterSpinGaps(player_t *player) // returns true if the player should use their skin's spinheight instead of their skin's height boolean P_PlayerShouldUseSpinHeight(player_t *player) { - return (P_PlayerCanEnterSpinGaps(player) + return ((player->pflags & (PF_SPINNING|PF_GLIDING)) || (player->mo->state == &states[player->mo->info->painstate]) || (player->panim == PA_ROLL) || ((player->powers[pw_tailsfly] || (player->charability == CA_FLY && player->mo->state-states == S_PLAY_FLY_TIRED)) - && !(player->charflags & SF_NOJUMPSPIN))); + && !(player->charflags & SF_NOJUMPSPIN)) + || (player->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING) + || JUMPCURLED(player)); } From c3caa55f22a0b957bf54800001c9516705d29b19 Mon Sep 17 00:00:00 2001 From: lachablock Date: Thu, 25 Mar 2021 21:42:25 +1100 Subject: [PATCH 5/6] Revise spinheight/gap entry conditions (again), let's keep things WAY simpler: - PF_NOJUMPDAMAGE no longer affects height at all (you're welcome katsy). - Characters with SF_NOJUMPSPIN will only use spinheight when panim is PA_ROLL. They cannot enter gaps when jumping with spinheight, unless also spinning or gliding. - All other characters use spinheight when panim is PA_JUMP or PA_ROLL. They can enter gaps when jumping with spinheight. --- src/p_user.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 56767f433..6c7cdb0d0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12958,9 +12958,7 @@ boolean P_PlayerFullbright(player_t *player) #define JUMPCURLED(player) ((player->pflags & PF_JUMPED)\ && (!(player->charflags & SF_NOJUMPSPIN))\ - && (!(player->pflags & PF_NOJUMPDAMAGE)\ - || ((player->charflags & SF_NOJUMPDAMAGE)\ - && (player->panim == PA_JUMP || player->panim == PA_ROLL))))\ + && (player->panim == PA_JUMP || player->panim == PA_ROLL))\ // returns true if the player can enter a sector that they could not if standing at their skin's full height boolean P_PlayerCanEnterSpinGaps(player_t *player) From b73e52476d1987a7c141cd76e586f76f5bd723bc Mon Sep 17 00:00:00 2001 From: lachablock Date: Fri, 26 Mar 2021 18:01:55 +1100 Subject: [PATCH 6/6] Fix LUAh_PlayerHeight returning wrong default value --- src/lua_hooklib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 6e9b9d65c..637809fd8 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1982,7 +1982,7 @@ fixed_t LUAh_PlayerHeight(player_t *player) hook_p hookp; fixed_t newheight = -1; if (!gL || !(hooksAvailable[hook_PlayerHeight/8] & (1<<(hook_PlayerHeight%8)))) - return 0; + return newheight; lua_settop(gL, 0); lua_pushcfunction(gL, LUA_GetErrorMessage);