diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 916fa9254bd8f07b9c071e5848dff3e5d215f132..a59ba546e9bd5e4d9da6206759d05788f456a0ff 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 8caab0d2716f97f376580b7fc53f6660e5e7082d..8568dd4f8c2d58481c1b15e7b5a9e65a864f77bc 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 a1cad524e14e2739af074b9ea24887b0d077eb95..7eec0937c20d27f0d192879be94b7ecbadeeff9f 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 02592053d051eef2d72cc34de5a4f3cb4237b1fa..38f13f8fdf4e73faacc3a80407cbcd3515ca1176 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)); +}