Add final position as a ranking requirement

1st is a large bonus, 2nd is a medium bonus, 3rd place is no bonus, and everything below is a penalty. This will help make Loser Valley grades never be above a C at most.
This commit is contained in:
Sally Coolatta 2023-03-04 16:16:37 -05:00
parent 3d1070c2f2
commit 3c07641938
6 changed files with 125 additions and 95 deletions

View file

@ -4128,6 +4128,7 @@ static void G_DoCompleted(void)
G_SetGamestate(GS_NULL);
wipegamestate = GS_NULL;
g_gpRank.position = MAXPLAYERS;
g_gpRank.difficulty = 0;
for (i = 0; i < MAXPLAYERS; i++)
@ -4160,6 +4161,10 @@ static void G_DoCompleted(void)
{
g_gpRank.difficulty = max(g_gpRank.difficulty, players[i].botvars.difficulty);
}
else
{
g_gpRank.position = min(g_gpRank.position, K_GetPodiumPosition(&players[i]));
}
}
}

View file

@ -4821,19 +4821,21 @@ static void K_DrawGPRankDebugger(void)
grade = K_CalculateGPGrade(&g_gpRank);
V_DrawThinString(0, 0, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("PTS: %d / %d", g_gpRank.winPoints, g_gpRank.totalPoints));
va("POS: %d / %d", g_gpRank.position, RANK_NEUTRAL_POSITION));
V_DrawThinString(0, 10, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("LAPS: %d / %d", g_gpRank.laps, g_gpRank.totalLaps));
va("PTS: %d / %d", g_gpRank.winPoints, g_gpRank.totalPoints));
V_DrawThinString(0, 20, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("CONTINUES: %d", g_gpRank.continuesUsed));
va("LAPS: %d / %d", g_gpRank.laps, g_gpRank.totalLaps));
V_DrawThinString(0, 30, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("CAPSULES: %d / %d", g_gpRank.capsules, g_gpRank.totalCapsules));
va("CONTINUES: %d", g_gpRank.continuesUsed));
V_DrawThinString(0, 40, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("RINGS: %d / %d", g_gpRank.rings, g_gpRank.totalRings));
va("CAPSULES: %d / %d", g_gpRank.capsules, g_gpRank.totalCapsules));
V_DrawThinString(0, 50, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("DIFFICULTY: %d / %d", g_gpRank.difficulty, g_gpRank.difficultyTarget));
va("RINGS: %d / %d", g_gpRank.rings, g_gpRank.totalRings));
V_DrawThinString(0, 60, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("SPECIAL: %s", (g_gpRank.specialWon == true) ? "YES" : "NO"));
va("DIFFICULTY: %d / %d", g_gpRank.difficulty, g_gpRank.difficultyTarget));
V_DrawThinString(0, 70, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
va("EMERALD: %s", (g_gpRank.specialWon == true) ? "YES" : "NO"));
switch (grade)
{
@ -4846,7 +4848,7 @@ static void K_DrawGPRankDebugger(void)
default: { break; }
}
V_DrawThinString(0, 80, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE|V_YELLOWMAP,
V_DrawThinString(0, 90, V_SNAPTOTOP|V_SNAPTOLEFT|V_6WIDTHSPACE|V_ALLOWLOWERCASE|V_YELLOWMAP,
va(" ** FINAL GRADE: %c", gradeChar));
}

View file

@ -9319,6 +9319,20 @@ void K_KartUpdatePosition(player_t *player)
return;
}
if (K_PodiumSequence() == true)
{
position = K_GetPodiumPosition(player);
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || !players[i].mo)
continue;
realplayers++;
}
}
else
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator || !players[i].mo)
@ -9326,28 +9340,7 @@ void K_KartUpdatePosition(player_t *player)
realplayers++;
if (K_PodiumSequence() == true)
{
if (players[i].score > player->score)
{
// Final score is the important part.
position++;
}
else if (players[i].score == player->score)
{
if (players[i].bot == false && player->bot == true)
{
// Bots are never as important as players.
position++;
}
else if (i < player - players)
{
// Port priority is the final tie breaker.
position++;
}
}
}
else if (gametyperules & GTR_CIRCUIT)
if (gametyperules & GTR_CIRCUIT)
{
if (player->exiting) // End of match standings
{
@ -9403,6 +9396,7 @@ void K_KartUpdatePosition(player_t *player)
}
}
}
}
if (leveltime < starttime || oldposition == 0)
oldposition = position;

View file

@ -57,7 +57,7 @@ static struct podiumData_s
UINT8 fade;
} podiumData;
#define PODIUM_STATES (9) // TODO: enum
#define PODIUM_STATES (10) // TODO: enum when this actually gets made
/*--------------------------------------------------
boolean K_PodiumSequence(void)
@ -326,7 +326,7 @@ void K_CeremonyTicker(boolean run)
{
podiumData.delay++;
if (podiumData.delay > TICRATE)
if (podiumData.delay > TICRATE/2)
{
podiumData.state++;
podiumData.delay = 0;
@ -429,60 +429,74 @@ void K_CeremonyDrawer(void)
{
case 1:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("PTS: %d / %d", g_gpRank.winPoints, g_gpRank.totalPoints)
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("POS: %d / %d", podiumData.rankData.position, RANK_NEUTRAL_POSITION)
);
break;
}
case 2:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("LAPS: %d / %d", g_gpRank.laps, g_gpRank.totalLaps)
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("PTS: %d / %d", podiumData.rankData.winPoints, podiumData.rankData.totalPoints)
);
break;
}
case 3:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("CONTINUES: %d", g_gpRank.continuesUsed)
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("LAPS: %d / %d", podiumData.rankData.laps, podiumData.rankData.totalLaps)
);
break;
}
case 4:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("CAPSULES: %d / %d", g_gpRank.capsules, g_gpRank.totalCapsules)
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("CONTINUES: %d", podiumData.rankData.continuesUsed)
);
break;
}
case 5:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("RINGS: %d / %d", g_gpRank.rings, g_gpRank.totalRings)
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("CAPSULES: %d / %d", podiumData.rankData.capsules, podiumData.rankData.totalCapsules)
);
break;
}
case 6:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("DIFFICULTY: %d / %d", g_gpRank.difficulty, g_gpRank.difficultyTarget)
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("RINGS: %d / %d", podiumData.rankData.rings, podiumData.rankData.totalRings)
);
break;
}
case 7:
{
V_DrawString(x, y, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
va("SPECIAL: %s", (g_gpRank.specialWon == true) ? "YES" : "NO")
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("DIFFICULTY: %d / %d", podiumData.rankData.difficulty, podiumData.rankData.difficultyTarget)
);
break;
}
case 8:
{
V_DrawString(x, y + 10, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE,
V_DrawString(x, y, V_ALLOWLOWERCASE,
va("EMERALD: %s", (podiumData.rankData.specialWon == true) ? "YES" : "NO")
);
break;
}
case 9:
{
V_DrawString(x, y + 10, V_YELLOWMAP|V_ALLOWLOWERCASE,
va(" ** FINAL GRADE: %c", gradeChar)
);
break;
}
case 10:
{
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, BASEVIDHEIGHT - 10, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_6WIDTHSPACE|V_ALLOWLOWERCASE,
"Press some button type deal to continue"
);
break;
}
}
y += 10;

View file

@ -56,6 +56,9 @@ void K_InitGrandPrixRank(gpRank_t *rankData)
rankData->players = numHumans;
rankData->totalPlayers = K_GetGPPlayerCount(numHumans);
// Initialize to the neutral value.
rankData->position = RANK_NEUTRAL_POSITION;
// Calculate total of points
// (Should this account for all coop players?)
for (i = 0; i < numHumans; i++)
@ -111,17 +114,25 @@ gp_rank_e K_CalculateGPGrade(gpRank_t *rankData)
gp_rank_e retGrade = GRADE_E;
const INT32 pointsWeight = 100;
const INT32 lapsWeight = 100;
const INT32 capsulesWeight = 100;
const INT32 ringsWeight = 50;
const INT32 difficultyWeight = 20;
const INT32 total = pointsWeight + lapsWeight + capsulesWeight + ringsWeight + difficultyWeight;
const INT32 continuesPenalty = 20;
const INT32 positionWeight = 1500;
const INT32 pointsWeight = 1000;
const INT32 lapsWeight = 1000;
const INT32 capsulesWeight = 1000;
const INT32 ringsWeight = 500;
const INT32 difficultyWeight = 200;
const INT32 total = positionWeight + pointsWeight + lapsWeight + capsulesWeight + ringsWeight + difficultyWeight;
const INT32 continuesPenalty = 200;
INT32 ours = 0;
fixed_t percent = 0;
if (rankData->position > 0)
{
const INT32 sc = (rankData->position - 1);
const INT32 loser = (RANK_NEUTRAL_POSITION - 1);
ours += ((loser - sc) * positionWeight) / loser;
}
if (rankData->totalPoints > 0)
{
ours += (rankData->winPoints * pointsWeight) / rankData->totalPoints;

View file

@ -25,6 +25,8 @@ struct gpRank_t
UINT8 players;
UINT8 totalPlayers;
UINT8 position;
UINT32 winPoints;
UINT32 totalPoints;
@ -57,6 +59,8 @@ typedef enum
GRADE_S
} gp_rank_e;
// 3rd place is neutral, anything below is a penalty
#define RANK_NEUTRAL_POSITION (3)
/*--------------------------------------------------
void K_InitGrandPrixRank(gpRank_t *rankData);