diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7b6c35eb6..14901360d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3461,7 +3461,7 @@ void SV_StartSinglePlayerServer(void) server = true; netgame = false; multiplayer = false; - gametype = GT_COOP; + G_SetGametype(GT_COOP); // no more tic the game with this settings! SV_StopServer(); @@ -3740,7 +3740,7 @@ static void HandlePacketFromAwayNode(SINT8 node) if (client) { maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); - gametype = netbuffer->u.servercfg.gametype; + G_SetGametype(netbuffer->u.servercfg.gametype); modifiedgame = netbuffer->u.servercfg.modifiedgame; for (j = 0; j < MAXPLAYERS; j++) adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; diff --git a/src/d_main.c b/src/d_main.c index ef6502aec..815136440 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -753,7 +753,7 @@ void D_StartTitle(void) gameaction = ga_nothing; displayplayer = consoleplayer = 0; - gametype = GT_COOP; + G_SetGametype(GT_COOP); paused = false; advancedemo = false; F_InitMenuPresValues(); @@ -1416,7 +1416,7 @@ void D_SRB2Main(void) if (newgametype != -1) { j = gametype; - gametype = newgametype; + G_SetGametype(newgametype); D_GameTypeChanged(j); } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 00cb6e65e..40d626185 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -125,6 +125,7 @@ static void Command_Version_f(void); static void Command_ModDetails_f(void); #endif static void Command_ShowGametype_f(void); +static void Command_SetGametype_f(void); FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void); static void Command_Playintro_f(void); @@ -381,6 +382,7 @@ char timedemo_csv_id[256]; boolean timedemo_quit; INT16 gametype = GT_COOP; +INT16 gametyperules = 0; boolean splitscreen = false; boolean circuitmap = false; INT32 adminplayers[MAXPLAYERS]; @@ -480,6 +482,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("suicide", Command_Suicide); COM_AddCommand("gametype", Command_ShowGametype_f); + COM_AddCommand("setgametype", Command_SetGametype_f); COM_AddCommand("version", Command_Version_f); #ifdef UPDATE_ALERT COM_AddCommand("mod_details", Command_ModDetails_f); @@ -2065,6 +2068,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) lastgametype = gametype; gametype = READUINT8(*cp); + G_SetGametype(gametype); // I fear putting that macro as an argument if (gametype < 0 || gametype >= NUMGAMETYPES) gametype = lastgametype; @@ -3623,6 +3627,12 @@ static void Command_ShowGametype_f(void) CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype); } +static void Command_SetGametype_f(void) +{ + if (COM_Argc() > 1) + G_SetGametype(atoi(COM_Argv(1))); +} + /** Plays the intro. */ static void Command_Playintro_f(void) @@ -3935,7 +3945,7 @@ void D_GameTypeChanged(INT32 lastgametype) } else if (!multiplayer && !netgame) { - gametype = GT_COOP; + G_SetGametype(GT_COOP); // These shouldn't matter anymore //CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); //CV_SetValue(&cv_itemrespawn, 0); diff --git a/src/doomstat.h b/src/doomstat.h index 772f6b3fb..2b493c917 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -84,6 +84,7 @@ extern boolean addedtogame; // true after the server has added you extern boolean multiplayer; extern INT16 gametype; +extern INT16 gametyperules; extern boolean splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; @@ -407,6 +408,17 @@ enum GameType }; // If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c +// Game type rules +enum GameTypeRules +{ + GTR_PLATFORM = 1, // Co-op, Competition, Race + GTR_TAG = 1<<1, // Tag, Hide and Seek + GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) + GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race + GTR_TEAMS = 1<<4, // Team Match, CTF + GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition +}; + // String names for gametypes extern const char *Gametype_Names[NUMGAMETYPES]; diff --git a/src/g_game.c b/src/g_game.c index 2a12dd298..d1fc61c35 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3058,6 +3058,34 @@ const char *Gametype_Names[NUMGAMETYPES] = "CTF" // GT_CTF }; +// Game type rules +INT16 gametypedefaultrules[NUMGAMETYPES] = +{ + GTR_PLATFORM|GTR_LIVES, // GT_COOP + GTR_PLATFORM|GTR_LIVES, // GT_COMPETITION + GTR_PLATFORM, // GT_RACE + + GTR_RINGSLINGER|GTR_SPECTATORS, // GT_MATCH + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS, // GT_TEAMMATCH + + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS, // GT_TAG + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS, // GT_HIDEANDSEEK + + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS // GT_CTF +}; + +// +// G_SetGametype +// +// Set a new gametype, also setting gametype rules accordingly. Yay! +// +void G_SetGametype(INT16 gtype) +{ + gametype = gtype; + gametyperules = gametypedefaultrules[gametype]; + CONS_Printf("Gametype set to %s (%d)\n", Gametype_Names[gametype], gametype); +} + // // G_GetGametypeByName // @@ -3101,7 +3129,8 @@ boolean G_IsSpecialStage(INT32 mapnum) boolean G_GametypeUsesLives(void) { // Coop, Competitive - if ((gametype == GT_COOP || gametype == GT_COMPETITION) + //if ((gametype == GT_COOP || gametype == GT_COMPETITION) + if ((gametyperules & GTR_LIVES) && !(modeattacking || metalrecording) // No lives in Time Attack && !G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS)) // No lives in NiGHTS @@ -3117,7 +3146,8 @@ boolean G_GametypeUsesLives(void) // boolean G_GametypeHasTeams(void) { - return (gametype == GT_TEAMMATCH || gametype == GT_CTF); + return (gametyperules & GTR_TEAMS); + //return (gametype == GT_TEAMMATCH || gametype == GT_CTF); } // @@ -3128,7 +3158,8 @@ boolean G_GametypeHasTeams(void) // boolean G_GametypeHasSpectators(void) { - return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); + return (gametyperules & GTR_SPECTATORS); + //return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); } // @@ -3139,7 +3170,8 @@ boolean G_GametypeHasSpectators(void) // boolean G_RingSlingerGametype(void) { - return ((gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE) || (cv_ringslinger.value)); + return ((gametyperules & GTR_RINGSLINGER) || (cv_ringslinger.value)); + //return ((gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE) || (cv_ringslinger.value)); } // @@ -3149,7 +3181,8 @@ boolean G_RingSlingerGametype(void) // boolean G_PlatformGametype(void) { - return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); + return (gametyperules & GTR_PLATFORM); + //return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); } // @@ -3159,7 +3192,8 @@ boolean G_PlatformGametype(void) // boolean G_TagGametype(void) { - return (gametype == GT_TAG || gametype == GT_HIDEANDSEEK); + return (gametyperules & GTR_TAG); + //return (gametype == GT_TAG || gametype == GT_HIDEANDSEEK); } /** Get the typeoflevel flag needed to indicate support of a gametype. diff --git a/src/g_game.h b/src/g_game.h index e7f4a4677..a925e14c1 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -201,6 +201,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); +void G_SetGametype(INT16 gametype); INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void);