PWR forfeit / calculation fixes

This commit is contained in:
Antonio Martinez 2025-08-25 02:46:08 -04:00
parent 487b7c0bb3
commit c0c71ab7ba
4 changed files with 32 additions and 25 deletions

View file

@ -182,10 +182,10 @@ INT16 K_CalculatePowerLevelAvg(void)
return (INT16)avg;
}
void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
void K_UpdatePowerLevels(player_t *player, UINT8 gradingpoint, boolean forfeit)
{
const UINT8 playerNum = player - players;
const boolean exitBonus = ((lap > numlaps) || (player->pflags & PF_NOCONTEST));
const boolean exitBonus = ((gradingpoint >= K_GetNumGradingPoints()) || (player->pflags & PF_NOCONTEST));
SINT8 powerType = K_UsingPowerLevels();
@ -204,13 +204,14 @@ void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
return;
}
if (!playeringame[playerNum] || player->spectator)
// Spectators don't have immunity if they're forfeiting: we're TRYING to punish them!
if (!playeringame[playerNum] || (player->spectator && !forfeit))
{
return;
}
CONS_Debug(DBG_PWRLV, "\n========\n");
CONS_Debug(DBG_PWRLV, "* Power Level change for player %s (LAP %d) *\n", player_names[playerNum], lap);
CONS_Debug(DBG_PWRLV, "* Power Level change for player %s (CHECKPOINT %d) *\n", player_names[playerNum], gradingpoint);
CONS_Debug(DBG_PWRLV, "========\n");
yourPower = clientpowerlevels[playerNum][powerType];
@ -310,7 +311,7 @@ void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
INT16 prevInc = inc;
// INT32 winnerscore = (yourScore > theirScore) ? player->duelscore : players[i].duelscore;
INT32 multiplier = 2;
INT16 multiplier = 2;
inc *= multiplier;
if (inc == 0)
@ -335,7 +336,11 @@ void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
{
INT16 prevInc = inc;
inc /= max(numlaps-1, 1);
// WARNING, BULLSHIT TYPING REASONS MAKE DOING THIS
// INLINE POSTFIX COMPLETE NONSENSE
// LIKE, -9 / 12 = 27000 NONSENSE
INT16 dvs = max(K_GetNumGradingPoints(), 1);
inc = inc / dvs;
if (inc == 0)
{
@ -349,7 +354,7 @@ void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
}
}
CONS_Debug(DBG_PWRLV, "Reduced (%d / %d = %d) because it's not the end of the race\n", prevInc, numlaps, inc);
CONS_Debug(DBG_PWRLV, "Reduced (%d / %d = %d) because it's not the end of the race\n", prevInc, dvs, inc);
}
}
@ -378,29 +383,31 @@ void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)
void K_UpdatePowerLevelsFinalize(player_t *player, boolean onForfeit)
{
// Finalize power level increments for any laps not yet calculated.
// Finalize power level increments for any checkpoints not yet calculated.
// For spectate / quit / NO CONTEST
INT16 lapsLeft = 0;
INT16 checksleft = 0;
UINT8 i;
// No remaining laps in Duel.
if (K_InRaceDuel())
return;
lapsLeft = (numlaps - player->latestlap) + 1;
checksleft = K_GetNumGradingPoints() - player->gradingpointnum;
if (lapsLeft <= 0)
if (checksleft <= 0)
{
// We've done every lap already.
// We've done every checkpoint already.
return;
}
for (i = 0; i < lapsLeft; i++)
for (i = 1; i <= checksleft; i++)
{
K_UpdatePowerLevels(player, player->latestlap + (i + 1), onForfeit);
K_UpdatePowerLevels(player, player->gradingpointnum + i, onForfeit);
}
player->latestlap = numlaps+1;
// Dubious, but if this is called multiple times better to not touch PWR?
// Only direct side effets should be on checkpoint cross...
player->gradingpointnum = K_GetNumGradingPoints();
}
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 baseInc)
@ -705,7 +712,7 @@ void K_PlayerForfeit(UINT8 playerNum, boolean pointLoss)
if (pointLoss)
{
clientpowerlevels[playerNum][powerType] += clientPowerAdd[playerNum];
clientpowerlevels[playerNum][powerType] += inc;
clientPowerAdd[playerNum] = 0;
SV_UpdateStats();
}

View file

@ -48,7 +48,7 @@ void K_ClearClientPowerLevels(void);
INT16 K_CalculatePowerLevelInc(INT16 diff);
INT16 K_PowerLevelPlacementScore(player_t *player);
INT16 K_CalculatePowerLevelAvg(void);
void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit);
void K_UpdatePowerLevels(player_t *player, UINT8 gradingpoint, boolean forfeit);
void K_UpdatePowerLevelsFinalize(player_t *player, boolean onForfeit);
INT16 K_FinalPowerIncrement(player_t *player, INT16 yourPower, INT16 increment);
void K_CashInPowerLevels(void);

View file

@ -520,8 +520,8 @@ struct CheckpointManager
chk->gingerbread();
}
void clear()
{
void clear()
{
lines_.clear();
list_.clear();
count_ = 0;
@ -588,7 +588,7 @@ void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y)
{
return;
}
LineOnDemand ray(old_x, old_y, player->mo->x, player->mo->y, player->mo->radius);
auto it = std::find_if(
@ -699,7 +699,7 @@ void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y)
K_SpawnEXP(player, expdiff, chk->other());
}
K_UpdatePowerLevels(player, player->laps, false);
K_UpdatePowerLevels(player, player->gradingpointnum, false);
}
mobj_t* Obj_FindCheckpoint(INT32 id)

View file

@ -2127,12 +2127,12 @@ static void K_HandleLapIncrement(player_t *player)
player->laptime[LAP_LAST] = player->laptime[LAP_CUR];
player->laptime[LAP_CUR] = 0;
// Update power levels for this lap.
K_UpdatePowerLevels(player, player->laps, false);
UINT16 oldexp = player->exp;
K_CheckpointCrossAward(player);
// Update power levels for this lap.
K_UpdatePowerLevels(player, player->gradingpointnum, false);
if (player->exp > oldexp)
{
K_SpawnFinishEXP(player, player->exp - oldexp);
@ -9638,7 +9638,7 @@ void P_DoQuakeOffset(UINT8 view, mappoint_t *viewPos, mappoint_t *offset)
{
if (r_splitscreen != 1)
maxShake = FixedMul(mapheaderinfo[gamemap-1]->cameraHeight, mapobjectscale) * 3 / 4;
// For 2p SPLITSCREEN SPECIFICALLY:
// The view is pretty narrow, so move it back 3/20 of the way towards default camera height.
else