diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 8edba171b..c2b7756a6 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2190,9 +2190,9 @@ void D_MapChange(UINT16 mapnum, INT32 newgametype, boolean pencoremode, boolean } } -void D_SetupVote(void) +void D_SetupVote(INT16 newgametype) { - UINT8 buf[(VOTE_NUM_LEVELS * 2) + 2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes + UINT8 buf[(VOTE_NUM_LEVELS * 2) + 4]; UINT8 *p = buf; INT32 i; @@ -2200,13 +2200,14 @@ void D_SetupVote(void) UINT16 votebuffer[VOTE_NUM_LEVELS + 1]; memset(votebuffer, UINT16_MAX, sizeof(votebuffer)); + WRITEINT16(p, newgametype); WRITEUINT8(p, ((cv_kartencore.value == 1) && (gametyperules & GTR_ENCORE))); WRITEUINT8(p, G_SometimesGetDifferentEncore()); for (i = 0; i < VOTE_NUM_LEVELS; i++) { UINT16 m = G_RandMap( - G_TOLFlag(gametype), + G_TOLFlag(newgametype), prevmap, false, (i < VOTE_NUM_LEVELS-1), votebuffer @@ -5305,6 +5306,7 @@ static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum) static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) { + INT16 newGametype = 0; boolean baseEncore = false; boolean optionalEncore = false; INT16 tempVoteLevels[VOTE_NUM_LEVELS][2]; @@ -5320,6 +5322,7 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) return; } + newGametype = READINT16(*cp); baseEncore = (boolean)READUINT8(*cp); optionalEncore = (boolean)READUINT8(*cp); @@ -5329,6 +5332,17 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) baseEncore = optionalEncore = false; } + if (newGametype < 0 || newGametype >= numgametypes) + { + if (server) + { + I_Error("Got_SetupVotecmd: Gametype %d out of range (numgametypes = %d)", newGametype, numgametypes); + } + + CONS_Alert(CONS_WARNING, M_GetText("Vote setup with bad gametype %d received from %s\n"), newGametype, player_names[playernum]); + return; + } + for (i = 0; i < VOTE_NUM_LEVELS; i++) { tempVoteLevels[i][0] = (UINT16)READUINT16(*cp); @@ -5348,6 +5362,12 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum) return; } + { + INT16 oldGametype = gametype; + G_SetGametype(newGametype); + D_GameTypeChanged(oldGametype); + } + if (optionalEncore == true) { tempVoteLevels[VOTE_NUM_LEVELS - 1][1] ^= VOTE_MOD_ENCORE; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index a2129195f..2a8b3bed7 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -241,7 +241,7 @@ void Command_Retry_f(void); boolean G_GamestateUsesExitLevel(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore void D_MapChange(UINT16 pmapnum, INT32 pgametype, boolean pencoremode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pforcespecialstage); -void D_SetupVote(void); +void D_SetupVote(INT16 newgametype); void D_ModifyClientVote(UINT8 player, SINT8 voted); void D_PickVote(void); void ObjectPlace_OnChange(void); diff --git a/src/g_game.c b/src/g_game.c index 19d513924..ef72e9eb3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3155,7 +3155,7 @@ INT32 G_GuessGametypeByTOL(UINT32 tol) // void G_SetGametype(INT16 gtype) { - if (gtype < 0 || gtype > numgametypes) + if (gtype < 0 || gtype >= numgametypes) { I_Error("G_SetGametype: Bad gametype change %d (was %d/\"%s\")", gtype, gametype, gametypes[gametype]->name); } @@ -4384,7 +4384,7 @@ static void G_DoStartVote(void) { if (gamestate == GS_VOTING) I_Error("G_DoStartVote: NEXTMAP_VOTING causes recursive vote!"); - D_SetupVote(); + D_SetupVote(gametype); } gameaction = ga_nothing; } diff --git a/src/menus/transient/pause-game.c b/src/menus/transient/pause-game.c index 4afe00d2e..839d69d4b 100644 --- a/src/menus/transient/pause-game.c +++ b/src/menus/transient/pause-game.c @@ -1,6 +1,7 @@ /// \file menus/transient/pause-game.c /// \brief In-game/pause menus +#include "../../d_netcmd.h" #include "../../k_menu.h" #include "../../k_grandprix.h" // K_CanChangeRules #include "../../m_cond.h" @@ -331,7 +332,10 @@ void M_HandlePauseMenuGametype(INT32 choice) if (menugametype != gametype) { M_ClearMenus(true); - COM_ImmedExecute(va("randommap -gt %s", gametypes[menugametype]->name)); + if (server || IsPlayerAdmin(consoleplayer)) + { + D_SetupVote(menugametype); + } return; }