From 4d9cec285e6cf3c098943cb52d88c20f3c028acf Mon Sep 17 00:00:00 2001 From: "Dr. Jaska" Date: Wed, 10 Jul 2024 18:27:36 +0000 Subject: [PATCH] Add support for up to 72 gametypes --- .../gamemodes/gamemode/assault/assault.qh | 2 +- qcsrc/common/gamemodes/gamemode/ctf/ctf.qh | 2 +- qcsrc/common/gamemodes/gamemode/cts/cts.qh | 2 +- .../gamemode/domination/domination.qh | 2 +- qcsrc/common/gamemodes/gamemode/duel/duel.qh | 2 +- .../gamemodes/gamemode/invasion/invasion.qh | 2 +- .../gamemodes/gamemode/mayhem/mayhem.qh | 4 +- .../gamemodes/gamemode/nexball/nexball.qh | 2 +- .../gamemodes/gamemode/onslaught/onslaught.qh | 2 +- qcsrc/common/gamemodes/gamemode/race/race.qh | 2 +- .../gamemodes/gamemode/survival/survival.qh | 2 +- qcsrc/common/gamemodes/gamemode/tdm/tdm.qh | 2 +- qcsrc/common/gamemodes/gamemode/tka/tka.qh | 4 +- .../gamemodes/gamemode/tmayhem/tmayhem.qh | 4 +- qcsrc/common/mapinfo.qc | 85 +++++++++++-------- qcsrc/common/mapinfo.qh | 24 ++++-- .../dialog_multiplayer_create_mapinfo.qc | 2 +- qcsrc/server/mapvoting.qc | 15 ++-- 18 files changed, 93 insertions(+), 67 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/assault/assault.qh b/qcsrc/common/gamemodes/gamemode/assault/assault.qh index f4f4b3f92..c07002d8f 100644 --- a/qcsrc/common/gamemodes/gamemode/assault/assault.qh +++ b/qcsrc/common/gamemodes/gamemode/assault/assault.qh @@ -10,7 +10,7 @@ CLASS(Assault, Gametype) METHOD(Assault, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "target_assault_roundend") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(Assault, m_isTwoBaseMode, bool()) { diff --git a/qcsrc/common/gamemodes/gamemode/ctf/ctf.qh b/qcsrc/common/gamemodes/gamemode/ctf/ctf.qh index 5d74f31cc..c5d15fec9 100644 --- a/qcsrc/common/gamemodes/gamemode/ctf/ctf.qh +++ b/qcsrc/common/gamemodes/gamemode/ctf/ctf.qh @@ -14,7 +14,7 @@ CLASS(CaptureTheFlag, Gametype) METHOD(CaptureTheFlag, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "item_flag_team2" || v == "team_CTF_blueflag") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(CaptureTheFlag, m_isTwoBaseMode, bool()) { diff --git a/qcsrc/common/gamemodes/gamemode/cts/cts.qh b/qcsrc/common/gamemodes/gamemode/cts/cts.qh index c59b73c36..c677ff602 100644 --- a/qcsrc/common/gamemodes/gamemode/cts/cts.qh +++ b/qcsrc/common/gamemodes/gamemode/cts/cts.qh @@ -13,7 +13,7 @@ CLASS(RaceCTS, Gametype) METHOD(RaceCTS, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "target_startTimer") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(RaceCTS, m_setTeams, void(string sa)) { diff --git a/qcsrc/common/gamemodes/gamemode/domination/domination.qh b/qcsrc/common/gamemodes/gamemode/domination/domination.qh index 494737c36..3117c2980 100644 --- a/qcsrc/common/gamemodes/gamemode/domination/domination.qh +++ b/qcsrc/common/gamemodes/gamemode/domination/domination.qh @@ -27,7 +27,7 @@ CLASS(Domination, Gametype) METHOD(Domination, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "dom_controlpoint" || v == "team_dom_point") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(Domination, m_configuremenu, void(Gametype this, entity menu, void(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip) returns)) { diff --git a/qcsrc/common/gamemodes/gamemode/duel/duel.qh b/qcsrc/common/gamemodes/gamemode/duel/duel.qh index ede5f9b42..316b6c341 100644 --- a/qcsrc/common/gamemodes/gamemode/duel/duel.qh +++ b/qcsrc/common/gamemodes/gamemode/duel/duel.qh @@ -18,7 +18,7 @@ CLASS(Duel, Gametype) { // if this is set, all DM maps support duel too // TODO: we should really check the size of maps, some DM maps do not work for duel! - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.gametype_flags)) return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported) } return false; diff --git a/qcsrc/common/gamemodes/gamemode/invasion/invasion.qh b/qcsrc/common/gamemodes/gamemode/invasion/invasion.qh index 7ac091d5c..71f6b7d14 100644 --- a/qcsrc/common/gamemodes/gamemode/invasion/invasion.qh +++ b/qcsrc/common/gamemodes/gamemode/invasion/invasion.qh @@ -19,7 +19,7 @@ CLASS(Invasion, Gametype) METHOD(Invasion, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "invasion_spawnpoint") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(Invasion, m_configuremenu, void(Gametype this, entity menu, void(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip) returns)) { diff --git a/qcsrc/common/gamemodes/gamemode/mayhem/mayhem.qh b/qcsrc/common/gamemodes/gamemode/mayhem/mayhem.qh index 930e3067b..68237e465 100644 --- a/qcsrc/common/gamemodes/gamemode/mayhem/mayhem.qh +++ b/qcsrc/common/gamemodes/gamemode/mayhem/mayhem.qh @@ -15,11 +15,11 @@ CLASS(mayhem, Gametype) } METHOD(mayhem, m_isForcedSupported, bool(Gametype this)) { - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.gametype_flags)) { return true; } - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH.gametype_flags)) { return true; } diff --git a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qh b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qh index be11699dd..845fb2ec1 100644 --- a/qcsrc/common/gamemodes/gamemode/nexball/nexball.qh +++ b/qcsrc/common/gamemodes/gamemode/nexball/nexball.qh @@ -13,7 +13,7 @@ CLASS(NexBall, Gametype) METHOD(NexBall, m_generate_mapinfo, void(Gametype this, string v)) { if(substring(v, 0, 8) == "nexball_" || substring(v, 0, 4) == "ball") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(NexBall, m_isTwoBaseMode, bool()) { diff --git a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qh b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qh index 3e7dece70..fc3938b92 100644 --- a/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qh +++ b/qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qh @@ -10,7 +10,7 @@ CLASS(Onslaught, Gametype) METHOD(Onslaught, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "onslaught_generator") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(Onslaught, m_configuremenu, void(Gametype this, entity menu, void(entity me, string pLabel, float pMin, float pMax, float pStep, string pCvar, string tCvar, string pTooltip) returns)) { diff --git a/qcsrc/common/gamemodes/gamemode/race/race.qh b/qcsrc/common/gamemodes/gamemode/race/race.qh index 2eed3433f..ddc11089c 100644 --- a/qcsrc/common/gamemodes/gamemode/race/race.qh +++ b/qcsrc/common/gamemodes/gamemode/race/race.qh @@ -26,7 +26,7 @@ CLASS(Race, Gametype) METHOD(Race, m_generate_mapinfo, void(Gametype this, string v)) { if(v == "trigger_race_checkpoint") - MapInfo_Map_supportedGametypes |= this.m_flags; + MapInfo_Map_supportedGametypes |= this.gametype_flags; } METHOD(Race, m_isTwoBaseMode, bool()) { diff --git a/qcsrc/common/gamemodes/gamemode/survival/survival.qh b/qcsrc/common/gamemodes/gamemode/survival/survival.qh index baddfb5c2..7c5d8c7c4 100644 --- a/qcsrc/common/gamemodes/gamemode/survival/survival.qh +++ b/qcsrc/common/gamemodes/gamemode/survival/survival.qh @@ -20,7 +20,7 @@ CLASS(Survival, Gametype) if(!cvar("g_survival_not_lms_maps")) { // if this is unset, all LMS maps support Survival too - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_LMS.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_LMS.gametype_flags)) return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported) } return false; diff --git a/qcsrc/common/gamemodes/gamemode/tdm/tdm.qh b/qcsrc/common/gamemodes/gamemode/tdm/tdm.qh index eeee581f4..ab7a16427 100644 --- a/qcsrc/common/gamemodes/gamemode/tdm/tdm.qh +++ b/qcsrc/common/gamemodes/gamemode/tdm/tdm.qh @@ -32,7 +32,7 @@ CLASS(TeamDeathmatch, Gametype) if(cvar("g_tdm_on_dm_maps")) { // if this is set, all DM maps support TDM too - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.gametype_flags)) return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported) } return false; diff --git a/qcsrc/common/gamemodes/gamemode/tka/tka.qh b/qcsrc/common/gamemodes/gamemode/tka/tka.qh index c6de0eefd..af9d60db3 100644 --- a/qcsrc/common/gamemodes/gamemode/tka/tka.qh +++ b/qcsrc/common/gamemodes/gamemode/tka/tka.qh @@ -36,13 +36,13 @@ CLASS(TeamKeepaway, Gametype) if(cvar("g_tka_on_ka_maps")) { // if this is set, all KA maps support TKA too - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_KEEPAWAY.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_KEEPAWAY.gametype_flags)) return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported) } if(cvar("g_tka_on_tdm_maps")) { // if this is set, all TDM maps support TKA too - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH.m_flags)) + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH.gametype_flags)) return true; // TODO: references another gametype (alternatively, we could check which gamemodes are always enabled and append this if any are supported) } return false; diff --git a/qcsrc/common/gamemodes/gamemode/tmayhem/tmayhem.qh b/qcsrc/common/gamemodes/gamemode/tmayhem/tmayhem.qh index 6e37f666f..5280e79fc 100644 --- a/qcsrc/common/gamemodes/gamemode/tmayhem/tmayhem.qh +++ b/qcsrc/common/gamemodes/gamemode/tmayhem/tmayhem.qh @@ -28,10 +28,10 @@ CLASS(tmayhem, Gametype) } METHOD(tmayhem, m_isForcedSupported, bool(Gametype this)) { - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.m_flags)){ + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_DEATHMATCH.gametype_flags)){ return true; } - if(!(MapInfo_Map_supportedGametypes & this.m_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH.m_flags)){ + if(!(MapInfo_Map_supportedGametypes & this.gametype_flags) && (MapInfo_Map_supportedGametypes & MAPINFO_TYPE_TEAM_DEATHMATCH.gametype_flags)){ return true; } return false; diff --git a/qcsrc/common/mapinfo.qc b/qcsrc/common/mapinfo.qc index 707c6826c..677a5f8f7 100644 --- a/qcsrc/common/mapinfo.qc +++ b/qcsrc/common/mapinfo.qc @@ -17,6 +17,23 @@ int autocvar_g_mapinfo_q3compat = 1; #define WARN_COND false #endif +vector _GametypeFlags_FromGametype(int a) +{ + if (REGISTRY_MAX(Gametypes) > 24) + if (a >= 24) + { + a -= 24; + if (REGISTRY_MAX(Gametypes) > 48) + if (a >= 24) + { + a -= 24; + return '0 0 1' * BIT(a); + } + return '0 1 0' * BIT(a); + } + return '1 0 0' * BIT(a); +} + // generic string stuff int _MapInfo_Cache_Active; @@ -71,7 +88,7 @@ void MapInfo_Cache_Store() bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_titlestring); bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_description); bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, MapInfo_Map_author); - bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedGametypes)); + bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, vtos(MapInfo_Map_supportedGametypes)); bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_supportedFeatures)); bufstr_set(_MapInfo_Cache_Buf_IndexToMapData, ++i, ftos(MapInfo_Map_flags)); } @@ -94,7 +111,7 @@ float MapInfo_Cache_Retrieve(string map) MapInfo_Map_titlestring = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i); MapInfo_Map_description = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i); MapInfo_Map_author = bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i); - MapInfo_Map_supportedGametypes = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i)); + MapInfo_Map_supportedGametypes = stov(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i)); MapInfo_Map_supportedFeatures = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i)); MapInfo_Map_flags = stof(bufstr_get(_MapInfo_Cache_Buf_IndexToMapData, ++i)); @@ -159,9 +176,9 @@ float _MapInfo_FilterList_cmp(float i, float j, entity pass) float MapInfo_FilterGametype(Gametype pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate) { - return _MapInfo_FilterGametype(pGametype.m_flags, pFeatures, pFlagsRequired, pFlagsForbidden, pAbortOnGenerate); + return _MapInfo_FilterGametype(pGametype.gametype_flags, pFeatures, pFlagsRequired, pFlagsForbidden, pAbortOnGenerate); } -float _MapInfo_FilterGametype(int pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate) +float _MapInfo_FilterGametype(vector pGametype, int pFeatures, int pFlagsRequired, int pFlagsForbidden, bool pAbortOnGenerate) { float i, j; if (!_MapInfo_filtered_allocated) @@ -179,7 +196,7 @@ float _MapInfo_FilterGametype(int pGametype, int pFeatures, int pFlagsRequired, MapInfo_progress = i / _MapInfo_globcount; return 0; } - if((MapInfo_Map_supportedGametypes & pGametype) != 0) + if(MapInfo_Map_supportedGametypes & pGametype) if((MapInfo_Map_supportedFeatures & pFeatures) == pFeatures) if((MapInfo_Map_flags & pFlagsForbidden) == 0) if((MapInfo_Map_flags & pFlagsRequired) == pFlagsRequired) @@ -397,27 +414,27 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp } diameter = vlen(mapMaxs - mapMins); - int twoBaseModes = 0; - FOREACH(Gametypes, it.m_isTwoBaseMode(), twoBaseModes |= it.m_flags); + vector twoBaseModes = '0 0 0'; + FOREACH(Gametypes, it.m_isTwoBaseMode(), twoBaseModes |= it.gametype_flags); if(twoBaseModes && (twoBaseModes &= MapInfo_Map_supportedGametypes)) { // we have a symmetrical map, don't add the modes without bases } else if(!is_q3df_map) { - FOREACH(Gametypes, it.m_isAlwaysSupported(it, spawnpoints, diameter), MapInfo_Map_supportedGametypes |= it.m_flags); + FOREACH(Gametypes, it.m_isAlwaysSupported(it, spawnpoints, diameter), MapInfo_Map_supportedGametypes |= it.gametype_flags); } - if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_RACE.m_flags) + if(MapInfo_Map_supportedGametypes & MAPINFO_TYPE_RACE.gametype_flags) if(!spawnplaces) { - MapInfo_Map_supportedGametypes &= ~MAPINFO_TYPE_RACE.m_flags; - MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTS.m_flags; + MapInfo_Map_supportedGametypes &= ~MAPINFO_TYPE_RACE.gametype_flags; + MapInfo_Map_supportedGametypes |= MAPINFO_TYPE_CTS.gametype_flags; } LOG_TRACE("-> diameter ", ftos(diameter)); LOG_TRACE("; spawnpoints ", ftos(spawnpoints)); - LOG_TRACE("; modes ", ftos(MapInfo_Map_supportedGametypes)); + LOG_TRACE("; modes ", vtos(MapInfo_Map_supportedGametypes)); fclose(fh); @@ -430,7 +447,7 @@ void _MapInfo_Map_Reset() MapInfo_Map_titlestring = ""; MapInfo_Map_description = "<DESCRIPTION>"; MapInfo_Map_author = "<AUTHOR>"; - MapInfo_Map_supportedGametypes = 0; + MapInfo_Map_supportedGametypes = '0 0 0'; MapInfo_Map_supportedFeatures = 0; MapInfo_Map_flags = 0; MapInfo_Map_clientstuff = ""; @@ -447,8 +464,8 @@ string _MapInfo_GetDefault(Gametype t) void _MapInfo_Map_ApplyGametype(string s, Gametype pWantedType, Gametype pThisType, int load_default) { string sa; - MapInfo_Map_supportedGametypes |= pThisType.m_flags; - if(!(pThisType.m_flags & pWantedType.m_flags)) + MapInfo_Map_supportedGametypes |= pThisType.gametype_flags; + if(!(pThisType.gametype_flags & pWantedType.gametype_flags)) return; if(load_default) @@ -526,8 +543,8 @@ float _MapInfo_GetTeamPlayBool(Gametype t) void _MapInfo_Map_ApplyGametypeEx(string s, Gametype pWantedType, Gametype pThisType) { - MapInfo_Map_supportedGametypes |= pThisType.m_flags; - if (!(pThisType.m_flags & pWantedType.m_flags)) + MapInfo_Map_supportedGametypes |= pThisType.gametype_flags; + if (!(pThisType.gametype_flags & pWantedType.gametype_flags)) return; // reset all the cvars to their defaults @@ -815,7 +832,7 @@ bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gamety string stored_Map_description = ""; string stored_Map_title = ""; string stored_Map_author = ""; - int stored_supportedGametypes = 0; + vector stored_supportedGametypes = '0 0 0'; int stored_supportedFeatures = 0; int stored_flags = 0; string t, s; @@ -862,7 +879,7 @@ bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gamety MapInfo_Map_supportedGametypes |= stored_supportedGametypes; else { - FOREACH(Gametypes, it.m_flags & stored_supportedGametypes, + FOREACH(Gametypes, it.gametype_flags & stored_supportedGametypes, { _MapInfo_Map_ApplyGametype ("", pGametypeToSet, it, true); }); @@ -877,7 +894,7 @@ bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gamety stored_Map_description = ""; stored_Map_title = ""; stored_Map_author = ""; - stored_supportedGametypes = 0; + stored_supportedGametypes = '0 0 0'; stored_supportedFeatures = 0; stored_flags = 0; continue; @@ -935,14 +952,14 @@ bool _MapInfo_ParseArena(string arena_filename, int fh, string pFilename, Gamety { Gametype f = MapInfo_Type_FromString(it, false, true); if(f) - stored_supportedGametypes |= f.m_flags; + stored_supportedGametypes |= f.gametype_flags; }); } else if(t == "style" && isdefi) { // we have a defrag map on our hands, add CTS! // TODO: styles - stored_supportedGametypes |= MAPINFO_TYPE_CTS.m_flags; + stored_supportedGametypes |= MAPINFO_TYPE_CTS.gametype_flags; } else if(t == "map") { @@ -1118,7 +1135,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet if(MapInfo_Map_flags & MAPINFO_FLAG_FRUSTRATING) fputs(fh, "frustrating\n"); - FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.m_flags, { + FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.gametype_flags, { fputs(fh, sprintf("gametype %s // defaults: %s\n", MapInfo_Type_ToString(it), _MapInfo_GetDefaultEx(it))); }); @@ -1266,7 +1283,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet Gametype f = NULL; if(all || (f = MapInfo_Type_FromString(t, true, false))) { - if((all ? MAPINFO_TYPE_ALL : f.m_flags) & pGametypeToSet.m_flags) + if((all ? MAPINFO_TYPE_ALL : f.gametype_flags) & pGametypeToSet.gametype_flags) { _MapInfo_Parse_Settemp(pFilename, acl, 0, s, 1); } @@ -1283,7 +1300,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet Gametype f = NULL; if(all || (f = MapInfo_Type_FromString(t, true, false))) { - if((all ? MAPINFO_TYPE_ALL : f.m_flags) & pGametypeToSet.m_flags) + if((all ? MAPINFO_TYPE_ALL : f.gametype_flags) & pGametypeToSet.gametype_flags) { _MapInfo_Parse_Settemp(pFilename, acl, 1, s, 1); } @@ -1359,7 +1376,7 @@ LABEL(mapinfo_handled) MapInfo_Map_author = ""; // don't display "<AUTHOR>" in the UI (we do write it to .mapinfo files) MapInfo_Cache_Store(); - if(MapInfo_Map_supportedGametypes != 0) + if(MapInfo_Map_supportedGametypes != '0 0 0') return r; if (WARN_COND) LOG_WARN("Map ", pFilename, " supports no game types, ignored"); @@ -1373,7 +1390,7 @@ int MapInfo_Get_ByName(string pFilename, float pAllowGenerate, Gametype pGametyp if(pGametypeToSet) { - if(!(MapInfo_Map_supportedGametypes & pGametypeToSet.m_flags)) + if(!(MapInfo_Map_supportedGametypes & pGametypeToSet.gametype_flags)) { error("Can't select the requested game type. This should never happen as the caller should prevent it!\n"); //_MapInfo_Map_ApplyGametypeEx("", pGametypeToSet, MAPINFO_TYPE_DEATHMATCH); @@ -1476,7 +1493,7 @@ float _MapInfo_CheckMap(string s, bool gametype_only) // returns 0 if the map ca { if(!MapInfo_Get_ByName(s, 1, NULL)) return 0; - if((MapInfo_Map_supportedGametypes & MapInfo_CurrentGametype().m_flags) == 0) + if(!(MapInfo_Map_supportedGametypes & MapInfo_CurrentGametype().gametype_flags)) return 0; if (gametype_only) return 1; @@ -1500,12 +1517,12 @@ void MapInfo_SwitchGameType(Gametype t) void MapInfo_LoadMap(string s, float reinit) { - MapInfo_Map_supportedGametypes = 0; + MapInfo_Map_supportedGametypes = '0 0 0'; // we shouldn't need this, as LoadMapSettings already fixes the gametype //if(!MapInfo_CheckMap(s)) //{ // print("EMERGENCY: can't play the selected map in the given game mode. Falling back to DM.\n"); - // MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH.m_flags); + // MapInfo_SwitchGameType(MAPINFO_TYPE_DEATHMATCH.gametype_flags); //} LOG_INFO("Switching to map ", s); @@ -1569,12 +1586,12 @@ void MapInfo_LoadMapSettings(string s) // to be called from worldspawn return; // do not call Get_ByName! } - if(MapInfo_Map_supportedGametypes == 0) + if(MapInfo_Map_supportedGametypes == '0 0 0') { RandomSelection_Init(); FOREACH(Gametypes, it.m_priority == 2, { - MapInfo_Map_supportedGametypes |= it.m_flags; + MapInfo_Map_supportedGametypes |= it.gametype_flags; RandomSelection_AddEnt(it, 1, 1); }); if(RandomSelection_chosen_ent) @@ -1597,7 +1614,7 @@ void MapInfo_LoadMapSettings(string s) // to be called from worldspawn #endif RandomSelection_Init(); Gametype t_prev = t; - FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.m_flags, + FOREACH(Gametypes, MapInfo_Map_supportedGametypes & it.gametype_flags, { RandomSelection_AddEnt(it, 1, it.m_priority); }); @@ -1622,7 +1639,7 @@ void MapInfo_ClearTemps() MapInfo_Map_description = string_null; MapInfo_Map_author = string_null; MapInfo_Map_clientstuff = string_null; - MapInfo_Map_supportedGametypes = 0; + MapInfo_Map_supportedGametypes = '0 0 0'; MapInfo_Map_supportedFeatures = 0; } diff --git a/qcsrc/common/mapinfo.qh b/qcsrc/common/mapinfo.qh index 4d65695ae..e1368871e 100644 --- a/qcsrc/common/mapinfo.qh +++ b/qcsrc/common/mapinfo.qh @@ -10,7 +10,7 @@ string MapInfo_Map_description; string MapInfo_Map_author; string MapInfo_Map_clientstuff; // not in cache, only for map load string MapInfo_Map_fog; // not in cache, only for map load -int MapInfo_Map_supportedGametypes; +vector MapInfo_Map_supportedGametypes; int MapInfo_Map_supportedFeatures; int MapInfo_Map_flags; vector MapInfo_Map_mins; // these are '0 0 0' if not supported! @@ -24,8 +24,11 @@ const int GAMETYPE_FLAG_HIDELIMITS = BIT(4); // don't display a score limit const int GAMETYPE_FLAG_WEAPONARENA = BIT(5); // gametype has a forced weapon arena, weapon arena mutators should disable themselves when this is set const int GAMETYPE_FLAG_1V1 = BIT(6); // 1v1 gameplay -int MAPINFO_TYPE_ALL; -.int m_flags; +vector MAPINFO_TYPE_ALL; +.vector gametype_flags; + +// must be defined before the registry +vector _GametypeFlags_FromGametype(int a); CLASS(Gametype, Object) ATTRIB(Gametype, m_id, int, 0); @@ -115,9 +118,6 @@ CLASS(Gametype, Object) this.m_hidelimits = (gflags & GAMETYPE_FLAG_HIDELIMITS); this.m_weaponarena = (gflags & GAMETYPE_FLAG_WEAPONARENA); this.m_1v1 = (gflags & GAMETYPE_FLAG_1V1); - - // same as `1 << m_id` - MAPINFO_TYPE_ALL |= this.items = this.m_flags = (MAPINFO_TYPE_ALL + 1); } ENDCLASS(Gametype) @@ -127,7 +127,15 @@ REGISTRY_SORT(Gametypes) REGISTRY_CHECK(Gametypes) REGISTRY_DEFINE_GET(Gametypes, NULL) -STATIC_INIT(Gametypes_renumber) { FOREACH(Gametypes, true, it.m_id = i); } +STATIC_INIT(Gametypes_renumber) +{ + FOREACH(Gametypes, true, + { + it.m_id = i; + vector set = it.gametype_flags = _GametypeFlags_FromGametype(it.m_id); + MAPINFO_TYPE_ALL |= set; + }); +} #define REGISTER_GAMETYPE(NAME, inst) REGISTER(Gametypes, MAPINFO_TYPE, NAME, m_id, inst) #ifndef CSQC @@ -154,7 +162,7 @@ void MapInfo_Enumerate(); // filter the info by game type mask (updates MapInfo_count) float MapInfo_progress; float MapInfo_FilterGametype(Gametype gametypeFlags, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator) -float _MapInfo_FilterGametype(int gametypeFlags, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator) +float _MapInfo_FilterGametype(vector gametypeFlags, float features, float pFlagsRequired, float pFlagsForbidden, float pAbortOnGenerate); // 1 on success, 0 on temporary failure (call it again next frame then; use MapInfo_progress as progress indicator) void MapInfo_FilterString(string sf); // filter _MapInfo_filtered (created by MapInfo_FilterGametype) with keyword int MapInfo_CurrentFeatures(); // retrieves currently required features from cvars Gametype MapInfo_CurrentGametype(); // retrieves current gametype from cvars diff --git a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc index d32bd0f84..80de0be27 100644 --- a/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc +++ b/qcsrc/menu/xonotic/dialog_multiplayer_create_mapinfo.qc @@ -33,7 +33,7 @@ void XonoticMapInfoDialog_loadMapInfo(entity me, int i, entity mlb) { entity e; e = me.(typeLabels[i]); - e.disabled = !(MapInfo_Map_supportedGametypes & GameType_GetID(i).m_flags); + e.disabled = !(MapInfo_Map_supportedGametypes & GameType_GetID(i).gametype_flags); } MapInfo_ClearTemps(); diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc index b9d19f611..72969a0ab 100644 --- a/qcsrc/server/mapvoting.qc +++ b/qcsrc/server/mapvoting.qc @@ -73,24 +73,25 @@ int GameTypeVote_AvailabilityStatus(string type_name) { if ( !MapInfo_Get_ByName(autocvar_nextmap, false, NULL) ) return flag; - if (!(MapInfo_Map_supportedGametypes & type.m_flags)) + if (!(MapInfo_Map_supportedGametypes & type.gametype_flags)) return flag; } return flag | GTV_AVAILABLE; } -int GameTypeVote_GetMask() +vector GameTypeVote_GetMask() { - int n, j, gametype_mask; + int n, j; + vector gametype_mask; n = tokenizebyseparator(autocvar_sv_vote_gametype_options, " "); n = min(MAPVOTE_COUNT, n); - gametype_mask = 0; + gametype_mask = '0 0 0'; for(j = 0; j < n; ++j) - gametype_mask |= GameTypeVote_Type_FromString(argv(j)).m_flags; + gametype_mask |= GameTypeVote_Type_FromString(argv(j)).gametype_flags; - if (gametype_mask == 0) - gametype_mask |= MapInfo_CurrentGametype().m_flags; + if (gametype_mask == '0 0 0') + gametype_mask |= MapInfo_CurrentGametype().gametype_flags; return gametype_mask; } -- 2.39.2