Add split modes: "Off", "Next", "Leader"

This commit is contained in:
Antonio Martinez 2025-08-18 20:43:29 -04:00
parent 6e8fdf7f59
commit 8583613578
7 changed files with 111 additions and 10 deletions

View file

@ -448,6 +448,9 @@ consvar_t cv_seenames = Player("seenames", "On").on_off();
consvar_t cv_shadow = Player("shadow", "On").on_off();
consvar_t cv_showfocuslost = Player("showfocuslost", "Yes").yes_no();
consvar_t cv_racesplits = Player("racesplits", "Leader").values({{0, "Off"}, {1, "Next"}, {2, "Leader"}}).save();
consvar_t cv_attacksplits = Player("attacksplits", "Next").values({{0, "Off"}, {1, "Next"}, {2, "Leader"}}).save();
void R_SetViewSize(void);
consvar_t cv_showhud = Player("showhud", "Yes").yes_no().onchange(R_SetViewSize).dont_save();

View file

@ -359,6 +359,7 @@ typedef enum
khud_splittimer, // How long to show splits HUD
khud_splitskin, // Skin index of the leading player
khud_splitcolor, // Skincolor of the leading player
khud_splitposition, // Who are we comparing to?
NUMKARTHUD
} karthudtype_t;

View file

@ -66,6 +66,7 @@
#include "k_vote.h"
#include "k_credits.h"
#include "k_grandprix.h"
#include "p_setup.h" // oldbest
static menuitem_t TitleEntry[] =
{
@ -2054,7 +2055,7 @@ void G_BeginRecording(void)
demosplits_p = demobuf.p;
for (i = 0; i < MAXSPLITS; i++)
{
WRITEUINT32(demobuf.p, INT32_MAX);
WRITEUINT32(demobuf.p, UINT32_MAX);
}
@ -2242,26 +2243,99 @@ void G_SetDemoCheckpointTiming(player_t *player, tic_t time, UINT8 checkpoint)
UINT32 *splits = (UINT32 *)demosplits_p;
splits[checkpoint] = time;
if (!cv_attacksplits.value)
return;
demoghost *g;
tic_t lowest = INT32_MAX;
tic_t lowest = UINT32_MAX;
UINT32 lowestskin = ((skin_t*)player->mo->skin)->skinnum;
UINT32 lowestcolor = player->skincolor;
for (g = ghosts; g; g = g->next)
boolean polite = (cv_attacksplits.value == 1);
// "Next" Mode: Find the weakest ghost who beats our best time.
// Don't set a ghost if we have no set time (oldbest == UINT32_MAX)
if (polite)
{
if (lowest > g->splits[checkpoint])
tic_t lowestend = UINT32_MAX;
for (g = ghosts; g; g = g->next)
{
lowest = g->splits[checkpoint];
lowestskin = g->initialskin;
lowestcolor = g->initialcolor;
boolean newtargetghost = false;
UINT32 points = K_GetNumGradingPoints();
tic_t endtime = UINT32_MAX;
if (points <= MAXSPLITS)
endtime = g->splits[points-1];
// Staff ghost oopsie. Fuckin, uh,
if (endtime == INT32_MAX)
endtime = UINT32_MAX;
if (lowestend > oldbest) // Not losing to any ghost
{
// Not currently losing to a ghost
if (endtime < oldbest)
{
// Show us any ghost who finishes faster than us
newtargetghost = true;
}
}
else
{
// Losing to a ghost already
if (endtime > lowestend && endtime < oldbest)
{
// Pick a slower ghost we are still losing to
newtargetghost = true;
}
}
if (newtargetghost)
{
lowest = g->splits[checkpoint];
lowestskin = g->initialskin;
lowestcolor = g->initialcolor;
lowestend = endtime;
}
}
}
if (lowest != INT32_MAX)
// If no ghost has been assigned to split against, and we are either
// - in "Leader" mode
// - in "Next" mode, but failed to find a ghost we lose to
// just split against the moment-to-moment leading ghost.
if (lowest == UINT32_MAX && (!polite || oldbest != UINT32_MAX))
{
for (g = ghosts; g; g = g->next)
{
if (lowest > g->splits[checkpoint])
{
lowest = g->splits[checkpoint];
lowestskin = g->initialskin;
lowestcolor = g->initialcolor;
}
}
}
// Final check: Where is our target ghost relative to other ghosts?
UINT32 ghostsbeatingtarget = 0;
for (g = ghosts; g; g = g->next)
{
if (g->splits[checkpoint] < lowest)
{
ghostsbeatingtarget++;
}
}
if (lowest != UINT32_MAX)
{
player->karthud[khud_splittimer] = 3*TICRATE;
player->karthud[khud_splitskin] = lowestskin;
player->karthud[khud_splitcolor] = lowestcolor;
player->karthud[khud_splittime] = (INT32)time - (INT32)lowest;
player->karthud[khud_splitposition] = ghostsbeatingtarget + 1;
if (lowest < time)
{

View file

@ -7792,6 +7792,7 @@ void K_drawKartHUD(void)
INT32 skin = stplyr->karthud[khud_splitskin];
INT32 color = stplyr->karthud[khud_splitcolor];
INT32 ahead = stplyr->karthud[khud_splitwin];
INT32 pos = stplyr->karthud[khud_splitposition];
// debug
if (!stplyr->karthud[khud_splittimer])
@ -7832,6 +7833,9 @@ void K_drawKartHUD(void)
// vibes offset
row.x(-35).colormap(skincolor).patch(R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap);
if (pos > 1)
row.x(-35).font(Draw::Font::kPing).text(va("%d", pos));
Draw::TextElement text = Draw::TextElement(
std::string(ahead >= 0 ? "-" : "+") + " " + "{:02}'{:02}\"{:02} " + arrow,
G_TicsToMinutes(split, true),

View file

@ -4459,6 +4459,8 @@ static void K_SetupSplitForPlayer(player_t *us, player_t *them, tic_t ourtime, t
us->karthud[khud_splitwin] = winning;
us->karthud[khud_splitskin] = them->skin;
us->karthud[khud_splitcolor] = them->skincolor;
if (us->position != 1)
us->karthud[khud_splitposition] = them->position;
}
static void K_HandleRaceSplits(player_t *player, tic_t time, UINT8 checkpoint)
@ -4469,6 +4471,7 @@ static void K_HandleRaceSplits(player_t *player, tic_t time, UINT8 checkpoint)
player->splits[checkpoint] = time;
player_t *lowest = player;
player_t *next = player;
UINT8 numrealsplits = 0;
// find fastest player for this checkpoint and # players who have already crossed
@ -4490,6 +4493,9 @@ static void K_HandleRaceSplits(player_t *player, tic_t time, UINT8 checkpoint)
if (check->splits[checkpoint] < lowest->splits[checkpoint])
lowest = check;
if (check->splits[checkpoint] > next->splits[checkpoint] || next == player)
next = check;
}
// no one to compare against yet
@ -4503,9 +4509,11 @@ static void K_HandleRaceSplits(player_t *player, tic_t time, UINT8 checkpoint)
K_SetupSplitForPlayer(lowest, player, lowest->splits[checkpoint], player->splits[checkpoint]);
}
if (numrealsplits)
extern consvar_t cv_racesplits;
if (numrealsplits && cv_racesplits.value)
{
K_SetupSplitForPlayer(player, lowest, player->splits[checkpoint], lowest->splits[checkpoint]);
player_t *target = (cv_racesplits.value == 2) ? lowest : next;
K_SetupSplitForPlayer(player, target, player->splits[checkpoint], target->splits[checkpoint]);
}
}

View file

@ -738,6 +738,8 @@ extern consvar_t cv_showfocuslost;
extern consvar_t cv_chooseskin, cv_serversort, cv_menujam_update, cv_menujam;
extern consvar_t cv_autorecord;
extern consvar_t cv_racesplits, cv_attacksplits;
void M_SetMenuDelay(UINT8 i);
void M_SortServerList(void);

View file

@ -37,6 +37,15 @@ menuitem_t OPTIONS_HUD[] =
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Race Splits", "Display time comparisons during races. Next = closest leading player.",
NULL, {.cvar = &cv_racesplits}, 0, 0},
{IT_STRING | IT_CVAR, "Time Attack Splits", "Display time comparisons during Time Attack. Next = closest leading player.",
NULL, {.cvar = &cv_attacksplits}, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_SUBMENU, "Online Chat Options...", "Visual options for the online chat box.",
NULL, {.submenu = &OPTIONS_HUDOnlineDef}, 0, 0},
};