From 74295638e3701f1df2d23cf3f5609e2a069cba0f Mon Sep 17 00:00:00 2001 From: minenice55 Date: Mon, 5 Jan 2026 22:17:50 -0500 Subject: [PATCH 01/12] start this while I can --- src/d_player.h | 3 +++ src/g_game.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/d_player.h b/src/d_player.h index 5120717b4..15a2c52b1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -504,6 +504,9 @@ struct player_t UINT8 kartspeed; // Kart speed stat between 1 and 9 UINT8 kartweight; // Kart weight stat between 1 and 9 + UINT8 kartspeedrestat; // Player's wanted kart speed from restat + UINT8 kartweightrestat; // Player's wanted kart weight from restat + INT32 followerskin; // Kart: This player's follower "skin" boolean followerready; // Kart: Used to know when we can have a follower or not. (This is set on the first NameAndColor follower update) UINT16 followercolor; // Kart: Used to store the follower colour the player wishes to use diff --git a/src/g_game.c b/src/g_game.c index 875deb445..b3ff0d7ba 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -493,6 +493,9 @@ consvar_t cv_deadzonestyle[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("deadzonestyle4", "Kart", CV_SAVE, deadzonestyle_cons_t, NULL) }; +// allows players to use restat (server toggle) +consvar_t cv_restat_allow = CVAR_INIT ("restat_allow", "Yes", CV_NETVAR, CV_YesNo, NULL); + // now automatically allocated in D_RegisterClientCommands // so that it doesn't have to be updated depending on the value of MAXPLAYERS char player_names[MAXPLAYERS][MAXPLAYERNAME+1]; From 2a1e8b54f0470a6bfbc185413aa8c12b4250417e Mon Sep 17 00:00:00 2001 From: minenice55 Date: Tue, 6 Jan 2026 02:23:40 -0500 Subject: [PATCH 02/12] cmd --- src/d_netcmd.c | 34 +++++++++++++++++++++++++++++++++- src/d_player.h | 1 + 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cbbb65c02..8f33ae5c0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1439,6 +1439,33 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_connectawaittime); CV_RegisterVar(&cv_serverinfoscreen); + + // player restat + COM_AddCommand("restat", Command_Restat); + COM_AddCommand("restat2", Command_Restat2); + COM_AddCommand("restat3", Command_Restat3); + COM_AddCommand("restat4", Command_Restat4); +} + +static void RestatForPlayer(UINT32 splitnum, UINT8 speed, UINT8 weight) +{ + +} + +static void Command_Restat(void) +{ +} + +static void Command_Restat2(void) +{ +} + +static void Command_Restat3(void) +{ +} + +static void Command_Restat4(void) +{ } /** @@ -2229,7 +2256,8 @@ enum { WP_KICKSTARTACCEL = 1<<0, WP_SHRINKME = 1<<1, WP_FLIPCAM = 1<<2, - WP_LEGACYJITTER = 1<<3 + WP_LEGACYJITTER = 1<<3, + WP_RANDOMRESTAT = 1<<4 }; void WeaponPref_Send(UINT8 ssplayer) @@ -2284,6 +2312,7 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum) player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME|PF_FLIPCAM); player->jitterlegacy = false; + player->randomrestat = false; if (prefs & WP_KICKSTARTACCEL) player->pflags |= PF_KICKSTARTACCEL; @@ -2297,6 +2326,9 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum) if (prefs & WP_LEGACYJITTER) player->jitterlegacy = true; + if (prefs & WP_RANDOMRESTAT) + player->randomrestat = true; + if (leveltime < 2) { // BAD HACK: No other place I tried to slot this in diff --git a/src/d_player.h b/src/d_player.h index 15a2c52b1..543bce1b7 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -506,6 +506,7 @@ struct player_t UINT8 kartspeedrestat; // Player's wanted kart speed from restat UINT8 kartweightrestat; // Player's wanted kart weight from restat + boolean randomrestat; // Randomly set the restat values of the player every game INT32 followerskin; // Kart: This player's follower "skin" boolean followerready; // Kart: Used to know when we can have a follower or not. (This is set on the first NameAndColor follower update) From c408f6963ecec5f4ae7d6c8013568364b1fcf874 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Wed, 7 Jan 2026 01:57:29 -0500 Subject: [PATCH 03/12] rough command implementation haven't tested yet will need to actually implement the restat --- src/d_netcmd.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++-- src/g_game.h | 2 + 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8f33ae5c0..f5e8f7c9a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1447,25 +1447,107 @@ void D_RegisterClientCommands(void) COM_AddCommand("restat4", Command_Restat4); } -static void RestatForPlayer(UINT32 splitnum, UINT8 speed, UINT8 weight) +static void RestatForPlayer(UINT32 ssplayer) { + player_t* player = &players[g_localplayers[ssplayer]]; + int speed; + int weight; + if (!cv_restat_allow.value) + { + CONS_Printf("This command has been disabled by the server host."); + return; + } + + if (COM_Argc() > 1) + { + if (fasticmp(COM_Argv(1), "random")) + { + player->randomrestat = !player->randomrestat; + if (player->randomrestat) + { + CONS_Printf("Random restat is now enabled."); + player->kartspeedrestat = 0; + player->kartweightrestat = 0; + } + else + { + CONS_Printf("Random restat is now disabled."); + } + + WeaponPref_Send(ssplayer); + return; + } + else if (fasticmp(COM_Argv(1), "off")) + { + player->kartspeedrestat = 0; + player->kartweightrestat = 0; + player->randomrestat = false; + WeaponPref_Send(ssplayer); + return; + } + else + { + CONS_Printf( + "Usage: \"restat \"\n" + "Alternatively: \"restat random\" to toggle using random stats each round.\n" + "or \"restat off\" to use your skin's default stats.\n"); + } + } + else if (COM_Argc() > 2) + { + if (sscanf(COM_Argv(1), " %d", &speed) == 0 || + sscanf(COM_Argv(2), " %d", &weight) == 0) + { + CONS_Printf("Expected two numbers ( ) in the range of 1-9.\n"); + return; + } + // range checking + if (speed < 1 || speed > 9 || + weight < 1 || weight > 9) + { + CONS_Printf("Expected two numbers ( ) in the range of 1-9.\n"); + return; + } + + // should be good now 🥲 + player->kartspeedrestat = speed; + player->kartweightrestat = weight; + player->randomrestat = false; + + CONS_Printf("You will be \130 %d speed, %d weight\140 for the next race.", speed, weight); + CONS_Printf("Use \135restat off\140 to return to your skin's default stats."); + + WeaponPref_Send(ssplayer); + return; + } + else + { + CONS_Printf( + "Usage: \"restat \"\n" + "Alternatively: \"restat random\" to use random stats each round.\n" + "or \"restat off\" to use your skin's default stats.\n"); + } } static void Command_Restat(void) { + RestatForPlayer(0); } static void Command_Restat2(void) { + RestatForPlayer(1); } static void Command_Restat3(void) { + RestatForPlayer(2); } static void Command_Restat4(void) { + RestatForPlayer(3); } /** @@ -2262,6 +2344,7 @@ enum { void WeaponPref_Send(UINT8 ssplayer) { + player_t* player = &players[g_localplayers[ssplayer]]; UINT8 prefs = 0; if (cv_kickstartaccel[ssplayer].value) @@ -2275,10 +2358,15 @@ void WeaponPref_Send(UINT8 ssplayer) if (!(cv_jitterlegacy[ssplayer].value)) prefs |= WP_LEGACYJITTER; + + if (player->randomrestat) + prefs |= WP_RANDOMRESTAT; - UINT8 buf[2]; + UINT8 buf[4]; buf[0] = prefs; buf[1] = cv_mindelay.value; + buf[2] = player->kartspeedrestat; + buf[3] = player->kartweightrestat; SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, sizeof buf); } @@ -2301,6 +2389,9 @@ void WeaponPref_Save(UINT8 **cp, INT32 playernum) if (player->jitterlegacy) prefs |= WP_LEGACYJITTER; + if (player->randomrestat) + prefs |= WP_RANDOMRESTAT; + WRITEUINT8(*cp, prefs); } @@ -2340,14 +2431,20 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum) static void Got_WeaponPref(UINT8 **cp,INT32 playernum) { + player_t *player = &players[playernum]; + WeaponPref_Parse(cp, playernum); UINT8 mindelay = READUINT8(*cp); if (server) { for (UINT8 i = 0; i < G_LocalSplitscreenPartySize(playernum); ++i) - playerdelaytable[G_LocalSplitscreenPartyMember(playernum, i)] = mindelay; + playerdelaytable[G_LocalSplitscreenPartyMember(playernum, i)] = mindelay; } + UINT8 kartspeedrestat = READUINT8(*cp); + UINT8 kartweightrestat = READUINT8(*cp); + player->kartspeedrestat = kartspeedrestat; + player->kartweightrestat = kartweightrestat; // SEE ALSO g_demo.c demo_extradata[playernum] |= DXD_WEAPONPREF; diff --git a/src/g_game.h b/src/g_game.h index b1d9a28d8..17f093a10 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -96,6 +96,8 @@ extern consvar_t cv_resetspecialmusic; extern consvar_t cv_resume; +extern consvar_t cv_restat_allow; + void weaponPrefChange(void); void weaponPrefChange2(void); void weaponPrefChange3(void); From 4b2f9bf839af6bfb10392bf418cf0d1a8f30ba60 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Wed, 7 Jan 2026 02:12:11 -0500 Subject: [PATCH 04/12] set the restat stats --- src/g_game.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index b3ff0d7ba..c1ae55bc7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2901,6 +2901,23 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) { laptime[i] = 0; } + + if (players[player].randomrestat) + { + kartspeed = P_RandomRange(1, 9); + kartweight = P_RandomRange(1, 9); + } + else if (players[player].kartspeedrestat != 0 && + players[player].kartweightrestat != 0) + { + kartspeed = players[player].kartspeedrestat; + kartweight = players[player].kartweightrestat; + } + else + { + kartspeed = skins[players[player].skin].kartspeed; + kartweight = skins[players[player].skin].kartweight; + } } else { From 74a5212c8d64c826ee68375fb79d085c586f59cd Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sat, 10 Jan 2026 20:32:08 -0500 Subject: [PATCH 05/12] get this buildable --- src/d_netcmd.c | 5 +++++ src/p_saveg.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f5e8f7c9a..c7d10f46d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -233,6 +233,11 @@ static void Command_Teamchange2_f(void); static void Command_Teamchange3_f(void); static void Command_Teamchange4_f(void); +static void Command_Restat(void); +static void Command_Restat2(void); +static void Command_Restat3(void); +static void Command_Restat4(void); + static void Command_ServerTeamChange_f(void); static void Command_Clearscores_f(void); diff --git a/src/p_saveg.c b/src/p_saveg.c index 57f7463b6..422446d38 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -555,6 +555,10 @@ static void P_NetSyncPlayers(savebuffer_t *save) SYNC(players[i].kartspeed); SYNC(players[i].kartweight); + SYNC(players[i].kartspeedrestat); + SYNC(players[i].kartweightrestat); + SYNC(players[i].randomrestat); + for (j = 0; j < MAXPREDICTTICS; j++) { SYNC(players[i].lturn_max[j]); From 4c83617de2d7dbb7e2f4bd3d5f450904a8e18477 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sat, 10 Jan 2026 21:55:39 -0500 Subject: [PATCH 06/12] make restat and allowrestat functional --- src/d_netcmd.c | 83 +++++++++++++++++++++++++------------------------- src/g_game.c | 35 ++++++++++++++++----- src/g_game.h | 2 +- 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c7d10f46d..84b46fe4d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1444,8 +1444,9 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_connectawaittime); CV_RegisterVar(&cv_serverinfoscreen); - + // player restat + CV_RegisterVar(&cv_allowrestat); COM_AddCommand("restat", Command_Restat); COM_AddCommand("restat2", Command_Restat2); COM_AddCommand("restat3", Command_Restat3); @@ -1458,48 +1459,13 @@ static void RestatForPlayer(UINT32 ssplayer) int speed; int weight; - if (!cv_restat_allow.value) + if (!cv_allowrestat.value) { - CONS_Printf("This command has been disabled by the server host."); + CONS_Printf("This command has been disabled by the server host.\n"); return; } - if (COM_Argc() > 1) - { - if (fasticmp(COM_Argv(1), "random")) - { - player->randomrestat = !player->randomrestat; - if (player->randomrestat) - { - CONS_Printf("Random restat is now enabled."); - player->kartspeedrestat = 0; - player->kartweightrestat = 0; - } - else - { - CONS_Printf("Random restat is now disabled."); - } - - WeaponPref_Send(ssplayer); - return; - } - else if (fasticmp(COM_Argv(1), "off")) - { - player->kartspeedrestat = 0; - player->kartweightrestat = 0; - player->randomrestat = false; - WeaponPref_Send(ssplayer); - return; - } - else - { - CONS_Printf( - "Usage: \"restat \"\n" - "Alternatively: \"restat random\" to toggle using random stats each round.\n" - "or \"restat off\" to use your skin's default stats.\n"); - } - } - else if (COM_Argc() > 2) + if (COM_Argc() > 2) { if (sscanf(COM_Argv(1), " %d", &speed) == 0 || sscanf(COM_Argv(2), " %d", &weight) == 0) @@ -1520,12 +1486,47 @@ static void RestatForPlayer(UINT32 ssplayer) player->kartweightrestat = weight; player->randomrestat = false; - CONS_Printf("You will be \130 %d speed, %d weight\140 for the next race.", speed, weight); - CONS_Printf("Use \135restat off\140 to return to your skin's default stats."); + CONS_Printf("You will be %d speed, %d weight for the next race.\n", speed, weight); + CONS_Printf("Use \"restat off\" to return to your skin's default stats.\n"); WeaponPref_Send(ssplayer); return; } + else if (COM_Argc() > 1) + { + if (fasticmp(COM_Argv(1), "random")) + { + player->randomrestat = !player->randomrestat; + if (player->randomrestat) + { + CONS_Printf("Random restat is now enabled.\n"); + } + else + { + CONS_Printf("Random restat is now disabled.\n"); + } + + WeaponPref_Send(ssplayer); + return; + } + else if (fasticmp(COM_Argv(1), "off")) + { + player->kartspeedrestat = 0; + player->kartweightrestat = 0; + player->randomrestat = false; + WeaponPref_Send(ssplayer); + + CONS_Printf("Now using skin default stats.\n"); + return; + } + else + { + CONS_Printf( + "Usage: \"restat \"\n" + "Alternatively: \"restat random\" to toggle the use of random stats each round.\n" + "or \"restat off\" to use your skin's default stats.\n"); + } + } else { CONS_Printf( diff --git a/src/g_game.c b/src/g_game.c index c1ae55bc7..2dfce20f6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -494,7 +494,7 @@ consvar_t cv_deadzonestyle[MAXSPLITSCREENPLAYERS] = { }; // allows players to use restat (server toggle) -consvar_t cv_restat_allow = CVAR_INIT ("restat_allow", "Yes", CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_allowrestat = CVAR_INIT ("allowrestat", "Yes", CV_NETVAR, CV_YesNo, NULL); // now automatically allocated in D_RegisterClientCommands // so that it doesn't have to be updated depending on the value of MAXPLAYERS @@ -2739,6 +2739,9 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 kartspeed; UINT8 kartweight; + UINT8 kartspeedrestat; + UINT8 kartweightrestat; + boolean randomrestat; boolean followerready; INT32 followerskin; @@ -2836,6 +2839,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) kartspeed = players[player].kartspeed; kartweight = players[player].kartweight; + kartspeedrestat = players[player].kartspeedrestat; + kartweightrestat = players[player].kartweightrestat; + randomrestat = players[player].randomrestat; + followerready = players[player].followerready; followercolor = players[player].followercolor; followerskin = players[player].followerskin; @@ -2902,16 +2909,24 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) laptime[i] = 0; } - if (players[player].randomrestat) + // might cause issues with weponpref sync? + if (!cv_allowrestat.value) { - kartspeed = P_RandomRange(1, 9); - kartweight = P_RandomRange(1, 9); + kartspeedrestat = 0; + kartweightrestat = 0; + randomrestat = false; } - else if (players[player].kartspeedrestat != 0 && - players[player].kartweightrestat != 0) + + if (randomrestat) { - kartspeed = players[player].kartspeedrestat; - kartweight = players[player].kartweightrestat; + kartspeedrestat = P_RandomRange(1, 9); + kartweightrestat = P_RandomRange(1, 9); + } + + if (kartspeedrestat != 0 && kartweightrestat != 0) + { + kartspeed = kartspeedrestat; + kartweight = kartweightrestat; } else { @@ -3041,6 +3056,10 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->voice_id = voice; p->kartspeed = kartspeed; p->kartweight = kartweight; + + p->kartspeedrestat = kartspeedrestat; + p->kartweightrestat = kartweightrestat; + p->randomrestat = randomrestat; // p->charflags = charflags; memcpy(players[player].availabilities, availabilities, sizeof(availabilities)); diff --git a/src/g_game.h b/src/g_game.h index 17f093a10..27244a282 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -96,7 +96,7 @@ extern consvar_t cv_resetspecialmusic; extern consvar_t cv_resume; -extern consvar_t cv_restat_allow; +extern consvar_t cv_allowrestat; void weaponPrefChange(void); void weaponPrefChange2(void); From 9411c90b793f8e807a1204af26bb6c4322a26d9b Mon Sep 17 00:00:00 2001 From: minenice55 Date: Fri, 23 Jan 2026 18:17:01 -0500 Subject: [PATCH 07/12] kick players that send illegal restat commands --- src/d_netcmd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 1bff0dd8f..532552982 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2450,6 +2450,14 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) } UINT8 kartspeedrestat = READUINT8(*cp); UINT8 kartweightrestat = READUINT8(*cp); + if (kartspeedrestat < 0 || kartspeedrestat > 9 || + kartweightrestat < 0 || kartweightrestat > 9) + { + CONS_Alert(CONS_WARNING, M_GetText("Illegal restat values received from %s\n"), player_names[playernum]); + if (server) + SendKick(playernum, KICK_MSG_CON_FAIL); + return; + } player->kartspeedrestat = kartspeedrestat; player->kartweightrestat = kartweightrestat; From 7bd4c0195b5424753f196e5552fe16b90522538e Mon Sep 17 00:00:00 2001 From: minenice55 Date: Fri, 23 Jan 2026 18:30:06 -0500 Subject: [PATCH 08/12] broadcast stat changes in chat (make this a server toggle) --- src/g_game.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 1c9b41aa6..f2d664534 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2927,11 +2927,29 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) { kartspeed = kartspeedrestat; kartweight = kartweightrestat; + + if (player == consoleplayer) + { + HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); + } + else + { + HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); + } } else { kartspeed = skins[players[player].skin].kartspeed; kartweight = skins[players[player].skin].kartweight; + + if (player == consoleplayer) + { + HU_AddChatText(va("You are now using your skin's default stats."), true); + } + else + { + HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); + } } } else From 30815b240d18f6de85c1b153dc3f5ff2adee288a Mon Sep 17 00:00:00 2001 From: minenice55 Date: Fri, 23 Jan 2026 18:38:44 -0500 Subject: [PATCH 09/12] apparently this runs even when the player slot is vacant --- src/g_game.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f2d664534..42bc6b198 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2928,27 +2928,33 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) kartspeed = kartspeedrestat; kartweight = kartweightrestat; - if (player == consoleplayer) + if (playeringame[player]) { - HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); - } - else - { - HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); + if (player == consoleplayer) + { + HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); + } + else + { + HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); + } } } else { kartspeed = skins[players[player].skin].kartspeed; kartweight = skins[players[player].skin].kartweight; - - if (player == consoleplayer) + + if (playeringame[player]) { - HU_AddChatText(va("You are now using your skin's default stats."), true); - } - else - { - HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); + if (player == consoleplayer) + { + HU_AddChatText(va("You are now using your skin's default stats."), true); + } + else + { + HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); + } } } } From 543b4549788892bdd20aa54860c69c80cac6c616 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Fri, 23 Jan 2026 20:02:22 -0500 Subject: [PATCH 10/12] fix notify printing lterally everyone's stats also add a toggle for server hosts to disable the message --- src/d_netcmd.c | 1 + src/g_game.c | 36 ++++++++++++++++++++++++++++-------- src/g_game.h | 2 +- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 532552982..f5f17199a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1448,6 +1448,7 @@ void D_RegisterClientCommands(void) // player restat CV_RegisterVar(&cv_allowrestat); + CV_RegisterVar(&cv_notifyrestat); COM_AddCommand("restat", Command_Restat); COM_AddCommand("restat2", Command_Restat2); COM_AddCommand("restat3", Command_Restat3); diff --git a/src/g_game.c b/src/g_game.c index 42bc6b198..0eecef29a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -495,6 +495,7 @@ consvar_t cv_deadzonestyle[MAXSPLITSCREENPLAYERS] = { // allows players to use restat (server toggle) consvar_t cv_allowrestat = CVAR_INIT ("allowrestat", "Yes", CV_NETVAR, CV_YesNo, NULL); +consvar_t cv_notifyrestat = CVAR_INIT ("notifyrestat", "Yes", CV_NETVAR, CV_YesNo, NULL); // now automatically allocated in D_RegisterClientCommands // so that it doesn't have to be updated depending on the value of MAXPLAYERS @@ -2742,6 +2743,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 kartspeedrestat; UINT8 kartweightrestat; boolean randomrestat; + boolean notifyrestat = false; boolean followerready; INT32 followerskin; @@ -2923,20 +2925,38 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) kartweightrestat = P_RandomRange(1, 9); } + // this is horrible 🥹 + notifyrestat = ( + ( + (kartspeedrestat == 0 || kartweightrestat == 0) && + ( + players[player].kartspeed != skins[players[player].skin].kartspeed || + players[player].kartweight != skins[players[player].skin].kartweight + ) + ) || + ( + ( + randomrestat || + kartspeedrestat != players[player].kartspeed || + kartweightrestat != players[player].kartweight + ) && (kartspeedrestat != 0 || kartweightrestat != 0) + ) + ) && cv_notifyrestat.value; + if (kartspeedrestat != 0 && kartweightrestat != 0) { kartspeed = kartspeedrestat; kartweight = kartweightrestat; - if (playeringame[player]) + if (playeringame[player] && notifyrestat) { - if (player == consoleplayer) + if ((splitscreen && player == consoleplayer) || player != consoleplayer) { - HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); + HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); } else { - HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); + HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); } } } @@ -2945,15 +2965,15 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) kartspeed = skins[players[player].skin].kartspeed; kartweight = skins[players[player].skin].kartweight; - if (playeringame[player]) + if (playeringame[player] && notifyrestat) { - if (player == consoleplayer) + if ((splitscreen && player == consoleplayer) || player != consoleplayer) { - HU_AddChatText(va("You are now using your skin's default stats."), true); + HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); } else { - HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); + HU_AddChatText(va("You are now using your skin's default stats."), true); } } } diff --git a/src/g_game.h b/src/g_game.h index 27244a282..64c04f360 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -96,7 +96,7 @@ extern consvar_t cv_resetspecialmusic; extern consvar_t cv_resume; -extern consvar_t cv_allowrestat; +extern consvar_t cv_allowrestat, cv_notifyrestat; void weaponPrefChange(void); void weaponPrefChange2(void); From 81ce7d00870f65fe478600b68f668636c331a4b8 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sat, 24 Jan 2026 12:37:33 -0500 Subject: [PATCH 11/12] check jointime here by suggestion --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 0eecef29a..dd5069f02 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2870,7 +2870,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_FLIPCAM)); // SRB2kart - if (betweenmaps || leveltime <= starttime || spectator == true) + if ((betweenmaps || leveltime <= starttime || spectator == true) && players[player].jointime) { itemroulette = 0; previtemroulette = 0; From 60e5fc65ca321a72c824d64ce3c57acd195cf90a Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sat, 24 Jan 2026 14:51:24 -0500 Subject: [PATCH 12/12] move restat logging elsewhere to fix cond --- src/g_game.c | 87 ++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 43 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index dd5069f02..b09253d3c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2743,7 +2743,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) UINT8 kartspeedrestat; UINT8 kartweightrestat; boolean randomrestat; - boolean notifyrestat = false; + boolean notifyrestat; boolean followerready; INT32 followerskin; @@ -2870,7 +2870,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) pflags = (players[player].pflags & (PF_WANTSTOJOIN|PF_KICKSTARTACCEL|PF_SHRINKME|PF_SHRINKACTIVE|PF_FLIPCAM)); // SRB2kart - if ((betweenmaps || leveltime <= starttime || spectator == true) && players[player].jointime) + if (betweenmaps || leveltime <= starttime || spectator == true || players[player].jointime == 0) { itemroulette = 0; previtemroulette = 0; @@ -2896,7 +2896,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) exiting = 0; khudfinish = 0; khudcardanimation = 0; - starpostx =0; + starpostx = 0; starposty = 0; starpostz = 0; starpostangle = 0; @@ -2925,57 +2925,26 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) kartweightrestat = P_RandomRange(1, 9); } - // this is horrible 🥹 - notifyrestat = ( - ( - (kartspeedrestat == 0 || kartweightrestat == 0) && - ( - players[player].kartspeed != skins[players[player].skin].kartspeed || - players[player].kartweight != skins[players[player].skin].kartweight - ) - ) || - ( - ( - randomrestat || - kartspeedrestat != players[player].kartspeed || - kartweightrestat != players[player].kartweight - ) && (kartspeedrestat != 0 || kartweightrestat != 0) - ) - ) && cv_notifyrestat.value; - if (kartspeedrestat != 0 && kartweightrestat != 0) { kartspeed = kartspeedrestat; kartweight = kartweightrestat; - if (playeringame[player] && notifyrestat) - { - if ((splitscreen && player == consoleplayer) || player != consoleplayer) - { - HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); - } - else - { - HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); - } - } + notifyrestat = ( + randomrestat || + kartspeedrestat != players[player].kartspeed || + kartweightrestat != players[player].kartweight + ) && cv_notifyrestat.value; } else { kartspeed = skins[players[player].skin].kartspeed; kartweight = skins[players[player].skin].kartweight; - if (playeringame[player] && notifyrestat) - { - if ((splitscreen && player == consoleplayer) || player != consoleplayer) - { - HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); - } - else - { - HU_AddChatText(va("You are now using your skin's default stats."), true); - } - } + notifyrestat = ( + players[player].kartspeed != skins[players[player].skin].kartspeed || + players[player].kartweight != skins[players[player].skin].kartweight + ) && cv_notifyrestat.value; } } else @@ -3069,6 +3038,38 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) else { follower = NULL; + + if (players[player].jointime > 0) + { + if (kartspeedrestat != 0 && kartweightrestat != 0) + { + if (playeringame[player] && notifyrestat) + { + if ((splitscreen && player == consoleplayer) || player != consoleplayer) + { + HU_AddChatText(va("%s is now %d speed, %d weight.", player_names[player], kartspeed, kartweight), true); + } + else + { + HU_AddChatText(va("You are now %d speed, %d weight.", kartspeed, kartweight), true); + } + } + } + else + { + if (playeringame[player] && notifyrestat) + { + if ((splitscreen && player == consoleplayer) || player != consoleplayer) + { + HU_AddChatText(va("%s is now using their skin's default stats.", player_names[player]), true); + } + else + { + HU_AddChatText(va("You are now using your skin's default stats."), true); + } + } + } + } } spectatorreentry = (betweenmaps ? 0 : players[player].spectatorreentry);