Merge branch 'playercanenterspingaps' into 'next'

Do not let SF_NOJUMPSPIN characters enter sectors they could not enter if standing at full height (Closes #457)

Closes #457

See merge request STJr/SRB2!1432
This commit is contained in:
LJ Sonic 2021-03-31 16:15:35 -04:00
commit a584d7edea
6 changed files with 165 additions and 7 deletions

View file

@ -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},

View file

@ -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);

View file

@ -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 newheight;
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;
}

View file

@ -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);

View file

@ -2723,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;
@ -3331,6 +3334,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;
}

View file

@ -8651,14 +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 ((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))
else if (P_PlayerShouldUseSpinHeight(player))
{
player->mo->height = P_GetPlayerSpinHeight(player);
atspinheight = true;
@ -12953,3 +12955,33 @@ 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 <=
}
#define JUMPCURLED(player) ((player->pflags & PF_JUMPED)\
&& (!(player->charflags & SF_NOJUMPSPIN))\
&& (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)
{
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
}
// returns true if the player should use their skin's spinheight instead of their skin's height
boolean P_PlayerShouldUseSpinHeight(player_t *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->charability == CA_GLIDEANDCLIMB && player->mo->state-states == S_PLAY_GLIDE_LANDING)
|| JUMPCURLED(player));
}