mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Add split modes: "Off", "Next", "Leader"
This commit is contained in:
		
							parent
							
								
									6e8fdf7f59
								
							
						
					
					
						commit
						8583613578
					
				
					 7 changed files with 111 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -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();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								src/k_kart.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/k_kart.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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},
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue