mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'more-exp-stuff' into 'master'
Exp Improvements See merge request kart-krew-dev/ring-racers-internal!2577
This commit is contained in:
commit
1cdf381aba
8 changed files with 82 additions and 44 deletions
|
|
@ -745,7 +745,7 @@ extern int
|
||||||
#define MAXAMPSCALINGDIST 18000
|
#define MAXAMPSCALINGDIST 18000
|
||||||
|
|
||||||
// Exp
|
// Exp
|
||||||
#define MINEXP 50 // The min value target
|
#define MINEXP 25 // The min value target
|
||||||
#define TARGETEXP 100 // The target value needed for A rank
|
#define TARGETEXP 100 // The target value needed for A rank
|
||||||
#define MAXEXP 125 // The max value displayed by the hud and in the tally screen and GP results screen
|
#define MAXEXP 125 // The max value displayed by the hud and in the tally screen and GP results screen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,31 +67,6 @@ INT16 K_CalculateGPRankPoints(UINT16 exp, UINT8 position, UINT8 numplayers)
|
||||||
|
|
||||||
points = exp;
|
points = exp;
|
||||||
|
|
||||||
// Give bonus to high-ranking players, depending on player count
|
|
||||||
// This rounds out the point gain when you get 1st every race,
|
|
||||||
// and gives bots able to catch up in points if a player gets an early lead.
|
|
||||||
// The maximum points you can get in a cup is: ((number of players - 1) + (max extra points)) * (number of races)
|
|
||||||
// 8P: (7 + 5) * 5 = 60 maximum points
|
|
||||||
// 12P: (11 + 5) * 5 = 80 maximum points
|
|
||||||
// 16P: (15 + 5) * 5 = 100 maximum points
|
|
||||||
switch (numplayers)
|
|
||||||
{
|
|
||||||
case 0: case 1: case 2: // 1v1
|
|
||||||
break; // No bonus needed.
|
|
||||||
case 3: case 4: // 3-4P
|
|
||||||
if (position == 1) { points += 5; } // 1st gets +1 extra point
|
|
||||||
break;
|
|
||||||
case 5: case 6: // 5-6P
|
|
||||||
if (position == 1) { points += 10; } // 1st gets +3 extra points
|
|
||||||
// else if (position == 2) { points += 4; } // 2nd gets +1 extra point
|
|
||||||
break;
|
|
||||||
default: // Normal matches
|
|
||||||
if (position == 1) { points += 10; } // 1st gets +5 extra points
|
|
||||||
// else if (position == 2) { points += 5; } // 2nd gets +3 extra points
|
|
||||||
// else if (position == 3) { points += 2; } // 3rd gets +1 extra point
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// somehow underflowed?
|
// somehow underflowed?
|
||||||
if (points < 0)
|
if (points < 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6888,10 +6888,8 @@ static void K_DrawGPRankDebugger(void)
|
||||||
|
|
||||||
V_DrawThinString(0, 0, V_SNAPTOTOP|V_SNAPTOLEFT,
|
V_DrawThinString(0, 0, V_SNAPTOTOP|V_SNAPTOLEFT,
|
||||||
va("POS: %d / %d", grandprixinfo.rank.position, RANK_NEUTRAL_POSITION));
|
va("POS: %d / %d", grandprixinfo.rank.position, RANK_NEUTRAL_POSITION));
|
||||||
V_DrawThinString(0, 10, V_SNAPTOTOP|V_SNAPTOLEFT,
|
|
||||||
va("PTS: %d / %d", grandprixinfo.rank.winPoints, grandprixinfo.rank.totalPoints));
|
|
||||||
V_DrawThinString(0, 20, V_SNAPTOTOP|V_SNAPTOLEFT,
|
V_DrawThinString(0, 20, V_SNAPTOTOP|V_SNAPTOLEFT,
|
||||||
va("LAPS: %d / %d", grandprixinfo.rank.exp, grandprixinfo.rank.totalExp));
|
va("EXP: %d / %d", grandprixinfo.rank.exp, grandprixinfo.rank.totalExp));
|
||||||
V_DrawThinString(0, 30, V_SNAPTOTOP|V_SNAPTOLEFT,
|
V_DrawThinString(0, 30, V_SNAPTOTOP|V_SNAPTOLEFT,
|
||||||
va("CONTINUES: %d", grandprixinfo.rank.continuesUsed));
|
va("CONTINUES: %d", grandprixinfo.rank.continuesUsed));
|
||||||
V_DrawThinString(0, 40, V_SNAPTOTOP|V_SNAPTOLEFT,
|
V_DrawThinString(0, 40, V_SNAPTOTOP|V_SNAPTOLEFT,
|
||||||
|
|
|
||||||
56
src/k_kart.c
56
src/k_kart.c
|
|
@ -4270,7 +4270,7 @@ void K_CheckpointCrossAward(player_t *player)
|
||||||
if (gametype != GT_RACE)
|
if (gametype != GT_RACE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
player->gradingfactor += K_GetGradingMultAdjustment(player);
|
player->gradingfactor += K_GetGradingFactorAdjustment(player);
|
||||||
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);
|
||||||
|
|
@ -15647,7 +15647,7 @@ boolean K_PlayerCanUseItem(player_t *player)
|
||||||
return (player->mo->health > 0 && !player->spectator && !P_PlayerInPain(player) && !mapreset && leveltime > introtime);
|
return (player->mo->health > 0 && !player->spectator && !P_PlayerInPain(player) && !mapreset && leveltime > introtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_t K_GetGradingMultAdjustment(player_t *player)
|
fixed_t K_GetGradingFactorAdjustment(player_t *player)
|
||||||
{
|
{
|
||||||
fixed_t power = 3*FRACUNIT/100; // adjust to change overall xp volatility
|
fixed_t power = 3*FRACUNIT/100; // adjust to change overall xp volatility
|
||||||
fixed_t stablerate = 3*FRACUNIT/10; // how low is your placement before losing XP? 4*FRACUNIT/10 = top 40% of race will gain
|
fixed_t stablerate = 3*FRACUNIT/10; // how low is your placement before losing XP? 4*FRACUNIT/10 = top 40% of race will gain
|
||||||
|
|
@ -15701,13 +15701,57 @@ fixed_t K_GetGradingMultAdjustment(player_t *player)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fixed_t K_GetGradingFactorMinMax(UINT32 gradingpointnum, boolean max)
|
||||||
|
{
|
||||||
|
// Create a dummy player structure for the theoretical last-place player
|
||||||
|
player_t dummy_player;
|
||||||
|
memset(&dummy_player, 0, sizeof(player_t));
|
||||||
|
dummy_player.gradingfactor = FRACUNIT; // Start at 1.0
|
||||||
|
|
||||||
|
if (G_GametypeHasTeams())
|
||||||
|
{
|
||||||
|
const UINT8 orange_count = G_CountTeam(TEAM_ORANGE);
|
||||||
|
const UINT8 blue_count = G_CountTeam(TEAM_BLUE);
|
||||||
|
if (orange_count <= blue_count)
|
||||||
|
{
|
||||||
|
dummy_player.team = TEAM_ORANGE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dummy_player.team = TEAM_BLUE;
|
||||||
|
}
|
||||||
|
dummy_player.position = max ? 0 : D_NumPlayersInRace() + 1; // Ensures that all enemy players are counted, and our dummy won't overlap
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dummy_player.position = max ? 1 : D_NumPlayersInRace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the adjustment for each grading point
|
||||||
|
for (UINT32 i = 0; i < gradingpointnum; i++)
|
||||||
|
{
|
||||||
|
dummy_player.gradingfactor += K_GetGradingFactorAdjustment(&dummy_player);
|
||||||
|
}
|
||||||
|
return dummy_player.gradingfactor;
|
||||||
|
}
|
||||||
|
|
||||||
UINT16 K_GetEXP(player_t *player)
|
UINT16 K_GetEXP(player_t *player)
|
||||||
{
|
{
|
||||||
UINT32 numgradingpoints = K_GetNumGradingPoints();
|
UINT32 numgradingpoints = K_GetNumGradingPoints();
|
||||||
// target is where you should be if you're doing good and at a 1.0 mult
|
UINT16 targetminexp = (MINEXP*player->gradingpointnum/max(1,numgradingpoints)); // about what a last place player should be at this stage of the race
|
||||||
fixed_t clampedmult = max(FRACUNIT/2, min(FRACUNIT*5/4, player->gradingfactor)); // clamp between 0.5 and 1.25
|
UINT16 targetexp = (MAXEXP*player->gradingpointnum/max(1,numgradingpoints)); // about what a 1.0 factor should be at this stage of the race
|
||||||
fixed_t targetexp = (TARGETEXP*player->gradingpointnum/max(1,numgradingpoints))<<FRACBITS;
|
fixed_t factormin = K_GetGradingFactorMinMax(player->gradingpointnum, false);
|
||||||
UINT16 exp = FixedMul(clampedmult, targetexp)>>FRACBITS;
|
fixed_t factormax = K_GetGradingFactorMinMax(player->gradingpointnum, true);
|
||||||
|
fixed_t clampedfactor = max(factormin, min(factormax, player->gradingfactor));
|
||||||
|
fixed_t range = factormax - factormin;
|
||||||
|
fixed_t normalizedfactor = FixedDiv(clampedfactor - factormin, range);
|
||||||
|
fixed_t easedexp = Easing_Linear(normalizedfactor, targetminexp, targetexp);
|
||||||
|
// fixed_t easedexp = Easing_Linear(normalizedfactor, MINEXP*FRACUNIT, MAXEXP*FRACUNIT);
|
||||||
|
UINT16 exp = easedexp;
|
||||||
|
// CONS_Printf("Player %s numgradingpoints=%d targetminexp=%d targetexp=%d factormin=%.2f factormax=%.2f clampedfactor=%.2f normalizedfactor=%.2f easedexp=%d\n",
|
||||||
|
// player_names[player - players], numgradingpoints, targetminexp, targetexp, FIXED_TO_FLOAT(factormin), FIXED_TO_FLOAT(factormax),
|
||||||
|
// FIXED_TO_FLOAT(clampedfactor), FIXED_TO_FLOAT(normalizedfactor), easedexp);
|
||||||
|
// UINT16 exp = (player->gradingfactor*100)>>FRACBITS;
|
||||||
return exp;
|
return exp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -315,8 +315,8 @@ boolean K_ThunderDome(void);
|
||||||
|
|
||||||
boolean K_PlayerCanUseItem(player_t *player);
|
boolean K_PlayerCanUseItem(player_t *player);
|
||||||
|
|
||||||
fixed_t K_GetGradingMultAdjustment(player_t *player);
|
fixed_t K_GetGradingFactorAdjustment(player_t *player);
|
||||||
|
fixed_t K_GetGradingFactorMinMax(UINT32 gradingpointnum, boolean max);
|
||||||
UINT16 K_GetEXP(player_t *player);
|
UINT16 K_GetEXP(player_t *player);
|
||||||
|
|
||||||
UINT32 K_GetNumGradingPoints(void);
|
UINT32 K_GetNumGradingPoints(void);
|
||||||
|
|
|
||||||
|
|
@ -221,7 +221,7 @@ INT32 level_tally_t::CalculateGrade(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const INT32 positionWeight = (position > 0 && numPlayers > 2) ? 50 : 0;
|
const INT32 positionWeight = (position > 0 && numPlayers > 2) ? 20 : 0;
|
||||||
const INT32 total = positionWeight + bonusWeights[0] + bonusWeights[1];
|
const INT32 total = positionWeight + bonusWeights[0] + bonusWeights[1];
|
||||||
|
|
||||||
INT32 ours = 0;
|
INT32 ours = 0;
|
||||||
|
|
@ -245,10 +245,7 @@ INT32 level_tally_t::CalculateGrade(void)
|
||||||
}
|
}
|
||||||
case TALLY_BONUS_EXP:
|
case TALLY_BONUS_EXP:
|
||||||
{
|
{
|
||||||
// Use a special curve for this.
|
const fixed_t frac = std::min(FRACUNIT, ((exp-15) * FRACUNIT) / std::max(1, static_cast<int>(totalExp)));
|
||||||
// Low Exp amounts are guaranteed, higher than half is where skill expression starts
|
|
||||||
// Magic numbers here are to reduce the range from 50-125 to 0-75 and compare with a max of 58, 85% of which is 49.3, which should put an even 100 or higher exp at A rank
|
|
||||||
const fixed_t frac = std::min(FRACUNIT, ((exp-50) * FRACUNIT) / std::max(1, static_cast<int>(totalExp-42)));
|
|
||||||
ours += Easing_Linear(frac, 0, bonusWeights[i]);
|
ours += Easing_Linear(frac, 0, bonusWeights[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -495,7 +495,24 @@ struct CheckpointManager
|
||||||
else // Checkpoint isn't in the list, find any associated tagged lines and make the pair
|
else // Checkpoint isn't in the list, find any associated tagged lines and make the pair
|
||||||
{
|
{
|
||||||
if (chk->linetag())
|
if (chk->linetag())
|
||||||
lines_.try_emplace(chk->linetag(), tagged_lines(chk->linetag()));
|
{
|
||||||
|
auto lines = tagged_lines(chk->linetag());
|
||||||
|
if (lines.empty() && gametype != GT_TUTORIAL)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, "Checkpoint thing %d, has linetag %d, but no lines found. Please ensure all checkpoints have associated lines.\n", chk->spawnpoint - mapthings, chk->linetag());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lines_.try_emplace(chk->linetag(), lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (gametype != GT_TUTORIAL)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_WARNING, "Checkpoint thing %d, has no linetag. Please ensure all checkpoint things have a linetag.\n", chk->spawnpoint - mapthings);
|
||||||
|
}
|
||||||
|
}
|
||||||
list_.push_front(chk);
|
list_.push_front(chk);
|
||||||
count_ += 1; // Mobjlist can't have a count on it, so we keep it here
|
count_ += 1; // Mobjlist can't have a count on it, so we keep it here
|
||||||
}
|
}
|
||||||
|
|
@ -567,6 +584,11 @@ void Obj_CheckpointThink(mobj_t* end)
|
||||||
|
|
||||||
void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y)
|
void Obj_CrossCheckpoints(player_t* player, fixed_t old_x, fixed_t old_y)
|
||||||
{
|
{
|
||||||
|
if (player->exiting) // can't cross checkpoints when exiting
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
LineOnDemand ray(old_x, old_y, player->mo->x, player->mo->y, player->mo->radius);
|
LineOnDemand ray(old_x, old_y, player->mo->x, player->mo->y, player->mo->radius);
|
||||||
|
|
||||||
auto it = std::find_if(
|
auto it = std::find_if(
|
||||||
|
|
|
||||||
|
|
@ -2175,7 +2175,9 @@ void Y_Ticker(void)
|
||||||
// Basic bitch points
|
// Basic bitch points
|
||||||
if (data.increase[data.num[q]])
|
if (data.increase[data.num[q]])
|
||||||
{
|
{
|
||||||
if (--data.increase[data.num[q]])
|
data.increase[data.num[q]] = std::max(data.increase[data.num[q]] - 3, 0);
|
||||||
|
|
||||||
|
if (data.increase[data.num[q]] != 0)
|
||||||
kaching = false;
|
kaching = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue