G_CompatLevel

Checks for gameplay differences per DEMOVERSION. Allows us to make necessary handling changes without hurting the staff ghosts.
This commit is contained in:
Sally Coolatta 2024-04-29 11:02:03 -04:00
parent fd83529745
commit 6d63167a0d
4 changed files with 84 additions and 24 deletions

View file

@ -161,7 +161,23 @@ demoghost *ghosts = NULL;
// - 0x0009 (older staff ghosts)
// - Player names, skin names and color names were 16
// bytes. See get_buffer_sizes().
#define DEMOVERSION 0x000A
// - 0x000A (Ring Racers v2.0)
// - A bug was preventing control after ending a drift.
// Older behavior is kept around for staff ghost compat.
#define DEMOVERSION 0x000B
boolean G_CompatLevel(UINT16 level)
{
if (demo.playback)
{
// Check gameplay differences for older ghosts
return (demo.version <= level);
}
return false;
}
#define DEMOHEADER "\xF0" "KartReplay" "\x0F"
#define DF_ATTACKMASK (ATTACKING_TIME|ATTACKING_LAP|ATTACKING_SPB) // This demo contains time/lap data

View file

@ -170,6 +170,8 @@ extern UINT8 demo_writerng;
#define DXD_PST_SPECTATING 0x02
#define DXD_PST_LEFT 0x03
boolean G_CompatLevel(UINT16 level);
// Record/playback tics
void G_ReadDemoExtraData(void);
void G_WriteDemoExtraData(void);

View file

@ -10456,16 +10456,24 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
}
else
{
// Turning dampens as you go faster, but at extremely high speeds, keeping some control is important.
// Dampening is applied in two stages, one harsh and one soft.
// The harsh window is larger for characters with better baseline maneuverability.
// TODO COMPATLEVEL
// Was p_speed = min(stageSpeed, p_maxspeed * 2);
fixed_t stageSpeed = min(currentSpeed, (100 + 2*(9-player->kartweight)) * p_maxspeed/100);
if (stageSpeed < currentSpeed)
stageSpeed += (currentSpeed - stageSpeed) / 3;
if (G_CompatLevel(0x000A))
{
// Compat level for 2.0 staff ghosts
p_speed = min(currentSpeed, p_maxspeed * 2);
}
else
{
// Turning dampens as you go faster, but at extremely high speeds, keeping some control is important.
// Dampening is applied in two stages, one harsh and one soft.
// The harsh window is larger for characters with better baseline maneuverability.
fixed_t stageSpeed = min(currentSpeed, (100 + 2*(9-player->kartweight)) * p_maxspeed/100);
if (stageSpeed < currentSpeed)
{
stageSpeed += (currentSpeed - stageSpeed) / 3;
}
p_speed = min(stageSpeed, p_maxspeed * 2);
p_speed = min(stageSpeed, p_maxspeed * 2);
}
}
if (K_PodiumSequence() == true)
@ -10486,20 +10494,34 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
if (player->drift != 0 && P_IsObjectOnGround(player->mo))
{
if (player->pflags & PF_DRIFTEND)
if (G_CompatLevel(0x000A))
{
// Sal: K_GetKartDriftValue is short-circuited to give a weird additive magic number,
// instead of an entirely replaced turn value. This gaslit me years ago when I was doing a
// code readability pass, where I missed that fact because it also returned early.
// TODO COMPATLEVEL (I have no fucking clue what's going on here)
turnfixed += K_GetKartDriftValue(player, FRACUNIT) * FRACUNIT;
return (turnfixed / FRACUNIT);
// Compat level for 2.0 staff ghosts
fixed_t countersteer = FixedDiv(turnfixed, KART_FULLTURN * FRACUNIT);
if (player->pflags & PF_DRIFTEND)
{
countersteer = FRACUNIT;
}
return K_GetKartDriftValue(player, countersteer);
}
else
{
// If we're drifting we have a completely different turning value
fixed_t countersteer = FixedDiv(turnfixed, KART_FULLTURN * FRACUNIT);
return K_GetKartDriftValue(player, countersteer);
if (player->pflags & PF_DRIFTEND)
{
// Sal: K_GetKartDriftValue is short-circuited to give a weird additive magic number,
// instead of an entirely replaced turn value. This gaslit me years ago when I was doing a
// code readability pass, where I missed that fact because it also returned early.
turnfixed += K_GetKartDriftValue(player, FRACUNIT) * FRACUNIT;
return (turnfixed / FRACUNIT);
}
else
{
// If we're drifting we have a completely different turning value
fixed_t countersteer = FixedDiv(turnfixed, KART_FULLTURN * FRACUNIT);
return K_GetKartDriftValue(player, countersteer);
}
}
}
@ -10510,8 +10532,19 @@ INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
fixed_t topspeed = K_GetKartSpeed(player, false, false);
if (K_Sliptiding(player))
{
// TODO COMPATLEVEL (was 5*SLIPTIDEHANDLING/4)
finalhandleboost = FixedMul(3*SLIPTIDEHANDLING/4, FixedDiv(player->speed, topspeed));
fixed_t sliptide_handle;
if (G_CompatLevel(0x000A))
{
// Compat level for 2.0 staff ghosts
sliptide_handle = 5 * SLIPTIDEHANDLING / 4;
}
else
{
sliptide_handle = 3 * SLIPTIDEHANDLING / 4;
}
finalhandleboost = FixedMul(sliptide_handle, FixedDiv(player->speed, topspeed));
}
if (finalhandleboost > 0 && player->respawn.state == RESPAWNST_NONE)

View file

@ -2338,8 +2338,17 @@ static void P_UpdatePlayerAngle(player_t *player)
// That means undoing them takes the same amount of time as doing them.
// This can lead to oscillating death spiral states on a multi-tic correction, as we swing past the target angle.
// So before we go into death-spirals, if our predicton is _almost_ right...
// TODO COMPATLEVEL (was 4*ANG1/3)
angle_t leniency = (8*ANG1/3) * min(player->cmd.latency, 6);
angle_t leniency_base;
if (G_CompatLevel(0x000A))
{
// Compat level for 2.0 staff ghosts
leniency_base = 4 * ANG1 / 3;
}
else
{
leniency_base = 8 * ANG1 / 3;
}
angle_t leniency = leniency_base * min(player->cmd.latency, 6);
// Don't force another turning tic, just give them the desired angle!
if (targetDelta == angleChange || (maxTurnRight == 0 && maxTurnLeft == 0))