mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'final-check-exp' into 'master'
"Final checkpoint" EXP bonus See merge request kart-krew-dev/ring-racers-internal!2878
This commit is contained in:
commit
fc4a2e9f80
7 changed files with 90 additions and 42 deletions
|
|
@ -757,8 +757,8 @@ extern int
|
||||||
#define EXP_STABLERATE 3*FRACUNIT/10 // how low is your placement before losing XP? 4*FRACUNIT/10 = top 40% of race will gain
|
#define EXP_STABLERATE 3*FRACUNIT/10 // how low is your placement before losing XP? 4*FRACUNIT/10 = top 40% of race will gain
|
||||||
#define EXP_POWER 3*FRACUNIT/100 // adjust to change overall xp volatility
|
#define EXP_POWER 3*FRACUNIT/100 // adjust to change overall xp volatility
|
||||||
#define EXP_MIN 25 // The min value target
|
#define EXP_MIN 25 // The min value target
|
||||||
#define EXP_TARGET 120 // Used for grading ...
|
#define EXP_TARGET 150 // Used for grading ...
|
||||||
#define EXP_MAX 120 // The max value displayed by the hud and in the tally screen and GP results screen
|
#define EXP_MAX 150 // The max value displayed by the hud and in the tally screen and GP results screen
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
|
||||||
|
|
@ -3307,19 +3307,13 @@ static void K_drawKartEmeralds(void)
|
||||||
|
|
||||||
INT32 K_GetTransFlagFromFixed(fixed_t value, boolean midrace)
|
INT32 K_GetTransFlagFromFixed(fixed_t value, boolean midrace)
|
||||||
{
|
{
|
||||||
fixed_t base = midrace ? GRADINGFACTORSOFTCAP : FRACUNIT;
|
fixed_t base = FRACUNIT;
|
||||||
|
|
||||||
value = std::clamp(value, base - FRACUNIT/2, base + FRACUNIT/2);
|
value = std::clamp(value, base - FRACUNIT/2, base + FRACUNIT/2);
|
||||||
|
|
||||||
// Calculate distance from "base""
|
// Calculate distance from "base""
|
||||||
fixed_t distance = abs(base - value);
|
fixed_t distance = abs(base - value);
|
||||||
|
|
||||||
if (midrace)
|
|
||||||
{
|
|
||||||
if (value > base)
|
|
||||||
distance = FixedMul(distance, GRADINGFACTORCAPSTRENGTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
distance = std::clamp(distance, 0, FRACUNIT/2);
|
distance = std::clamp(distance, 0, FRACUNIT/2);
|
||||||
|
|
||||||
// Map the distance to 0-10 range (10 = closest to 1.0, 0 = farthest from 1.0)
|
// Map the distance to 0-10 range (10 = closest to 1.0, 0 = farthest from 1.0)
|
||||||
|
|
|
||||||
89
src/k_kart.c
89
src/k_kart.c
|
|
@ -158,11 +158,8 @@ fixed_t K_EffectiveGradingFactor(const player_t *player)
|
||||||
return min;
|
return min;
|
||||||
|
|
||||||
fixed_t gf = player->gradingfactor;
|
fixed_t gf = player->gradingfactor;
|
||||||
|
if (franticitems)
|
||||||
if (gf > GRADINGFACTORSOFTCAP && !K_PlayerUsesBotMovement(player))
|
gf = (gf + FRACUNIT)/2;
|
||||||
gf = GRADINGFACTORSOFTCAP + FixedDiv(gf - GRADINGFACTORSOFTCAP, GRADINGFACTORCAPSTRENGTH);
|
|
||||||
|
|
||||||
gf = (gf + FRACUNIT)/2;
|
|
||||||
|
|
||||||
return max(min, gf);
|
return max(min, gf);
|
||||||
}
|
}
|
||||||
|
|
@ -4500,6 +4497,15 @@ void K_SpawnEXP(player_t *player, UINT8 exp, mobj_t *impact)
|
||||||
if (exp == 0)
|
if (exp == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
boolean special = false;
|
||||||
|
|
||||||
|
if (player->gradingpointnum == K_GetNumGradingPoints())
|
||||||
|
{
|
||||||
|
exp *= 3;
|
||||||
|
special = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < exp; i++)
|
for (int i = 0; i < exp; i++)
|
||||||
{
|
{
|
||||||
mobj_t *pickup = P_SpawnMobj(impact->x, impact->y, impact->z, MT_EXP);
|
mobj_t *pickup = P_SpawnMobj(impact->x, impact->y, impact->z, MT_EXP);
|
||||||
|
|
@ -4510,6 +4516,14 @@ void K_SpawnEXP(player_t *player, UINT8 exp, mobj_t *impact)
|
||||||
pickup->momy += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
|
pickup->momy += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
|
||||||
pickup->momz += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
|
pickup->momz += P_RandomRange(PR_ITEM_DEBRIS, -20*mapobjectscale, 20*mapobjectscale);
|
||||||
// pickup->color = player->skincolor;
|
// pickup->color = player->skincolor;
|
||||||
|
|
||||||
|
if (special)
|
||||||
|
{
|
||||||
|
P_InstaScale(pickup, 3*pickup->scale/2);
|
||||||
|
pickup->color = SKINCOLOR_SAPPHIRE;
|
||||||
|
pickup->colorized = true;
|
||||||
|
}
|
||||||
|
|
||||||
P_SetTarget(&pickup->target, player->mo);
|
P_SetTarget(&pickup->target, player->mo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4719,7 +4733,7 @@ void K_CheckpointCrossAward(player_t *player)
|
||||||
K_HandleRaceSplits(player, leveltime - starttime, player->gradingpointnum);
|
K_HandleRaceSplits(player, leveltime - starttime, player->gradingpointnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
player->gradingfactor += K_GetGradingFactorAdjustment(player);
|
player->gradingfactor += K_GetGradingFactorAdjustment(player, player->gradingpointnum);
|
||||||
player->gradingpointnum++;
|
player->gradingpointnum++;
|
||||||
player->exp = K_GetEXP(player);
|
player->exp = K_GetEXP(player);
|
||||||
//CONS_Printf("player: %s factor: %.2f exp: %d\n", player_names[player-players], FIXED_TO_FLOAT(player->gradingfactor), player->exp);
|
//CONS_Printf("player: %s factor: %.2f exp: %d\n", player_names[player-players], FIXED_TO_FLOAT(player->gradingfactor), player->exp);
|
||||||
|
|
@ -17095,7 +17109,19 @@ static UINT8 K_Opponents(player_t *player)
|
||||||
return opponents;
|
return opponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fixed_t K_GradingFactorPower(player_t *player)
|
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)
|
||||||
{
|
{
|
||||||
fixed_t power = EXP_POWER; // adjust to change overall exp volatility
|
fixed_t power = EXP_POWER; // adjust to change overall exp volatility
|
||||||
UINT8 opponents = K_Opponents(player);
|
UINT8 opponents = K_Opponents(player);
|
||||||
|
|
@ -17109,23 +17135,30 @@ static fixed_t K_GradingFactorPower(player_t *player)
|
||||||
if (opponents > 8)
|
if (opponents > 8)
|
||||||
power -= (opponents - 8) * (power/24);
|
power -= (opponents - 8) * (power/24);
|
||||||
|
|
||||||
|
UINT32 gp = K_GetNumGradingPoints();
|
||||||
|
|
||||||
|
if (gradingpoint-1 == gp)
|
||||||
|
{
|
||||||
|
power += FixedMul(power, K_FinalCheckpointPower());
|
||||||
|
}
|
||||||
|
|
||||||
return power;
|
return power;
|
||||||
}
|
}
|
||||||
|
|
||||||
static fixed_t K_GradingFactorGainPerWin(player_t *player)
|
static fixed_t K_GradingFactorGainPerWin(player_t *player, UINT32 gradingpoint)
|
||||||
{
|
{
|
||||||
return K_GradingFactorPower(player);
|
return K_GradingFactorPower(player, gradingpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
static fixed_t K_GradingFactorDrainPerCheckpoint(player_t *player)
|
static fixed_t K_GradingFactorDrainPerCheckpoint(player_t *player, UINT32 gradingpoint)
|
||||||
{
|
{
|
||||||
// EXP_STABLERATE: How low do you have to place before losing gradingfactor? 4*FRACUNIT/10 = top 40% of race gains, 60% loses.
|
// EXP_STABLERATE: How low do you have to place before losing gradingfactor? 4*FRACUNIT/10 = top 40% of race gains, 60% loses.
|
||||||
UINT8 opponents = K_Opponents(player);
|
UINT8 opponents = K_Opponents(player);
|
||||||
fixed_t power = K_GradingFactorPower(player);
|
fixed_t power = K_GradingFactorPower(player, gradingpoint);
|
||||||
return FixedMul(power, FixedMul(opponents*FRACUNIT, FRACUNIT - EXP_STABLERATE));
|
return FixedMul(power, FixedMul(opponents*FRACUNIT, FRACUNIT - EXP_STABLERATE));
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t K_GetGradingFactorAdjustment(player_t *player)
|
fixed_t K_GetGradingFactorAdjustment(player_t *player, UINT32 gradingpoint)
|
||||||
{
|
{
|
||||||
fixed_t result = 0;
|
fixed_t result = 0;
|
||||||
|
|
||||||
|
|
@ -17136,13 +17169,13 @@ fixed_t K_GetGradingFactorAdjustment(player_t *player)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (player->position < players[i].position)
|
if (player->position < players[i].position)
|
||||||
result += K_GradingFactorGainPerWin(player);
|
result += K_GradingFactorGainPerWin(player, gradingpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...then take all of the gradingfactor you could possibly have earned,
|
// ...then take all of the gradingfactor you could possibly have earned,
|
||||||
// and lose it proportional to the stable rate. If you're below
|
// and lose it proportional to the stable rate. If you're below
|
||||||
// the stable threshold, this results in you losing gradingfactor
|
// the stable threshold, this results in you losing gradingfactor
|
||||||
result -= K_GradingFactorDrainPerCheckpoint(player);
|
result -= K_GradingFactorDrainPerCheckpoint(player, gradingpoint);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -17156,8 +17189,8 @@ fixed_t K_GetGradingFactorMinMax(player_t *player, boolean max)
|
||||||
for (UINT8 i = 0; i < player->gradingpointnum; i++) // For each gradingpoint you've reached...
|
for (UINT8 i = 0; i < player->gradingpointnum; i++) // For each gradingpoint you've reached...
|
||||||
{
|
{
|
||||||
for (UINT8 j = 0; j < winning; j++)
|
for (UINT8 j = 0; j < winning; j++)
|
||||||
factor += K_GradingFactorGainPerWin(player); // If max, increase gradingfactor for each player you could have been beating.
|
factor += K_GradingFactorGainPerWin(player, i); // If max, increase gradingfactor for each player you could have been beating.
|
||||||
factor -= K_GradingFactorDrainPerCheckpoint(player); // Then, drain like usual.
|
factor -= K_GradingFactorDrainPerCheckpoint(player, i); // Then, drain like usual.
|
||||||
}
|
}
|
||||||
|
|
||||||
return factor;
|
return factor;
|
||||||
|
|
@ -17165,19 +17198,33 @@ fixed_t K_GetGradingFactorMinMax(player_t *player, boolean max)
|
||||||
|
|
||||||
UINT16 K_GetEXP(player_t *player)
|
UINT16 K_GetEXP(player_t *player)
|
||||||
{
|
{
|
||||||
|
fixed_t gradingpointnum = FRACUNIT * player->gradingpointnum;
|
||||||
|
|
||||||
UINT32 numgradingpoints = K_GetNumGradingPoints();
|
UINT32 numgradingpoints = K_GetNumGradingPoints();
|
||||||
fixed_t targetminexp = (EXP_MIN*player->gradingpointnum<<FRACBITS) / max(1,numgradingpoints); // about what a last place player should be at this stage of the race
|
fixed_t fixedgradingpoints = numgradingpoints * FRACUNIT;
|
||||||
fixed_t targetmaxexp = (EXP_MAX*player->gradingpointnum<<FRACBITS) / max(1,numgradingpoints); // about what a 1.0 factor should be at this stage of the race
|
fixed_t effgradingpoints = fixedgradingpoints + K_FinalCheckpointPower();
|
||||||
|
|
||||||
|
// Account for Final Check bonus
|
||||||
|
if (player->gradingpointnum == numgradingpoints)
|
||||||
|
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 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 / numgradingpoints;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,10 @@ 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)
|
||||||
#define GRADINGFACTORSOFTCAP (2*FRACUNIT)
|
|
||||||
#define GRADINGFACTORCAPSTRENGTH (3*FRACUNIT)
|
|
||||||
|
|
||||||
void K_TimerReset(void);
|
void K_TimerReset(void);
|
||||||
void K_TimerInit(void);
|
void K_TimerInit(void);
|
||||||
|
|
@ -347,7 +346,7 @@ boolean K_ThunderDome(void);
|
||||||
|
|
||||||
boolean K_PlayerCanUseItem(player_t *player);
|
boolean K_PlayerCanUseItem(player_t *player);
|
||||||
|
|
||||||
fixed_t K_GetGradingFactorAdjustment(player_t *player);
|
fixed_t K_GetGradingFactorAdjustment(player_t *player, UINT32 gradingpoint);
|
||||||
fixed_t K_GetGradingFactorMinMax(player_t *player, boolean max);
|
fixed_t K_GetGradingFactorMinMax(player_t *player, boolean max);
|
||||||
UINT16 K_GetEXP(player_t *player);
|
UINT16 K_GetEXP(player_t *player);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -384,14 +384,20 @@ void K_UpdatePowerLevels(player_t *player, UINT8 gradingpoint, boolean forfeit)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (exitBonus == false)
|
fixed_t prevInc = ourinc;
|
||||||
|
|
||||||
|
INT16 dvs = max(K_GetNumGradingPoints(), 1);
|
||||||
|
ourinc = FixedDiv(ourinc, dvs*FRACUNIT);
|
||||||
|
theirinc = FixedDiv(theirinc, dvs*FRACUNIT);
|
||||||
|
|
||||||
|
if (exitBonus)
|
||||||
|
{
|
||||||
|
ourinc = FixedMul(ourinc, FRACUNIT + K_FinalCheckpointPower());
|
||||||
|
theirinc = FixedMul(theirinc, FRACUNIT + K_FinalCheckpointPower());
|
||||||
|
CONS_Debug(DBG_PWRLV, "Final check bonus (%d / %d * %d = %d)\n", prevInc/FRACUNIT, dvs, K_FinalCheckpointPower(), ourinc/FRACUNIT);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
fixed_t prevInc = ourinc;
|
|
||||||
|
|
||||||
INT16 dvs = max(K_GetNumGradingPoints(), 1);
|
|
||||||
ourinc = FixedDiv(ourinc, dvs*FRACUNIT);
|
|
||||||
theirinc = FixedDiv(theirinc, dvs*FRACUNIT);
|
|
||||||
|
|
||||||
CONS_Debug(DBG_PWRLV, "Reduced (%d / %d = %d) because it's not the end of the race\n", prevInc/FRACUNIT, dvs, ourinc/FRACUNIT);
|
CONS_Debug(DBG_PWRLV, "Reduced (%d / %d = %d) because it's not the end of the race\n", prevInc/FRACUNIT, dvs, ourinc/FRACUNIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -432,6 +438,8 @@ void K_UpdatePowerLevelsFinalize(player_t *player, boolean onForfeit)
|
||||||
|
|
||||||
if (checksleft <= 0)
|
if (checksleft <= 0)
|
||||||
{
|
{
|
||||||
|
if (!(gametyperules & GTR_CHECKPOINTS)) // We should probably do at least _one_ PWR update.
|
||||||
|
K_UpdatePowerLevels(player, player->gradingpointnum, onForfeit);
|
||||||
// We've done every checkpoint already.
|
// We've done every checkpoint already.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1457,7 +1457,7 @@ void K_FillItemRouletteData(player_t *player, itemroulette_t *const roulette, bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t largegamescaler = roulette->playing * 5 + 100; // Spread out item odds in large games for a less insane experience.
|
fixed_t largegamescaler = roulette->playing * 8 + 100; // Spread out item odds in large games for a less insane experience.
|
||||||
if (franticitems)
|
if (franticitems)
|
||||||
largegamescaler = 100; // Except in Frantic, where you know what you're getting
|
largegamescaler = 100; // Except in Frantic, where you know what you're getting
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,7 @@ INT32 level_tally_t::CalculateGrade(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const INT32 positionWeight = (position > 0 && numPlayers > 2) ? 50 : 0;
|
const INT32 positionWeight = 0; // (position > 0 && numPlayers > 2) ? 50 : 0;
|
||||||
const INT32 total = positionWeight + bonusWeights[0] + bonusWeights[1];
|
const INT32 total = positionWeight + bonusWeights[0] + bonusWeights[1];
|
||||||
|
|
||||||
INT32 ours = 0;
|
INT32 ours = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue