From 622e94797bb587a8a6feb99c8d3af3e0c2af99f4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 22:55:49 -0500 Subject: [PATCH 01/39] basic start on VR --- src/doomstat.h | 1 + src/g_game.c | 11 +++++++++++ src/m_menu.c | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/doomstat.h b/src/doomstat.h index 34456b321..0ff47dce6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -326,6 +326,7 @@ enum GameType // SRB2Kart extern tic_t totalplaytime; extern UINT32 matchesplayed; +extern UINT16 versusrecord[2]; extern UINT8 stagefailed; diff --git a/src/g_game.c b/src/g_game.c index e9309b807..cdb5d3717 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -169,6 +169,7 @@ INT32 sstimer; // Time allotted in the special stage tic_t totalplaytime; UINT32 matchesplayed; // SRB2Kart +UINT16 versusrecord[2]; // SRB2Kart: Online rankings boolean gamedataloaded = false; // Time attack data for levels @@ -3744,9 +3745,13 @@ void G_LoadGameData(void) // to new gamedata G_ClearRecords(); // main and nights records M_ClearSecrets(); // emblems, unlocks, maps visited, etc + totalplaytime = 0; // total play time (separate from all) matchesplayed = 0; // SRB2Kart: matches played & finished + for (i = 0; i < 2; i++) // SRB2Kart: online VR system + versusrecord[i] = 5000; + if (M_CheckParm("-nodata")) return; // Don't load. @@ -3777,6 +3782,9 @@ void G_LoadGameData(void) totalplaytime = READUINT32(save_p); matchesplayed = READUINT32(save_p); + for (i = 0; i < 2; i++) + versusrecord[i] = READUINT16(save_p); + modded = READUINT8(save_p); // Aha! Someone's been screwing with the save file! @@ -3925,6 +3933,9 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, totalplaytime); WRITEUINT32(save_p, matchesplayed); + for (i = 0; i < 2; i++) + WRITEUINT16(save_p, versusrecord[i]); + btemp = (UINT8)(savemoddata || modifiedgame); WRITEUINT8(save_p, btemp); diff --git a/src/m_menu.c b/src/m_menu.c index 8e49b2155..2484cd9a3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6319,9 +6319,16 @@ static void M_DrawLevelStats(void) G_TicsToHours(totalplaytime), G_TicsToMinutes(totalplaytime, false), G_TicsToSeconds(totalplaytime))); + V_DrawString(20, 42, highlightflags, "Total Matches:"); V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); + V_DrawString(20, 50, highlightflags, "Race Versus Record:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 50, 0, va("%i", versusrecord[0])); + + V_DrawString(20, 58, highlightflags, "Battle Versus Record:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 58, 0, va("%i", versusrecord[1])); + for (i = 0; i < NUMMAPS; i++) { if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) @@ -8452,6 +8459,8 @@ static UINT8 erasecontext = 0; static void M_EraseDataResponse(INT32 ch) { + UINT8 i; + if (ch != 'y' && ch != KEY_ENTER) return; @@ -8463,6 +8472,8 @@ static void M_EraseDataResponse(INT32 ch) // SRB2Kart: This actually needs to be done FIRST, so that you don't immediately regain playtime/matches secrets totalplaytime = 0; matchesplayed = 0; + for (i = 0; i < 2; i++) + versusrecord[i] = 5000; F_StartIntro(); } if (erasecontext != 1) From 3246ca6b33e8562df46bb54cc12b115fb7b172b5 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 16 Jan 2019 14:49:42 -0500 Subject: [PATCH 02/39] More finished power level broken, can't finish --- src/d_clisrv.c | 117 +++++++++++++++++++++++--------------- src/d_clisrv.h | 1 + src/d_netcmd.c | 50 +++++++++++++++++ src/d_netcmd.h | 6 +- src/doomstat.h | 5 +- src/g_game.c | 12 ++-- src/k_kart.c | 111 +++++++++++++++++++++++++++++++++++- src/k_kart.h | 2 + src/m_menu.c | 24 ++++---- src/p_inter.c | 63 ++++++++++----------- src/p_saveg.c | 10 +++- src/p_setup.c | 5 +- src/p_spec.c | 4 -- src/y_inter.c | 149 ++++++++++++++++++++++++++++++++++++++++++------- 14 files changed, 428 insertions(+), 131 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3dc641cdd..9c79d8ef6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1461,7 +1461,7 @@ static void SV_SendPlayerInfo(INT32 node) */ static boolean SV_SendServerConfig(INT32 node) { - INT32 i; + INT32 i, j; UINT8 *p, *op; boolean waspacketsent; @@ -1485,9 +1485,15 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); + for (i = 0; i < MAXPLAYERS; i++) + for (j = 0; j < 2; j++) + netbuffer->u.servercfg.powerlevels[i][j] = 0; // Not sure if memset works on something like this + for (i = 0; i < MAXPLAYERS; i++) { netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i]; + for (j = 0; j < 2; j++) + netbuffer->u.servercfg.powerlevels[i][j] = clientpowerlevels[i][j]; if (!playeringame[i]) continue; @@ -2163,6 +2169,7 @@ static void CL_ConnectToServer(boolean viams) wipegamestate = GS_WAITINGPLAYERS; ClearAdminPlayers(); + ClearClientPowerLevels(); pnumnodes = 1; oldtic = I_GetTime() - 1; #ifndef NONET @@ -2971,6 +2978,21 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) break; } + // SRB2Kart: kicks count as forfeit + switch (kickreason) + { + case KR_KICK: + case KR_BAN: + case KR_LEAVE: + // Intentional removals should be hit with a true forfeit. + K_PlayerForfeit(pnum, true); + break; + default: + // Otherwise, give remaining players the point compensation, but doesn't penalize who left. + K_PlayerForfeit(pnum, false); + break; + } + if (playernode[pnum] == playernode[consoleplayer]) { #ifdef DUMPCONSISTENCY @@ -3145,6 +3167,7 @@ void SV_ResetServer(void) playernode[i] = UINT8_MAX; sprintf(player_names[i], "Player %d", i + 1); adminplayers[i] = -1; // Populate the entire adminplayers array with -1. + ClearClientPowerLevels(); } mynode = 0; @@ -3220,6 +3243,7 @@ void D_QuitNetGame(void) D_CloseConnection(); ClearAdminPlayers(); + ClearClientPowerLevels(); DEBFILE("===========================================================================\n" " Log finish\n" @@ -3247,8 +3271,7 @@ static inline void SV_AddNode(INT32 node) // Xcmd XD_ADDPLAYER static void Got_AddPlayer(UINT8 **p, INT32 playernum) { - INT16 node, newplayernum; - UINT8 splitscreenplayer = 0; + UINT8 node, newplayernum, splitscreenplayer; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3265,11 +3288,12 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) return; } - node = READUINT8(*p); - newplayernum = READUINT8(*p); - splitscreenplayer = newplayernum/MAXPLAYERS; - newplayernum %= MAXPLAYERS; + node = (UINT8)READUINT8(*p); + newplayernum = (UINT8)READUINT8(*p); + splitscreenplayer = (UINT8)READUINT8(*p); + CONS_Printf("addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer); + // Clear player before joining, lest some things get set incorrectly CL_ClearPlayer(newplayernum); @@ -3282,28 +3306,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (node == mynode) { playernode[newplayernum] = 0; // for information only - if (splitscreenplayer) - { - if (splitscreenplayer == 1) - { - secondarydisplayplayer = newplayernum; - DEBFILE("spawning my brother\n"); - if (botingame) - players[newplayernum].bot = 1; - // Same goes for player 2 when relevant - } - else if (splitscreenplayer == 2) - { - thirddisplayplayer = newplayernum; - DEBFILE("spawning my sister\n"); - } - else if (splitscreenplayer == 3) - { - fourthdisplayplayer = newplayernum; - DEBFILE("spawning my trusty pet dog\n"); - } - } - else + + if (splitscreenplayer == 0) { consoleplayer = newplayernum; displayplayer = newplayernum; @@ -3312,6 +3316,25 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) fourthdisplayplayer = newplayernum; DEBFILE("spawning me\n"); } + else if (splitscreenplayer == 1) + { + secondarydisplayplayer = newplayernum; + DEBFILE("spawning my brother\n"); + if (botingame) + players[newplayernum].bot = 1; + // Same goes for player 2 when relevant + } + else if (splitscreenplayer == 2) + { + thirddisplayplayer = newplayernum; + DEBFILE("spawning my sister\n"); + } + else if (splitscreenplayer == 3) + { + fourthdisplayplayer = newplayernum; + DEBFILE("spawning my trusty pet dog\n"); + } + D_SendPlayerConfig(); addedtogame = true; } @@ -3365,8 +3388,9 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum) static boolean SV_AddWaitingPlayers(void) { INT32 node, n, newplayer = false; - XBOXSTATIC UINT8 buf[2]; UINT8 newplayernum = 0; + static UINT8 buf[3]; + static UINT8 *buf_p = buf; // What is the reason for this? Why can't newplayernum always be 0? // Sal: Because the dedicated player is stupidly forced into players[0]..... @@ -3385,8 +3409,10 @@ static boolean SV_AddWaitingPlayers(void) for (; newplayernum < MAXPLAYERS; newplayernum++) { for (n = 0; n < MAXNETNODES; n++) - if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum - || nodetoplayer3[n] == newplayernum || nodetoplayer4[n] == newplayernum) + if (nodetoplayer[n] == newplayernum + || nodetoplayer2[n] == newplayernum + || nodetoplayer3[n] == newplayernum + || nodetoplayer4[n] == newplayernum) break; if (n == MAXNETNODES) break; @@ -3398,28 +3424,23 @@ static boolean SV_AddWaitingPlayers(void) playernode[newplayernum] = (UINT8)node; - buf[0] = (UINT8)node; - buf[1] = newplayernum; + WRITEUINT8(buf_p, (UINT8)node); + WRITEUINT8(buf_p, newplayernum); + if (playerpernode[node] < 1) nodetoplayer[node] = newplayernum; else if (playerpernode[node] < 2) - { nodetoplayer2[node] = newplayernum; - buf[1] += MAXPLAYERS; - } else if (playerpernode[node] < 3) - { nodetoplayer3[node] = newplayernum; - buf[1] += MAXPLAYERS*2; - } - else - { + else if (playerpernode[node] < 4) nodetoplayer4[node] = newplayernum; - buf[1] += MAXPLAYERS*3; - } + + WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num + playerpernode[node]++; - SendNetXCmd(XD_ADDPLAYER, &buf, 2); + SendNetXCmd(XD_ADDPLAYER, buf, buf_p - buf); DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); // use the next free slot (we can't put playeringame[newplayernum] = true here) @@ -3775,7 +3796,7 @@ static void HandlePacketFromAwayNode(SINT8 node) case PT_SERVERCFG: // Positive response of client join request { - INT32 j; + INT32 j, k; UINT8 *scp; if (server && serverrunning && node != servernode) @@ -3795,7 +3816,11 @@ static void HandlePacketFromAwayNode(SINT8 node) I_Error("Bad gametype in cliserv!"); modifiedgame = netbuffer->u.servercfg.modifiedgame; for (j = 0; j < MAXPLAYERS; j++) + { adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; + for (k = 0; k < 2; k++) + clientpowerlevels[j][k] = netbuffer->u.servercfg.powerlevels[j][k]; + } memcpy(server_context, netbuffer->u.servercfg.server_context, 8); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 5cf72bbc7..1c85144eb 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -328,6 +328,7 @@ typedef struct UINT8 gametype; UINT8 modifiedgame; SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed + UINT16 powerlevels[MAXPLAYERS][2]; // SRB2kart: player power levels char server_context[8]; // Unique context id, generated at server startup. diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e15ed9aac..4f42a6bef 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -61,6 +61,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum); static void Got_WeaponPref(UINT8 **cp, INT32 playernum); +static void Got_PowerLevel(UINT8 **cp, INT32 playernum); static void Got_Mapcmd(UINT8 **cp, INT32 playernum); static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum); @@ -455,6 +456,7 @@ boolean deferencoremode = false; UINT8 splitscreen = 0; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; +UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \warning Keep this up-to-date if you add/remove/rename net text commands const char *netxcmdnames[MAXNETXCMD - 1] = @@ -483,6 +485,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "SETUPVOTE", "MODIFYVOTE", "PICKVOTE", + "REMOVEPLAYER", + "POWERLEVEL", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -502,6 +506,7 @@ void D_RegisterServerCommands(void) { RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor); RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref); + RegisterNetXCmd(XD_POWERLEVEL, Got_PowerLevel); RegisterNetXCmd(XD_MAP, Got_Mapcmd); RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd); RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); @@ -1864,6 +1869,16 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) players[playernum].pflags |= PF_ANALOGMODE; } +static void Got_PowerLevel(UINT8 **cp,INT32 playernum) +{ + UINT16 race = (UINT16)READUINT16(*cp); + UINT16 battle = (UINT16)READUINT16(*cp); + + clientpowerlevels[playernum][0] = min(9999, race); + clientpowerlevels[playernum][1] = min(9999, battle); + CONS_Printf("set player %d to power %d\n", playernum, race); +} + void D_SendPlayerConfig(void) { SendNameAndColor(); @@ -1880,6 +1895,31 @@ void D_SendPlayerConfig(void) SendWeaponPref3(); if (splitscreen > 2) SendWeaponPref4(); + + { + UINT8 buf[4]; + UINT8 *buf_p = buf; + + WRITEUINT16(buf_p, vspowerlevel[0]); + WRITEUINT16(buf_p, vspowerlevel[1]); + + SendNetXCmd(XD_POWERLEVEL, buf, 4); + } + + if (splitscreen) + { + UINT8 buf[4]; + UINT8 *buf_p = buf; + + WRITEUINT16(buf_p, 0); + WRITEUINT16(buf_p, 0); + + SendNetXCmd2(XD_POWERLEVEL, buf, 4); + if (splitscreen > 1) + SendNetXCmd3(XD_POWERLEVEL, buf, 4); + if (splitscreen > 2) + SendNetXCmd4(XD_POWERLEVEL, buf, 4); + } } // Only works for displayplayer, sorry! @@ -3373,6 +3413,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (K_IsPlayerWanted(&players[playernum])) K_CalculateBattleWanted(); } + K_PlayerForfeit(playernum, true); + players[playernum].health = 1; if (players[playernum].mo) players[playernum].mo->health = 1; @@ -3521,6 +3563,14 @@ static void Got_Login(UINT8 **cp, INT32 playernum) #endif } +void ClearClientPowerLevels(void) +{ + INT32 i, j; + for (i = 0; i < MAXPLAYERS; i++) + for (j = 0; j < 2; j++) + clientpowerlevels[i][j] = 0; +} + boolean IsPlayerAdmin(INT32 playernum) { INT32 i; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7927aea00..22fc80da2 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -176,9 +176,10 @@ typedef enum XD_MODIFYVOTE, // 23 XD_PICKVOTE, // 24 XD_REMOVEPLAYER,// 25 + XD_POWERLEVEL, // 26 #ifdef HAVE_BLUA - XD_LUACMD, // 26 - XD_LUAVAR, // 27 + XD_LUACMD, // 27 + XD_LUAVAR, // 28 #endif MAXNETXCMD } netxcmd_t; @@ -237,6 +238,7 @@ void D_SetupVote(void); void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer); void D_PickVote(void); void ObjectPlace_OnChange(void); +void ClearClientPowerLevels(void); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); void ClearAdminPlayers(void); diff --git a/src/doomstat.h b/src/doomstat.h index 5831d4f47..4826e94fd 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -332,7 +332,7 @@ enum GameType // SRB2Kart extern tic_t totalplaytime; extern UINT32 matchesplayed; -extern UINT16 versusrecord[2]; +extern UINT16 vspowerlevel[2]; extern UINT8 stagefailed; @@ -467,7 +467,7 @@ extern SINT8 battlewanted[4]; extern tic_t wantedcalcdelay; extern tic_t indirectitemcooldown; extern tic_t mapreset; -extern UINT8 nospectategrief; +extern INT16 nospectategrief[MAXPLAYERS]; extern boolean thwompsactive; extern SINT8 spbplace; @@ -547,6 +547,7 @@ extern consvar_t cv_maxping; extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern INT32 serverplayer; extern INT32 adminplayers[MAXPLAYERS]; +extern UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \note put these in d_clisrv outright? diff --git a/src/g_game.c b/src/g_game.c index 8292004a6..ec085914d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -169,7 +169,7 @@ INT32 sstimer; // Time allotted in the special stage tic_t totalplaytime; UINT32 matchesplayed; // SRB2Kart -UINT16 versusrecord[2]; // SRB2Kart: Online rankings +UINT16 vspowerlevel[2]; // SRB2Kart: Online rankings for each gametype boolean gamedataloaded = false; // Time attack data for levels @@ -267,7 +267,7 @@ SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded tic_t mapreset; // Map reset delay when enough players have joined an empty game -UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing +INT16 nospectategrief[MAXPLAYERS]; // Which players spec-scummed, and their power level before scumming. boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items @@ -3782,8 +3782,8 @@ void G_LoadGameData(void) totalplaytime = 0; // total play time (separate from all) matchesplayed = 0; // SRB2Kart: matches played & finished - for (i = 0; i < 2; i++) // SRB2Kart: online VR system - versusrecord[i] = 5000; + for (i = 0; i < 2; i++) // SRB2Kart: online rank system + vspowerlevel[i] = 5000; if (M_CheckParm("-nodata")) return; // Don't load. @@ -3816,7 +3816,7 @@ void G_LoadGameData(void) matchesplayed = READUINT32(save_p); for (i = 0; i < 2; i++) - versusrecord[i] = READUINT16(save_p); + vspowerlevel[i] = READUINT16(save_p); modded = READUINT8(save_p); @@ -3967,7 +3967,7 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, matchesplayed); for (i = 0; i < 2; i++) - WRITEUINT16(save_p, versusrecord[i]); + WRITEUINT16(save_p, vspowerlevel[i]); btemp = (UINT8)(savemoddata || modifiedgame); WRITEUINT8(save_p, btemp); diff --git a/src/k_kart.c b/src/k_kart.c index 476bff462..fdfdc4933 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -31,7 +31,7 @@ // battlewanted is an array of the WANTED player nums, -1 for no player in that slot // indirectitemcooldown is timer before anyone's allowed another Shrink/SPB // mapreset is set when enough players fill an empty server -// nospectategrief is the players in-game needed to eliminate the person in last +// nospectategrief is a list of griefers' power levels //{ SRB2kart Color Code @@ -5741,6 +5741,115 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating +INT16 K_CalculatePowerLevelInc(INT16 diff) +{ + INT16 control[10] = {0,0,0,1,8,50,125,125,125,125}; + fixed_t increment = 0; + fixed_t x; + UINT8 j; + +#define MAXDIFF 9998 + if (diff > MAXDIFF) + diff = MAXDIFF; + if (diff < -MAXDIFF) + diff = -MAXDIFF; +#undef MAXDIFF + + x = ((diff-2)<= (2<= (1<> FRACBITS); +} + +void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) +{ + INT32 powertype = -1; + UINT16 yourpower = 5000; + UINT16 theirpower = 5000; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; + UINT8 i; + + // power level is netgames only + if (!netgame) + return; + + // 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match. + if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) + return; + + if (G_RaceGametype()) + powertype = 0; + else if (G_BattleGametype()) + powertype = 1; + + if (powertype == -1) // Not using power levels + return; + + if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes + return; + yourpower = clientpowerlevels[playernum][powertype]; + + // Set up the point compensation. + nospectategrief[playernum] = yourpower; + + if (nopointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (i == playernum) + continue; + + theirpower = 5000; + if (clientpowerlevels[i][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[i][powertype]; + + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + } + + if (inc == 0) // No change. + return; + + if (yourpower + inc > 9999) // I mean... we're subtracting... but y'know how it is :V + inc -= ((yourpower + inc) - 9999); + if (yourpower + inc < 1) + inc -= ((yourpower + inc) - 1); + + clientpowerlevels[playernum][powertype] += inc; + + if (playernum == consoleplayer) + { + vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); // save your punishment! + } +} + void K_CheckSpectateStatus(void) { UINT8 respawnlist[MAXPLAYERS]; diff --git a/src/k_kart.h b/src/k_kart.h index 3f7120913..ce5203675 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -63,6 +63,8 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); +INT16 K_CalculatePowerLevelInc(INT16 diff); +void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); void K_CheckSpectateStatus(void); const char *K_GetItemPatch(UINT8 item, boolean tiny); diff --git a/src/m_menu.c b/src/m_menu.c index a8c5ad486..bcbc6cb78 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6252,7 +6252,7 @@ static void M_Statistics(INT32 choice) static void M_DrawStatsMaps(int location) { - INT32 y = 80, i = -1; + INT32 y = 88, i = -1; INT16 mnum; extraemblem_t *exemblem; boolean dotopname = true, dobottomarrow = (location < statsMax); @@ -6365,11 +6365,9 @@ static void M_DrawLevelStats(void) V_DrawString(20, 42, highlightflags, "Total Matches:"); V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); - V_DrawString(20, 50, highlightflags, "Race Versus Record:"); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 50, 0, va("%i", versusrecord[0])); - - V_DrawString(20, 58, highlightflags, "Battle Versus Record:"); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 58, 0, va("%i", versusrecord[1])); + V_DrawString(20, 52, highlightflags, "Online Power Level:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[0])); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[1])); for (i = 0; i < NUMMAPS; i++) { @@ -6385,18 +6383,18 @@ static void M_DrawLevelStats(void) besttime += mainrecords[i]->time; } - V_DrawString(20, 62, highlightflags, "Combined time records:"); + V_DrawString(20, 70, highlightflags, "Combined time records:"); sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime)); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 62, (mapsunfinished ? warningflags : 0), beststr); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, (mapsunfinished ? warningflags : 0), beststr); if (mapsunfinished) - V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, warningflags, va("(%d unfinished)", mapsunfinished)); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 78, warningflags, va("(%d unfinished)", mapsunfinished)); else - V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, recommendedflags, "(complete)"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 78, recommendedflags, "(complete)"); - V_DrawString(32, 70, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawSmallScaledPatch(20, 70, 0, W_CachePatchName("GOTITA", PU_STATIC)); + V_DrawString(32, 78, V_ALLOWLOWERCASE, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); + V_DrawSmallScaledPatch(20, 78, 0, W_CachePatchName("GOTITA", PU_STATIC)); M_DrawStatsMaps(statsLocation); } @@ -8515,7 +8513,7 @@ static void M_EraseDataResponse(INT32 ch) totalplaytime = 0; matchesplayed = 0; for (i = 0; i < 2; i++) - versusrecord[i] = 5000; + vspowerlevel[i] = 5000; F_StartIntro(); } if (erasecontext != 1) diff --git a/src/p_inter.c b/src/p_inter.c index dd27858fc..a4f1fe84b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2010,7 +2010,8 @@ void P_CheckPointLimit(void) // Checks whether or not to end a race netgame. boolean P_CheckRacers(void) { - INT32 i, j, numplayersingame = 0; + INT32 i, j, numplayersingame = 0, numexiting = 0; + boolean griefed = false; // Check if all the players in the race have finished. If so, end the level. for (i = 0; i < MAXPLAYERS; i++) @@ -2027,57 +2028,53 @@ boolean P_CheckRacers(void) return true; } - if (cv_karteliminatelast.value) + for (j = 0; j < MAXPLAYERS; j++) { - for (j = 0; j < MAXPLAYERS; j++) + if (nospectategrief[j] != -1) // prevent spectate griefing + griefed = true; + if (!playeringame[j] || players[j].spectator) + continue; + numplayersingame++; + if (players[j].exiting) + numexiting++; + } + + if (cv_karteliminatelast.value && numplayersingame > 1 && !griefed) + { + // check if we just got unlucky and there was only one guy who was a problem + for (j = i+1; j < MAXPLAYERS; j++) { - if (!playeringame[j] || players[j].spectator) + if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) continue; - numplayersingame++; + break; } - if (numplayersingame > 1 && nospectategrief > 0 && numplayersingame >= nospectategrief) // prevent spectate griefing + if (j == MAXPLAYERS) // finish anyways, force a time over { - // check if we just got unlucky and there was only one guy who was a problem - for (j = i+1; j < MAXPLAYERS; j++) - { - if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) - continue; - - break; - } - - if (j == MAXPLAYERS) // finish anyways, force a time over - { - P_DoTimeOver(&players[i]); - countdown = countdown2 = 0; - return true; - } + P_DoTimeOver(&players[i]); + countdown = countdown2 = 0; + return true; } } if (!countdown) // Check to see if the winners have finished, to set countdown. { - UINT8 numingame = 0, numexiting = 0; UINT8 winningpos = 1; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - numingame++; - if (players[i].exiting) - numexiting++; - } - - winningpos = max(1, numingame/2); - if (numingame % 2) // any remainder? + winningpos = max(1, numplayersingame/2); + if (numplayersingame % 2) // any remainder? winningpos++; if (numexiting >= winningpos) countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going! } + if (numplayersingame < 2) // reset nospectategrief in free play + { + for (j = 0; j < MAXPLAYERS; j++) + nospectategrief[j] = -1; + } + return false; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 975a4a5d2..075b2ccb2 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3314,7 +3314,10 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, wantedcalcdelay); WRITEUINT32(save_p, indirectitemcooldown); WRITEUINT32(save_p, mapreset); - WRITEUINT8(save_p, nospectategrief); + + for (i = 0; i < MAXPLAYERS; i++) + WRITEINT16(save_p, nospectategrief[i]); + WRITEUINT8(save_p, thwompsactive); WRITESINT8(save_p, spbplace); @@ -3422,7 +3425,10 @@ static inline boolean P_NetUnArchiveMisc(void) wantedcalcdelay = READUINT32(save_p); indirectitemcooldown = READUINT32(save_p); mapreset = READUINT32(save_p); - nospectategrief = READUINT8(save_p); + + for (i = 0; i < MAXPLAYERS; i++) + nospectategrief[i] = READINT16(save_p); + thwompsactive = (boolean)READUINT8(save_p); spbplace = READSINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 49b22184e..d1c0b1092 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3242,7 +3242,10 @@ boolean P_SetupLevel(boolean skipprecip) wantedcalcdelay = wantedfrequency*2; indirectitemcooldown = 0; mapreset = 0; - nospectategrief = 0; + + for (i = 0; i < MAXPLAYERS; i++) + nospectategrief[i] = -1; + thwompsactive = false; spbplace = -1; diff --git a/src/p_spec.c b/src/p_spec.c index ca4967ce3..a11cc5c44 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4278,10 +4278,6 @@ DoneSection2: // Play the starpost sound for 'consistency' // S_StartSound(player->mo, sfx_strpst); - // Figure out how many are playing on the last lap, to prevent spectate griefing - if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1)) - nospectategrief = nump; - thwompsactive = true; // Lap 2 effects } else if (player->starpostnum) diff --git a/src/y_inter.c b/src/y_inter.c index 021519e3b..8000fd2b1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -89,7 +89,7 @@ typedef union INT32 numplayers; // Number of players being displayed char levelstring[64]; // holds levelnames up to 64 characters // SRB2kart - UINT8 increase[MAXPLAYERS]; // how much did the score increase by? + INT16 increase[MAXPLAYERS]; // how much did the score increase by? UINT8 jitter[MAXPLAYERS]; // wiggle UINT32 val[MAXPLAYERS]; // Gametype-specific value UINT8 pos[MAXPLAYERS]; // player positions. used for ties @@ -109,6 +109,7 @@ static boolean usetile; boolean usebuffer = false; static boolean useinterpic; static INT32 timer; +static INT32 powertype = 0; static INT32 intertic; static INT32 endtic = -1; @@ -192,11 +193,16 @@ static void Y_CompareBattle(INT32 i) static void Y_CompareRank(INT32 i) { - UINT8 increase = ((data.match.increase[i] == UINT8_MAX) ? 0 : data.match.increase[i]); - if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (players[i].score - increase) > data.match.val[data.match.numplayers])) + INT16 increase = ((data.match.increase[i] == INT16_MIN) ? 0 : data.match.increase[i]); + UINT32 score = (powertype != -1 ? clientpowerlevels[i][powertype] : players[i].score); + + if (!(data.match.val[data.match.numplayers] == UINT32_MAX)) return; - data.match.val[data.match.numplayers] = (players[i].score - increase); + if (powertype == -1 && (players[i].score - increase) > data.match.val[data.match.numplayers]) + return; + + data.match.val[data.match.numplayers] = (score - increase); data.match.num[data.match.numplayers] = i; } @@ -204,7 +210,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) { INT32 i, j; boolean completed[MAXPLAYERS]; - INT32 numplayersingame = 0; + INT32 numplayersingame = 0, numgriefers = 0; // Initialize variables if (rankingsmode > 1) @@ -256,14 +262,17 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) { data.match.val[i] = UINT32_MAX; + if (nospectategrief[i] != -1) + numgriefers++; + if (!playeringame[i] || players[i].spectator) { - data.match.increase[i] = UINT8_MAX; + data.match.increase[i] = INT16_MIN; continue; } if (!rankingsmode) - data.match.increase[i] = UINT8_MAX; + data.match.increase[i] = INT16_MIN; numplayersingame++; } @@ -275,8 +284,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) for (j = 0; j < numplayersingame; j++) { - INT32 nump = ((G_RaceGametype() && nospectategrief > 0) ? nospectategrief : numplayersingame); - for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator || completed[i]) @@ -298,14 +305,98 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) else data.match.pos[data.match.numplayers] = data.match.numplayers+1; - if (!rankingsmode && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < nump)) + if ((!rankingsmode && powertype == -1) // Single player rankings (grand prix). Online rank is handled below. + && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < (numplayersingame + numgriefers))) { - data.match.increase[i] = nump - data.match.pos[data.match.numplayers]; + data.match.increase[i] = (numplayersingame + numgriefers) - data.match.pos[data.match.numplayers]; players[i].score += data.match.increase[i]; } data.match.numplayers++; } + + // Compare every single player against each other for power level increases. + // Every player you won against gives you more points, and vice versa. + // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. + // See K_CalculatePowerLevelInc for more info. + // (I'm bad at understanding this code, so I had no idea how to incorporate it with the above loop properly.) + + if (!rankingsmode && powertype != -1) + { + for (i = 0; i < data.match.numplayers; i++) + { + UINT16 yourpower = 5000; + UINT16 theirpower = 5000; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; // Total pt increment + + if (clientpowerlevels[i][powertype] == 0) // splitscreen guests don't record power level changes + continue; + yourpower = clientpowerlevels[i][powertype]; + + for (j = 0; j < data.match.numplayers; j++) + { + if (i == j || data.match.pos[i] == data.match.pos[j]) // Tie -- neither get any points for this match up. + continue; + + theirpower = 5000; + if (clientpowerlevels[j][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[j][powertype]; + + if (data.match.pos[i] > data.match.pos[j]) // This player won! + { + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + } + else if (data.match.pos[i] < data.match.pos[j]) // This player lost... + { + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + } + } + + if (numgriefers != 0) // Automatic win against quitters. + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (nospectategrief[j] == -1) // Empty slot + continue; + + if (i == j) // Yourself?? + continue; + + theirpower = 5000; + if (nospectategrief[j] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = nospectategrief[j]; + + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + } + } + + if (inc == 0) + { + data.match.increase[i] = INT16_MIN; + continue; + } + + if (yourpower + inc > 9999) + inc -= ((yourpower + inc) - 9999); + if (yourpower + inc < 1) + inc -= ((yourpower + inc) - 1); + + data.match.increase[i] = inc; + clientpowerlevels[i][powertype] += data.match.increase[i]; + + if (i == consoleplayer) + { + vspowerlevel[powertype] = clientpowerlevels[i][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); + } + } + } } // @@ -421,7 +512,7 @@ void Y_IntermissionDrawer(void) const char *timeheader; if (data.match.rankingsmode) - timeheader = "RANK"; + timeheader = "PWR.LV"; else timeheader = (intertype == int_race ? "TIME" : "SCORE"); @@ -487,18 +578,23 @@ void Y_IntermissionDrawer(void) if (data.match.rankingsmode) { - if (data.match.increase[data.match.num[i]] != UINT8_MAX) + if (!clientpowerlevels[i][powertype]) // No power level (splitscreen guests) + STRBUFCPY(strtime, "----"); + else { - if (data.match.increase[data.match.num[i]] > 9) - snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[data.match.num[i]]); - else - snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]); + if (data.match.increase[data.match.num[i]] != INT16_MIN) + { + if (data.match.increase[data.match.num[i]] > 9) + snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[data.match.num[i]]); + else + snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]); - V_DrawRightAlignedString(x+120+gutter, y, 0, strtime); + V_DrawRightAlignedString(x+118+gutter, y, 0, strtime); + } + + snprintf(strtime, sizeof strtime, "%d", data.match.val[i]); } - snprintf(strtime, sizeof strtime, "%d", data.match.val[i]); - V_DrawRightAlignedString(x+152+gutter, y, 0, strtime); } else @@ -617,7 +713,7 @@ void Y_Ticker(void) { if (data.match.num[q] == MAXPLAYERS || !data.match.increase[data.match.num[q]] - || data.match.increase[data.match.num[q]] == UINT8_MAX) + || data.match.increase[data.match.num[q]] == INT16_MIN) continue; r++; @@ -737,6 +833,17 @@ void Y_StartIntermission(void) I_Error("endtic is dirty"); #endif + // set player Power Level type + powertype = -1; + + if (netgame) + { + if (G_RaceGametype()) + powertype = 0; + else if (G_BattleGametype()) + powertype = 1; + } + if (!multiplayer) { timer = 0; From a5f23091cc2ebc6984d5e769a9b95245c404913d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 16 Jan 2019 16:13:34 -0500 Subject: [PATCH 03/39] Fix buffer overwrite & increment --- src/d_clisrv.c | 5 +++-- src/y_inter.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9c79d8ef6..24ec5137e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3389,8 +3389,6 @@ static boolean SV_AddWaitingPlayers(void) { INT32 node, n, newplayer = false; UINT8 newplayernum = 0; - static UINT8 buf[3]; - static UINT8 *buf_p = buf; // What is the reason for this? Why can't newplayernum always be 0? // Sal: Because the dedicated player is stupidly forced into players[0]..... @@ -3402,6 +3400,9 @@ static boolean SV_AddWaitingPlayers(void) // splitscreen can allow 2+ players in one node for (; nodewaiting[node] > 0; nodewaiting[node]--) { + UINT8 buf[3]; + UINT8 *buf_p = buf; + newplayer = true; // search for a free playernum diff --git a/src/y_inter.c b/src/y_inter.c index 8000fd2b1..3cca4f7fc 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -718,8 +718,16 @@ void Y_Ticker(void) r++; data.match.jitter[data.match.num[q]] = 1; - if (--data.match.increase[data.match.num[q]]) - kaching = false; + if (data.match.increase[data.match.num[q]] > 0) + { + if (--data.match.increase[data.match.num[q]]) + kaching = false; + } + else if (data.match.increase[data.match.num[q]] < 0) + { + if (++data.match.increase[data.match.num[q]]) + kaching = false; + } } if (r) From 88af2ff3bc67ed9a82f01330de2cb0c252d9ed8e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 17 Jan 2019 01:28:11 -0500 Subject: [PATCH 04/39] Use val instead of pos? Let's see if this fixes it... --- src/g_game.c | 2 +- src/y_inter.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 0c9f7c911..b63af6c51 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -64,7 +64,7 @@ JoyType_t Joystick4; #define SAVEGAMESIZE (1024) // SRB2kart -char gamedatafilename[64] = "kartdata.dat"; +char gamedatafilename[64] = "vr.dat"; char timeattackfolder[64] = "kart"; char customversionstring[32] = "\0"; diff --git a/src/y_inter.c b/src/y_inter.c index 53be9893c..b617db274 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -336,22 +336,35 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) for (j = 0; j < numplayersingame; j++) { + boolean won = false; + if (i == j) // Same person continue; - if (data.match.pos[i] == data.match.pos[j]) // Tie -- neither get any points for this match up. + if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. continue; theirpower = 5000; if (clientpowerlevels[j][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) theirpower = clientpowerlevels[j][powertype]; - if (data.match.pos[i] < data.match.pos[j]) // This player won! + if (G_RaceGametype()) + { + if (data.match.val[i] < data.match.val[j]) + won = true; + } + else + { + if (data.match.val[i] > data.match.val[j]) + won = true; + } + + if (won) // This player won! { diff = theirpower - yourpower; inc += K_CalculatePowerLevelInc(diff); } - else if (data.match.pos[i] > data.match.pos[j]) // This player lost... + else // This player lost... { diff = yourpower - theirpower; inc -= K_CalculatePowerLevelInc(diff); From a55fb0729d3f869a909f13da4e0406f04704b6aa Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 17 Jan 2019 22:39:26 -0500 Subject: [PATCH 05/39] Improvements to power level updating & forfeit handling --- src/k_kart.c | 14 +++- src/y_inter.c | 198 +++++++++++++++++++++++++++++++------------------- 2 files changed, 135 insertions(+), 77 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index f1542e958..7ea2fd0b0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5783,8 +5783,9 @@ INT16 K_CalculatePowerLevelInc(INT16 diff) return (INT16)(increment >> FRACBITS); } -void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) +void K_PlayerForfeit(UINT8 playernum, boolean pointloss) { + UINT8 p = 0; INT32 powertype = -1; UINT16 yourpower = 5000; UINT16 theirpower = 5000; @@ -5800,6 +5801,15 @@ void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) return; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + p++; + } + + if (p < 2) // no players + return; + if (G_RaceGametype()) powertype = 0; else if (G_BattleGametype()) @@ -5815,7 +5825,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) // Set up the point compensation. nospectategrief[playernum] = yourpower; - if (nopointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! + if (!pointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! return; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/y_inter.c b/src/y_inter.c index b617db274..0bbb04b14 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -196,10 +196,7 @@ static void Y_CompareRank(INT32 i) INT16 increase = ((data.match.increase[i] == INT16_MIN) ? 0 : data.match.increase[i]); UINT32 score = (powertype != -1 ? clientpowerlevels[i][powertype] : players[i].score); - if (!(data.match.val[data.match.numplayers] == UINT32_MAX)) - return; - - if (powertype == -1 && (players[i].score - increase) > data.match.val[data.match.numplayers]) + if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (score - increase) > data.match.val[data.match.numplayers])) return; data.match.val[data.match.numplayers] = (score - increase); @@ -314,103 +311,151 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) data.match.numplayers++; } +} + +static void Y_UpdatePowerLevels(void) +{ + INT32 i, j; + INT32 numplayersingame = 0, numgriefers = 0; + INT16 increment[MAXPLAYERS]; // Compare every single player against each other for power level increases. // Every player you won against gives you more points, and vice versa. // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. // See K_CalculatePowerLevelInc for more info. - // (I'm bad at understanding this code, so I had no idea how to incorporate it with the above loop properly.) - if (!rankingsmode && powertype != -1) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < numplayersingame; i++) + increment[i] = 0; + + if (nospectategrief[i] != -1) + numgriefers++; + + if (!playeringame[i] || players[i].spectator) + continue; + + numplayersingame++; + } + + for (i = 0; i < numplayersingame; i++) + { + UINT16 yourpower = 5000; + UINT16 theirpower = 5000; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; // Total pt increment + UINT8 ipnum = data.match.num[i]; + UINT8 jpnum; + + CONS_Printf("Power Level Gain for player %d:\n", ipnum); + + if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes + continue; + yourpower = clientpowerlevels[ipnum][powertype]; + + CONS_Printf("Player %d's PWR.LV: %d\n", ipnum, yourpower); + + for (j = 0; j < numplayersingame; j++) { - UINT16 yourpower = 5000; - UINT16 theirpower = 5000; - INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV - INT16 inc = 0; // Total pt increment + boolean won = false; - if (clientpowerlevels[i][powertype] == 0) // splitscreen guests don't record power level changes + jpnum = data.match.num[j]; + + if (i == j || ipnum == jpnum) // Same person continue; - yourpower = clientpowerlevels[i][powertype]; - for (j = 0; j < numplayersingame; j++) + CONS_Printf("Player %d VS Player %d:\n", ipnum, jpnum); + + if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. { - boolean won = false; + CONS_Printf("TIE, no change.\n"); + continue; + } - if (i == j) // Same person + theirpower = 5000; + if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[jpnum][powertype]; + CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); + + if (G_RaceGametype()) + { + if (data.match.val[i] < data.match.val[j]) + won = true; + } + else + { + if (data.match.val[i] > data.match.val[j]) + won = true; + } + + if (won) // This player won! + { + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Printf("WON! Diff is %d, total increment is %d\n", diff, inc); + } + else // This player lost... + { + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + CONS_Printf("LOST... Diff is %d, total increment is %d\n", diff, inc); + } + } + + if (numgriefers != 0) // Automatic win against quitters. + { + for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++) + { + if (nospectategrief[jpnum] == -1) // Empty slot continue; - if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. + if (ipnum == jpnum) // Same person continue; + CONS_Printf("Player %d VS Player %d (griefer):\n", ipnum, jpnum); + theirpower = 5000; - if (clientpowerlevels[j][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = clientpowerlevels[j][powertype]; + if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = nospectategrief[jpnum]; + CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); - if (G_RaceGametype()) - { - if (data.match.val[i] < data.match.val[j]) - won = true; - } - else - { - if (data.match.val[i] > data.match.val[j]) - won = true; - } - - if (won) // This player won! - { - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - } - else // This player lost... - { - diff = yourpower - theirpower; - inc -= K_CalculatePowerLevelInc(diff); - } + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Printf("AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); } + } - if (numgriefers != 0) // Automatic win against quitters. - { - for (j = 0; j < MAXPLAYERS; j++) - { - if (nospectategrief[j] == -1) // Empty slot - continue; + if (inc == 0) + { + data.match.increase[ipnum] = INT16_MIN; + CONS_Printf("Total Result: No increment, no change.\n"); + continue; + } - if (i == j) // Yourself?? - continue; + if (yourpower + inc > 9999) + inc -= ((yourpower + inc) - 9999); + if (yourpower + inc < 1) + inc -= ((yourpower + inc) - 1); - theirpower = 5000; - if (nospectategrief[j] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = nospectategrief[j]; + CONS_Printf("Total Result: Increment of %d.\n", inc); + increment[ipnum] = inc; + } - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - } - } + CONS_Printf("Setting final power levels...\n", inc); + for (i = 0; i < MAXPLAYERS; i++) + { + if (increment[i] == 0) + continue; - if (inc == 0) - { - data.match.increase[i] = INT16_MIN; - continue; - } + data.match.increase[i] = increment[i]; + clientpowerlevels[i][powertype] += data.match.increase[i]; - if (yourpower + inc > 9999) - inc -= ((yourpower + inc) - 9999); - if (yourpower + inc < 1) - inc -= ((yourpower + inc) - 1); - - data.match.increase[i] = inc; - clientpowerlevels[i][powertype] += data.match.increase[i]; - - if (i == consoleplayer) - { - vspowerlevel[powertype] = clientpowerlevels[i][powertype]; - if (M_UpdateUnlockablesAndExtraEmblems(true)) - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); - } + if (i == consoleplayer) + { + CONS_Printf("Player %d is you! Saving...\n", i); + vspowerlevel[powertype] = clientpowerlevels[i][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); } } } @@ -939,6 +984,9 @@ void Y_StartIntermission(void) break; } + if (powertype != -1) + Y_UpdatePowerLevels(); + //if (intertype == int_race || intertype == int_match) { //bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); From 0c3e36ddf009dde6687d6b1d5911365b31c74e3f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 18 Jan 2019 00:49:40 -0500 Subject: [PATCH 06/39] bad print --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 0bbb04b14..a8ada4b2e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -440,7 +440,7 @@ static void Y_UpdatePowerLevels(void) increment[ipnum] = inc; } - CONS_Printf("Setting final power levels...\n", inc); + CONS_Printf("Setting final power levels...\n"); for (i = 0; i < MAXPLAYERS; i++) { if (increment[i] == 0) From 3545b80459883f83502116b0cfc12735168b5e4e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 21 Jan 2019 09:43:39 -0500 Subject: [PATCH 07/39] - Power level condition type (for emblems later) - Spectator forfeit doesn't kick in if you just joined the server --- src/d_netcmd.c | 1 + src/dehacked.c | 15 ++++++++++++++- src/k_kart.c | 8 ++++++-- src/m_cond.c | 2 ++ src/m_cond.h | 45 +++++++++++++++++++++++---------------------- src/m_menu.c | 2 ++ 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ce9bcbf3a..6e75d3eb1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3413,6 +3413,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (K_IsPlayerWanted(&players[playernum])) K_CalculateBattleWanted(); } + K_PlayerForfeit(playernum, true); players[playernum].health = 1; diff --git a/src/dehacked.c b/src/dehacked.c index 49b274d3f..b18abc34d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2530,6 +2530,19 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) ty = UC_PLAYTIME + offset; re = atoi(params[1]); } + else if ((offset=0) || fastcmp(params[0], "POWERLEVEL")) + { + PARAMCHECK(2); + ty = UC_POWERLEVEL; + re = atoi(params[1]); + x1 = atoi(params[2]); + + if (x1 < 0 || x1 > 1) + { + deh_warning("Power level type %d out of range (0 - 1)", x1); + return; + } + } else if ((offset=0) || fastcmp(params[0], "GAMECLEAR") || (++offset && fastcmp(params[0], "ALLEMERALDS"))) //|| (++offset && fastcmp(params[0], "ULTIMATECLEAR"))) @@ -2582,7 +2595,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) if (x1 < 0 || x1 >= NUMMAPS) { - deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS); + deh_warning("Level number %d out of range (1 - %d)", x1, NUMMAPS); return; } } diff --git a/src/k_kart.c b/src/k_kart.c index 7ea2fd0b0..d13cd047e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5793,10 +5793,14 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) INT16 inc = 0; UINT8 i; - // power level is netgames only + // power level & spectating is netgames only if (!netgame) return; + // Hey, I just got here! + if (players[playernum].jointime <= 1) + return; + // 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match. if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) return; @@ -5815,7 +5819,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) else if (G_BattleGametype()) powertype = 1; - if (powertype == -1) // Not using power levels + if (powertype == -1) // Not using power levels? return; if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes diff --git a/src/m_cond.c b/src/m_cond.c index 35eccd1c4..3158074fc 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -289,6 +289,8 @@ UINT8 M_CheckCondition(condition_t *cn) return (totalplaytime >= (unsigned)cn->requirement); case UC_MATCHESPLAYED: // Requires any level completed >= x times return (matchesplayed >= (unsigned)cn->requirement); + case UC_POWERLEVEL: // Requires power level >= x on a certain gametype + return (vspowerlevel[cn->extrainfo1] >= (unsigned)cn->requirement); case UC_GAMECLEAR: // Requires game beaten >= x times return (timesBeaten >= (unsigned)cn->requirement); case UC_ALLEMERALDS: // Requires game beaten with all 7 emeralds >= x times diff --git a/src/m_cond.h b/src/m_cond.h index 07e4480d1..4d3fe7248 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -22,28 +22,29 @@ typedef enum { UC_PLAYTIME, // PLAYTIME [tics] UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played] - UC_GAMECLEAR, // GAMECLEAR - UC_ALLEMERALDS, // ALLEMERALDS - //UC_ULTIMATECLEAR, // ULTIMATECLEAR - //UC_OVERALLSCORE, // OVERALLSCORE [score to beat] - UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] - //UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] - UC_MAPVISITED, // MAPVISITED [map number] - UC_MAPBEATEN, // MAPBEATEN [map number] - UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] - //UC_MAPULTIMATE, // MAPULTIMATE [map number] - //UC_MAPPERFECT, // MAPPERFECT [map number] - //UC_MAPSCORE, // MAPSCORE [map number] [score to beat] - UC_MAPTIME, // MAPTIME [map number] [time to beat, tics] - //UC_MAPRINGS, // MAPRINGS [map number] [rings to beat] - //UC_NIGHTSSCORE, // NIGHTSSCORE [map number] [score to beat] - //UC_NIGHTSTIME, // NIGHTSTIME [map number] [time to beat, tics] - //UC_NIGHTSGRADE, // NIGHTSGRADE [map number] [grade] - UC_TRIGGER, // TRIGGER [trigger number] - UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems] - UC_EMBLEM, // EMBLEM [emblem number] - UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number] - UC_CONDITIONSET, // CONDITIONSET [condition set number] + UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle] + UC_GAMECLEAR, // GAMECLEAR + UC_ALLEMERALDS, // ALLEMERALDS + //UC_ULTIMATECLEAR, // ULTIMATECLEAR + //UC_OVERALLSCORE, // OVERALLSCORE [score to beat] + UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] + UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] + UC_MAPVISITED, // MAPVISITED [map number] + UC_MAPBEATEN, // MAPBEATEN [map number] + UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] + //UC_MAPULTIMATE, // MAPULTIMATE [map number] + //UC_MAPPERFECT, // MAPPERFECT [map number] + //UC_MAPSCORE, // MAPSCORE [map number] [score to beat] + UC_MAPTIME, // MAPTIME [map number] [time to beat, tics] + //UC_MAPRINGS, // MAPRINGS [map number] [rings to beat] + //UC_NIGHTSSCORE, // NIGHTSSCORE [map number] [score to beat] + //UC_NIGHTSTIME, // NIGHTSTIME [map number] [time to beat, tics] + //UC_NIGHTSGRADE, // NIGHTSGRADE [map number] [grade] + UC_TRIGGER, // TRIGGER [trigger number] + UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems] + UC_EMBLEM, // EMBLEM [emblem number] + UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number] + UC_CONDITIONSET, // CONDITIONSET [condition set number] } conditiontype_t; // Condition Set information diff --git a/src/m_menu.c b/src/m_menu.c index 900ff4f56..d28f44d20 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5170,6 +5170,8 @@ static char *M_GetConditionString(condition_t cond) G_TicsToSeconds(cond.requirement)); case UC_MATCHESPLAYED: return va("Play %d matches", cond.requirement); + case UC_POWERLEVEL: + return va("Reach power level %d in %s", cond.requirement, (cond.extrainfo1 == 1 ? "Battle" : "Race")); case UC_GAMECLEAR: if (cond.requirement > 1) return va("Beat game %d times", cond.requirement); From e1d5233dbac2689e3e438966218ad9beeb339767 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 19 Apr 2019 20:50:50 -0400 Subject: [PATCH 08/39] Update spawn positions in Race to use power levels --- src/g_game.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 57bc1829e..cd388b8bd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2839,11 +2839,16 @@ mapthing_t *G_FindRaceStart(INT32 playernum) { UINT8 i; UINT8 pos = 0; + boolean usepowerlvl = false; // SRB2Kart: figure out player spawn pos from points if (!playeringame[playernum] || players[playernum].spectator) return playerstarts[0]; // go to first spot if you're a spectator + // Setup power level type + if (netgame) + usepowerlvl = true; + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -2864,8 +2869,17 @@ mapthing_t *G_FindRaceStart(INT32 playernum) continue; if (j == i) continue; - if (players[j].score == players[i].score) - num++; + + if (usepowerlvl) + { + if (clientpowerlevels[j][0] == clientpowerlevels[i][0]) + num++; + } + else + { + if (players[j].score == players[i].score) + num++; + } } if (num > 1) // found dupes @@ -2873,8 +2887,21 @@ mapthing_t *G_FindRaceStart(INT32 playernum) } else { - if (players[i].score > players[playernum].score || i < playernum) + if (i < playernum) pos++; + else + { + if (usepowerlvl) + { + if (clientpowerlevels[i][0] > clientpowerlevels[playernum][0]) + pos++; + } + else + { + if (players[i].score > players[playernum].score) + pos++; + } + } } } From b669069098628b79aebc608e773a009f2710985b Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 19 Apr 2019 20:58:34 -0400 Subject: [PATCH 09/39] This doesn't exist --- src/m_cond.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_cond.h b/src/m_cond.h index 4d3fe7248..c6362ec5d 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -28,7 +28,7 @@ typedef enum //UC_ULTIMATECLEAR, // ULTIMATECLEAR //UC_OVERALLSCORE, // OVERALLSCORE [score to beat] UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] - UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] + //UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] UC_MAPVISITED, // MAPVISITED [map number] UC_MAPBEATEN, // MAPBEATEN [map number] UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] From 8f3efa75987ec7bd46b21e190c27869850343531 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 23 Apr 2019 00:56:28 -0400 Subject: [PATCH 10/39] Remove 10 points at a time for power levels --- src/y_inter.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index a0f6ad16c..bd78e7f4e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -786,15 +786,40 @@ void Y_Ticker(void) r++; data.match.jitter[data.match.num[q]] = 1; - if (data.match.increase[data.match.num[q]] > 0) + + if (powertype != -1) { - if (--data.match.increase[data.match.num[q]]) - kaching = false; + // Power Levels + if (abs(data.match.increase[data.match.num[q]]) < 10) + { + // Not a lot of point increase left, just set to 0 instantly + data.match.increase[data.match.num[q]] = 0; + } + else + { + SINT8 remove = 0; // default (should not happen) + + if (data.match.increase[data.match.num[q]] < 0) + remove = -10; + else if (data.match.increase[data.match.num[q]] > 0) + remove = 10; + + // Remove 10 points at a time + data.match.increase[data.match.num[q]] -= remove; + + // Still not zero, no kaching yet + if (data.match.increase[data.match.num[q]] != 0) + kaching = false; + } } - else if (data.match.increase[data.match.num[q]] < 0) + else { - if (++data.match.increase[data.match.num[q]]) - kaching = false; + // Basic bitch points + if (data.match.increase[data.match.num[q]]) + { + if (--data.match.increase[data.match.num[q]]) + kaching = false; + } } } From da7437947a9966df3bb6c670a7a5c701349462ca Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 23 Apr 2019 00:56:50 -0400 Subject: [PATCH 11/39] Display ---- on the right player --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index bd78e7f4e..ff99b7ff4 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -635,7 +635,7 @@ void Y_IntermissionDrawer(void) if (data.match.rankingsmode) { - if (!clientpowerlevels[i][powertype]) // No power level (splitscreen guests) + if (!clientpowerlevels[data.match.num[i]][powertype]) // No power level (splitscreen guests) STRBUFCPY(strtime, "----"); else { From 6f6bc3333fa502a31faf2a4e28f690d891debb2a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 23 Apr 2019 01:10:16 -0400 Subject: [PATCH 12/39] Put behind cvar --- src/d_netcmd.c | 1 + src/d_netcmd.h | 2 +- src/g_game.c | 9 ++------- src/k_kart.c | 7 ++++++- src/m_menu.c | 3 +-- src/y_inter.c | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 49dfae28f..46a57b340 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -369,6 +369,7 @@ static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index efd314701..aa5f08b2b 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -120,8 +120,8 @@ extern consvar_t cv_kartencore; extern consvar_t cv_kartvoterulechanges; extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; - extern consvar_t cv_karteliminatelast; +extern consvar_t cv_kartusepwrlv; extern consvar_t cv_votetime; diff --git a/src/g_game.c b/src/g_game.c index cd388b8bd..169933084 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2839,16 +2839,11 @@ mapthing_t *G_FindRaceStart(INT32 playernum) { UINT8 i; UINT8 pos = 0; - boolean usepowerlvl = false; // SRB2Kart: figure out player spawn pos from points if (!playeringame[playernum] || players[playernum].spectator) return playerstarts[0]; // go to first spot if you're a spectator - // Setup power level type - if (netgame) - usepowerlvl = true; - for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -2870,7 +2865,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) if (j == i) continue; - if (usepowerlvl) + if (netgame && cv_kartusepwrlv.value) { if (clientpowerlevels[j][0] == clientpowerlevels[i][0]) num++; @@ -2891,7 +2886,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) pos++; else { - if (usepowerlvl) + if (netgame && cv_kartusepwrlv.value) { if (clientpowerlevels[i][0] > clientpowerlevels[playernum][0]) pos++; diff --git a/src/k_kart.c b/src/k_kart.c index 2ec21d0f1..d07afda66 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -544,6 +544,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartspeedometer); CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); + CV_RegisterVar(&cv_kartusepwrlv); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); @@ -6122,6 +6123,10 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) if (!netgame) return; + // This server isn't using power levels anyway! + if (!cv_kartusepwrlv.value) + return; + // Hey, I just got here! if (players[playernum].jointime <= 1) return; @@ -6144,7 +6149,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) else if (G_BattleGametype()) powertype = 1; - if (powertype == -1) // Not using power levels? + if (powertype == -1) // No power type?! return; if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes diff --git a/src/m_menu.c b/src/m_menu.c index d3541ebde..1d11a2805 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1445,8 +1445,7 @@ static menuitem_t OP_GameOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 110}, {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 120}, - {IT_STRING | IT_CVAR, NULL, "Force Character", &cv_forceskin, 140}, - {IT_STRING | IT_CVAR, NULL, "Restrict Character Changes", &cv_restrictskinchange, 150}, + {IT_STRING | IT_CVAR, NULL, "Track Power Levels", &cv_kartusepwrlv, 140}, }; static menuitem_t OP_ServerOptionsMenu[] = diff --git a/src/y_inter.c b/src/y_inter.c index ff99b7ff4..42a5b0921 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -937,7 +937,7 @@ void Y_StartIntermission(void) // set player Power Level type powertype = -1; - if (netgame) + if (netgame && cv_kartusepwrlv.value) { if (G_RaceGametype()) powertype = 0; From 5abe25d0a552d05b79489df29e914760758b56b1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 24 Apr 2019 01:47:43 -0400 Subject: [PATCH 13/39] Speed/Encore scrambles based on power level Did not test yet --- src/g_game.c | 39 ++++++++++++++++-------- src/k_kart.c | 33 +++++++++++++++++++++ src/k_kart.h | 1 + src/y_inter.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 140 insertions(+), 15 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 169933084..95b4c4b8d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -273,6 +273,10 @@ INT16 nospectategrief[MAXPLAYERS]; // Which players spec-scummed, and their powe boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items +// Scrambles +SINT8 speedscramble; +SINT8 encorescramble; + // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? @@ -3194,9 +3198,10 @@ boolean G_BattleGametype(void) // INT16 G_SometimesGetDifferentGametype(void) { - boolean encorepossible = (M_SecretUnlocked(SECRET_ENCORE) && G_RaceGametype()); + boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE) || encorescramble == 1) && G_RaceGametype()); - if (!cv_kartvoterulechanges.value) // never + if (!cv_kartvoterulechanges.value // never + && encorescramble != 1) // destroying the code for this one instance return gametype; if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3)) @@ -3204,18 +3209,23 @@ INT16 G_SometimesGetDifferentGametype(void) randmapbuffer[NUMMAPS]--; if (encorepossible) { - switch (cv_kartvoterulechanges.value) + if (encorescramble >= 0) + encorepossible = (boolean)encorescramble; + else { - case 3: // always - randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set - break; - case 2: // frequent - encorepossible = M_RandomChance(FRACUNIT>>1); - break; - case 1: // sometimes - default: - encorepossible = M_RandomChance(FRACUNIT>>2); - break; + switch (cv_kartvoterulechanges.value) + { + case 3: // always + randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set + break; + case 2: // frequent + encorepossible = M_RandomChance(FRACUNIT>>1); + break; + case 1: // sometimes + default: + encorepossible = M_RandomChance(FRACUNIT>>2); + break; + } } if (encorepossible != (boolean)cv_kartencore.value) return (gametype|0x80); @@ -3223,6 +3233,9 @@ INT16 G_SometimesGetDifferentGametype(void) return gametype; } + if (!cv_kartvoterulechanges.value) // never (again) + return gametype; + switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv? { case 3: // always diff --git a/src/k_kart.c b/src/k_kart.c index d07afda66..8ff2db66d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6109,6 +6109,39 @@ INT16 K_CalculatePowerLevelInc(INT16 diff) return (INT16)(increment >> FRACBITS); } +INT16 K_CalculatePowerLevelAvg(void) +{ + fixed_t avg = 0; + UINT8 div = 0; + SINT8 t = -1; + UINT8 i; + + if (!netgame || !cv_kartusepwrlv.value) + return 0; // No average. + + if (G_RaceGametype()) + t = 0; + else if (G_BattleGametype()) + t = 1; + + if (t == -1) + return 0; // Hmm?! + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || clientpowerlevels[i][t] == 0) + continue; + + avg += clientpowerlevels[i][t]; + div++; + } + + avg /= div; + + return (INT16)(avg >> FRACBITS); +} + void K_PlayerForfeit(UINT8 playernum, boolean pointloss) { UINT8 p = 0; diff --git a/src/k_kart.h b/src/k_kart.h index 0844abc5a..396ebdc55 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -66,6 +66,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); INT16 K_CalculatePowerLevelInc(INT16 diff); +INT16 K_CalculatePowerLevelAvg(void); void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); void K_CheckSpectateStatus(void); diff --git a/src/y_inter.c b/src/y_inter.c index 42a5b0921..67c4b797b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -710,8 +710,14 @@ dotimer: } // Make it obvious that scrambling is happening next round. - if (cv_scrambleonchange.value && cv_teamscramble.value && (intertic/TICRATE % 2 == 0)) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!")); + if ((intertic/TICRATE) & 1) + { + /*if (cv_scrambleonchange.value && cv_teamscramble.value) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ + if (speedscramble != -1) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-12, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, + M_GetText("The next race will be %s Speed!", (speedscramble == 2 ? "Hard" : "Normal"))); + } } // @@ -943,6 +949,78 @@ void Y_StartIntermission(void) powertype = 0; else if (G_BattleGametype()) powertype = 1; + + // Race scrambles + if ((intertype == int_race) && (cv_speedscramble.value || cv_encorescramble.value)) + { + boolean hardmode = false; + boolean encore = false; + INT16 avg = 0, min = 0; + UINT8 i, t = 0; + + avg = K_CalculatePowerLevelAvg(); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (min == 0 || clientpowerlevels[i][0] < min) + min = clientpowerlevels[i][0]; + } + + if (min >= 4000) + { + if (avg >= 5000) + t = 3; + else + t = 2; + } + else if (min >= 2500) + { + if (avg >= 3000) + t = 2; + else + t = 1; + } + else if (min >= 500) + { + if (avg >= 2000) + t = 1; + else + t = 0; + } + else + t = 0; + + switch (t) + { + case 3: + hardmode = true; + encore = M_RandomChance(FRACUNIT>>1); + break; + case 2: + hardmode = M_RandomChance((7<>2); + break; + case 1: + hardmode = M_RandomChance((3< Date: Fri, 26 Apr 2019 13:34:30 -0400 Subject: [PATCH 14/39] finished scrambles --- src/d_netcmd.c | 3 + src/d_netcmd.h | 2 + src/doomstat.h | 3 + src/g_game.c | 6 +- src/k_kart.c | 5 ++ src/p_setup.c | 9 ++- src/y_inter.c | 149 ++++++++++++++++++++++++++----------------------- 7 files changed, 103 insertions(+), 74 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 46a57b340..2606311af 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -369,7 +369,10 @@ static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_speedscramble = {"kartscramblespeed", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_encorescramble = {"kartscrambleencore", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index aa5f08b2b..24bc0a31b 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -122,6 +122,8 @@ extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; extern consvar_t cv_karteliminatelast; extern consvar_t cv_kartusepwrlv; +extern consvar_t cv_speedscramble; +extern consvar_t cv_encorescramble; extern consvar_t cv_votetime; diff --git a/src/doomstat.h b/src/doomstat.h index 139660cc9..43cadcda5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -474,6 +474,9 @@ extern INT16 nospectategrief[MAXPLAYERS]; extern boolean thwompsactive; extern SINT8 spbplace; +extern SINT8 speedscramble; +extern SINT8 encorescramble; + extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t curlap, bestlap; diff --git a/src/g_game.c b/src/g_game.c index 95b4c4b8d..39d7f2957 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -274,8 +274,8 @@ boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items // Scrambles -SINT8 speedscramble; -SINT8 encorescramble; +SINT8 speedscramble = -1; +SINT8 encorescramble = -1; // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? @@ -3210,7 +3210,7 @@ INT16 G_SometimesGetDifferentGametype(void) if (encorepossible) { if (encorescramble >= 0) - encorepossible = (boolean)encorescramble; + encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission else { switch (cv_kartvoterulechanges.value) diff --git a/src/k_kart.c b/src/k_kart.c index 8ff2db66d..742c3417a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -545,6 +545,8 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_kartusepwrlv); + CV_RegisterVar(&cv_speedscramble); + CV_RegisterVar(&cv_encorescramble); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); @@ -6137,6 +6139,9 @@ INT16 K_CalculatePowerLevelAvg(void) div++; } + if (!div) + return 0; // No average. + avg /= div; return (INT16)(avg >> FRACBITS); diff --git a/src/p_setup.c b/src/p_setup.c index 9e8cd3c08..5c42b437a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2370,13 +2370,20 @@ static void P_LevelInitStuff(void) if (G_BattleGametype()) gamespeed = 0; else - gamespeed = (UINT8)cv_kartspeed.value; + { + if (cv_speedscramble.value && speedscramble != -1) + gamespeed = (UINT8)speedscramble; + else + gamespeed = (UINT8)cv_kartspeed.value; + } franticitems = (boolean)cv_kartfrantic.value; comeback = (boolean)cv_kartcomeback.value; } for (i = 0; i < 4; i++) battlewanted[i] = -1; + + speedscramble = encorescramble = -1; } // diff --git a/src/y_inter.c b/src/y_inter.c index 67c4b797b..19189e0c3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -705,7 +705,7 @@ dotimer: if (timer) { INT32 tickdown = (timer+1)/TICRATE; - V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, + V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol|V_SNAPTOBOTTOM, va("%s starts in %d", cv_advancemap.string, tickdown)); } @@ -714,9 +714,9 @@ dotimer: { /*if (cv_scrambleonchange.value && cv_teamscramble.value) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ - if (speedscramble != -1) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-12, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, - M_GetText("The next race will be %s Speed!", (speedscramble == 2 ? "Hard" : "Normal"))); + if (speedscramble != -1 && speedscramble != gamespeed) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, + va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue)); } } @@ -949,78 +949,87 @@ void Y_StartIntermission(void) powertype = 0; else if (G_BattleGametype()) powertype = 1; + } - // Race scrambles - if ((intertype == int_race) && (cv_speedscramble.value || cv_encorescramble.value)) + // Race scrambles + if (powertype == 0 && (cv_speedscramble.value || cv_encorescramble.value)) + { + boolean hardmode = false; + boolean encore = false; + INT16 avg = 0, min = 0; + UINT8 i, t = 0; + + avg = K_CalculatePowerLevelAvg(); + + for (i = 0; i < MAXPLAYERS; i++) { - boolean hardmode = false; - boolean encore = false; - INT16 avg = 0, min = 0; - UINT8 i, t = 0; + if (min == 0 || clientpowerlevels[i][0] < min) + min = clientpowerlevels[i][0]; + } - avg = K_CalculatePowerLevelAvg(); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (min == 0 || clientpowerlevels[i][0] < min) - min = clientpowerlevels[i][0]; - } - - if (min >= 4000) - { - if (avg >= 5000) - t = 3; - else - t = 2; - } - else if (min >= 2500) - { - if (avg >= 3000) - t = 2; - else - t = 1; - } - else if (min >= 500) - { - if (avg >= 2000) - t = 1; - else - t = 0; - } + if (min >= 6000) + { + if (avg >= 8000) + t = 4; + else + t = 3; + } + else if (min >= 4000) + { + if (avg >= 5000) + t = 3; + else + t = 2; + } + else if (min >= 2500) + { + if (avg >= 3000) + t = 2; + else + t = 1; + } + else if (min >= 500) + { + if (avg >= 2000) + t = 1; else t = 0; - - switch (t) - { - case 3: - hardmode = true; - encore = M_RandomChance(FRACUNIT>>1); - break; - case 2: - hardmode = M_RandomChance((7<>2); - break; - case 1: - hardmode = M_RandomChance((3<>1); + break; + case 2: + hardmode = M_RandomChance((7<>2); + break; + case 1: + hardmode = M_RandomChance((3< Date: Fri, 26 Apr 2019 13:40:14 -0400 Subject: [PATCH 15/39] no flash --- src/y_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 19189e0c3..8b9d7e2ca 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -709,15 +709,15 @@ dotimer: va("%s starts in %d", cv_advancemap.string, tickdown)); } - // Make it obvious that scrambling is happening next round. - if ((intertic/TICRATE) & 1) - { + // Make it obvious that scrambling is happening next round. (OR NOT I GUESS.) + //if ((intertic/TICRATE) & 1) + //{ /*if (cv_scrambleonchange.value && cv_teamscramble.value) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ if (speedscramble != -1 && speedscramble != gamespeed) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue)); - } + //} } // From ed093e0856199addf8585c934c1ab7c8eed50368 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 26 Apr 2019 14:07:48 -0400 Subject: [PATCH 16/39] Display on server browser --- src/d_clisrv.c | 5 +++++ src/d_clisrv.h | 1 + src/k_kart.c | 2 +- src/m_menu.c | 34 ++++++++++++++++++++-------------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7727ba8a9..2d9606839 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1435,6 +1435,11 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) p = PutFileNeeded(); + if (cv_kartusepwrlv.value) + netbuffer->u.serverinfo.avgpwrlv = K_CalculatePowerLevelAvg(); + else + netbuffer->u.serverinfo.avgpwrlv = -1; + HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 3241b25e7..4ce6581a0 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -399,6 +399,7 @@ typedef struct UINT8 actnum; UINT8 iszone; UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) + INT16 avgpwrlv; // Kart avg power level } ATTRPACK serverinfo_pak; typedef struct diff --git a/src/k_kart.c b/src/k_kart.c index 742c3417a..00692acde 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6132,7 +6132,7 @@ INT16 K_CalculatePowerLevelAvg(void) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator - || clientpowerlevels[i][t] == 0) + || clientpowerlevels[i][t] == 0) // splitscreen player continue; avg += clientpowerlevels[i][t]; diff --git a/src/m_menu.c b/src/m_menu.c index 1d11a2805..723a5f7fd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7288,6 +7288,7 @@ static void M_DrawConnectMenu(void) UINT16 i, j; const char *gt = "Unknown"; const char *spd = ""; + const char *pwr = "----"; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) @@ -7322,36 +7323,41 @@ static void M_DrawConnectMenu(void) V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); - // Don't use color flags intentionally, the global yellow color will auto override the text color code - if (serverlist[slindex].info.modifiedgame) - V_DrawSmallString(currentMenu->x+202, S_LINEY(i)+8, globalflags, "\x85" "Mod"); - if (serverlist[slindex].info.cheatsenabled) - V_DrawSmallString(currentMenu->x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); + if (serverlist[slindex].info.kartvars & SV_PASSWORD) + V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL); V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); + V_DrawSmallString(currentMenu->x+44,S_LINEY(i)+8, globalflags, + va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); + gt = "Unknown"; for (j = 0; gametype_cons_t[j].strvalue; j++) { if (gametype_cons_t[j].value == serverlist[slindex].info.gametype) gt = gametype_cons_t[j].strvalue; } - - V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, - va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); - - V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); + V_DrawSmallString(currentMenu->x+108, S_LINEY(i)+8, globalflags, gt); if (serverlist[slindex].info.gametype == GT_RACE) { spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue; - - V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd)); + V_DrawSmallString(currentMenu->x+128, S_LINEY(i)+8, globalflags, va("(%s)", spd)); } - if (serverlist[slindex].info.kartvars & SV_PASSWORD) - V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL); + pwr = "----"; + if (serverlist[slindex].info.avgpwrlv == -1) + pwr = "Off"; + else if (serverlist[slindex].info.avgpwrlv > 0) + pwr = va("%04d", serverlist[slindex].info.avgpwrlv); + V_DrawSmallString(currentMenu->x+171, S_LINEY(i)+8, globalflags, va("Power Level: %s", pwr)); + + // Don't use color flags intentionally, the global yellow color will auto override the text color code + if (serverlist[slindex].info.modifiedgame) + V_DrawSmallString(currentMenu->x+245, S_LINEY(i)+8, globalflags, "\x85" "Mod"); + if (serverlist[slindex].info.cheatsenabled) + V_DrawSmallString(currentMenu->x+265, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; } From 932f8a1f618ee5c386714da9b13588db85e7f520 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 07:03:00 -0400 Subject: [PATCH 17/39] Update demos to save power levels --- src/doomdef.h | 3 - src/g_game.c | 346 ++++++-------------------------------------------- src/p_tick.c | 45 ++----- 3 files changed, 51 insertions(+), 343 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 4d3934773..ba3810858 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -158,9 +158,6 @@ extern FILE *logstream; // AND appveyor.yml, for the build bots! #endif -// Maintain compatibility with 1.0.x record attack replays? -#define DEMO_COMPAT_100 - // Does this version require an added patch file? // Comment or uncomment this as necessary. //#define USE_PATCH_FILE diff --git a/src/g_game.c b/src/g_game.c index 12b3a23b3..3c5cb33f6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4776,7 +4776,7 @@ char *G_BuildMapTitle(INT32 mapnum) // DEMO RECORDING // -#define DEMOVERSION 0x0002 +#define DEMOVERSION 0x0003 #define DEMOHEADER "\xF0" "KartReplay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -4787,12 +4787,6 @@ char *G_BuildMapTitle(INT32 mapnum) #define DF_ENCORE 0x40 #define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode! -#ifdef DEMO_COMPAT_100 -#define DF_FILELIST 0x08 // This demo contains an extra files list -#define DF_GAMETYPEMASK 0x30 -#define DF_GAMESHIFT 4 -#endif - #define DEMO_SPECTATOR 0x40 // For demos @@ -5651,16 +5645,9 @@ void G_ConsGhostTic(INT32 playernum) else ghostext[playernum].desyncframes = 0; - if ( -#ifdef DEMO_COMPAT_100 - demo.version != 0x0001 && -#endif - ( - players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem || - players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount || - players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers - ) - ) + if (players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem + || players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount + || players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers) { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); @@ -5688,10 +5675,6 @@ void G_GhostTicker(void) // Skip normal demo data. UINT8 ziptic = READUINT8(g->p); -#ifdef DEMO_COMPAT_100 - if (g->version != 0x0001) - { -#endif while (ziptic != DW_END) // Get rid of extradata stuff { if (ziptic == 0) // Only support player 0 info for now @@ -5715,9 +5698,6 @@ void G_GhostTicker(void) } ziptic = READUINT8(g->p); // Back to actual ziptic stuff -#ifdef DEMO_COMPAT_100 - } -#endif if (ziptic & ZT_FWD) g->p++; @@ -5737,18 +5717,12 @@ void G_GhostTicker(void) // Grab ghost data. ziptic = READUINT8(g->p); -#ifdef DEMO_COMPAT_100 - if (g->version != 0x0001) - { -#endif if (ziptic == 0xFF) goto skippedghosttic; // Didn't write ghost info this frame else if (ziptic != 0) I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); -#ifdef DEMO_COMPAT_100 - } -#endif + if (ziptic & GZT_XYZ) { g->oldmo.x = READFIXED(g->p); @@ -5889,15 +5863,8 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } -#ifdef DEMO_COMPAT_100 - if (g->version != 0x0001) - { -#endif if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this -#ifdef DEMO_COMPAT_100 - } -#endif skippedghosttic: // Tick ghost colors (Super and Mario Invincibility flashing) @@ -6407,20 +6374,15 @@ void G_BeginRecording(void) switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,UINT32_MAX); // lap - break; - /*case ATTACKING_NIGHTS: // 2 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - break;*/ - default: // 3 - break; + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,UINT32_MAX); // lap + break; + default: // 3 + break; } WRITEUINT32(demo_p,P_GetInitSeed()); @@ -6460,6 +6422,9 @@ void G_BeginRecording(void) // Score, since Kart uses this to determine where you start on the map WRITEUINT32(demo_p, player->score); + // Power Levels + WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? 1 : 0]); + // Kart speed and weight WRITEUINT8(demo_p, skins[player->skin].kartspeed); WRITEUINT8(demo_p, skins[player->skin].kartweight); @@ -6558,18 +6523,13 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap) { if (!demo.recording || !demotime_p) return; + if (demoflags & DF_RECORDATTACK) { WRITEUINT32(demotime_p, ptime); WRITEUINT32(demotime_p, plap); demotime_p = NULL; } - /*else if (demoflags & DF_NIGHTSATTACK) - { - WRITEUINT32(demotime_p, ptime); - WRITEUINT32(demotime_p, pscore); - demotime_p = NULL; - }*/ } static void G_LoadDemoExtraFiles(UINT8 **pp) @@ -6812,13 +6772,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) case DEMOVERSION: // latest always supported p += 64; // full demo title break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - // Old replays gotta go :] - CONS_Alert(CONS_NOTICE, M_GetText("File '%s' outdated version. It will be overwritten. Nyeheheh.\n"), oldname); - Z_Free(buffer); - return UINT8_MAX; -#endif // too old, cannot support. default: CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); @@ -6910,12 +6863,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo) info_p += 64; break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - pdemo->type = MD_OUTDATED; - sprintf(pdemo->title, "Legacy Replay"); - break; -#endif // too old, cannot support. default: CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath); @@ -6950,16 +6897,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo) Z_Free(infobuffer); return; } -#ifdef DEMO_COMPAT_100 - else if (pdemoversion == 0x0001) - { - CONS_Alert(CONS_ERROR, M_GetText("%s is a legacy multiplayer replay and cannot be played.\n"), pdemo->filepath); - pdemo->type = MD_INVALID; - sprintf(pdemo->title, "INVALID REPLAY"); - Z_Free(infobuffer); - return; - } -#endif pdemo->gametype = READUINT8(info_p); @@ -7160,10 +7097,6 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 64; break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - break; -#endif // too old, cannot support. default: snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); @@ -7192,24 +7125,6 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 16; // mapmd5 demoflags = READUINT8(demo_p); -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - { - if (demoflags & DF_MULTIPLAYER) - { - snprintf(msg, 1024, M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - } - else - { -#endif gametype = READUINT8(demo_p); if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running. @@ -7267,9 +7182,6 @@ void G_DoPlayDemo(char *defdemoname) return; } } -#ifdef DEMO_COMPAT_100 - } -#endif modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT; multiplayer = !!(demoflags & DF_MULTIPLAYER); @@ -7297,110 +7209,8 @@ void G_DoPlayDemo(char *defdemoname) // Random seed randseed = READUINT32(demo_p); -#ifdef DEMO_COMPAT_100 - if (demo.version != 0x0001) -#endif demo_p += 4; // Extrainfo location -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - { - // Player name - M_Memcpy(player_names[0],demo_p,16); - demo_p += 16; - - // Skin - M_Memcpy(skin,demo_p,16); - demo_p += 16; - - // Color - M_Memcpy(color,demo_p,16); - demo_p += 16; - - demo_p += 5; // Backwards compat - some stats - // SRB2kart - kartspeed[0] = READUINT8(demo_p); - kartweight[0] = READUINT8(demo_p); - // - demo_p += 9; // Backwards compat - more stats - - // Skin not loaded? - if (!SetPlayerSkin(0, skin)) - { - snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - - // ...*map* not loaded? - if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK)) - { - snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - - // Set color - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(KartColor_Names[i],color)) // SRB2kart - { - players[0].skincolor = i; - break; - } - - // net var data - CV_LoadNetVars(&demo_p); - - // Sigh ... it's an empty demo. - if (*demo_p == DEMOMARKER) - { - snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - - Z_Free(pdemoname); - - memset(&oldcmd,0,sizeof(oldcmd)); - memset(&oldghost,0,sizeof(oldghost)); - memset(&ghostext,0,sizeof(ghostext)); - - CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n")); - - // console warning messages -#if defined(SKIPERRORS) && !defined(DEVELOP) - demosynced = (!skiperrors); -#else - demosynced = true; -#endif - - // didn't start recording right away. - demo.deferstart = false; - - consoleplayer = 0; - memset(displayplayers, 0, sizeof(displayplayers)); - memset(playeringame, 0, sizeof(playeringame)); - playeringame[0] = true; - - goto post_compat; - } -#endif - // net var data CV_LoadNetVars(&demo_p); @@ -7514,6 +7324,9 @@ void G_DoPlayDemo(char *defdemoname) // Score, since Kart uses this to determine where you start on the map players[p].score = READUINT32(demo_p); + // Power Levels + clientpowerlevels[p][G_BattleGametype() ? 1 : 0] = READUINT16(demo_p); + // Kart stats, temporarily kartspeed[p] = READUINT8(demo_p); kartweight[p] = READUINT8(demo_p); @@ -7538,10 +7351,6 @@ void G_DoPlayDemo(char *defdemoname) R_ExecuteSetViewSize(); -#ifdef DEMO_COMPAT_100 -post_compat: -#endif - P_SetRandSeed(randseed); G_InitNew(demoflags & DF_ENCORE, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer. @@ -7632,10 +7441,6 @@ void G_AddGhost(char *defdemoname) case DEMOVERSION: // latest always supported p += 64; // title break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - break; -#endif // too old, cannot support. default: CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname); @@ -7676,15 +7481,9 @@ void G_AddGhost(char *defdemoname) return; } -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif - p++; // gametype + p++; // gametype + G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif - G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { case ATTACKING_NONE: // 0 @@ -7700,41 +7499,6 @@ void G_AddGhost(char *defdemoname) } p += 4; // random seed - -#ifdef DEMO_COMPAT_100 - if (ghostversion == 0x0001) - { - // Player name (TODO: Display this somehow if it doesn't match cv_playername!) - M_Memcpy(name, p,16); - p += 16; - - // Skin - M_Memcpy(skin, p,16); - p += 16; - - // Color - M_Memcpy(color, p,16); - p += 16; - - // Ghosts do not have a player structure to put this in. - p++; // charability - p++; // charability2 - p++; // actionspd - p++; // mindash - p++; // maxdash - // SRB2kart - p++; // kartspeed - p++; // kartweight - // - p++; // normalspeed - p++; // runspeed - p++; // thrustfactor - p++; // accelstart - p++; // acceleration - p += 4; // jumpfactor - } - else -#endif p += 4; // Extra data location reference // net var data @@ -7754,10 +7518,6 @@ void G_AddGhost(char *defdemoname) return; } -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) - { -#endif if (READUINT8(p) != 0) { CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname); @@ -7779,6 +7539,7 @@ void G_AddGhost(char *defdemoname) p += 16; p += 4; // score + p += 2; // powerlevel kartspeed = READUINT8(p); kartweight = READUINT8(p); @@ -7790,9 +7551,6 @@ void G_AddGhost(char *defdemoname) Z_Free(buffer); return; } -#ifdef DEMO_COMPAT_100 - } -#endif for (i = 0; i < numskins; i++) if (!stricmp(skins[i].name,skin)) @@ -7892,18 +7650,13 @@ void G_UpdateStaffGhostName(lumpnum_t l) ghostversion = READUINT16(p); switch(ghostversion) { - case DEMOVERSION: // latest always supported - p += 64; // full demo title - break; + case DEMOVERSION: // latest always supported + p += 64; // full demo title + break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - break; -#endif - - // too old, cannot support. - default: - goto fail; + // too old, cannot support. + default: + goto fail; } p += 16; // demo checksum @@ -7923,43 +7676,22 @@ void G_UpdateStaffGhostName(lumpnum_t l) goto fail; // we don't NEED to do it here, but whatever } -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif p++; // Gametype -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif G_SkipDemoExtraFiles(&p); switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - p += 8; // demo time, lap - break; - /*case ATTACKING_NIGHTS: // 2 - p += 8; // demo time left, score - break;*/ - default: // 3 - break; + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + p += 8; // demo time, lap + break; + default: // 3 + break; } p += 4; // random seed - - -#ifdef DEMO_COMPAT_100 - if (ghostversion == 0x0001) - { - // Player name - M_Memcpy(dummystaffname, p,16); - dummystaffname[16] = '\0'; - goto fail; // Not really a failure but whatever - } -#endif - p += 4; // Extrainfo location marker // Ehhhh don't need ghostversion here (?) so I'll reuse the var here @@ -8044,10 +7776,6 @@ void G_DoPlayMetal(void) { case DEMOVERSION: // latest always supported break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - I_Error("You need to implement demo compat here, doofus! %s:%d", __FILE__, __LINE__); -#endif // too old, cannot support. default: CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n")); diff --git a/src/p_tick.c b/src/p_tick.c index 2502c7213..8312afe81 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -617,33 +617,21 @@ void P_Ticker(boolean run) } if (demo.playback) { + G_ReadDemoExtraData(); + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i]) + { + //@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now... + // Remove for 1.1! + if (players[i].cmd.buttons & BT_FORWARD) + players[i].kartstuff[k_throwdir] = 1; + else if (players[i].cmd.buttons & BT_BACKWARD) + players[i].kartstuff[k_throwdir] = -1; + else + players[i].kartstuff[k_throwdir] = 0; -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - { - G_ReadDemoTiccmd(&players[consoleplayer].cmd, 0); - } - else - { -#endif - G_ReadDemoExtraData(); - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - { - //@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now... - // Remove for 1.1! - if (players[i].cmd.buttons & BT_FORWARD) - players[i].kartstuff[k_throwdir] = 1; - else if (players[i].cmd.buttons & BT_BACKWARD) - players[i].kartstuff[k_throwdir] = -1; - else - players[i].kartstuff[k_throwdir] = 0; - - G_ReadDemoTiccmd(&players[i].cmd, i); - } -#ifdef DEMO_COMPAT_100 - } -#endif + G_ReadDemoTiccmd(&players[i].cmd, i); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -759,11 +747,6 @@ void P_Ticker(boolean run) } else if (demo.playback) // Use Ghost data for consistency checks. { -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - G_ConsGhostTic(0); - else -#endif G_ConsAllGhostTics(); } From 9e587f4d0d4a09a27ac6c748e2e872f881149eea Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 07:26:36 -0400 Subject: [PATCH 18/39] Put prints behind CONS_Debug --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 3 ++- src/y_inter.c | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9e1f46e5a..a4e5e4968 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3478,7 +3478,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) newplayernum = (UINT8)READUINT8(*p); splitscreenplayer = (UINT8)READUINT8(*p); - CONS_Printf("addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer); + CONS_Debug(DBG_NETPLAY, "addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer); // Clear player before joining, lest some things get set incorrectly CL_ClearPlayer(newplayernum); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 37d91a765..3569bca24 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1938,7 +1938,8 @@ static void Got_PowerLevel(UINT8 **cp,INT32 playernum) clientpowerlevels[playernum][0] = min(9999, race); clientpowerlevels[playernum][1] = min(9999, battle); - CONS_Printf("set player %d to power %d\n", playernum, race); + + CONS_Debug(DBG_GAMELOGIC, "set player %d to power %d\n", playernum, race); } void D_SendPlayerConfig(void) diff --git a/src/y_inter.c b/src/y_inter.c index 5558de011..7dc97559b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -356,13 +356,13 @@ static void Y_UpdatePowerLevels(void) UINT8 ipnum = data.match.num[i]; UINT8 jpnum; - CONS_Printf("Power Level Gain for player %d:\n", ipnum); + CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum); if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes continue; yourpower = clientpowerlevels[ipnum][powertype]; - CONS_Printf("Player %d's PWR.LV: %d\n", ipnum, yourpower); + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower); for (j = 0; j < numplayersingame; j++) { @@ -373,18 +373,18 @@ static void Y_UpdatePowerLevels(void) if (i == j || ipnum == jpnum) // Same person continue; - CONS_Printf("Player %d VS Player %d:\n", ipnum, jpnum); + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum); if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. { - CONS_Printf("TIE, no change.\n"); + CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n"); continue; } theirpower = 5000; if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) theirpower = clientpowerlevels[jpnum][powertype]; - CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); if (G_RaceGametype()) { @@ -401,13 +401,13 @@ static void Y_UpdatePowerLevels(void) { diff = theirpower - yourpower; inc += K_CalculatePowerLevelInc(diff); - CONS_Printf("WON! Diff is %d, total increment is %d\n", diff, inc); + CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc); } else // This player lost... { diff = yourpower - theirpower; inc -= K_CalculatePowerLevelInc(diff); - CONS_Printf("LOST... Diff is %d, total increment is %d\n", diff, inc); + CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc); } } @@ -421,23 +421,23 @@ static void Y_UpdatePowerLevels(void) if (ipnum == jpnum) // Same person continue; - CONS_Printf("Player %d VS Player %d (griefer):\n", ipnum, jpnum); + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum); theirpower = 5000; if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) theirpower = nospectategrief[jpnum]; - CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); diff = theirpower - yourpower; inc += K_CalculatePowerLevelInc(diff); - CONS_Printf("AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); + CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); } } if (inc == 0) { data.match.increase[ipnum] = INT16_MIN; - CONS_Printf("Total Result: No increment, no change.\n"); + CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n"); continue; } @@ -446,11 +446,11 @@ static void Y_UpdatePowerLevels(void) if (yourpower + inc < 1) inc -= ((yourpower + inc) - 1); - CONS_Printf("Total Result: Increment of %d.\n", inc); + CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc); increment[ipnum] = inc; } - CONS_Printf("Setting final power levels...\n"); + CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n"); for (i = 0; i < MAXPLAYERS; i++) { if (increment[i] == 0) @@ -461,7 +461,7 @@ static void Y_UpdatePowerLevels(void) if (i == consoleplayer) { - CONS_Printf("Player %d is you! Saving...\n", i); + CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); vspowerlevel[powertype] = clientpowerlevels[i][powertype]; if (M_UpdateUnlockablesAndExtraEmblems(true)) S_StartSound(NULL, sfx_ncitem); From 38bb44e732e31813a3625b1fe10ebabbaae78637 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 08:26:42 -0400 Subject: [PATCH 19/39] Separate into k_pwrlv.c, add defines to reduce amount of magic numbers --- src/Makefile | 1 + src/d_clisrv.c | 7 +- src/d_netcmd.c | 14 +- src/d_netcmd.h | 1 - src/doomstat.h | 6 - src/g_game.c | 15 +- src/k_kart.c | 169 +--------------------- src/k_kart.h | 3 - src/k_pwrlv.c | 289 +++++++++++++++++++++++++++++++++++++ src/k_pwrlv.h | 31 ++++ src/m_cond.c | 1 + src/m_menu.c | 5 +- src/p_inter.c | 1 + src/p_saveg.c | 3 + src/p_setup.c | 1 + src/y_inter.c | 378 ++++++++++++++++++++----------------------------- 16 files changed, 494 insertions(+), 431 deletions(-) create mode 100644 src/k_pwrlv.c create mode 100644 src/k_pwrlv.h diff --git a/src/Makefile b/src/Makefile index f4a77aedd..9c6bb0be4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -489,6 +489,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/y_inter.o \ $(OBJDIR)/st_stuff.o \ $(OBJDIR)/k_kart.o \ + $(OBJDIR)/k_pwrlv.o \ $(OBJDIR)/m_aatree.o \ $(OBJDIR)/m_anigif.o \ $(OBJDIR)/m_argv.o \ diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a4e5e4968..d0de5f3f8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -47,6 +47,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "k_kart.h" +#include "k_pwrlv.h" #ifdef CLIENT_LOADINGSCREEN // cl loading screen @@ -2317,7 +2318,7 @@ static void CL_ConnectToServer(boolean viams) wipegamestate = GS_WAITINGPLAYERS; ClearAdminPlayers(); - ClearClientPowerLevels(); + K_ClearClientPowerLevels(); pnumnodes = 1; oldtic = I_GetTime() - 1; #ifndef NONET @@ -3351,7 +3352,7 @@ void SV_ResetServer(void) playernode[i] = UINT8_MAX; sprintf(player_names[i], "Player %d", i + 1); adminplayers[i] = -1; // Populate the entire adminplayers array with -1. - ClearClientPowerLevels(); + K_ClearClientPowerLevels(); } mynode = 0; @@ -3427,7 +3428,7 @@ void D_QuitNetGame(void) D_CloseConnection(); ClearAdminPlayers(); - ClearClientPowerLevels(); + K_ClearClientPowerLevels(); DEBFILE("===========================================================================\n" " Log finish\n" diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3569bca24..ffeb049fd 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -47,6 +47,7 @@ #include "m_cond.h" #include "m_anigif.h" #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" #include "y_inter.h" #ifdef NETGAME_DEVMODE @@ -475,7 +476,6 @@ boolean deferencoremode = false; UINT8 splitscreen = 0; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; -UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \warning Keep this up-to-date if you add/remove/rename net text commands const char *netxcmdnames[MAXNETXCMD - 1] = @@ -1936,8 +1936,8 @@ static void Got_PowerLevel(UINT8 **cp,INT32 playernum) UINT16 race = (UINT16)READUINT16(*cp); UINT16 battle = (UINT16)READUINT16(*cp); - clientpowerlevels[playernum][0] = min(9999, race); - clientpowerlevels[playernum][1] = min(9999, battle); + clientpowerlevels[playernum][PWRLV_RACE] = min(PWRLVRECORD_MAX, race); + clientpowerlevels[playernum][PWRLV_BATTLE] = min(PWRLVRECORD_MAX, battle); CONS_Debug(DBG_GAMELOGIC, "set player %d to power %d\n", playernum, race); } @@ -3845,14 +3845,6 @@ static void Got_Login(UINT8 **cp, INT32 playernum) #endif } -void ClearClientPowerLevels(void) -{ - INT32 i, j; - for (i = 0; i < MAXPLAYERS; i++) - for (j = 0; j < 2; j++) - clientpowerlevels[i][j] = 0; -} - boolean IsPlayerAdmin(INT32 playernum) { INT32 i; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 0b88d2bc8..7d81f1164 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -242,7 +242,6 @@ void D_SetupVote(void); void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer); void D_PickVote(void); void ObjectPlace_OnChange(void); -void ClearClientPowerLevels(void); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); void ClearAdminPlayers(void); diff --git a/src/doomstat.h b/src/doomstat.h index af4abecf9..4f410aa53 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -339,7 +339,6 @@ extern const char *Gametype_Names[NUMGAMETYPES]; extern tic_t totalplaytime; extern UINT32 matchesplayed; -extern UINT16 vspowerlevel[2]; extern UINT8 stagefailed; @@ -475,13 +474,9 @@ extern tic_t wantedcalcdelay; extern tic_t indirectitemcooldown; extern tic_t hyubgone; extern tic_t mapreset; -extern INT16 nospectategrief[MAXPLAYERS]; extern boolean thwompsactive; extern SINT8 spbplace; -extern SINT8 speedscramble; -extern SINT8 encorescramble; - extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t curlap, bestlap; @@ -556,7 +551,6 @@ extern consvar_t cv_maxping; extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern INT32 serverplayer; extern INT32 adminplayers[MAXPLAYERS]; -extern UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \note put these in d_clisrv outright? diff --git a/src/g_game.c b/src/g_game.c index b07b764ec..4275e1356 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -48,6 +48,7 @@ #include "m_cond.h" // condition sets #include "md5.h" // demo checksums #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" gameaction_t gameaction; gamestate_t gamestate = GS_NULL; @@ -168,7 +169,6 @@ INT32 sstimer; // Time allotted in the special stage tic_t totalplaytime; UINT32 matchesplayed; // SRB2Kart -UINT16 vspowerlevel[2]; // SRB2Kart: Online rankings for each gametype boolean gamedataloaded = false; // Time attack data for levels @@ -267,14 +267,9 @@ tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled tic_t mapreset; // Map reset delay when enough players have joined an empty game -INT16 nospectategrief[MAXPLAYERS]; // Which players spec-scummed, and their power level before scumming. boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items -// Scrambles -SINT8 speedscramble = -1; -SINT8 encorescramble = -1; - // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? @@ -4085,8 +4080,8 @@ void G_LoadGameData(void) totalplaytime = 0; // total play time (separate from all) matchesplayed = 0; // SRB2Kart: matches played & finished - for (i = 0; i < 2; i++) // SRB2Kart: online rank system - vspowerlevel[i] = 1000; + for (i = 0; i < PWRLV_NUMTYPES; i++) // SRB2Kart: online rank system + vspowerlevel[i] = PWRLVRECORD_START; if (M_CheckParm("-nodata")) return; // Don't load. @@ -6429,7 +6424,7 @@ void G_BeginRecording(void) WRITEUINT32(demo_p, player->score); // Power Levels - WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? 1 : 0]); + WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE]); // Kart speed and weight WRITEUINT8(demo_p, skins[player->skin].kartspeed); @@ -7331,7 +7326,7 @@ void G_DoPlayDemo(char *defdemoname) players[p].score = READUINT32(demo_p); // Power Levels - clientpowerlevels[p][G_BattleGametype() ? 1 : 0] = READUINT16(demo_p); + clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE] = READUINT16(demo_p); // Kart stats, temporarily kartspeed[p] = READUINT8(demo_p); diff --git a/src/k_kart.c b/src/k_kart.c index e1a611d8a..969be4443 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4,6 +4,8 @@ /// \brief SRB2kart general. /// All of the SRB2kart-unique stuff. +#include "k_kart.h" +#include "k_pwrlv.h" #include "doomdef.h" #include "hu_stuff.h" #include "g_game.h" @@ -18,7 +20,6 @@ #include "z_zone.h" #include "m_misc.h" #include "m_cond.h" -#include "k_kart.h" #include "f_finale.h" #include "lua_hud.h" // For Lua hud checks #include "lua_hook.h" // For MobjDamage and ShouldDamage @@ -31,8 +32,6 @@ // battlewanted is an array of the WANTED player nums, -1 for no player in that slot // indirectitemcooldown is timer before anyone's allowed another Shrink/SPB // mapreset is set when enough players fill an empty server -// nospectategrief is the players in-game needed to eliminate the person in last - //{ SRB2kart Color Code @@ -6820,170 +6819,6 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } -// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating -INT16 K_CalculatePowerLevelInc(INT16 diff) -{ - INT16 control[10] = {0,0,0,1,8,50,125,125,125,125}; - fixed_t increment = 0; - fixed_t x; - UINT8 j; - -#define MAXDIFF 9998 - if (diff > MAXDIFF) - diff = MAXDIFF; - if (diff < -MAXDIFF) - diff = -MAXDIFF; -#undef MAXDIFF - - x = ((diff-2)<= (2<= (1<> FRACBITS); -} - -INT16 K_CalculatePowerLevelAvg(void) -{ - fixed_t avg = 0; - UINT8 div = 0; - SINT8 t = -1; - UINT8 i; - - if (!netgame || !cv_kartusepwrlv.value) - return 0; // No average. - - if (G_RaceGametype()) - t = 0; - else if (G_BattleGametype()) - t = 1; - - if (t == -1) - return 0; // Hmm?! - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator - || clientpowerlevels[i][t] == 0) // splitscreen player - continue; - - avg += clientpowerlevels[i][t]; - div++; - } - - if (!div) - return 0; // No average. - - avg /= div; - - return (INT16)(avg >> FRACBITS); -} - -void K_PlayerForfeit(UINT8 playernum, boolean pointloss) -{ - UINT8 p = 0; - INT32 powertype = -1; - UINT16 yourpower = 5000; - UINT16 theirpower = 5000; - INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV - INT16 inc = 0; - UINT8 i; - - // power level & spectating is netgames only - if (!netgame) - return; - - // This server isn't using power levels anyway! - if (!cv_kartusepwrlv.value) - return; - - // Hey, I just got here! - if (players[playernum].jointime <= 1) - return; - - // 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match. - if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) - return; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - p++; - } - - if (p < 2) // no players - return; - - if (G_RaceGametype()) - powertype = 0; - else if (G_BattleGametype()) - powertype = 1; - - if (powertype == -1) // No power type?! - return; - - if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes - return; - yourpower = clientpowerlevels[playernum][powertype]; - - // Set up the point compensation. - nospectategrief[playernum] = yourpower; - - if (!pointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! - return; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (i == playernum) - continue; - - theirpower = 5000; - if (clientpowerlevels[i][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = clientpowerlevels[i][powertype]; - - diff = yourpower - theirpower; - inc -= K_CalculatePowerLevelInc(diff); - } - - if (inc == 0) // No change. - return; - - if (yourpower + inc > 9999) // I mean... we're subtracting... but y'know how it is :V - inc -= ((yourpower + inc) - 9999); - if (yourpower + inc < 1) - inc -= ((yourpower + inc) - 1); - - clientpowerlevels[playernum][powertype] += inc; - - if (playernum == consoleplayer) - { - vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; - if (M_UpdateUnlockablesAndExtraEmblems(true)) - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); // save your punishment! - } -} - - void K_CheckSpectateStatus(void) { UINT8 respawnlist[MAXPLAYERS]; diff --git a/src/k_kart.h b/src/k_kart.h index 4b9a442d1..b91e8c8a1 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -68,9 +68,6 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); -INT16 K_CalculatePowerLevelInc(INT16 diff); -INT16 K_CalculatePowerLevelAvg(void); -void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); void K_CheckSpectateStatus(void); // sound stuff for lua diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c new file mode 100644 index 000000000..31a4bd314 --- /dev/null +++ b/src/k_pwrlv.c @@ -0,0 +1,289 @@ +/// \file k_pwrlv.c +/// \brief SRB2Kart Power Levels + +#include "k_pwrlv.h" +#include "d_netcmd.h" +#include "g_game.h" +#include "s_sound.h" +#include "m_random.h" +#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems +#include "p_tick.h" // leveltime + +// Online rankings for the main gametypes. +// This array is saved to the gamedata. +UINT16 vspowerlevel[PWRLV_NUMTYPES]; + +// Client-sided calculations done for Power Levels. +// This is done so that clients will never be able to hack someone else's score over the server. +UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; + +// Which players spec-scummed, and their power level before scumming. +// On race finish, everyone is considered to have "won" against these people. +INT16 nospectategrief[MAXPLAYERS]; + +// Game setting scrambles based on server Power Level +SINT8 speedscramble = -1; +SINT8 encorescramble = -1; + +void K_ClearClientPowerLevels(void) +{ + UINT8 i, j; + for (i = 0; i < MAXPLAYERS; i++) + for (j = 0; j < PWRLV_NUMTYPES; j++) + clientpowerlevels[i][j] = 0; +} + +// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating +INT16 K_CalculatePowerLevelInc(INT16 diff) +{ + INT16 control[10] = {0,0,0,1,8,50,125,125,125,125}; + fixed_t increment = 0; + fixed_t x; + UINT8 j; + +#define MAXDIFF (PWRLVRECORD_MAX - 1) + if (diff > MAXDIFF) + diff = MAXDIFF; + if (diff < -MAXDIFF) + diff = -MAXDIFF; +#undef MAXDIFF + + x = ((diff-2)<= (2<= (1<> FRACBITS); +} + +INT16 K_CalculatePowerLevelAvg(void) +{ + fixed_t avg = 0; + UINT8 div = 0; + SINT8 t = PWRLV_DISABLED; + UINT8 i; + + if (!netgame || !cv_kartusepwrlv.value) + return 0; // No average. + + if (G_RaceGametype()) + t = PWRLV_RACE; + else if (G_BattleGametype()) + t = PWRLV_BATTLE; + + if (t == PWRLV_DISABLED) + return 0; // Hmm?! + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || clientpowerlevels[i][t] == 0) // splitscreen player + continue; + + avg += clientpowerlevels[i][t]; + div++; + } + + if (!div) + return 0; // No average. + + avg /= div; + + return (INT16)(avg >> FRACBITS); +} + +// -- K_UpdatePowerLevels could not be moved here due to usage of y_data, unfortunately. -- + +void K_SetPowerLevelScrambles(SINT8 powertype) +{ + switch (powertype) + { + case PWRLV_RACE: + if (cv_speedscramble.value || cv_encorescramble.value) + { + boolean hardmode = false; + boolean encore = false; + INT16 avg = 0, min = 0; + UINT8 i, t = 0; + + avg = K_CalculatePowerLevelAvg(); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (min == 0 || clientpowerlevels[i][0] < min) + min = clientpowerlevels[i][0]; + } + + if (min >= 6000) + { + if (avg >= 8000) + t = 4; + else + t = 3; + } + else if (min >= 4000) + { + if (avg >= 5000) + t = 3; + else + t = 2; + } + else if (min >= 2500) + { + if (avg >= 3000) + t = 2; + else + t = 1; + } + else if (min >= 500) + { + if (avg >= 2000) + t = 1; + else + t = 0; + } + else + t = 0; + + switch (t) + { + case 4: + hardmode = encore = true; + break; + case 3: + hardmode = true; + encore = M_RandomChance(FRACUNIT>>1); + break; + case 2: + hardmode = M_RandomChance((7<>2); + break; + case 1: + hardmode = M_RandomChance((3< PWRLVRECORD_MAX) // I mean... we're subtracting... but y'know how it is :V + inc -= ((yourpower + inc) - PWRLVRECORD_MAX); + if (yourpower + inc < PWRLVRECORD_MIN) + inc -= ((yourpower + inc) - PWRLVRECORD_MIN); + + clientpowerlevels[playernum][powertype] += inc; + + if (playernum == consoleplayer) + { + vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); // save your punishment! + } +} diff --git a/src/k_pwrlv.h b/src/k_pwrlv.h new file mode 100644 index 000000000..dfa300114 --- /dev/null +++ b/src/k_pwrlv.h @@ -0,0 +1,31 @@ +#ifndef __K_PWRLV__ +#define __K_PWRLV__ + +#include "doomtype.h" +#include "doomdef.h" + +#define PWRLV_DISABLED -1 +#define PWRLV_RACE 0 +#define PWRLV_BATTLE 1 +#define PWRLV_NUMTYPES 2 + +#define PWRLVRECORD_START 1000 +#define PWRLVRECORD_DEF 5000 +#define PWRLVRECORD_MIN 1 +#define PWRLVRECORD_MAX 9999 + +extern SINT8 speedscramble; +extern SINT8 encorescramble; + +extern UINT16 vspowerlevel[PWRLV_NUMTYPES]; +extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; +extern INT16 nospectategrief[MAXPLAYERS]; + +void K_ClearClientPowerLevels(void); +INT16 K_CalculatePowerLevelInc(INT16 diff); +INT16 K_CalculatePowerLevelAvg(void); +//void K_UpdatePowerLevels(void); +void K_SetPowerLevelScrambles(SINT8 powertype); +void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); + +#endif diff --git a/src/m_cond.c b/src/m_cond.c index 6335d9f08..b56882c90 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -21,6 +21,7 @@ #include "r_things.h" // numskins //#include "r_draw.h" // R_GetColorByName #include "k_kart.h" // K_GetKartColorByName +#include "k_pwrlv.h" // Map triggers for linedef executors // 32 triggers, one bit each diff --git a/src/m_menu.c b/src/m_menu.c index 216eaab29..0dd9822c5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -57,6 +57,7 @@ #include "st_stuff.h" #include "i_sound.h" #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" #include "d_player.h" // KITEM_ constants #include "i_joy.h" // for joystick menu controls @@ -9608,8 +9609,8 @@ static void M_EraseDataResponse(INT32 ch) // SRB2Kart: This actually needs to be done FIRST, so that you don't immediately regain playtime/matches secrets totalplaytime = 0; matchesplayed = 0; - for (i = 0; i < 2; i++) - vspowerlevel[i] = 1000; + for (i = 0; i < PWRLV_NUMTYPES; i++) + vspowerlevel[i] = PWRLVRECORD_START; F_StartIntro(); } if (erasecontext != 1) diff --git a/src/p_inter.c b/src/p_inter.c index b4d5c51dc..64bd573f1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -27,6 +27,7 @@ #include "m_misc.h" #include "v_video.h" // video flags for CEchos #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" // CTF player names #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" diff --git a/src/p_saveg.c b/src/p_saveg.c index da625e867..c86758058 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -34,6 +34,9 @@ #include "p_slopes.h" #endif +// SRB2Kart +#include "k_pwrlv.h" + savedata_t savedata; UINT8 *save_p; diff --git a/src/p_setup.c b/src/p_setup.c index d61406054..b19093d9a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -84,6 +84,7 @@ // SRB2Kart #include "k_kart.h" +#include "k_pwrlv.h" // // Map MD5, calculated on level load. diff --git a/src/y_inter.c b/src/y_inter.c index 7dc97559b..4e130620b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -39,6 +39,7 @@ #include "m_random.h" // M_RandomKey #include "g_input.h" // PLAYER1INPUTDOWN #include "k_kart.h" // colortranslations +#include "k_pwrlv.h" #include "console.h" // cons_menuhighlight #include "lua_hook.h" // IntermissionThinker hook @@ -323,153 +324,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) } } -static void Y_UpdatePowerLevels(void) -{ - INT32 i, j; - INT32 numplayersingame = 0, numgriefers = 0; - INT16 increment[MAXPLAYERS]; - - // Compare every single player against each other for power level increases. - // Every player you won against gives you more points, and vice versa. - // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. - // See K_CalculatePowerLevelInc for more info. - - for (i = 0; i < MAXPLAYERS; i++) - { - increment[i] = 0; - - if (nospectategrief[i] != -1) - numgriefers++; - - if (!playeringame[i] || players[i].spectator) - continue; - - numplayersingame++; - } - - for (i = 0; i < numplayersingame; i++) - { - UINT16 yourpower = 5000; - UINT16 theirpower = 5000; - INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV - INT16 inc = 0; // Total pt increment - UINT8 ipnum = data.match.num[i]; - UINT8 jpnum; - - CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum); - - if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes - continue; - yourpower = clientpowerlevels[ipnum][powertype]; - - CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower); - - for (j = 0; j < numplayersingame; j++) - { - boolean won = false; - - jpnum = data.match.num[j]; - - if (i == j || ipnum == jpnum) // Same person - continue; - - CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum); - - if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. - { - CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n"); - continue; - } - - theirpower = 5000; - if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = clientpowerlevels[jpnum][powertype]; - CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); - - if (G_RaceGametype()) - { - if (data.match.val[i] < data.match.val[j]) - won = true; - } - else - { - if (data.match.val[i] > data.match.val[j]) - won = true; - } - - if (won) // This player won! - { - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc); - } - else // This player lost... - { - diff = yourpower - theirpower; - inc -= K_CalculatePowerLevelInc(diff); - CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc); - } - } - - if (numgriefers != 0) // Automatic win against quitters. - { - for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++) - { - if (nospectategrief[jpnum] == -1) // Empty slot - continue; - - if (ipnum == jpnum) // Same person - continue; - - CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum); - - theirpower = 5000; - if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = nospectategrief[jpnum]; - CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); - - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); - } - } - - if (inc == 0) - { - data.match.increase[ipnum] = INT16_MIN; - CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n"); - continue; - } - - if (yourpower + inc > 9999) - inc -= ((yourpower + inc) - 9999); - if (yourpower + inc < 1) - inc -= ((yourpower + inc) - 1); - - CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc); - increment[ipnum] = inc; - } - - CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n"); - for (i = 0; i < MAXPLAYERS; i++) - { - if (increment[i] == 0) - continue; - - data.match.increase[i] = increment[i]; - clientpowerlevels[i][powertype] += data.match.increase[i]; - - if (i == consoleplayer) - { - CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); - vspowerlevel[powertype] = clientpowerlevels[i][powertype]; - if (M_UpdateUnlockablesAndExtraEmblems(true)) - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); - } - } -} - // // Y_IntermissionDrawer // @@ -974,6 +828,153 @@ static void Y_UpdateRecordReplays(void) CV_AddValue(&cv_nextmap, -1); } +static void K_UpdatePowerLevels(void) +{ + INT32 i, j; + INT32 numplayersingame = 0, numgriefers = 0; + INT16 increment[MAXPLAYERS]; + + // Compare every single player against each other for power level increases. + // Every player you won against gives you more points, and vice versa. + // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. + // See K_CalculatePowerLevelInc for more info. + + for (i = 0; i < MAXPLAYERS; i++) + { + increment[i] = 0; + + if (nospectategrief[i] != -1) + numgriefers++; + + if (!playeringame[i] || players[i].spectator) + continue; + + numplayersingame++; + } + + for (i = 0; i < numplayersingame; i++) + { + UINT16 yourpower = PWRLVRECORD_DEF; + UINT16 theirpower = PWRLVRECORD_DEF; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; // Total pt increment + UINT8 ipnum = data.match.num[i]; + UINT8 jpnum; + + CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum); + + if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes + continue; + yourpower = clientpowerlevels[ipnum][powertype]; + + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower); + + for (j = 0; j < numplayersingame; j++) + { + boolean won = false; + + jpnum = data.match.num[j]; + + if (i == j || ipnum == jpnum) // Same person + continue; + + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum); + + if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. + { + CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n"); + continue; + } + + theirpower = PWRLVRECORD_DEF; + if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[jpnum][powertype]; + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); + + if (G_RaceGametype()) + { + if (data.match.val[i] < data.match.val[j]) + won = true; + } + else + { + if (data.match.val[i] > data.match.val[j]) + won = true; + } + + if (won) // This player won! + { + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc); + } + else // This player lost... + { + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc); + } + } + + if (numgriefers != 0) // Automatic win against quitters. + { + for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++) + { + if (nospectategrief[jpnum] == -1) // Empty slot + continue; + + if (ipnum == jpnum) // Same person + continue; + + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum); + + theirpower = PWRLVRECORD_DEF; + if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = nospectategrief[jpnum]; + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); + + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); + } + } + + if (inc == 0) + { + data.match.increase[ipnum] = INT16_MIN; + CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n"); + continue; + } + + if (yourpower + inc > PWRLVRECORD_MAX) + inc -= ((yourpower + inc) - PWRLVRECORD_MAX); + if (yourpower + inc < PWRLVRECORD_MIN) + inc -= ((yourpower + inc) - PWRLVRECORD_MIN); + + CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc); + increment[ipnum] = inc; + } + + CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n"); + for (i = 0; i < MAXPLAYERS; i++) + { + if (increment[i] == 0) + continue; + + data.match.increase[i] = increment[i]; + clientpowerlevels[i][powertype] += data.match.increase[i]; + + if (i == consoleplayer) + { + CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); + vspowerlevel[powertype] = clientpowerlevels[i][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); + } + } +} + // // Y_StartIntermission // @@ -999,86 +1000,7 @@ void Y_StartIntermission(void) powertype = 1; } - // Race scrambles - if (powertype == 0 && (cv_speedscramble.value || cv_encorescramble.value)) - { - boolean hardmode = false; - boolean encore = false; - INT16 avg = 0, min = 0; - UINT8 i, t = 0; - - avg = K_CalculatePowerLevelAvg(); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (min == 0 || clientpowerlevels[i][0] < min) - min = clientpowerlevels[i][0]; - } - - if (min >= 6000) - { - if (avg >= 8000) - t = 4; - else - t = 3; - } - else if (min >= 4000) - { - if (avg >= 5000) - t = 3; - else - t = 2; - } - else if (min >= 2500) - { - if (avg >= 3000) - t = 2; - else - t = 1; - } - else if (min >= 500) - { - if (avg >= 2000) - t = 1; - else - t = 0; - } - else - t = 0; - - switch (t) - { - case 4: - hardmode = encore = true; - break; - case 3: - hardmode = true; - encore = M_RandomChance(FRACUNIT>>1); - break; - case 2: - hardmode = M_RandomChance((7<>2); - break; - case 1: - hardmode = M_RandomChance((3< Date: Mon, 23 Sep 2019 08:31:36 -0400 Subject: [PATCH 20/39] Remove a few more magic numbers --- src/d_clisrv.c | 6 +++--- src/d_netcmd.c | 4 ++-- src/g_game.c | 8 ++++---- src/m_menu.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d0de5f3f8..6df5a03d9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1525,13 +1525,13 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); for (i = 0; i < MAXPLAYERS; i++) - for (j = 0; j < 2; j++) + for (j = 0; j < PWRLV_NUMTYPES; j++) netbuffer->u.servercfg.powerlevels[i][j] = 0; // Not sure if memset works on something like this for (i = 0; i < MAXPLAYERS; i++) { netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i]; - for (j = 0; j < 2; j++) + for (j = 0; j < PWRLV_NUMTYPES; j++) netbuffer->u.servercfg.powerlevels[i][j] = clientpowerlevels[i][j]; if (!playeringame[i]) @@ -4131,7 +4131,7 @@ static void HandlePacketFromAwayNode(SINT8 node) for (j = 0; j < MAXPLAYERS; j++) { adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; - for (k = 0; k < 2; k++) + for (k = 0; k < PWRLV_NUMTYPES; k++) clientpowerlevels[j][k] = netbuffer->u.servercfg.powerlevels[j][k]; } memcpy(server_context, netbuffer->u.servercfg.server_context, 8); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ffeb049fd..752e4b919 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1963,8 +1963,8 @@ void D_SendPlayerConfig(void) UINT8 buf[4]; UINT8 *buf_p = buf; - WRITEUINT16(buf_p, vspowerlevel[0]); - WRITEUINT16(buf_p, vspowerlevel[1]); + WRITEUINT16(buf_p, vspowerlevel[PWRLV_RACE]); + WRITEUINT16(buf_p, vspowerlevel[PWRLV_BATTLE]); SendNetXCmd(XD_POWERLEVEL, buf, 4); } diff --git a/src/g_game.c b/src/g_game.c index 4275e1356..fb0654c8e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3049,7 +3049,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) if (netgame && cv_kartusepwrlv.value) { - if (clientpowerlevels[j][0] == clientpowerlevels[i][0]) + if (clientpowerlevels[j][PWRLV_RACE] == clientpowerlevels[i][PWRLV_RACE]) num++; } else @@ -3070,7 +3070,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) { if (netgame && cv_kartusepwrlv.value) { - if (clientpowerlevels[i][0] > clientpowerlevels[playernum][0]) + if (clientpowerlevels[i][PWRLV_RACE] > clientpowerlevels[playernum][PWRLV_RACE]) pos++; } else @@ -4113,7 +4113,7 @@ void G_LoadGameData(void) totalplaytime = READUINT32(save_p); matchesplayed = READUINT32(save_p); - for (i = 0; i < 2; i++) + for (i = 0; i < PWRLV_NUMTYPES; i++) vspowerlevel[i] = READUINT16(save_p); modded = READUINT8(save_p); @@ -4261,7 +4261,7 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, totalplaytime); WRITEUINT32(save_p, matchesplayed); - for (i = 0; i < 2; i++) + for (i = 0; i < PWRLV_NUMTYPES; i++) WRITEUINT16(save_p, vspowerlevel[i]); btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded diff --git a/src/m_menu.c b/src/m_menu.c index 0dd9822c5..362c7ea5c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7410,8 +7410,8 @@ static void M_DrawLevelStats(void) V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); V_DrawString(20, 52, highlightflags, "Online Power Level:"); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[0])); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[1])); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[PWRLV_RACE])); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[PWRLV_BATTLE])); for (i = 0; i < NUMMAPS; i++) { From a46036e489f55b6840674265df75a65801f82bd6 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 08:50:59 -0400 Subject: [PATCH 21/39] Last few magic numbers I could find --- src/d_clisrv.h | 2 +- src/dehacked.c | 4 ++-- src/m_menu.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 87147aeb8..013ccca01 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -325,7 +325,7 @@ typedef struct UINT8 gametype; UINT8 modifiedgame; SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed - UINT16 powerlevels[MAXPLAYERS][2]; // SRB2kart: player power levels + UINT16 powerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; // SRB2kart: player power levels char server_context[8]; // Unique context id, generated at server startup. diff --git a/src/dehacked.c b/src/dehacked.c index 383183a0f..b8f292a69 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2559,9 +2559,9 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) re = atoi(params[1]); x1 = atoi(params[2]); - if (x1 < 0 || x1 > 1) + if (x1 < 0 || x1 >= PWRLV_NUMTYPES) { - deh_warning("Power level type %d out of range (0 - 1)", x1); + deh_warning("Power level type %d out of range (0 - %d)", x1, PWRLV_NUMTYPES-1); return; } } diff --git a/src/m_menu.c b/src/m_menu.c index 362c7ea5c..9f4c3cda5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6211,7 +6211,7 @@ static char *M_GetConditionString(condition_t cond) case UC_MATCHESPLAYED: return va("Play %d matches", cond.requirement); case UC_POWERLEVEL: - return va("Reach power level %d in %s", cond.requirement, (cond.extrainfo1 == 1 ? "Battle" : "Race")); + return va("Reach power level %d in %s", cond.requirement, (cond.extrainfo1 == PWRLV_BATTLE ? "Battle" : "Race")); case UC_GAMECLEAR: if (cond.requirement > 1) return va("Beat game %d times", cond.requirement); From 53848bd5faf2a8bfcf194af93c9294fc75cf1250 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 08:51:49 -0400 Subject: [PATCH 22/39] commit throwdir fix I did a bunch of other demo-related cleanup in this branch so I'm throwing it in here too --- src/g_game.c | 14 -------------- src/p_tick.c | 11 ----------- src/p_user.c | 3 --- 3 files changed, 28 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index fb0654c8e..cf2378d09 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2368,21 +2368,7 @@ void G_Ticker(boolean run) if (playeringame[i]) { - //@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat... - // Remove for 1.1! - - // SRB2kart - // Save the dir the player is holding - // to allow items to be thrown forward or backward. - if (cmd->buttons & BT_FORWARD) - players[i].kartstuff[k_throwdir] = 1; - else if (cmd->buttons & BT_BACKWARD) - players[i].kartstuff[k_throwdir] = -1; - else - players[i].kartstuff[k_throwdir] = 0; - G_CopyTiccmd(cmd, &netcmds[buf][i], 1); - // Use the leveltime sent in the player's ticcmd to determine control lag cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max } diff --git a/src/p_tick.c b/src/p_tick.c index 8312afe81..02a532bc1 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -620,18 +620,7 @@ void P_Ticker(boolean run) G_ReadDemoExtraData(); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) - { - //@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now... - // Remove for 1.1! - if (players[i].cmd.buttons & BT_FORWARD) - players[i].kartstuff[k_throwdir] = 1; - else if (players[i].cmd.buttons & BT_BACKWARD) - players[i].kartstuff[k_throwdir] = -1; - else - players[i].kartstuff[k_throwdir] = 0; - G_ReadDemoTiccmd(&players[i].cmd, i); - } } for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_user.c b/src/p_user.c index 8932a49c8..d5d7dc6fd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8136,8 +8136,6 @@ void P_PlayerThink(player_t *player) cmd = &player->cmd; - //@TODO This fixes a one-tic latency on direction handling, AND makes behavior consistent while paused, but is not BC with 1.0.4. Do this for 1.1! -#if 0 // SRB2kart // Save the dir the player is holding // to allow items to be thrown forward or backward. @@ -8147,7 +8145,6 @@ void P_PlayerThink(player_t *player) player->kartstuff[k_throwdir] = -1; else player->kartstuff[k_throwdir] = 0; -#endif // Add some extra randomization. if (cmd->forwardmove) From 8dc946e6bbdfc934fdd9c55ee69b7a33aaac4f3c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 09:02:23 -0400 Subject: [PATCH 23/39] Yup, 1 more batch of magic numbers --- src/y_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 4e130620b..c51ac1e3f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -111,7 +111,7 @@ static boolean usetile; boolean usebuffer = false; static boolean useinterpic; static INT32 timer; -static INT32 powertype = 0; +static INT32 powertype = PWRLV_DISABLED; static INT32 intertic; static INT32 endtic = -1; @@ -990,14 +990,14 @@ void Y_StartIntermission(void) #endif // set player Power Level type - powertype = -1; + powertype = PWRLV_DISABLED; if (netgame && cv_kartusepwrlv.value) { if (G_RaceGametype()) - powertype = 0; + powertype = PWRLV_RACE; else if (G_BattleGametype()) - powertype = 1; + powertype = PWRLV_BATTLE; } K_SetPowerLevelScrambles(powertype); From e502a74a3fb3957ee0c8fbd2b339d482bff45ac4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 20:19:57 -0400 Subject: [PATCH 24/39] Use memset --- src/d_clisrv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6df5a03d9..ffc5b5772 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1523,10 +1523,7 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor)); memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); - - for (i = 0; i < MAXPLAYERS; i++) - for (j = 0; j < PWRLV_NUMTYPES; j++) - netbuffer->u.servercfg.powerlevels[i][j] = 0; // Not sure if memset works on something like this + memset(netbuffer->u.servercfg.powerlevels, 0, sizeof(netbuffer->u.servercfg.powerlevels)); for (i = 0; i < MAXPLAYERS; i++) { From 45fd60a4ab69bae271c803eb6cdefac06dd996a1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 20:26:47 -0400 Subject: [PATCH 25/39] Master Server scary --- src/d_clisrv.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 013ccca01..ab0c3ef82 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -388,6 +388,9 @@ typedef struct UINT8 actnum; UINT8 iszone; UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) + // Anything beyond this point won't be read by the normal SRB2 Master Server display. + // The MS uses a simple unpack, so the size of the packet above shouldn't be changed, either. + // As long as those two conditions are met, we can add as much information as we want to the end. INT16 avgpwrlv; // Kart avg power level } ATTRPACK serverinfo_pak; From f75392109da44eb386f93269aba1d0b9a22c2703 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 21:28:45 -0400 Subject: [PATCH 26/39] Forgotten include --- src/d_clisrv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index ab0c3ef82..0bd85b614 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -18,6 +18,7 @@ #include "d_netcmd.h" #include "tables.h" #include "d_player.h" +#include "k_pwrlv.h" // PWRLV_NUMTYPES #include "md5.h" From d907158b120941a5bd4c1c5843dfd4ccb5e8be66 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 15:12:55 -0400 Subject: [PATCH 27/39] Revert this --- 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 cf2378d09..ac7987291 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -67,7 +67,7 @@ JoyType_t Joystick4; #define SAVEGAMESIZE (1024) // SRB2kart -char gamedatafilename[64] = "vr.dat"; +char gamedatafilename[64] = "kartdata.dat"; char timeattackfolder[64] = "kart"; char customversionstring[32] = "\0"; From 217f61897fa3d6cad4b76ace3c7da5330933315d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 2 Oct 2019 11:47:56 -0400 Subject: [PATCH 28/39] K_PlayerForfeit on I_Quit (I believe these are the only i_systems that matter?) --- src/djgppdos/i_system.c | 7 +++++++ src/sdl/i_system.c | 6 ++++++ src/sdl12/i_system.c | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/src/djgppdos/i_system.c b/src/djgppdos/i_system.c index bc3c8b2bc..b5785bb36 100644 --- a/src/djgppdos/i_system.c +++ b/src/djgppdos/i_system.c @@ -59,6 +59,8 @@ #include "../z_zone.h" #include "../g_input.h" +#include "../k_pwrlv.h" + #include "../console.h" #ifdef __GNUG__ @@ -618,6 +620,11 @@ void I_Quit (void) #ifndef NONET D_SaveBan(); // save the ban list #endif + + // Make sure you lose points for ALT-F4 + if (Playing()) + K_PlayerForfeit(consoleplayer, true); + G_SaveGameData(); // Tails 12-08-2002 if (demorecording) G_CheckDemoStatus(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d24bd5ade..8695bd1fc 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -165,6 +165,7 @@ static char returnWadPath[256]; #include "../d_net.h" #include "../g_game.h" #include "../filesrch.h" +#include "../k_pwrlv.h" #include "endtxt.h" #include "sdlmain.h" @@ -3056,6 +3057,11 @@ void I_Quit(void) #ifndef NONET D_SaveBan(); // save the ban list #endif + + // Make sure you lose points for ALT-F4 + if (Playing()) + K_PlayerForfeit(consoleplayer, true); + G_SaveGameData(false); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index 62256f3a5..14d183748 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -233,6 +233,7 @@ static char returnWadPath[256]; #include "../d_net.h" #include "../g_game.h" #include "../filesrch.h" +#include "../k_pwrlv.h" #include "endtxt.h" #include "sdlmain.h" @@ -2977,6 +2978,11 @@ void I_Quit(void) #ifndef NONET D_SaveBan(); // save the ban list #endif + + // Make sure you lose points for ALT-F4 + if (Playing()) + K_PlayerForfeit(consoleplayer, true); + G_SaveGameData(); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. From 7433becd7a44eb1cf492dbeb9d727c6eaa316305 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 2 Oct 2019 12:07:37 -0400 Subject: [PATCH 29/39] Move map loaded failure error from the deleted backwards compat code --- src/g_game.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index ac7987291..2fbd106d5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4914,7 +4914,6 @@ void G_ReadDemoExtraData(void) kartspeed = READUINT8(demo_p); kartweight = READUINT8(demo_p); - if (stricmp(skins[players[p].skin].name, name) != 0) FindClosestSkinForStats(p, kartspeed, kartweight); @@ -7198,6 +7197,19 @@ void G_DoPlayDemo(char *defdemoname) randseed = READUINT32(demo_p); demo_p += 4; // Extrainfo location + // ...*map* not loaded? + if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK)) + { + snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demo.playback = false; + demo.title = false; + return; + } + // net var data CV_LoadNetVars(&demo_p); From a5ea6a97998d5b306df8eb9bd2a93e227354ac0b Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 01:48:16 -0400 Subject: [PATCH 30/39] Merge speed/encore scrambles into the normal cvars as an "auto" option --- src/command.c | 12 ++++++++---- src/d_clisrv.c | 2 +- src/d_netcmd.c | 9 ++++----- src/d_netcmd.h | 2 -- src/g_game.c | 2 +- src/k_kart.c | 2 -- src/k_pwrlv.c | 6 +++--- src/p_setup.c | 4 ++-- 8 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/command.c b/src/command.c index 6d9c86d3e..664eb950c 100644 --- a/src/command.c +++ b/src/command.c @@ -70,8 +70,12 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; //SRB2kart CV_PossibleValue_t kartspeed_cons_t[] = { - {0, "Easy"}, {1, "Normal"}, {2, "Hard"}, - {0, NULL}}; + {-1, "Auto"}, + {0, "Easy"}, + {1, "Normal"}, + {2, "Hard"}, + {0, NULL} +}; // Filter consvars by EXECVERSION // First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0) @@ -1769,7 +1773,7 @@ void CV_AddValue(consvar_t *var, INT32 increment) { newvalue = var->value + 1; if (newvalue > maxspeed) - newvalue = 0; + newvalue = -1; var->value = newvalue; var->string = var->PossibleValue[var->value].strvalue; var->func(); @@ -1778,7 +1782,7 @@ void CV_AddValue(consvar_t *var, INT32 increment) else if (increment < 0) // Going down! { newvalue = var->value - 1; - if (newvalue < 0) + if (newvalue < -1) newvalue = maxspeed; var->value = newvalue; var->string = var->PossibleValue[var->value].strvalue; diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 523c92778..d67f6b48e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1351,7 +1351,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.kartvars = (UINT8) ( - (cv_kartspeed.value & SV_SPEEDMASK) | + (gamespeed & SV_SPEEDMASK) | (dedicated ? SV_DEDICATED : 0) | (D_IsJoinPasswordOn() ? SV_PASSWORD : 0) ); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a5085864e..29a09fb06 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -360,12 +360,13 @@ consvar_t cv_kartminimap = {"kartminimap", "4", CV_SAVE, kartminimap_cons_t, NUL consvar_t cv_kartcheck = {"kartcheck", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartinvinsfx_cons_t[] = {{0, "Music"}, {1, "SFX"}, {0, NULL}}; consvar_t cv_kartinvinsfx = {"kartinvinsfx", "SFX", CV_SAVE, kartinvinsfx_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_kartspeed = {"kartspeed", "Normal", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartspeed = {"kartspeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; consvar_t cv_kartbumpers = {"kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "On"}, {0, NULL}}; +consvar_t cv_kartencore = {"kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}}; consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}}; @@ -376,8 +377,6 @@ consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_speedscramble = {"kartscramblespeed", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_encorescramble = {"kartscrambleencore", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -5783,7 +5782,7 @@ static void KartSpeed_OnChange(void) if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); - CV_StealthSetValue(&cv_kartspeed, 1); + CV_StealthSetValue(&cv_kartspeed, cv_kartspeed.defaultvalue); return; } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7d81f1164..d1f28665c 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -122,8 +122,6 @@ extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; extern consvar_t cv_karteliminatelast; extern consvar_t cv_kartusepwrlv; -extern consvar_t cv_speedscramble; -extern consvar_t cv_encorescramble; extern consvar_t cv_votetime; diff --git a/src/g_game.c b/src/g_game.c index 4459abe52..642f62bc1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3408,7 +3408,7 @@ INT16 G_SometimesGetDifferentGametype(void) randmapbuffer[NUMMAPS]--; if (encorepossible) { - if (encorescramble >= 0) + if (encorescramble != -1) encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission else { diff --git a/src/k_kart.c b/src/k_kart.c index 83b48c4a9..230662d2a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -580,8 +580,6 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_kartusepwrlv); - CV_RegisterVar(&cv_speedscramble); - CV_RegisterVar(&cv_encorescramble); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index 31a4bd314..c1096d4a3 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -118,7 +118,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) switch (powertype) { case PWRLV_RACE: - if (cv_speedscramble.value || cv_encorescramble.value) + if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { boolean hardmode = false; boolean encore = false; @@ -187,12 +187,12 @@ void K_SetPowerLevelScrambles(SINT8 powertype) break; } - if (cv_speedscramble.value) + if (cv_kartspeed.value == -1) speedscramble = (hardmode ? 2 : 1); else speedscramble = -1; - if (cv_encorescramble.value) + if (cv_kartencore.value == -1) encorescramble = (encore ? 1 : 0); else encorescramble = -1; diff --git a/src/p_setup.c b/src/p_setup.c index 3498c443b..7ffe84d0a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2398,8 +2398,8 @@ static void P_LevelInitStuff(void) gamespeed = 0; else { - if (cv_speedscramble.value && speedscramble != -1) - gamespeed = (UINT8)speedscramble; + if (cv_kartspeed.value == -1) + gamespeed = ((speedscramble == -1) ? cv_kartspeed.defaultvalue : (UINT8)speedscramble); else gamespeed = (UINT8)cv_kartspeed.value; } From 12829743ae1b99737bfcfc03f1850c0954fcd540 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 01:54:52 -0400 Subject: [PATCH 31/39] Add easy scrambles to the list now that easy is playable --- src/k_pwrlv.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index c1096d4a3..e43348362 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -120,7 +120,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) case PWRLV_RACE: if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { - boolean hardmode = false; + UINT8 speed = cv_kartspeed.defaultvalue; boolean encore = false; INT16 avg = 0, min = 0; UINT8 i, t = 0; @@ -167,28 +167,29 @@ void K_SetPowerLevelScrambles(SINT8 powertype) switch (t) { case 4: - hardmode = encore = true; + speed = 2; + encore = true; break; case 3: - hardmode = true; + speed = M_RandomChance((7<>1); break; case 2: - hardmode = M_RandomChance((7<>2); break; - case 1: - hardmode = M_RandomChance((3< Date: Thu, 3 Oct 2019 10:16:10 -0400 Subject: [PATCH 32/39] atoi --- src/d_netcmd.c | 2 +- src/k_pwrlv.c | 2 +- src/p_setup.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 29a09fb06..e5a7109a9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5782,7 +5782,7 @@ static void KartSpeed_OnChange(void) if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); - CV_StealthSetValue(&cv_kartspeed, cv_kartspeed.defaultvalue); + CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue); return; } diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index e43348362..2f0d3f2e1 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -120,7 +120,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) case PWRLV_RACE: if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { - UINT8 speed = cv_kartspeed.defaultvalue; + UINT8 speed = atoi(cv_kartspeed.defaultvalue); boolean encore = false; INT16 avg = 0, min = 0; UINT8 i, t = 0; diff --git a/src/p_setup.c b/src/p_setup.c index 7ffe84d0a..5ec0f97e6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2399,7 +2399,7 @@ static void P_LevelInitStuff(void) else { if (cv_kartspeed.value == -1) - gamespeed = ((speedscramble == -1) ? cv_kartspeed.defaultvalue : (UINT8)speedscramble); + gamespeed = ((speedscramble == -1) ? atoi(cv_kartspeed.defaultvalue) : (UINT8)speedscramble); else gamespeed = (UINT8)cv_kartspeed.value; } From d10e4aebacd26da6a7981924dc836f7b20615261 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:22:58 -0400 Subject: [PATCH 33/39] Fix a few messups due to the merged cvars --- src/d_main.c | 2 +- src/d_netcmd.c | 10 +++++----- src/g_game.c | 6 +++--- src/hu_stuff.c | 2 +- src/m_menu.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 05a9fa603..597eea87c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1559,7 +1559,7 @@ void D_SRB2Main(void) else if (!dedicated && M_MapLocked(pstartmap)) I_Error("You need to unlock this level before you can warp to it!\n"); else - D_MapChange(pstartmap, gametype, (boolean)cv_kartencore.value, true, 0, false, false); + D_MapChange(pstartmap, gametype, (cv_kartencore.value == 1), true, 0, false, false); } } else if (M_CheckParm("-skipintro")) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e5a7109a9..51ec3b980 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2395,7 +2395,7 @@ void D_SetupVote(void) UINT8 secondgt = G_SometimesGetDifferentGametype(); INT16 votebuffer[3] = {-1,-1,-1}; - if (cv_kartencore.value && G_RaceGametype()) + if ((cv_kartencore.value == 1) && G_RaceGametype()) WRITEUINT8(p, (gametype|0x80)); else WRITEUINT8(p, gametype); @@ -2566,7 +2566,7 @@ static void Command_Map_f(void) // new encoremode value // use cvar by default - newencoremode = (boolean)cv_kartencore.value; + newencoremode = (cv_kartencore.value == 1); if (COM_CheckParm("-encore")) { @@ -5802,10 +5802,10 @@ static void KartEncore_OnChange(void) { if (G_RaceGametype()) { - if ((boolean)cv_kartencore.value != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/) - CONS_Printf(M_GetText("Encore Mode will be turned %s next round.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); + if ((cv_kartencore.value == 1) != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/) + CONS_Printf(M_GetText("Encore Mode will be set to %s next round.\n"), cv_kartencore.string); else - CONS_Printf(M_GetText("Encore Mode has been turned %s.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); + CONS_Printf(M_GetText("Encore Mode has been set to %s.\n"), cv_kartencore.string); } } diff --git a/src/g_game.c b/src/g_game.c index 642f62bc1..d5ed9af7d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2340,7 +2340,7 @@ void G_Ticker(boolean run) G_DoReborn(consoleplayer);*/ - D_MapChange(gamemap, gametype, cv_kartencore.value, true, 1, false, false); + D_MapChange(gamemap, gametype, (cv_kartencore.value == 1), true, 1, false, false); } for (i = 0; i < MAXPLAYERS; i++) @@ -3426,7 +3426,7 @@ INT16 G_SometimesGetDifferentGametype(void) break; } } - if (encorepossible != (boolean)cv_kartencore.value) + if (encorepossible != (cv_kartencore.value == 1)) return (gametype|0x80); } return gametype; @@ -3903,7 +3903,7 @@ void G_NextLevel(void) } forceresetplayers = false; - deferencoremode = (boolean)cv_kartencore.value; + deferencoremode = (cv_kartencore.value == 1); } gameaction = ga_worlddone; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 38324dbd9..dc8ca0dd2 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3017,7 +3017,7 @@ static void HU_DrawRankings(void) } V_DrawCenteredString(256, 8, 0, "GAME SPEED"); - V_DrawCenteredString(256, 16, hilicol, cv_kartspeed.string); + V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].string); } // When you play, you quickly see your score because your name is displayed in white. diff --git a/src/m_menu.c b/src/m_menu.c index 4a3102925..d0d818db6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8644,11 +8644,11 @@ static void M_StartServer(INT32 choice) paused = false; SV_StartSinglePlayerServer(); multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this... - D_MapChange(cv_nextmap.value, cv_newgametype.value, (boolean)cv_kartencore.value, 1, 1, false, false); + D_MapChange(cv_nextmap.value, cv_newgametype.value, (cv_kartencore.value == 1), 1, 1, false, false); } else { - D_MapChange(cv_nextmap.value, cv_newgametype.value, (boolean)cv_kartencore.value, 1, 1, false, false); + D_MapChange(cv_nextmap.value, cv_newgametype.value, (cv_kartencore.value == 1), 1, 1, false, false); COM_BufAddText("dummyconsvar 1\n"); } @@ -8685,7 +8685,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) V_DrawFill(x-1, y-1, w+2, i+2, trans); // variable reuse... - if (!cv_kartencore.value || gamestate == GS_TIMEATTACK || cv_newgametype.value != GT_RACE) + if ((cv_kartencore.value != 1) || gamestate == GS_TIMEATTACK || cv_newgametype.value != GT_RACE) V_DrawSmallScaledPatch(x, y, 0, PictureOfLevel); else { From bcd142c2a0f3d117df2338b5d6de1093887f7cb1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:36:35 -0400 Subject: [PATCH 34/39] Start at 5000, rebalance scrambles --- src/k_pwrlv.c | 33 ++++++++++++++++++++++----------- src/k_pwrlv.h | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index 2f0d3f2e1..257b8ad06 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -133,30 +133,37 @@ void K_SetPowerLevelScrambles(SINT8 powertype) min = clientpowerlevels[i][0]; } - if (min >= 6000) + if (min >= 7800) { - if (avg >= 8000) + if (avg >= 8200) + t = 5; + else + t = 4; + } + else if (min >= 6800) + { + if (avg >= 7200) t = 4; else t = 3; } - else if (min >= 4000) + else if (min >= 5800) { - if (avg >= 5000) + if (avg >= 6200) t = 3; else t = 2; } - else if (min >= 2500) + else if (min >= 3800) { - if (avg >= 3000) + if (avg >= 4200) t = 2; else t = 1; } - else if (min >= 500) + else if (min >= 1800) { - if (avg >= 2000) + if (avg >= 2200) t = 1; else t = 0; @@ -166,18 +173,22 @@ void K_SetPowerLevelScrambles(SINT8 powertype) switch (t) { - case 4: + case 5: speed = 2; encore = true; break; - case 3: + case 4: speed = M_RandomChance((7<>1); break; - case 2: + case 3: speed = M_RandomChance((3<>2); break; + case 2: + speed = 1; + encore = M_RandomChance(FRACUNIT>>3); + break; case 1: default: speed = 1; encore = false; diff --git a/src/k_pwrlv.h b/src/k_pwrlv.h index dfa300114..1dae566ed 100644 --- a/src/k_pwrlv.h +++ b/src/k_pwrlv.h @@ -9,7 +9,7 @@ #define PWRLV_BATTLE 1 #define PWRLV_NUMTYPES 2 -#define PWRLVRECORD_START 1000 +#define PWRLVRECORD_START 5000 //1000 #define PWRLVRECORD_DEF 5000 #define PWRLVRECORD_MIN 1 #define PWRLVRECORD_MAX 9999 From 706c6be627ba8147088ae05ce9a62046c779ed1f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:37:58 -0400 Subject: [PATCH 35/39] Wrong var name --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index dc8ca0dd2..6126f7bec 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3017,7 +3017,7 @@ static void HU_DrawRankings(void) } V_DrawCenteredString(256, 8, 0, "GAME SPEED"); - V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].string); + V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].strvalue); } // When you play, you quickly see your score because your name is displayed in white. From 03ec42da6da6b334901b5a3b3dd8b350b460c102 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:46:00 -0400 Subject: [PATCH 36/39] Back to 1000 --- src/k_pwrlv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_pwrlv.h b/src/k_pwrlv.h index 1dae566ed..05fbf1c8a 100644 --- a/src/k_pwrlv.h +++ b/src/k_pwrlv.h @@ -9,7 +9,7 @@ #define PWRLV_BATTLE 1 #define PWRLV_NUMTYPES 2 -#define PWRLVRECORD_START 5000 //1000 +#define PWRLVRECORD_START 1000 // 5000? #define PWRLVRECORD_DEF 5000 #define PWRLVRECORD_MIN 1 #define PWRLVRECORD_MAX 9999 From f1e5f64e66f4c9809bf825909e68b03ad065c0a6 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Oct 2019 12:38:44 -0700 Subject: [PATCH 37/39] Use K_MatchGenericExtraFlags for reverse gravity rings Also corrected a mistaken usage of scale. --- src/p_enemy.c | 22 ++++++++-------------- src/p_mobj.c | 17 ++++++----------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3c59c40f5..aadb27329 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3558,8 +3558,6 @@ void A_BubbleCheck(mobj_t *actor) // void A_AttractChase(mobj_t *actor) { - fixed_t z; - #ifdef HAVE_BLUA if (LUA_CallAction("A_AttractChase", actor)) return; @@ -3603,12 +3601,11 @@ void A_AttractChase(mobj_t *actor) { fixed_t offz = FixedMul(80*actor->target->scale, FINESINE(FixedAngle((90 - (9 * abs(10 - actor->extravalue1))) << FRACBITS) >> ANGLETOFINESHIFT)); //P_SetScale(actor, (actor->destscale = actor->target->scale)); - z = actor->target->z; - if (( actor->eflags & MFE_VERTICALFLIP )) - z -= actor->height + offz; - else - z += actor->target->height + offz; - P_TeleportMove(actor, actor->target->x, actor->target->y, z); + actor->z = actor->target->z; + K_MatchGenericExtraFlags(actor, actor->target); + P_TeleportMove(actor, actor->target->x, actor->target->y, + actor->z + + ( actor->target->height + offz )* P_MobjFlip(actor)); actor->extravalue1++; } } @@ -3635,15 +3632,12 @@ void A_AttractChase(mobj_t *actor) fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1); P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1))); - z = actor->target->z; - if (( actor->eflags & MFE_VERTICALFLIP )) - z += actor->target->height - actor->height - 24 * actor->target->scale; - else - z += 24 * actor->target->scale; + actor->z = actor->target->z; + K_MatchGenericExtraFlags(actor, actor->target); P_TeleportMove(actor, actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), - z); + actor->z + FixedMul(actor->target->scale, 24<angle += ANG30; actor->extravalue1++; diff --git a/src/p_mobj.c b/src/p_mobj.c index b1d862718..f54eca41e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8744,18 +8744,13 @@ void P_MobjThinker(mobj_t *mobj) return; } + mobj->z = mobj->target->z; + K_MatchGenericExtraFlags(mobj, mobj->target); - { - fixed_t z; - z = mobj->target->z; - if (( mobj->eflags & MFE_VERTICALFLIP )) - z -= mobj->height; - else - z += mobj->target->height; - P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), - mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), - z); - } + + P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), + mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), + mobj->z + mobj->target->height * P_MobjFlip(mobj)); break; case MT_TIREGREASE: if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player From 675c896417a0c2f5b67c01dddd20a63b0a01c718 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Oct 2019 12:46:24 -0700 Subject: [PATCH 38/39] Nevermind the FixedMul --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index aadb27329..76f6b3159 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3637,7 +3637,7 @@ void A_AttractChase(mobj_t *actor) P_TeleportMove(actor, actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), - actor->z + FixedMul(actor->target->scale, 24<z + actor->target->scale * 24 * P_MobjFlip(actor)); actor->angle += ANG30; actor->extravalue1++; From 027dec67025481e19ec00cb43d8336ed25982672 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 5 Oct 2019 19:07:26 -0500 Subject: [PATCH 39/39] Fix Ring Drain sectors for v2 rings --- src/p_spec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index aa43583a4..93e88e2ce 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3637,10 +3637,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers break; case 9: // Ring Drainer (Floor Touch) case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1) + if (leveltime % (TICRATE/2) == 0 && player->kartstuff[k_rings] > 0) { - player->mo->health--; - player->health--; + player->kartstuff[k_rings]--; S_StartSound(player->mo, sfx_itemup); } break;