mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-25 13:51:43 +00:00
Teetering now supports slopes properly.
Behaves ALMOST as you'd expect. It gets the z position of the slope at the player coordinates when it comes to the sectorlist check (which is first), though, so there's a few oddities that are amplified with steep slopes: * If the slope's sloping away from you at a steep angle, you might not be able to step down onto it, but you won't teeter (because it's at a step-down-able height if it extended to directly beneath you) * If the slope's sloping towards you at a steep angle, you might end up in teetering frames when you're able to step down onto it (because it's NOT at a step-down-able height if it extended to directly beneath you) HOWEVER, it would be pretty obnoxious to hold back code which is functionally superior in every way otherwise, and it doesn't really seem like there's a good way to get that checked tbph
This commit is contained in:
parent
3591e92dfa
commit
9d221f4f3f
1 changed files with 132 additions and 70 deletions
114
src/p_user.c
114
src/p_user.c
|
@ -2853,13 +2853,31 @@ static void P_DoTeeter(player_t *player)
|
||||||
boolean teeter = false;
|
boolean teeter = false;
|
||||||
boolean roverfloor; // solid 3d floors?
|
boolean roverfloor; // solid 3d floors?
|
||||||
boolean checkedforteeter = false;
|
boolean checkedforteeter = false;
|
||||||
|
fixed_t floorheight, ceilingheight;
|
||||||
|
fixed_t topheight, bottomheight; // for 3d floor usage
|
||||||
const fixed_t tiptop = FixedMul(MAXSTEPMOVE, player->mo->scale); // Distance you have to be above the ground in order to teeter.
|
const fixed_t tiptop = FixedMul(MAXSTEPMOVE, player->mo->scale); // Distance you have to be above the ground in order to teeter.
|
||||||
|
|
||||||
|
#define maxzdelta 3<<(FRACBITS-2) // 3/4 on the fixed scale
|
||||||
|
if (player->mo->standingslope && player->mo->standingslope->zdelta >= maxzdelta) // Always teeter if the slope is too steep.
|
||||||
|
teeter = true;
|
||||||
|
#undef maxzdelta
|
||||||
|
else // Let's do some checks...
|
||||||
|
{
|
||||||
for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
|
for (node = player->mo->touching_sectorlist; node; node = node->m_snext)
|
||||||
{
|
{
|
||||||
// Ledge teetering. Check if any nearby sectors are low enough from your current one.
|
// Ledge teetering. Check if any nearby sectors are low enough from your current one.
|
||||||
checkedforteeter = true;
|
checkedforteeter = true;
|
||||||
roverfloor = false;
|
roverfloor = false;
|
||||||
|
|
||||||
|
ceilingheight = node->m_sector->ceilingheight;
|
||||||
|
floorheight = node->m_sector->floorheight;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (node->m_sector->c_slope)
|
||||||
|
ceilingheight = P_GetZAt(node->m_sector->c_slope, player->mo->x, player->mo->y) + FixedMul(node->m_sector->c_slope->zdelta, tiptop);
|
||||||
|
if (node->m_sector->f_slope)
|
||||||
|
floorheight = P_GetZAt(node->m_sector->f_slope, player->mo->x, player->mo->y);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (node->m_sector->ffloors)
|
if (node->m_sector->ffloors)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
@ -2867,6 +2885,16 @@ static void P_DoTeeter(player_t *player)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS)) continue;
|
if (!(rover->flags & FF_EXISTS)) continue;
|
||||||
|
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->t_slope)
|
||||||
|
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
|
||||||
|
if (*rover->b_slope)
|
||||||
|
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (P_CheckSolidLava(player->mo, rover))
|
if (P_CheckSolidLava(player->mo, rover))
|
||||||
;
|
;
|
||||||
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
|
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
|
||||||
|
@ -2874,12 +2902,12 @@ static void P_DoTeeter(player_t *player)
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
{
|
||||||
if (*rover->bottomheight > node->m_sector->ceilingheight) // Above the ceiling
|
if (bottomheight > ceilingheight) // Above the ceiling
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*rover->bottomheight > player->mo->z + player->mo->height + tiptop
|
if (bottomheight > player->mo->z + player->mo->height + tiptop
|
||||||
|| (*rover->topheight < player->mo->z
|
|| (topheight < player->mo->z
|
||||||
&& player->mo->z + player->mo->height < node->m_sector->ceilingheight - tiptop))
|
&& player->mo->z + player->mo->height < ceilingheight - tiptop))
|
||||||
{
|
{
|
||||||
teeter = true;
|
teeter = true;
|
||||||
roverfloor = true;
|
roverfloor = true;
|
||||||
|
@ -2893,12 +2921,12 @@ static void P_DoTeeter(player_t *player)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*rover->topheight < node->m_sector->floorheight) // Below the floor
|
if (topheight < floorheight) // Below the floor
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*rover->topheight < player->mo->z - tiptop
|
if (topheight < player->mo->z - tiptop
|
||||||
|| (*rover->bottomheight > player->mo->z + player->mo->height
|
|| (bottomheight > player->mo->z + player->mo->height
|
||||||
&& player->mo->z > node->m_sector->floorheight + tiptop))
|
&& player->mo->z > floorheight + tiptop))
|
||||||
{
|
{
|
||||||
teeter = true;
|
teeter = true;
|
||||||
roverfloor = true;
|
roverfloor = true;
|
||||||
|
@ -2917,26 +2945,32 @@ static void P_DoTeeter(player_t *player)
|
||||||
{
|
{
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
{
|
||||||
if (node->m_sector->ceilingheight > player->mo->z + player->mo->height + tiptop)
|
if (ceilingheight > player->mo->z + player->mo->height + tiptop)
|
||||||
teeter = true;
|
teeter = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (node->m_sector->floorheight < player->mo->z - tiptop)
|
if (floorheight < player->mo->z - tiptop)
|
||||||
teeter = true;
|
teeter = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (checkedforteeter && !teeter) // Backup code
|
if (checkedforteeter && !teeter) // Backup code
|
||||||
{
|
{
|
||||||
subsector_t *subsec[4]; // changed abcd into array instead
|
subsector_t *subsec[4]; // changed abcd into array instead
|
||||||
|
fixed_t subsecfloorheight[4];
|
||||||
|
fixed_t subsecceilingheight[4];
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
|
// Following is replaced by xsign and ysign code
|
||||||
|
/*
|
||||||
subsec[0] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale));
|
subsec[0] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale));
|
||||||
subsec[1] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale));
|
subsec[1] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y + FixedMul(5*FRACUNIT, player->mo->scale));
|
||||||
subsec[2] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
|
subsec[2] = R_PointInSubsector(player->mo->x + FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
|
||||||
subsec[3] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
|
subsec[3] = R_PointInSubsector(player->mo->x - FixedMul(5*FRACUNIT, player->mo->scale), player->mo->y - FixedMul(5*FRACUNIT, player->mo->scale));
|
||||||
|
*/
|
||||||
|
|
||||||
teeter = false;
|
teeter = false;
|
||||||
roverfloor = false;
|
roverfloor = false;
|
||||||
|
@ -2944,6 +2978,24 @@ static void P_DoTeeter(player_t *player)
|
||||||
{
|
{
|
||||||
ffloor_t *rover;
|
ffloor_t *rover;
|
||||||
|
|
||||||
|
#define xsign ((i & 1) ? -1 : 1) // 0 -> 1 | 1 -> -1 | 2 -> 1 | 3 -> -1
|
||||||
|
#define ysign ((i & 2) ? 1 : -1) // 0 -> 1 | 1 -> 1 | 2 -> -1 | 3 -> -1
|
||||||
|
fixed_t checkx = player->mo->x + (xsign*FixedMul(5*FRACUNIT, player->mo->scale));
|
||||||
|
fixed_t checky = player->mo->y + (ysign*FixedMul(5*FRACUNIT, player->mo->scale));
|
||||||
|
|
||||||
|
subsec[i] = R_PointInSubsector(checkx, checky);
|
||||||
|
|
||||||
|
subsecceilingheight[i] = subsec[i]->sector->ceilingheight;
|
||||||
|
subsecfloorheight[i] = subsec[i]->sector->floorheight;
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (subsec[i]->sector->c_slope)
|
||||||
|
subsecceilingheight[i] = P_GetZAt(subsec[i]->sector->c_slope, checkx, checky);
|
||||||
|
if (subsec[i]->sector->f_slope)
|
||||||
|
subsecfloorheight[i] = P_GetZAt(subsec[i]->sector->f_slope, checkx, checky);
|
||||||
|
#endif
|
||||||
|
#undef xsign
|
||||||
|
#undef ysign
|
||||||
|
|
||||||
if (!(subsec[i]->sector->ffloors))
|
if (!(subsec[i]->sector->ffloors))
|
||||||
continue; // move on to the next subsector
|
continue; // move on to the next subsector
|
||||||
|
|
||||||
|
@ -2951,6 +3003,16 @@ static void P_DoTeeter(player_t *player)
|
||||||
{
|
{
|
||||||
if (!(rover->flags & FF_EXISTS)) continue;
|
if (!(rover->flags & FF_EXISTS)) continue;
|
||||||
|
|
||||||
|
topheight = *rover->topheight;
|
||||||
|
bottomheight = *rover->bottomheight;
|
||||||
|
|
||||||
|
#ifdef ESLOPE
|
||||||
|
if (*rover->t_slope)
|
||||||
|
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
|
||||||
|
if (*rover->b_slope)
|
||||||
|
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (P_CheckSolidLava(player->mo, rover))
|
if (P_CheckSolidLava(player->mo, rover))
|
||||||
;
|
;
|
||||||
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
|
else if (!(rover->flags & FF_BLOCKPLAYER || rover->flags & FF_QUICKSAND))
|
||||||
|
@ -2958,12 +3020,12 @@ static void P_DoTeeter(player_t *player)
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
{
|
||||||
if (*rover->bottomheight > subsec[i]->sector->ceilingheight) // Above the ceiling
|
if (bottomheight > subsecceilingheight[i]) // Above the ceiling
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*rover->bottomheight > player->mo->z + player->mo->height + tiptop
|
if (bottomheight > player->mo->z + player->mo->height + tiptop
|
||||||
|| (*rover->topheight < player->mo->z
|
|| (topheight < player->mo->z
|
||||||
&& player->mo->z + player->mo->height < subsec[i]->sector->ceilingheight - tiptop))
|
&& player->mo->z + player->mo->height < subsecceilingheight[i] - tiptop))
|
||||||
{
|
{
|
||||||
teeter = true;
|
teeter = true;
|
||||||
roverfloor = true;
|
roverfloor = true;
|
||||||
|
@ -2977,12 +3039,12 @@ static void P_DoTeeter(player_t *player)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*rover->topheight < subsec[i]->sector->floorheight) // Below the floor
|
if (topheight < subsecfloorheight[i]) // Below the floor
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (*rover->topheight < player->mo->z - tiptop
|
if (topheight < player->mo->z - tiptop
|
||||||
|| (*rover->bottomheight > player->mo->z + player->mo->height
|
|| (bottomheight > player->mo->z + player->mo->height
|
||||||
&& player->mo->z > subsec[i]->sector->floorheight + tiptop))
|
&& player->mo->z > subsecfloorheight[i] + tiptop))
|
||||||
{
|
{
|
||||||
teeter = true;
|
teeter = true;
|
||||||
roverfloor = true;
|
roverfloor = true;
|
||||||
|
@ -3000,18 +3062,18 @@ static void P_DoTeeter(player_t *player)
|
||||||
|
|
||||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||||
{
|
{
|
||||||
if (!teeter && !roverfloor && (subsec[0]->sector->ceilingheight > player->mo->ceilingz + tiptop
|
if (!teeter && !roverfloor && (subsecceilingheight[0] > player->mo->ceilingz + tiptop
|
||||||
|| subsec[1]->sector->ceilingheight > player->mo->ceilingz + tiptop
|
|| subsecceilingheight[1] > player->mo->ceilingz + tiptop
|
||||||
|| subsec[2]->sector->ceilingheight > player->mo->ceilingz + tiptop
|
|| subsecceilingheight[2] > player->mo->ceilingz + tiptop
|
||||||
|| subsec[3]->sector->ceilingheight > player->mo->ceilingz + tiptop))
|
|| subsecceilingheight[3] > player->mo->ceilingz + tiptop))
|
||||||
teeter = true;
|
teeter = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!teeter && !roverfloor && (subsec[0]->sector->floorheight < player->mo->floorz - tiptop
|
if (!teeter && !roverfloor && (subsecfloorheight[0] < player->mo->floorz - tiptop
|
||||||
|| subsec[1]->sector->floorheight < player->mo->floorz - tiptop
|
|| subsecfloorheight[1] < player->mo->floorz - tiptop
|
||||||
|| subsec[2]->sector->floorheight < player->mo->floorz - tiptop
|
|| subsecfloorheight[2] < player->mo->floorz - tiptop
|
||||||
|| subsec[3]->sector->floorheight < player->mo->floorz - tiptop))
|
|| subsecfloorheight[3] < player->mo->floorz - tiptop))
|
||||||
teeter = true;
|
teeter = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue