mirror of
				https://github.com/KartKrewDev/RingRacers.git
				synced 2025-10-30 08:01:28 +00:00 
			
		
		
		
	Merge remote-tracking branch 'remotes/origin/master' into reasonable-drawdist
This commit is contained in:
		
						commit
						e1998e731e
					
				
					 23 changed files with 267 additions and 89 deletions
				
			
		|  | @ -4043,10 +4043,27 @@ static void HandleConnect(SINT8 node) | |||
| 	UINT8 maxplayers = min((dedicated ? MAXPLAYERS-1 : MAXPLAYERS), cv_maxconnections.value); | ||||
| 	UINT8 connectedplayers = 0; | ||||
| 
 | ||||
| 
 | ||||
| 	for (i = dedicated ? 1 : 0; i < MAXPLAYERS; i++) | ||||
| 		if (playernode[i] != UINT8_MAX) // We use this to count players because it is affected by SV_AddWaitingPlayers when more than one client joins on the same tic, unlike playeringame and D_NumPlayers. UINT8_MAX denotes no node for that player
 | ||||
| 	{ | ||||
| 		// We use this to count players because it is affected by SV_AddWaitingPlayers when
 | ||||
| 		// more than one client joins on the same tic, unlike playeringame and D_NumPlayers.
 | ||||
| 		// UINT8_MAX denotes no node for that player.
 | ||||
| 
 | ||||
| 		if (playernode[i] != UINT8_MAX) | ||||
| 		{ | ||||
| 			// Sal: This hack sucks, but it should be safe.
 | ||||
| 			// playeringame is set for bots immediately; they are deterministic instead of a netxcmd.
 | ||||
| 			// If a bot is added with netxcmd in the future, then the node check is still here too.
 | ||||
| 			// So at worst, a theoretical netxcmd added bot will block real joiners for the time
 | ||||
| 			// it takes for the command to process, but not cause any horrifying player overwriting.
 | ||||
| 			if (playeringame[i] && players[i].bot) | ||||
| 			{ | ||||
| 				continue; | ||||
| 			} | ||||
| 
 | ||||
| 			connectedplayers++; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	banrecord_t *ban = SV_GetBanByAddress(node); | ||||
| 	if (ban == NULL) | ||||
|  |  | |||
|  | @ -7282,13 +7282,6 @@ void KartEncore_OnChange(void) | |||
| void KartEliminateLast_OnChange(void); | ||||
| void KartEliminateLast_OnChange(void) | ||||
| { | ||||
| #ifndef DEVELOP | ||||
| 	if (K_CanChangeRules(false) == false) | ||||
| 	{ | ||||
| 		CV_StealthSet(&cv_karteliminatelast, cv_karteliminatelast.defaultvalue); | ||||
| 	} | ||||
| #endif | ||||
| 
 | ||||
| 	P_CheckRacers(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -578,6 +578,15 @@ struct altview_t | |||
| 	INT32 tics; | ||||
| }; | ||||
| 
 | ||||
| // enum for saved lap times
 | ||||
| typedef enum | ||||
| { | ||||
| 	LAP_CUR, | ||||
| 	LAP_BEST, | ||||
| 	LAP_LAST, | ||||
| 	LAP__MAX | ||||
| } laptime_e; | ||||
| 
 | ||||
| extern altview_t titlemapcam; | ||||
| 
 | ||||
| // ========================================================================
 | ||||
|  | @ -897,6 +906,7 @@ struct player_t | |||
| 
 | ||||
| 	INT16 totalring; // Total number of rings obtained for GP
 | ||||
| 	tic_t realtime; // integer replacement for leveltime
 | ||||
| 	tic_t laptime[LAP__MAX]; | ||||
| 	UINT8 laps; // Number of laps (optional)
 | ||||
| 	UINT8 latestlap; | ||||
| 	UINT32 lapPoints; // Points given from laps
 | ||||
|  |  | |||
|  | @ -871,7 +871,6 @@ extern boolean inDuel; | |||
| extern tic_t bombflashtimer;	// Used to avoid causing seizures if multiple mines explode close to you :)
 | ||||
| extern boolean legitimateexit; | ||||
| extern boolean comebackshowninfo; | ||||
| extern tic_t curlap, bestlap; | ||||
| 
 | ||||
| #define VOTE_SPECIAL (MAXPLAYERS) | ||||
| #define VOTE_TOTAL (MAXPLAYERS+1) | ||||
|  |  | |||
							
								
								
									
										51
									
								
								src/g_game.c
									
										
									
									
									
								
							
							
						
						
									
										51
									
								
								src/g_game.c
									
										
									
									
									
								
							|  | @ -147,6 +147,7 @@ boolean modifiedgame = false; // Set if homebrew PWAD stuff has been added. | |||
| boolean majormods = false; // Set if Lua/Gameplay SOC/replacement map has been added.
 | ||||
| boolean savemoddata = false; | ||||
| boolean usedCheats = false; // Set when a "cheats on" is ever used.
 | ||||
| boolean usedTourney = false; // Entered the "Tournament Mode" cheat.
 | ||||
| UINT8 paused; | ||||
| UINT8 modeattacking = ATTACKING_NONE; | ||||
| boolean imcontinuing = false; | ||||
|  | @ -322,8 +323,6 @@ boolean inDuel; // Boolean, keeps track of if it is a 1v1 | |||
| tic_t bombflashtimer = 0;	// Cooldown before another FlashPal can be intialized by a bomb exploding near a displayplayer. Avoids seizures.
 | ||||
| boolean legitimateexit; // Did this client actually finish the match?
 | ||||
| boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message?
 | ||||
| tic_t curlap; // Current lap time
 | ||||
| tic_t bestlap; // Best lap time
 | ||||
| 
 | ||||
| boolean precache = true; // if true, load all graphics at start
 | ||||
| 
 | ||||
|  | @ -344,14 +343,10 @@ void G_ClearRecords(void) | |||
| { | ||||
| 	UINT16 i; | ||||
| 
 | ||||
| 	for (i = 0; i < numskins; i++) | ||||
| 	{ | ||||
| 		memset(&skins[i].records, 0, sizeof(skins[i].records)); | ||||
| 	} | ||||
| 
 | ||||
| 	for (i = 0; i < nummapheaders; i++) | ||||
| 	{ | ||||
| 		memset(&mapheaderinfo[i]->records, 0, sizeof(recorddata_t)); | ||||
| 		memset(&mapheaderinfo[i]->records.timeattack, 0, sizeof(recordtimes_t)); | ||||
| 		memset(&mapheaderinfo[i]->records.spbattack, 0, sizeof(recordtimes_t)); | ||||
| 	} | ||||
| 
 | ||||
| 	cupheader_t *cup; | ||||
|  | @ -360,14 +355,11 @@ void G_ClearRecords(void) | |||
| 		memset(&cup->windata, 0, sizeof(cup->windata)); | ||||
| 	} | ||||
| 
 | ||||
| 	unloaded_skin_t *unloadedskin, *nextunloadedskin = NULL; | ||||
| 	for (unloadedskin = unloadedskins; unloadedskin; unloadedskin = nextunloadedskin) | ||||
| 	{ | ||||
| 		nextunloadedskin = unloadedskin->next; | ||||
| 		Z_Free(unloadedskin); | ||||
| 	} | ||||
| 	unloadedskins = NULL; | ||||
| 
 | ||||
| 	// TODO: Technically, these should only remove time attack records here.
 | ||||
| 	// But I'm out of juice for dev (+ literally, just finished some OJ).
 | ||||
| 	// The stats need to be cleared in M_ClearStats, and I guess there's 
 | ||||
| 	// no perfect place to wipe mapvisited because it's not actually part of
 | ||||
| 	// basegame progression... so here's fine for launch.  ~toast 100424
 | ||||
| 	unloaded_mapheader_t *unloadedmap, *nextunloadedmap = NULL; | ||||
| 	for (unloadedmap = unloadedmapheaders; unloadedmap; unloadedmap = nextunloadedmap) | ||||
| 	{ | ||||
|  | @ -561,8 +553,8 @@ void G_UpdateRecords(void) | |||
| 
 | ||||
| 	if (modeattacking & ATTACKING_LAP) | ||||
| 	{ | ||||
| 		if ((record->lap == 0) || (bestlap < record->lap)) | ||||
| 			record->lap = bestlap; | ||||
| 		if ((record->lap == 0) || (players[consoleplayer].laptime[LAP_BEST] < record->lap)) | ||||
| 			record->lap = players[consoleplayer].laptime[LAP_BEST]; | ||||
| 	} | ||||
| 
 | ||||
| 	// Check emblems when level data is updated
 | ||||
|  | @ -606,7 +598,7 @@ static void G_UpdateRecordReplays(void) | |||
| 	// Save demo!
 | ||||
| 	bestdemo[255] = '\0'; | ||||
| 	lastdemo[255] = '\0'; | ||||
| 	G_SetDemoTime(players[consoleplayer].realtime, bestlap); | ||||
| 	G_SetDemoTime(players[consoleplayer].realtime, players[consoleplayer].laptime[LAP_BEST]); | ||||
| 	G_CheckDemoStatus(); | ||||
| 
 | ||||
| 	gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s", | ||||
|  | @ -2179,6 +2171,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) | |||
| 	level_tally_t tally; | ||||
| 	boolean tallyactive; | ||||
| 
 | ||||
| 	tic_t laptime[LAP__MAX]; | ||||
| 
 | ||||
| 	INT32 i; | ||||
| 
 | ||||
| 	// This needs to be first, to permit it to wipe extra information
 | ||||
| 	jointime = players[player].jointime; | ||||
| 	if (jointime <= 1) | ||||
|  | @ -2206,6 +2202,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) | |||
| 		kartspeed = skins[players[player].skin].kartspeed; | ||||
| 		kartweight = skins[players[player].skin].kartweight; | ||||
| 		charflags = skins[players[player].skin].flags; | ||||
| 
 | ||||
| 		for (i = 0; i < LAP__MAX; i++) | ||||
| 		{ | ||||
| 			laptime[i] = 0; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|  | @ -2218,6 +2219,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) | |||
| 		kartweight = players[player].kartweight; | ||||
| 
 | ||||
| 		charflags = (skinflags & SF_IRONMAN) ? skinflags : players[player].charflags; | ||||
| 
 | ||||
| 		for (i = 0; i < LAP__MAX; i++) | ||||
| 		{ | ||||
| 			laptime[i] = players[player].laptime[i]; | ||||
| 		} | ||||
| 	} | ||||
| 	lastfakeskin = players[player].lastfakeskin; | ||||
| 
 | ||||
|  | @ -2456,6 +2462,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) | |||
| 	p->lapPoints = lapPoints; | ||||
| 	p->totalring = totalring; | ||||
| 
 | ||||
| 	for (i = 0; i < LAP__MAX; i++) | ||||
| 	{ | ||||
| 		p->laptime[i] = laptime[i]; | ||||
| 	} | ||||
| 
 | ||||
| 	p->bot = bot; | ||||
| 	p->botvars.difficulty = botdifficulty; | ||||
| 	p->rings = rings; | ||||
|  | @ -2519,8 +2530,6 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) | |||
| 	// Check to make sure their color didn't change somehow...
 | ||||
| 	if (G_GametypeHasTeams()) | ||||
| 	{ | ||||
| 		UINT8 i; | ||||
| 
 | ||||
| 		if (p->ctfteam == 1 && p->skincolor != skincolor_redteam) | ||||
| 		{ | ||||
| 			for (i = 0; i <= splitscreen; i++) | ||||
|  |  | |||
|  | @ -84,6 +84,8 @@ extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard di | |||
| extern INT32 pausedelay; | ||||
| extern boolean pausebreakkey; | ||||
| 
 | ||||
| extern boolean usedTourney; | ||||
| 
 | ||||
| extern boolean promptactive; | ||||
| 
 | ||||
| extern consvar_t cv_tutorialprompt; | ||||
|  |  | |||
|  | @ -60,7 +60,7 @@ INT32 K_StartingBumperCount(void) | |||
| 	if (tutorialchallenge == TUTORIALSKIP_INPROGRESS) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (battleprisons || K_CheckBossIntro()) | ||||
| 	if (battleprisons || K_CheckBossIntro() || !K_CanChangeRules(true)) | ||||
| 	{ | ||||
| 		if (grandprixinfo.gp) | ||||
| 		{ | ||||
|  |  | |||
|  | @ -1889,7 +1889,7 @@ tic_t K_TranslateTimer(tic_t drawtime, UINT8 mode, INT32 *return_jitter) | |||
| { | ||||
| 	INT32 jitter = 0; | ||||
| 
 | ||||
| 	if (!mode) | ||||
| 	if (!mode && drawtime != UINT32_MAX) | ||||
| 	{ | ||||
| 		if (timelimitintics > 0) | ||||
| 		{ | ||||
|  | @ -1948,7 +1948,6 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U | |||
| 	// TIME_X = BASEVIDWIDTH-124;	// 196
 | ||||
| 	// TIME_Y = 6;					//   6
 | ||||
| 
 | ||||
| 	tic_t worktime; | ||||
| 	INT32 jitter = 0; | ||||
| 
 | ||||
| 	drawtime = K_TranslateTimer(drawtime, mode, &jitter); | ||||
|  | @ -1957,19 +1956,27 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U | |||
| 
 | ||||
| 	TX += 33; | ||||
| 
 | ||||
| 	worktime = drawtime/(60*TICRATE); | ||||
| 
 | ||||
| 	if (worktime >= 100) | ||||
| 	if (drawtime == UINT32_MAX) | ||||
| 		; | ||||
| 	else if (mode && !drawtime) | ||||
| 	{ | ||||
| 		jitter = (drawtime & 1 ? 1 : -1); | ||||
| 		worktime = 99; | ||||
| 		drawtime = (100*(60*TICRATE))-1; | ||||
| 	} | ||||
| 		// apostrophe location     _'__ __
 | ||||
| 		V_DrawTimerString(TX+24, TY+3, splitflags, va("'")); | ||||
| 
 | ||||
| 	if (mode && !drawtime) | ||||
| 		V_DrawTimerString(TX, TY+3, splitflags, "--'--\"--"); | ||||
| 		// quotation mark location    _ __"__
 | ||||
| 		V_DrawTimerString(TX+60, TY+3, splitflags, va("\"")); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		tic_t worktime = drawtime/(60*TICRATE); | ||||
| 
 | ||||
| 		if (worktime >= 100) | ||||
| 		{ | ||||
| 			jitter = (drawtime & 1 ? 1 : -1); | ||||
| 			worktime = 99; | ||||
| 			drawtime = (100*(60*TICRATE))-1; | ||||
| 		} | ||||
| 
 | ||||
| 		// minutes time      00 __ __
 | ||||
| 		V_DrawTimerString(TX,    TY+3+jitter, splitflags, va("%d", worktime/10)); | ||||
| 		V_DrawTimerString(TX+12, TY+3-jitter, splitflags, va("%d", worktime%10)); | ||||
|  | @ -6089,7 +6096,26 @@ void K_drawKartHUD(void) | |||
| 		{ | ||||
| 			bool ta = modeattacking && !demo.playback; | ||||
| 			INT32 flags = V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP|V_SNAPTORIGHT; | ||||
| 			K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y + (ta ? 2 : 0), flags, 0); | ||||
| 
 | ||||
| 			tic_t realtime = stplyr->realtime; | ||||
| 
 | ||||
| 			if (stplyr->karthud[khud_lapanimation] | ||||
| 				&& !stplyr->exiting | ||||
| 				&& stplyr->laptime[LAP_LAST] != 0 | ||||
| 				&& stplyr->laptime[LAP_LAST] != UINT32_MAX) | ||||
| 			{ | ||||
| 				if ((stplyr->karthud[khud_lapanimation] / 5) & 1) | ||||
| 				{ | ||||
| 					realtime = stplyr->laptime[LAP_LAST]; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					realtime = UINT32_MAX; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			K_drawKartTimestamp(realtime, TIME_X, TIME_Y + (ta ? 2 : 0), flags, 0); | ||||
| 
 | ||||
| 			if (modeattacking) | ||||
| 			{ | ||||
| 				if (ta) | ||||
|  |  | |||
							
								
								
									
										70
									
								
								src/k_kart.c
									
										
									
									
									
								
							
							
						
						
									
										70
									
								
								src/k_kart.c
									
										
									
									
									
								
							|  | @ -72,6 +72,16 @@ | |||
| // comeback is Battle Mode's karma comeback, also bool
 | ||||
| // mapreset is set when enough players fill an empty server
 | ||||
| 
 | ||||
| boolean K_ThunderDome(void) | ||||
| { | ||||
| 	if (K_CanChangeRules(true)) | ||||
| 	{ | ||||
| 		return (boolean)cv_thunderdome.value; | ||||
| 	} | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| // lat: used for when the player is in some weird state where it wouldn't be wise for it to be overwritten by another object that does similarly wacky shit.
 | ||||
| boolean K_isPlayerInSpecialState(player_t *p) | ||||
| { | ||||
|  | @ -12181,7 +12191,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) | |||
| 		if (player->ringboxdelay == 0) | ||||
| 		{ | ||||
| 			UINT32 award = 5*player->ringboxaward + 10; | ||||
| 			if (!cv_thunderdome.value) | ||||
| 			if (!K_ThunderDome()) | ||||
| 				award = 3 * award / 2; | ||||
| 
 | ||||
| 			if (modeattacking & ATTACKING_SPB) | ||||
|  | @ -13559,6 +13569,7 @@ void K_CheckSpectateStatus(boolean considermapreset) | |||
| { | ||||
| 	UINT8 respawnlist[MAXPLAYERS]; | ||||
| 	UINT8 i, j, numingame = 0, numjoiners = 0; | ||||
| 	UINT8 numhumans = 0, numbots = 0; | ||||
| 
 | ||||
| 	// Maintain spectate wait timer
 | ||||
| 	for (i = 0; i < MAXPLAYERS; i++) | ||||
|  | @ -13571,6 +13582,16 @@ void K_CheckSpectateStatus(boolean considermapreset) | |||
| 		if (!players[i].spectator) | ||||
| 		{ | ||||
| 			numingame++; | ||||
| 
 | ||||
| 			if (players[i].bot) | ||||
| 			{ | ||||
| 				numbots++; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				numhumans++; | ||||
| 			} | ||||
| 
 | ||||
| 			players[i].spectatewait = 0; | ||||
| 			players[i].spectatorReentry = 0; | ||||
| 			continue; | ||||
|  | @ -13600,7 +13621,7 @@ void K_CheckSpectateStatus(boolean considermapreset) | |||
| 		return; | ||||
| 
 | ||||
| 	// DON'T allow if you've hit the in-game player cap
 | ||||
| 	if (cv_maxplayers.value && numingame >= cv_maxplayers.value) | ||||
| 	if (cv_maxplayers.value && numhumans >= cv_maxplayers.value) | ||||
| 		return; | ||||
| 
 | ||||
| 	// Get the number of players in game, and the players to be de-spectated.
 | ||||
|  | @ -13684,16 +13705,47 @@ void K_CheckSpectateStatus(boolean considermapreset) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	const UINT8 previngame = numingame; | ||||
| 	INT16 removeBotID = MAXPLAYERS - 1; | ||||
| 
 | ||||
| 	// Finally, we can de-spectate everyone!
 | ||||
| 	for (i = 0; i < numjoiners; i++) | ||||
| 	{ | ||||
| 		//CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime);
 | ||||
| 
 | ||||
| 		P_SpectatorJoinGame(&players[respawnlist[i]]); | ||||
| 
 | ||||
| 		// Hit the in-game player cap while adding people?
 | ||||
| 		if (cv_maxplayers.value && numingame+i >= cv_maxplayers.value) | ||||
| 			break; | ||||
| 		if (cv_maxplayers.value && numingame >= cv_maxplayers.value) | ||||
| 		{ | ||||
| 			if (numbots > 0) | ||||
| 			{ | ||||
| 				// Find a bot to kill to make room
 | ||||
| 				while (removeBotID >= 0) | ||||
| 				{ | ||||
| 					if (playeringame[removeBotID] && players[removeBotID].bot) | ||||
| 					{ | ||||
| 						//CONS_Printf("bot %s kicked to make room on tic %d\n", player_names[removeBotID], leveltime);
 | ||||
| 						CL_RemovePlayer(removeBotID, KR_LEAVE); | ||||
| 						numbots--; | ||||
| 						numingame--; | ||||
| 						break; | ||||
| 					} | ||||
| 
 | ||||
| 					removeBotID--; | ||||
| 				} | ||||
| 
 | ||||
| 				if (removeBotID < 0) | ||||
| 				{ | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime);
 | ||||
| 		P_SpectatorJoinGame(&players[respawnlist[i]]); | ||||
| 		numhumans++; | ||||
| 		numingame++; | ||||
| 	} | ||||
| 
 | ||||
| 	if (considermapreset == false) | ||||
|  | @ -13702,7 +13754,7 @@ void K_CheckSpectateStatus(boolean considermapreset) | |||
| 	// Reset the match when 2P joins 1P, DUEL mode
 | ||||
| 	// Reset the match when 3P joins 1P and 2P, DUEL mode must be disabled
 | ||||
| 	extern consvar_t cv_debugnewchallenger; | ||||
| 	if (i > 0 && !mapreset && gamestate == GS_LEVEL && (numingame < 3 && numingame+i >= 2) && !cv_debugnewchallenger.value) | ||||
| 	if (i > 0 && !mapreset && gamestate == GS_LEVEL && (previngame < 3 && numingame >= 2) && !cv_debugnewchallenger.value) | ||||
| 	{ | ||||
| 		Music_Play("comeon"); // COME ON
 | ||||
| 		mapreset = 3*TICRATE; // Even though only the server uses this for game logic, set for everyone for HUD
 | ||||
|  |  | |||
|  | @ -274,6 +274,8 @@ void K_MakeObjectReappear(mobj_t *mo); | |||
| 
 | ||||
| void K_BumperInflate(player_t *player); | ||||
| 
 | ||||
| boolean K_ThunderDome(void); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } // extern "C"
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -478,7 +478,6 @@ typedef enum | |||
| { | ||||
| 	gopt_spacer0 = 0, | ||||
| 	gopt_gamespeed, | ||||
| 	gopt_baselapcount, | ||||
| 	gopt_frantic, | ||||
| 	gopt_encore, | ||||
| 	gopt_exitcountdown, | ||||
|  |  | |||
|  | @ -640,12 +640,15 @@ void podiumData_s::Draw(void) | |||
| 
 | ||||
| 							if (emeraldNum == 0) | ||||
| 							{ | ||||
| 								emeraldPatch = static_cast<patch_t*>( W_CachePatchName("K_BLNA", PU_CACHE) ); | ||||
| 								// Prize -- todo, currently using fake Emerald
 | ||||
| 								emeraldColor = SKINCOLOR_GOLD; | ||||
| 							} | ||||
| 							else | ||||
| 							{ | ||||
| 								emeraldColor = static_cast<skincolornum_t>( SKINCOLOR_CHAOSEMERALD1 + ((emeraldNum - 1) % 7) ); | ||||
| 							} | ||||
| 
 | ||||
| 							{ | ||||
| 								std::string emeraldName; | ||||
| 								if (emeraldNum > 7) | ||||
| 								{ | ||||
|  | @ -853,12 +856,15 @@ void podiumData_s::Draw(void) | |||
| 
 | ||||
| 			if (emeraldNum == 0) | ||||
| 			{ | ||||
| 				emeraldOverlay = static_cast<patch_t*>( W_CachePatchName("KBLNC0", PU_CACHE) ); | ||||
| 				// Prize -- todo, currently using fake Emerald
 | ||||
| 				emeraldColor = SKINCOLOR_GOLD; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				emeraldColor = static_cast<skincolornum_t>( SKINCOLOR_CHAOSEMERALD1 + ((emeraldNum - 1) % 7) ); | ||||
| 			} | ||||
| 
 | ||||
| 			{ | ||||
| 				if (emeraldNum > 7) | ||||
| 				{ | ||||
| 					emeraldOverlay = static_cast<patch_t*>( W_CachePatchName("SEMRA0", PU_CACHE) ); | ||||
|  |  | |||
							
								
								
									
										58
									
								
								src/m_cond.c
									
										
									
									
									
								
							
							
						
						
									
										58
									
								
								src/m_cond.c
									
										
									
									
									
								
							|  | @ -650,7 +650,8 @@ void M_ClearConditionSet(UINT16 set) | |||
| // Clear ALL secrets.
 | ||||
| void M_ClearStats(void) | ||||
| { | ||||
| 	UINT8 i; | ||||
| 	UINT16 i; | ||||
| 
 | ||||
| 	gamedata->totalplaytime = 0; | ||||
| 	gamedata->totalnetgametime = 0; | ||||
| 	gamedata->timeattackingtotaltime = 0; | ||||
|  | @ -678,6 +679,54 @@ void M_ClearStats(void) | |||
| 	gamedata->musicstate = GDMUSIC_NONE; | ||||
| 
 | ||||
| 	gamedata->importprofilewins = false; | ||||
| 
 | ||||
| 	// Skins only store stats, not progression metrics. Good to clear entirely here.
 | ||||
| 
 | ||||
| 	for (i = 0; i < numskins; i++) | ||||
| 	{ | ||||
| 		memset(&skins[i].records, 0, sizeof(skins[i].records)); | ||||
| 	} | ||||
| 
 | ||||
| 	unloaded_skin_t *unloadedskin, *nextunloadedskin = NULL; | ||||
| 	for (unloadedskin = unloadedskins; unloadedskin; unloadedskin = nextunloadedskin) | ||||
| 	{ | ||||
| 		nextunloadedskin = unloadedskin->next; | ||||
| 		Z_Free(unloadedskin); | ||||
| 	} | ||||
| 	unloadedskins = NULL; | ||||
| 
 | ||||
| 	// We retain exclusively the most important stuff from maps.
 | ||||
| 
 | ||||
| 	UINT8 restoremapvisited; | ||||
| 	recordtimes_t restoretimeattack; | ||||
| 	recordtimes_t restorespbattack; | ||||
| 
 | ||||
| 	for (i = 0; i < nummapheaders; i++) | ||||
| 	{ | ||||
| 		restoremapvisited = mapheaderinfo[i]->records.mapvisited; | ||||
| 		restoretimeattack = mapheaderinfo[i]->records.timeattack; | ||||
| 		restorespbattack = mapheaderinfo[i]->records.spbattack; | ||||
| 
 | ||||
| 		memset(&mapheaderinfo[i]->records, 0, sizeof(recorddata_t)); | ||||
| 
 | ||||
| 		mapheaderinfo[i]->records.mapvisited = restoremapvisited; | ||||
| 		mapheaderinfo[i]->records.timeattack = restoretimeattack; | ||||
| 		mapheaderinfo[i]->records.spbattack = restorespbattack; | ||||
| 	} | ||||
| 
 | ||||
| 	unloaded_mapheader_t *unloadedmap; | ||||
| 	for (unloadedmap = unloadedmapheaders; unloadedmap; unloadedmap = unloadedmap->next) | ||||
| 	{ | ||||
| 		restoremapvisited = unloadedmap->records.mapvisited; | ||||
| 		restoretimeattack = unloadedmap->records.timeattack; | ||||
| 		restorespbattack = unloadedmap->records.spbattack; | ||||
| 
 | ||||
| 		memset(&unloadedmap->records, 0, sizeof(recorddata_t)); | ||||
| 
 | ||||
| 		unloadedmap->records.mapvisited = restoremapvisited; | ||||
| 		unloadedmap->records.timeattack = restoretimeattack; | ||||
| 		unloadedmap->records.spbattack = restorespbattack; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void M_ClearSecrets(void) | ||||
|  | @ -707,6 +756,8 @@ void M_ClearSecrets(void) | |||
| 		if (!mapheaderinfo[i]) | ||||
| 			continue; | ||||
| 
 | ||||
| 		mapheaderinfo[i]->records.mapvisited = 0; | ||||
| 
 | ||||
| 		mapheaderinfo[i]->cache_spraycan = UINT16_MAX; | ||||
| 
 | ||||
| 		mapheaderinfo[i]->cache_maplock = MAXUNLOCKABLES; | ||||
|  | @ -2972,6 +3023,11 @@ char *M_BuildConditionSetString(UINT16 unlockid) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (usedTourney && unlockables[unlockid].conditionset == 55 && gamedata->unlocked[unlockid] == false) | ||||
| 	{ | ||||
| 		strcpy(message, "Power shrouds this challenge in darkness... (Return here without Tournament Mode!)\0"); | ||||
| 	} | ||||
| 
 | ||||
| 	// Finally, do a clean wordwrap!
 | ||||
| 	return V_ScaledWordWrap( | ||||
| 		DESCRIPTIONWIDTH << FRACBITS, | ||||
|  |  | |||
							
								
								
									
										20
									
								
								src/m_pw.cpp
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								src/m_pw.cpp
									
										
									
									
									
								
							|  | @ -110,6 +110,8 @@ void f_tournament() | |||
| 	{ | ||||
| 		if (!unlockables[i].conditionset) | ||||
| 			continue; | ||||
| 		if (unlockables[i].conditionset == 55) | ||||
| 			continue; | ||||
| 		if (gamedata->unlocked[i]) | ||||
| 			continue; | ||||
| 
 | ||||
|  | @ -146,10 +148,12 @@ void f_tournament() | |||
| 		S_StartSound(0, sfx_kc42); | ||||
| 
 | ||||
| 		text = M_GetText( | ||||
| 			"All challenges temporarily unlocked.\n" | ||||
| 			"Unlocked\x83 almost\x80 everything.\n" | ||||
| 			"Saving is disabled - the game will\n" | ||||
| 			"return to normal on next launch.\n" | ||||
| 		); | ||||
| 
 | ||||
| 		usedTourney = true; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|  | @ -158,18 +162,20 @@ void f_tournament() | |||
| 		if (usedCheats) | ||||
| 		{ | ||||
| 			text = M_GetText( | ||||
| 				"This is the correct password, but\n" | ||||
| 				"you already have every challenge\n" | ||||
| 				"unlocked, so nothing has changed.\n" | ||||
| 				"This is the correct password,\n" | ||||
| 				"but there's nothing to unlock\n" | ||||
| 				"right now -- nothing has changed.\n" | ||||
| 			); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			text = M_GetText( | ||||
| 				"This is the correct password, but\n" | ||||
| 				"you already have every challenge\n" | ||||
| 				"unlocked, so saving is still allowed!\n" | ||||
| 				"there's nothing to unlock right\n" | ||||
| 				"now, so saving is still allowed!\n" | ||||
| 			); | ||||
| 
 | ||||
| 			usedTourney = true; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  | @ -308,7 +314,7 @@ try_password_e M_TryPassword(const char *password, boolean conditions) | |||
| 		add_job(pw.hash_.data(), &pw); | ||||
| 
 | ||||
| 	// Only consider challenges passwords as needed.
 | ||||
| 	if (conditions) | ||||
| 	if (conditions && !usedTourney) | ||||
| 		iter_conditions([&](condition_t* cn) { add_job((const UINT8*)cn->stringvar, cn); }); | ||||
| 
 | ||||
| 	try_password_e return_code = M_PW_INVALID; | ||||
|  |  | |||
|  | @ -847,7 +847,7 @@ boolean M_ChallengesInputs(INT32 ch) | |||
| 		{ | ||||
| 			M_ChallengesTutorial(CCTUTORIAL_MAJORSKIP); | ||||
| 		} | ||||
| 		else if (M_CanKeyHiliTile()) | ||||
| 		else if (M_CanKeyHiliTile() && !usedTourney) | ||||
| 		{ | ||||
| 			challengesmenu.chaokeyhold = 1; | ||||
| 		} | ||||
|  |  | |||
|  | @ -21,9 +21,6 @@ menuitem_t OPTIONS_Gameplay[] = | |||
| 	{IT_STRING | IT_CVAR, "Game Speed", "Gear for the next map.", | ||||
| 		NULL, {.cvar = &cv_kartspeed}, 0, 0}, | ||||
| 
 | ||||
| 	{IT_STRING | IT_CVAR, "Base Lap Count", "How many laps must be completed per race.", | ||||
| 		NULL, {.cvar = &cv_numlaps}, 0, 0}, | ||||
| 
 | ||||
| 	{IT_STRING | IT_CVAR, "Frantic Items", "Make item odds crazier with more powerful items!", | ||||
| 		NULL, {.cvar = &cv_kartfrantic}, 0, 0}, | ||||
| 
 | ||||
|  |  | |||
|  | @ -19,6 +19,7 @@ | |||
| #include "../k_battle.h" | ||||
| #include "../m_random.h" | ||||
| #include "../k_specialstage.h" // specialstageinfo | ||||
| #include "../k_kart.h" | ||||
| 
 | ||||
| #define FLOAT_HEIGHT ( 12 * FRACUNIT ) | ||||
| #define FLOAT_TIME ( 2 * TICRATE ) | ||||
|  | @ -122,7 +123,7 @@ void Obj_RandomItemVisuals(mobj_t *mobj) | |||
| 	// the player's cleared out a good portion of the map.
 | ||||
| 	//
 | ||||
| 	// Then extraval1 starts ticking up and triggers the transformation from Ringbox to Random Item.
 | ||||
| 	if (mobj->fuse == 0 && !(mobj->flags & MF_NOCLIPTHING) && !(mobj->flags2 & MF2_BOSSDEAD) && !cv_thunderdome.value | ||||
| 	if (mobj->fuse == 0 && !(mobj->flags & MF_NOCLIPTHING) && !(mobj->flags2 & MF2_BOSSDEAD) && !K_ThunderDome() | ||||
| 		&& (modeattacking == ATTACKING_NONE || !!(modeattacking & ATTACKING_SPB) || specialstageinfo.valid)) // Time Attacking in Special is a fucked-looking exception
 | ||||
| 	{ | ||||
| 		mobj->extravalue1++; | ||||
|  |  | |||
|  | @ -1244,9 +1244,10 @@ static mobj_t *InitSpecialUFO(waypoint_t *start) | |||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Prize -- todo, currently using standard Emerald
 | ||||
| 			// Prize -- todo, currently using fake Emerald
 | ||||
| 			P_SetMobjState(emerald, S_CHAOSEMERALD1); | ||||
| 			P_SetMobjState(overlay, S_CHAOSEMERALD_UNDER); | ||||
| 			emerald->color = SKINCOLOR_GOLD; | ||||
| 		} | ||||
| 
 | ||||
| 		P_SetTarget(&emerald->target, ufo); | ||||
|  |  | |||
|  | @ -1525,7 +1525,7 @@ boolean P_CheckRacers(void) | |||
| { | ||||
| 	const boolean griefed = (spectateGriefed > 0); | ||||
| 
 | ||||
| 	boolean eliminateLast = cv_karteliminatelast.value; | ||||
| 	boolean eliminateLast = (!K_CanChangeRules(true) || (cv_karteliminatelast.value != 0)); | ||||
| 	boolean allHumansDone = true; | ||||
| 	//boolean allBotsDone = true;
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -274,6 +274,10 @@ static void P_NetArchivePlayers(savebuffer_t *save) | |||
| 
 | ||||
| 		WRITEINT16(save->p, players[i].totalring); | ||||
| 		WRITEUINT32(save->p, players[i].realtime); | ||||
| 		for (j = 0; j < LAP__MAX; j++) | ||||
| 		{ | ||||
| 			WRITEUINT32(save->p, players[i].laptime[j]); | ||||
| 		} | ||||
| 		WRITEUINT8(save->p, players[i].laps); | ||||
| 		WRITEUINT8(save->p, players[i].latestlap); | ||||
| 		WRITEUINT32(save->p, players[i].lapPoints); | ||||
|  | @ -910,6 +914,10 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) | |||
| 
 | ||||
| 		players[i].totalring = READINT16(save->p); // Total number of rings obtained for GP
 | ||||
| 		players[i].realtime = READUINT32(save->p); // integer replacement for leveltime
 | ||||
| 		for (j = 0; j < LAP__MAX; j++) | ||||
| 		{ | ||||
| 			players[i].laptime[j] = READUINT32(save->p); | ||||
| 		} | ||||
| 		players[i].laps = READUINT8(save->p); // Number of laps (optional)
 | ||||
| 		players[i].latestlap = READUINT8(save->p); | ||||
| 		players[i].lapPoints = READUINT32(save->p); | ||||
|  |  | |||
|  | @ -7675,7 +7675,6 @@ static void P_InitLevelSettings(void) | |||
| 	} | ||||
| 
 | ||||
| 	racecountdown = exitcountdown = musiccountdown = exitfadestarted = 0; | ||||
| 	curlap = bestlap = 0; // SRB2Kart
 | ||||
| 
 | ||||
| 	g_exit.losing = false; | ||||
| 	g_exit.retry = false; | ||||
|  |  | |||
							
								
								
									
										14
									
								
								src/p_spec.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/p_spec.c
									
										
									
									
									
								
							|  | @ -2094,16 +2094,14 @@ static void K_HandleLapIncrement(player_t *player) | |||
| 				if (player->laps > 1) | ||||
| 				{ | ||||
| 					// save best lap for record attack
 | ||||
| 					if (modeattacking && player == &players[consoleplayer]) | ||||
| 					if (player->laptime[LAP_CUR] < player->laptime[LAP_BEST] || player->laptime[LAP_BEST] == 0) | ||||
| 					{ | ||||
| 						if (curlap < bestlap || bestlap == 0) | ||||
| 						{ | ||||
| 							bestlap = curlap; | ||||
| 						} | ||||
| 
 | ||||
| 						curlap = 0; | ||||
| 						player->laptime[LAP_BEST] = player->laptime[LAP_CUR]; | ||||
| 					} | ||||
| 
 | ||||
| 					player->laptime[LAP_LAST] = player->laptime[LAP_CUR]; | ||||
| 					player->laptime[LAP_CUR] = 0; | ||||
| 
 | ||||
| 					// Update power levels for this lap.
 | ||||
| 					K_UpdatePowerLevels(player, player->laps, false); | ||||
| 
 | ||||
|  | @ -2223,7 +2221,7 @@ static void K_HandleLapDecrement(player_t *player) | |||
| 			player->cheatchecknum = numcheatchecks; | ||||
| 			player->laps--; | ||||
| 			K_UpdateAllPlayerPositions(); | ||||
| 			curlap = UINT32_MAX; | ||||
| 			player->laptime[LAP_CUR] = UINT32_MAX; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										15
									
								
								src/p_user.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								src/p_user.c
									
										
									
									
									
								
							|  | @ -4322,19 +4322,16 @@ void P_PlayerThink(player_t *player) | |||
| 		if (leveltime >= starttime) | ||||
| 		{ | ||||
| 			player->realtime = leveltime - starttime; | ||||
| 			if (player == &players[consoleplayer]) | ||||
| 			{ | ||||
| 				if (player->spectator) | ||||
| 					curlap = 0; | ||||
| 				else if (curlap != UINT32_MAX) | ||||
| 					curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V
 | ||||
| 			} | ||||
| 
 | ||||
| 			if (player->spectator) | ||||
| 				player->laptime[LAP_CUR] = 0; | ||||
| 			else if (player->laptime[LAP_CUR] != UINT32_MAX) | ||||
| 				player->laptime[LAP_CUR]++; // This is too complicated to sync to realtime, just sorta hope for the best :V
 | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			player->realtime = 0; | ||||
| 			if (player == &players[consoleplayer]) | ||||
| 				curlap = 0; | ||||
| 			player->laptime[LAP_CUR] = 0; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 wolfs
						wolfs