Fix double-exit conditions WITHOUT changing checkpoint count

This commit is contained in:
Antonio Martinez 2025-08-25 06:24:07 -04:00
parent c0c71ab7ba
commit 1e49453d78
5 changed files with 25 additions and 5 deletions

View file

@ -900,6 +900,8 @@ struct player_t
boolean pullup; // True if the player is attached to a pullup hook boolean pullup; // True if the player is attached to a pullup hook
boolean finalized; // Did PWR finalize already, don't repeat it even if exit conditions are weird.
tic_t ebrakefor; // Ebrake timer, used for visuals. tic_t ebrakefor; // Ebrake timer, used for visuals.
UINT16 faultflash; // Used for misc FAULT visuals UINT16 faultflash; // Used for misc FAULT visuals

View file

@ -2290,6 +2290,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
boolean cangrabitems; boolean cangrabitems;
boolean finalized;
SINT8 xtralife; SINT8 xtralife;
uint8_t public_key[PUBKEYLENGTH]; uint8_t public_key[PUBKEYLENGTH];
@ -2482,6 +2484,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
bigwaypointgap = 0; bigwaypointgap = 0;
duelscore = 0; duelscore = 0;
finalized = false;
tallyactive = false; tallyactive = false;
cangrabitems = 0; cangrabitems = 0;
@ -2518,6 +2522,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
gradingfactor = players[player].gradingfactor; gradingfactor = players[player].gradingfactor;
gradingpointnum = players[player].gradingpointnum; gradingpointnum = players[player].gradingpointnum;
finalized = players[player].finalized;
roundscore = players[player].roundscore; roundscore = players[player].roundscore;
exiting = players[player].exiting; exiting = players[player].exiting;
@ -2668,6 +2674,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->botvars.foe = botfoe; p->botvars.foe = botfoe;
p->xtralife = xtralife; p->xtralife = xtralife;
p->finalized = finalized;
// SRB2kart // SRB2kart
p->itemtype = itemtype; p->itemtype = itemtype;
p->itemamount = itemamount; p->itemamount = itemamount;

View file

@ -210,6 +210,13 @@ void K_UpdatePowerLevels(player_t *player, UINT8 gradingpoint, boolean forfeit)
return; return;
} }
// Probably being called from some stray codepath or a double exit.
// We have already finished calculating PWR, don't touch anything!
if (player->finalized)
{
return;
}
CONS_Debug(DBG_PWRLV, "\n========\n"); CONS_Debug(DBG_PWRLV, "\n========\n");
CONS_Debug(DBG_PWRLV, "* Power Level change for player %s (CHECKPOINT %d) *\n", player_names[playerNum], gradingpoint); CONS_Debug(DBG_PWRLV, "* Power Level change for player %s (CHECKPOINT %d) *\n", player_names[playerNum], gradingpoint);
CONS_Debug(DBG_PWRLV, "========\n"); CONS_Debug(DBG_PWRLV, "========\n");
@ -383,6 +390,9 @@ void K_UpdatePowerLevels(player_t *player, UINT8 gradingpoint, boolean forfeit)
void K_UpdatePowerLevelsFinalize(player_t *player, boolean onForfeit) void K_UpdatePowerLevelsFinalize(player_t *player, boolean onForfeit)
{ {
if (player->finalized)
return;
// Finalize power level increments for any checkpoints not yet calculated. // Finalize power level increments for any checkpoints not yet calculated.
// For spectate / quit / NO CONTEST // For spectate / quit / NO CONTEST
INT16 checksleft = 0; INT16 checksleft = 0;
@ -405,9 +415,7 @@ void K_UpdatePowerLevelsFinalize(player_t *player, boolean onForfeit)
K_UpdatePowerLevels(player, player->gradingpointnum + i, onForfeit); K_UpdatePowerLevels(player, player->gradingpointnum + i, onForfeit);
} }
// Dubious, but if this is called multiple times better to not touch PWR? player->finalized = true;
// Only direct side effets should be on checkpoint cross...
player->gradingpointnum = K_GetNumGradingPoints();
} }
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 baseInc) INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 baseInc)

View file

@ -610,6 +610,8 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT8(save->p, players[i].pullup); WRITEUINT8(save->p, players[i].pullup);
WRITEUINT8(save->p, players[i].finalized);
WRITEUINT32(save->p, players[i].ebrakefor); WRITEUINT32(save->p, players[i].ebrakefor);
WRITEUINT32(save->p, players[i].roundscore); WRITEUINT32(save->p, players[i].roundscore);
@ -1283,6 +1285,8 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].pullup = READUINT8(save->p); players[i].pullup = READUINT8(save->p);
players[i].finalized = READUINT8(save->p);
players[i].ebrakefor = READUINT32(save->p); players[i].ebrakefor = READUINT32(save->p);
players[i].roundscore = READUINT32(save->p); players[i].roundscore = READUINT32(save->p);

View file

@ -2129,8 +2129,6 @@ static void K_HandleLapIncrement(player_t *player)
UINT16 oldexp = player->exp; UINT16 oldexp = player->exp;
K_CheckpointCrossAward(player); K_CheckpointCrossAward(player);
// Update power levels for this lap.
K_UpdatePowerLevels(player, player->gradingpointnum, false); K_UpdatePowerLevels(player, player->gradingpointnum, false);
if (player->exp > oldexp) if (player->exp > oldexp)