Clean up water skip conditions

- Use Digital Empire's water running conditions (fully prevents ever being able to water-run on water that isn't level)
- Code cleanup of other parts of this code
- Made the threshold for water skipping much more strict
- Fixed water skip being scaled to player scale instead of map scale
- Make water run / tripwire easier for rubberbanding bots
This commit is contained in:
Sally Coolatta 2022-09-27 11:07:25 -04:00
parent 8811e66409
commit f6b62b6ac6
3 changed files with 119 additions and 31 deletions

View file

@ -3232,7 +3232,7 @@ tripwirepass_t K_TripwirePassConditions(player_t *player)
if (
player->flamedash ||
player->speed > 2 * K_GetKartSpeed(player, false, true)
player->speed > 2 * K_GetKartSpeed(player, false, false)
)
return TRIPWIRE_BOOST;
@ -3250,6 +3250,11 @@ boolean K_TripwirePass(player_t *player)
return (player->tripwirePass != TRIPWIRE_NONE);
}
boolean K_MovingHorizontally(mobj_t *mobj)
{
return (P_AproxDistance(mobj->momx, mobj->momy) / 5 > abs(mobj->momz));
}
boolean K_WaterRun(player_t *player)
{
if (
@ -3257,12 +3262,30 @@ boolean K_WaterRun(player_t *player)
player->sneakertimer ||
player->tiregrease ||
player->flamedash ||
player->speed > 2 * K_GetKartSpeed(player, false, true)
player->speed > 2 * K_GetKartSpeed(player, false, false)
)
return true;
return false;
}
boolean K_WaterSkip(player_t *player)
{
if (player->waterskip >= 2)
{
// Already finished waterskipping.
return false;
}
if (player->waterskip > 0)
{
// Already waterskipping.
// Simply make sure you haven't slowed down drastically.
return (player->speed > 20 * mapobjectscale);
}
return K_MovingHorizontally(player->mo);
}
static fixed_t K_FlameShieldDashVar(INT32 val)
{
// 1 second = 75% + 50% top speed

View file

@ -142,7 +142,9 @@ boolean K_ApplyOffroad(player_t *player);
boolean K_SlopeResistance(player_t *player);
tripwirepass_t K_TripwirePassConditions(player_t *player);
boolean K_TripwirePass(player_t *player);
boolean K_MovingHorizontally(mobj_t *mobj);
boolean K_WaterRun(player_t *player);
boolean K_WaterSkip(player_t *player);
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
INT16 K_GetSpindashChargeTime(player_t *player);
fixed_t K_GetSpindashChargeSpeed(player_t *player);

View file

@ -3073,25 +3073,92 @@ boolean P_SceneryZMovement(mobj_t *mo)
return true;
}
//
// P_CanRunOnWater
//
// Returns true if player can waterrun on the 3D floor
// Returns true if player can water run on a 3D floor
//
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{
boolean flip = player->mo->eflags & MFE_VERTICALFLIP;
fixed_t surfaceheight = flip ? player->mo->waterbottom : player->mo->watertop;
fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z;
fixed_t clip = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight);
fixed_t span = player->mo->watertop - player->mo->waterbottom;
const boolean flip = (player->mo->eflags & MFE_VERTICALFLIP);
fixed_t surfaceheight = INT32_MAX;
fixed_t playerbottom = INT32_MAX;
fixed_t surfDiff = INT32_MAX;
fixed_t maxStep = INT32_MAX;
boolean doifit = false;
return
clip > -(player->mo->height / 2) &&
span > player->mo->height &&
player->speed / 5 > abs(player->mo->momz) &&
player->speed > K_GetKartSpeed(player, false, false) &&
K_WaterRun(player) &&
(rover->flags & FF_SWIMMABLE);
pslope_t *waterSlope = NULL;
angle_t ourZAng = 0;
angle_t waterZAng = 0;
if (rover == NULL)
{
// No rover.
return false;
}
if (!(rover->flags & FF_SWIMMABLE))
{
// It's not even a water FOF.
return false;
}
if (player->carry != CR_NONE) // Special carry state.
{
// No good player state.
return false;
}
if (P_IsObjectOnGround(player->mo) == false)
{
// Don't allow jumping onto water to start a water run.
// (Already water running still counts as being on the ground.)
return false;
}
if (K_WaterRun(player) == false)
{
// Basic conditions for enabling water run.
return false;
}
if (player->mo->standingslope != NULL)
{
ourZAng = player->mo->standingslope->zangle;
}
waterSlope = (flip ? *rover->b_slope : *rover->t_slope);
if (waterSlope != NULL)
{
waterZAng = waterSlope->zangle;
}
if (ourZAng != waterZAng)
{
// The surface slopes are different.
return false;
}
surfaceheight = flip ? P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y) : P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y);
playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z;
doifit = flip ? (surfaceheight - player->mo->floorz >= player->mo->height) : (player->mo->ceilingz - surfaceheight >= player->mo->height);
if (!doifit)
{
// Player can't fit in this space.
return false;
}
surfDiff = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight);
maxStep = P_GetThingStepUp(player->mo);
if (surfDiff <= maxStep && surfDiff >= 0)
{
// We start water run IF we can step-down!
return true;
}
return false;
}
boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover)
@ -3308,23 +3375,19 @@ void P_MobjCheckWater(mobj_t *mobj)
splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale);
// skipping stone!
if (K_WaterSkip(p) == true)
{
const fixed_t hop = 5 * mapobjectscale;
mobj->momx = (4*mobj->momx)/5;
mobj->momy = (4*mobj->momy)/5;
mobj->momz = hop * P_MobjFlip(mobj);
p->waterskip++;
}
}
// skipping stone!
if (p && p->waterskip < 2
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|| (p->speed > 20*mapobjectscale && p->waterskip)) // Already skipped once, so you can skip once more!
&& (splashValid == true))
{
const fixed_t hop = 5 * mobj->scale;
mobj->momx = (4*mobj->momx)/5;
mobj->momy = (4*mobj->momy)/5;
mobj->momz = hop * P_MobjFlip(mobj);
p->waterskip++;
}
}
else if (P_MobjFlip(mobj) * mobj->momz > 0)
{