Convert displayexp math to fixed, use autocalibrated final checkpoint power

This commit is contained in:
Antonio Martinez 2025-09-23 17:07:01 -04:00 committed by AJ Martinez
parent 2be14316cf
commit d5f131dcc2
3 changed files with 33 additions and 28 deletions

View file

@ -4504,7 +4504,7 @@ void K_SpawnEXP(player_t *player, UINT8 exp, mobj_t *impact)
if (player->gradingpointnum == K_GetNumGradingPoints()) if (player->gradingpointnum == K_GetNumGradingPoints())
{ {
exp *= FINAL_CHECK_POWER; exp *= 3;
special = true; special = true;
} }
@ -17112,6 +17112,18 @@ static UINT8 K_Opponents(player_t *player)
return opponents; return opponents;
} }
fixed_t K_FinalCheckpointPower(void)
{
// How much of the final total is given out as a bonus for the last check?
fixed_t FINAL_CHECK_PERCENT = 25*FRACUNIT/100;
fixed_t theentirerace = K_GetNumGradingPoints()*FRACUNIT;
fixed_t theentireraceplusbonus = FixedDiv(theentirerace, FRACUNIT - FINAL_CHECK_PERCENT);
fixed_t bonusonly = theentireraceplusbonus - theentirerace;
return bonusonly;
}
static fixed_t K_GradingFactorPower(player_t *player, UINT32 gradingpoint) static fixed_t K_GradingFactorPower(player_t *player, UINT32 gradingpoint)
{ {
fixed_t power = EXP_POWER; // adjust to change overall exp volatility fixed_t power = EXP_POWER; // adjust to change overall exp volatility
@ -17130,7 +17142,7 @@ static fixed_t K_GradingFactorPower(player_t *player, UINT32 gradingpoint)
if (gradingpoint-1 == gp) if (gradingpoint-1 == gp)
{ {
power *= FINAL_CHECK_POWER; power += FixedMul(power, K_FinalCheckpointPower());
} }
return power; return power;
@ -17189,27 +17201,33 @@ fixed_t K_GetGradingFactorMinMax(player_t *player, boolean max)
UINT16 K_GetEXP(player_t *player) UINT16 K_GetEXP(player_t *player)
{ {
UINT32 gpn = player->gradingpointnum; fixed_t gradingpointnum = FRACUNIT * player->gradingpointnum;
UINT32 numgradingpoints = K_GetNumGradingPoints(); UINT32 numgradingpoints = K_GetNumGradingPoints();
UINT32 effgradingpoints = K_GetNumEffectiveGradingPoints(); fixed_t fixedgradingpoints = numgradingpoints * FRACUNIT;
fixed_t effgradingpoints = fixedgradingpoints + K_FinalCheckpointPower();
// Account for Final Check bonus // Account for Final Check bonus
if (gpn == numgradingpoints) if (player->gradingpointnum == numgradingpoints)
gpn = effgradingpoints; gradingpointnum = effgradingpoints;
fixed_t targetminexp = (EXP_MIN*gpn<<FRACBITS) / max(1,effgradingpoints); // about what a last place player should be at this stage of the race // fixed_t targetminexp = (EXP_MIN*gpn<<FRACBITS) / max(1,effgradingpoints); // about what a last place player should be at this stage of the race
fixed_t targetmaxexp = (EXP_MAX*gpn<<FRACBITS) / max(1,effgradingpoints); // about what a 1.0 factor should be at this stage of the race // fixed_t targetmaxexp = (EXP_MAX*gpn<<FRACBITS) / max(1,effgradingpoints); // about what a 1.0 factor should be at this stage of the race
fixed_t targetminexp = FixedDiv(EXP_MIN * gradingpointnum, max(FRACUNIT, effgradingpoints));
fixed_t targetmaxexp = FixedDiv(EXP_MAX * gradingpointnum, max(FRACUNIT, effgradingpoints));
fixed_t factormin = K_GetGradingFactorMinMax(player, false); fixed_t factormin = K_GetGradingFactorMinMax(player, false);
fixed_t factormax = K_GetGradingFactorMinMax(player, true); fixed_t factormax = K_GetGradingFactorMinMax(player, true);
UINT16 exp = FixedRescale(player->gradingfactor, factormin, factormax, Easing_Linear, targetminexp, targetmaxexp)>>FRACBITS; UINT16 exp = FixedRescale(player->gradingfactor, factormin, factormax, Easing_Linear, targetminexp, targetmaxexp)>>FRACBITS;
if (modeattacking) if (modeattacking)
exp = 100 * player->gradingpointnum / max(1, numgradingpoints); // No Final Check here, just a linear slide exp = EXP_MAX * player->gradingpointnum / max(1, numgradingpoints); // No Final Check here, just a linear slide
// CONS_Printf("Player %s numgradingpoints=%d gradingpoint=%d targetminexp=%d targetmaxexp=%d factor=%.2f factormin=%.2f factormax=%.2f exp=%d\n", /*
// player_names[player - players], numgradingpoints, player->gradingpointnum, targetminexp, targetmaxexp, FIXED_TO_FLOAT(player->gradingfactor), FIXED_TO_FLOAT(factormin), FIXED_TO_FLOAT(factormax), exp); if (!player->bot)
CONS_Printf("Player %s fcp=%d effgradingpoints=%d gradingpoint=%d targetminexp=%d targetmaxexp=%d factor=%.2f factormin=%.2f factormax=%.2f exp=%d\n",
player_names[player - players], K_FinalCheckpointPower(), effgradingpoints, gradingpointnum, targetminexp, targetmaxexp, FIXED_TO_FLOAT(player->gradingfactor), FIXED_TO_FLOAT(factormin), FIXED_TO_FLOAT(factormax), exp);
*/
return exp; return exp;
} }
@ -17222,16 +17240,6 @@ UINT32 K_GetNumGradingPoints(void)
return numlaps * (1 + Obj_GetCheckpointCount()); return numlaps * (1 + Obj_GetCheckpointCount());
} }
// Final check counts for extra, used for EXP minmax etc
UINT32 K_GetNumEffectiveGradingPoints(void)
{
UINT32 gp = K_GetNumGradingPoints();
if (gp == 0)
return 0;
else
return gp + FINAL_CHECK_POWER - 1;
}
// === // ===
// END EXP ZONE // END EXP ZONE
// === // ===

View file

@ -123,9 +123,6 @@ Make sure this matches the actual number of states
#define AUTORESPAWN_TIME (10*TICRATE) #define AUTORESPAWN_TIME (10*TICRATE)
#define AUTORESPAWN_THRESHOLD (7*TICRATE) #define AUTORESPAWN_THRESHOLD (7*TICRATE)
// How many checkpoints is the last checkpoint worth?
#define FINAL_CHECK_POWER (3)
angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed);
void K_PopBubbleShield(player_t *player); void K_PopBubbleShield(player_t *player);
@ -135,6 +132,7 @@ boolean K_DuelItemAlwaysSpawns(mapthing_t *mt);
boolean K_InRaceDuel(void); boolean K_InRaceDuel(void);
player_t *K_DuelOpponent(player_t *player); player_t *K_DuelOpponent(player_t *player);
fixed_t K_FinalCheckpointPower(void);
fixed_t K_EffectiveGradingFactor(const player_t *player); fixed_t K_EffectiveGradingFactor(const player_t *player);
#define MINGRADINGFACTOR (FRACUNIT/2) #define MINGRADINGFACTOR (FRACUNIT/2)
#define MINFRANTICFACTOR (8*FRACUNIT/10) #define MINFRANTICFACTOR (8*FRACUNIT/10)
@ -355,7 +353,6 @@ fixed_t K_GetGradingFactorMinMax(player_t *player, boolean max);
UINT16 K_GetEXP(player_t *player); UINT16 K_GetEXP(player_t *player);
UINT32 K_GetNumGradingPoints(void); UINT32 K_GetNumGradingPoints(void);
UINT32 K_GetNumEffectiveGradingPoints(void);
boolean K_LegacyRingboost(const player_t *player); boolean K_LegacyRingboost(const player_t *player);

View file

@ -392,9 +392,9 @@ void K_UpdatePowerLevels(player_t *player, UINT8 gradingpoint, boolean forfeit)
if (exitBonus) if (exitBonus)
{ {
ourinc *= FINAL_CHECK_POWER; ourinc = FixedMul(ourinc, K_FinalCheckpointPower());
theirinc *= FINAL_CHECK_POWER; theirinc = FixedMul(ourinc, K_FinalCheckpointPower());
CONS_Debug(DBG_PWRLV, "Final check bonus (%d / %d * %d = %d)\n", prevInc/FRACUNIT, dvs, FINAL_CHECK_POWER, ourinc/FRACUNIT); CONS_Debug(DBG_PWRLV, "Final check bonus (%d / %d * %d = %d)\n", prevInc/FRACUNIT, dvs, K_FinalCheckpointPower(), ourinc/FRACUNIT);
} }
else else
{ {