From 01d975ef584acf1cfd3ecc739955ee10f916c75c Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Tue, 24 Oct 2023 07:25:32 +1000 Subject: [PATCH] g_maplist: refactor initialisation Reduces code duplication. Checks/initialises once when adding maps to the voting screen, instead of doing it again for each map added. Always uses gametype-specific g_maplist generation, instead of sometimes including maps from other gametypes (depending which code path was used). Updates some declarations and removes an unused global. --- qcsrc/server/command/sv_cmd.qc | 1 + qcsrc/server/intermission.qc | 72 ++++++++++++++++------------------ qcsrc/server/intermission.qh | 5 +-- qcsrc/server/mapvoting.qc | 24 +----------- qcsrc/server/mapvoting.qh | 1 + qcsrc/server/world.qc | 7 +--- 6 files changed, 40 insertions(+), 70 deletions(-) diff --git a/qcsrc/server/command/sv_cmd.qc b/qcsrc/server/command/sv_cmd.qc index 8cd6125ab..3fdb1f968 100644 --- a/qcsrc/server/command/sv_cmd.qc +++ b/qcsrc/server/command/sv_cmd.qc @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/qcsrc/server/intermission.qc b/qcsrc/server/intermission.qc index 31b0559c7..f2e9cc53a 100644 --- a/qcsrc/server/intermission.qc +++ b/qcsrc/server/intermission.qc @@ -20,8 +20,7 @@ string GetMapname() return mapname; } -float Map_Count, Map_Current; -string Map_Current_Name; +int Map_Count, Map_Current; // NOTE: this now expects the map list to be already tokenized and the count in Map_Count int GetMaplistPosition() @@ -153,7 +152,7 @@ void Map_Goto_SetStr(string nextmapname) getmapname_stored = strzone(nextmapname); } -void Map_Goto_SetFloat(float position) +void Map_Goto_SetIndex(int position) { cvar_set("g_maplist_index", ftos(position)); Map_Goto_SetStr(argv(position)); @@ -167,9 +166,9 @@ void Map_Goto(float reinit) // return codes of map selectors: // -1 = temporary failure (that is, try some method that is guaranteed to succeed) // -2 = permanent failure -float MaplistMethod_Iterate() // usual method +int MaplistMethod_Iterate(void) // usual method { - float pass, i; + int pass, i; LOG_TRACE("Trying MaplistMethod_Iterate"); @@ -177,7 +176,7 @@ float MaplistMethod_Iterate() // usual method { for(i = 1; i < Map_Count; ++i) { - float mapindex; + int mapindex; mapindex = (i + Map_Current) % Map_Count; if(Map_Check(mapindex, pass)) return mapindex; @@ -186,7 +185,7 @@ float MaplistMethod_Iterate() // usual method return -1; } -float MaplistMethod_Repeat() // fallback method +int MaplistMethod_Repeat(void) // fallback method { LOG_TRACE("Trying MaplistMethod_Repeat"); @@ -195,9 +194,9 @@ float MaplistMethod_Repeat() // fallback method return -2; } -float MaplistMethod_Random() // random map selection +int MaplistMethod_Random(void) // random map selection { - float i, imax; + int i, imax; LOG_TRACE("Trying MaplistMethod_Random"); @@ -205,7 +204,7 @@ float MaplistMethod_Random() // random map selection for(i = 0; i <= imax; ++i) { - float mapindex; + int mapindex; mapindex = (Map_Current + floor(random() * (Map_Count - 1) + 1)) % Map_Count; // any OTHER map if(Map_Check(mapindex, 1)) return mapindex; @@ -215,7 +214,7 @@ float MaplistMethod_Random() // random map selection // the exponent sets a bias on the map selection: // the higher the exponent, the less likely "shortly repeated" same maps are -float MaplistMethod_Shuffle(float exponent) // more clever shuffling +int MaplistMethod_Shuffle(float exponent) // more clever shuffling { float i, j, imax, insertpos; @@ -262,50 +261,51 @@ float MaplistMethod_Shuffle(float exponent) // more clever shuffling return -1; } -void Maplist_Init() +int Maplist_Init(void) { - float i = Map_Count = 0; + int i, available_maps = 0; + Map_Count = 0; if(autocvar_g_maplist != "") { Map_Count = tokenizebyseparator(autocvar_g_maplist, " "); for (i = 0; i < Map_Count; ++i) - { if (Map_Check(i, 2)) - break; - } + ++available_maps; } - if (i == Map_Count) + if (!available_maps) { bprint( "Maplist contains no usable maps! Resetting it to default map list.\n" ); - cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags())); - if(autocvar_g_maplist_shuffle) - ShuffleMaplist(); + cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_CurrentGametype(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags())); if(!server_is_dedicated) localcmd("\nmenu_cmd sync\n"); Map_Count = tokenizebyseparator(autocvar_g_maplist, " "); + for (i = 0; i < Map_Count; ++i) + if (Map_Check(i, 2)) + ++available_maps; } + if(Map_Count == 0) error("empty maplist, cannot select a new map"); + Map_Current = bound(0, GetMaplistPosition(), Map_Count - 1); - strcpy(Map_Current_Name, argv(Map_Current)); // will be automatically freed on exit thanks to DP - // this may or may not be correct, but who cares, in the worst case a map - // isn't chosen in the first pass that should have been + if(autocvar_g_maplist_shuffle) + cvar_set("g_maplist", shufflewords(autocvar_g_maplist)); + + return available_maps; } -string GetNextMap() +// NOTE: call Maplist_Init() before making GetNextMap() call(s) +string GetNextMap(void) { - Maplist_Init(); - float nextMap = -1; + int nextMap = -1; - if(nextMap == -1) - if(autocvar_g_maplist_shuffle > 0) - nextMap = MaplistMethod_Shuffle(autocvar_g_maplist_shuffle + 1); + if(nextMap == -1 && autocvar_g_maplist_shuffle > 0) + nextMap = MaplistMethod_Shuffle(autocvar_g_maplist_shuffle + 1); - if(nextMap == -1) - if(autocvar_g_maplist_selectrandom) - nextMap = MaplistMethod_Random(); + if(nextMap == -1 && autocvar_g_maplist_selectrandom) + nextMap = MaplistMethod_Random(); if(nextMap == -1) nextMap = MaplistMethod_Iterate(); @@ -315,7 +315,7 @@ string GetNextMap() if(nextMap >= 0) { - Map_Goto_SetFloat(nextMap); + Map_Goto_SetIndex(nextMap); return getmapname_stored; } @@ -392,17 +392,13 @@ void GotoNextMap(float reinit) return; alreadychangedlevel = true; + Maplist_Init(); string nextMap = GetNextMap(); if(nextMap == "") error("Everything is broken - cannot find a next map. Please report this to the developers."); Map_Goto(reinit); } -void ShuffleMaplist() -{ - cvar_set("g_maplist", shufflewords(autocvar_g_maplist)); -} - string GotoMap(string m) { m = GameTypeVote_MapInfo_FixName(m); diff --git a/qcsrc/server/intermission.qh b/qcsrc/server/intermission.qh index e3504829b..67413147c 100644 --- a/qcsrc/server/intermission.qh +++ b/qcsrc/server/intermission.qh @@ -24,9 +24,8 @@ bool Map_IsRecent(string m); bool Map_Check(int position, float pass); -string GetNextMap(); - -void ShuffleMaplist(); +int Maplist_Init(void); +string GetNextMap(void); void Map_Goto_SetStr(string nextmapname); diff --git a/qcsrc/server/mapvoting.qc b/qcsrc/server/mapvoting.qc index c3ddeeea3..5ac9b0472 100644 --- a/qcsrc/server/mapvoting.qc +++ b/qcsrc/server/mapvoting.qc @@ -12,7 +12,6 @@ #include #include #include -#include #include // definitions @@ -203,16 +202,7 @@ void MapVote_AddVotable(string nextMap, bool isSuggestion) void MapVote_AddVotableMaps(int nmax, int smax) { - int available_maps = 0; - if (autocvar_g_maplist != "") - { - int c = tokenizebyseparator(autocvar_g_maplist, " "); - for (int i = 0; i < c; ++i) - { - if (Map_Check(i, 1) || Map_Check(i, 2)) - ++available_maps; - } - } + int available_maps = Maplist_Init(); int max_attempts = available_maps; if (available_maps >= 2) max_attempts = min(available_maps * 5, 100); @@ -252,16 +242,6 @@ void MapVote_Init() MapVote_AddVotableMaps(nmax, smax); - if(mapvote_count == 0) - { - bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" ); - cvar_set("g_maplist", MapInfo_ListAllowedMaps(MapInfo_CurrentGametype(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags())); - if(autocvar_g_maplist_shuffle) - ShuffleMaplist(); - localcmd("\nmenu_cmd sync\n"); - MapVote_AddVotableMaps(nmax, 0); - } - mapvote_count_real = mapvote_count; if(mapvote_abstain) MapVote_AddVotable("don't care", false); @@ -773,8 +753,6 @@ bool GameTypeVote_SetGametype(Gametype type) } cvar_set("g_maplist", MapInfo_ListAllowedMaps(type, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()) ); - if(autocvar_g_maplist_shuffle) - ShuffleMaplist(); return true; } diff --git a/qcsrc/server/mapvoting.qh b/qcsrc/server/mapvoting.qh index ed8ef6ca1..c33dd5242 100644 --- a/qcsrc/server/mapvoting.qh +++ b/qcsrc/server/mapvoting.qh @@ -30,6 +30,7 @@ void MapVote_Start(); void MapVote_Spawn(); void MapVote_Think(); void MapVote_SendPicture(entity to, int id); +bool GameTypeVote_SetGametype(entity type); float GameTypeVote_Start(); float GameTypeVote_Finished(float pos); string GameTypeVote_MapInfo_FixName(string m); diff --git a/qcsrc/server/world.qc b/qcsrc/server/world.qc index 6e79c73ef..04706f615 100644 --- a/qcsrc/server/world.qc +++ b/qcsrc/server/world.qc @@ -118,12 +118,7 @@ void GotoFirstMap(entity this) { // cvar_set("_sv_init", "0"); // we do NOT set this to 0 any more, so someone "accidentally" changing - // to this "init" map on a dedicated server will cause no permanent - // harm - if(autocvar_g_maplist_shuffle) - ShuffleMaplist(); - n = tokenizebyseparator(autocvar_g_maplist, " "); - cvar_set("g_maplist_index", ftos(n - 1)); // jump to map 0 in GotoNextMap + // to this "init" map on a dedicated server will cause no permanent harm MapInfo_Enumerate(); MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); -- 2.39.2