diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 43c728b75..b4a6c2d42 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3705,7 +3705,8 @@ static void HandlePacketFromAwayNode(SINT8 node) if (client) { maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); - gametype = netbuffer->u.servercfg.gametype; + if ((gametype = netbuffer->u.servercfg.gametype) >= NUMGAMETYPES) + I_Error("Bad gametype in cliserv!"); modifiedgame = netbuffer->u.servercfg.modifiedgame; for (j = 0; j < MAXPLAYERS; j++) adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 82cbc4bf0..9ad7e4ba0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -447,6 +447,7 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL}; INT16 gametype = GT_RACE; // SRB2kart +INT16 deferredgametype = GT_RACE; // SRB2kart UINT8 splitscreen = 0; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; @@ -2117,7 +2118,6 @@ static void Command_Map_f(void) // Don't do any variable setting here. Wait until you get your // map packet first to avoid sending the same info twice! newgametype = gametype_cons_t[j].value; - break; } @@ -2135,26 +2135,23 @@ static void Command_Map_f(void) } } + if (!(i = COM_CheckParm("-force")) && newgametype == gametype) // SRB2Kart + newresetplayers = false; // if not forcing and gametypes is the same + // don't use a gametype the map doesn't support - if (cv_debug || COM_CheckParm("-force") || cv_skipmapcheck.value) + if (cv_debug || i || cv_skipmapcheck.value) ; // The player wants us to trek on anyway. Do so. // G_TOLFlag handles both multiplayer gametype and ignores it for !multiplayer // Alternatively, bail if the map header is completely missing anyway. - else if (!mapheaderinfo[newmapnum-1] - || !(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype))) + else { - char gametypestring[32] = "Single Player"; - - if (multiplayer) - for (i = 0; gametype_cons_t[i].strvalue != NULL; i++) - if (gametype_cons_t[i].value == newgametype) - { - strcpy(gametypestring, gametype_cons_t[i].strvalue); - break; - } - - CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, gametypestring); - return; + if (!mapheaderinfo[newmapnum-1] + || !(mapheaderinfo[newmapnum-1]->typeoflevel & G_TOLFlag(newgametype))) + { + CONS_Alert(CONS_WARNING, M_GetText("%s doesn't support %s mode!\n(Use -force to override)\n"), mapname, + (multiplayer ? gametype_cons_t[newgametype].strvalue : "Single Player")); + return; + } } // Prevent warping to locked levels @@ -4044,24 +4041,12 @@ static void Command_ShowGametype_f(void) INT32 j; const char *gametypestr = NULL; - if (!(netgame || multiplayer)) // print "Single player" instead of "Co-op" + if (!(netgame || multiplayer)) // print "Single player" instead of "Race" { - CONS_Printf(M_GetText("Current gametype is %s\n"), M_GetText("Single player")); + CONS_Printf(M_GetText("Current gametype is %s\n"), "Single Player"); return; } - // find name string for current gametype - for (j = 0; gametype_cons_t[j].strvalue; j++) - { - if (gametype_cons_t[j].value == gametype) - { - gametypestr = gametype_cons_t[j].strvalue; - break; - } - } - if (gametypestr) - CONS_Printf(M_GetText("Current gametype is %s\n"), gametypestr); - else // string for current gametype was not found above (should never happen) - CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype); + CONS_Printf(M_GetText("Current gametype is %s\n"), gametype_cons_t[gametype].strvalue); } /** Plays the intro. @@ -4195,19 +4180,8 @@ static void TimeLimit_OnChange(void) void D_GameTypeChanged(INT32 lastgametype) { if (netgame) - { - INT32 j; - const char *oldgt = NULL, *newgt = NULL; - for (j = 0; gametype_cons_t[j].strvalue; j++) - { - if (gametype_cons_t[j].value == lastgametype) - oldgt = gametype_cons_t[j].strvalue; - if (gametype_cons_t[j].value == gametype) - newgt = gametype_cons_t[j].strvalue; - } - if (oldgt && newgt) - CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), oldgt, newgt); - } + CONS_Printf(M_GetText("Gametype was changed from %s to %s\n"), gametype_cons_t[lastgametype].strvalue, gametype_cons_t[gametype].strvalue); + // Only do the following as the server, not as remote admin. // There will always be a server, and this only needs to be done once. if (server && (multiplayer || netgame)) diff --git a/src/doomstat.h b/src/doomstat.h index cf2998163..433cfbd76 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -76,7 +76,7 @@ extern boolean addedtogame; // true after the server has added you // Only true if >1 player. netgame => multiplayer but not (multiplayer=>netgame) extern boolean multiplayer; -extern INT16 gametype; +extern INT16 gametype, deferredgametype; extern UINT8 splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; @@ -303,21 +303,19 @@ enum TypeOfLevel }; // Gametypes -enum GameType +enum GameType // SRB2Kart { - GT_COOP = 0, // also used in single player - GT_COMPETITION, // Classic "Race" - GT_RACE, + GT_RACE = 0, // also used in record attack + GT_MATCH, // battle, but renaming would be silly + NUMGAMETYPES, - GT_MATCH, + // the following have been left in on account of just not wanting to deal with removing all the checks for them + GT_COOP, + GT_COMPETITION, GT_TEAMMATCH, - GT_TAG, GT_HIDEANDSEEK, - - GT_CTF, // capture the flag - - NUMGAMETYPES + GT_CTF }; // If you alter this list, update gametype_cons_t in m_menu.c diff --git a/src/g_game.c b/src/g_game.c index 548c26cda..1ca679180 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3379,7 +3379,11 @@ void G_NextLevel(void) && !modeattacking && !skipstats && (multiplayer || netgame)) gameaction = ga_startvote; else + { + if (gamestate != GS_VOTING) + deferredgametype = gametype; gameaction = ga_worlddone; + } } static void G_DoWorldDone(void) @@ -3387,7 +3391,7 @@ static void G_DoWorldDone(void) if (server) { // SRB2kart: don't reset player between maps - D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); + D_MapChange(nextmap+1, deferredgametype, ultimatemode, (deferredgametype != gametype), 0, false, false); } gameaction = ga_nothing; @@ -4032,7 +4036,8 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (!demoplayback && !netgame) // Netgame sets random seed elsewhere, demo playback sets seed just before us! P_SetRandSeed(M_RandomizedSeed()); // Use a more "Random" random seed - if (resetplayer) + //SRB2Kart - Score is literally the only thing you SHOULDN'T reset at all times + //if (resetplayer) { // Clear a bunch of variables tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; @@ -4045,7 +4050,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean players[i].starpostx = players[i].starposty = players[i].starpostz = 0; players[i].starpostcount = 0; // srb2kart - if (netgame || multiplayer) + /*if (netgame || multiplayer) { players[i].lives = cv_startinglives.value; players[i].continues = 0; @@ -4061,13 +4066,18 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean players[i].continues = 1; } + players[i].xtralife = 0;*/ + // The latter two should clear by themselves, but just in case players[i].pflags &= ~(PF_TAGIT|PF_TAGGED|PF_FULLSTASIS); // Clear cheatcodes too, just in case. players[i].pflags &= ~(PF_GODMODE|PF_NOCLIP|PF_INVIS); - players[i].score = players[i].xtralife = 0; + if (resetplayer) // SRB2Kart + { + players[i].score = 0; + } } // Reset unlockable triggers @@ -5601,8 +5611,7 @@ void G_DoPlayDemo(char *defdemoname) memset(playeringame,0,sizeof(playeringame)); playeringame[0] = true; P_SetRandSeed(randseed); - //G_InitNew(false, G_BuildMapName(gamemap), false, true); // resetplayer needs to be false to retain score - G_InitNew(false, G_BuildMapName(gamemap), true, true); // ...but uh, for demos? doing that makes them start in different positions depending on the last demo you watched + G_InitNew(false, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer. // Set skin SetPlayerSkin(0, skin); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c3c04bedd..61b8ce72e 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1123,19 +1123,7 @@ static void HU_DrawCEcho(void) static void HU_drawGametype(void) { - INT32 i = 0; - - for (i = 0; gametype_cons_t[i].strvalue; i++) - { - if (gametype_cons_t[i].value == gametype) - { - if (splitscreen) - V_DrawString(4, 184, 0, gametype_cons_t[i].strvalue); - else - V_DrawString(4, 192, 0, gametype_cons_t[i].strvalue); - return; - } - } + V_DrawString(4, (splitscreen ? 184 : 192), 0, gametype_cons_t[gametype].strvalue); } // diff --git a/src/st_stuff.c b/src/st_stuff.c index 2b3c770aa..87d29556d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -774,11 +774,14 @@ static void ST_drawLevelTitle(void) else lvlttlxpos = ((BASEVIDWIDTH/2) - (lvlw/2)); - ttlnumxpos = lvlttlxpos + lvlw; - if (zonttl[0]) - zonexpos = ttlnumxpos - V_LevelNameWidth(zonttl); // SRB2kart - else - zonexpos = ttlnumxpos - V_LevelNameWidth(M_GetText("ZONE")); + zonexpos = ttlnumxpos = lvlttlxpos + lvlw; + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + { + if (zonttl[0]) + zonexpos -= V_LevelNameWidth(zonttl); // SRB2kart + else + zonexpos -= V_LevelNameWidth(M_GetText("ZONE")); + } if (lvlttlxpos < 0) lvlttlxpos = 0; @@ -795,11 +798,14 @@ static void ST_drawLevelTitle(void) { dupcalc = (dupcalc - BASEVIDWIDTH)>>1; INT32 h = lvlttly + V_LevelNameHeight(lvlttl) + 2; - V_DrawFill(sub - dupcalc, h+9, lvlttlxpos + lvlw + 1 - dupcalc, 2, 31); - V_DrawDiag(sub + lvlttlxpos + lvlw + 1, h, 11, 31); - V_DrawFill(sub - dupcalc, h, lvlttlxpos + lvlw - dupcalc, 10, gtc); - V_DrawDiag(sub + lvlttlxpos + lvlw, h, 10, gtc); - V_DrawString(sub + lvlttlxpos, h+1, V_ALLOWLOWERCASE, subttl); + V_DrawFill(sub - dupcalc, h+9, ttlnumxpos+dupcalc + 1, 2, 31); + V_DrawDiag(sub + ttlnumxpos + 1, h, 11, 31); + V_DrawFill(sub - dupcalc, h, ttlnumxpos+dupcalc, 10, gtc); + V_DrawDiag(sub + ttlnumxpos, h, 10, gtc); + if (subttl[0]) + V_DrawRightAlignedString(sub + zonexpos - 8, h+1, V_ALLOWLOWERCASE, va("%s - %s", gametype_cons_t[gametype].strvalue, subttl)); + else + V_DrawRightAlignedString(sub + zonexpos - 8, h+1, V_ALLOWLOWERCASE, gametype_cons_t[gametype].strvalue); } ttlnumxpos += sub; diff --git a/src/y_inter.c b/src/y_inter.c index 33d62157e..fb1f612bc 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -2617,16 +2617,13 @@ void Y_StartVote(void) levelinfo[i].str[sizeof levelinfo[i].str - 1] = '\0'; // set up the gtc and gts - levelinfo[i].gts = NULL; if (i == 2 && votelevels[i][1] != votelevels[0][1]) { levelinfo[i].gtc = G_GetGametypeColor(votelevels[i][1]); - for (j = 0; gametype_cons_t[j].strvalue; j++) - { - if (gametype_cons_t[j].value == votelevels[i][1]) - levelinfo[i].gts = gametype_cons_t[j].strvalue; - } + levelinfo[i].gts = gametype_cons_t[votelevels[i][1]].strvalue; } + else + levelinfo[i].gts = NULL; // gtc is never accessed in this case // set up the pic lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(votelevels[i][0]+1))); @@ -2726,10 +2723,6 @@ void Y_SetupVoteFinish(SINT8 pick, SINT8 level) pickedvote = pick; nextmap = votelevels[level][0]; - if (gametype != votelevels[level][1]) - { - //CONS_Printf("yer dun\n"); -- if we want to do anything else special for a gametype switch, it'd be here - gametype = votelevels[level][1]; - } + deferredgametype = votelevels[level][1]; timer = 0; }