]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'Spike29/balance_council_vote19' into 'master'
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 10 Feb 2024 09:00:45 +0000 (09:00 +0000)
committerbones_was_here <bones_was_here@xonotic.au>
Sat, 10 Feb 2024 09:00:45 +0000 (09:00 +0000)
Apply the balance council vote 19

See merge request xonotic/xonotic-data.pk3dir!1260

qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/mapobjects/subs.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/intermission.qc
qcsrc/server/intermission.qh
qcsrc/server/mapvoting.qc
qcsrc/server/mapvoting.qh
qcsrc/server/world.qc
xonotic-server.cfg

index 82a7e758413de31ffd73eae094b93717c67fb678..e66ebb7671d4b85e9dc832d690d9e11e67392b44 100644 (file)
@@ -1167,14 +1167,14 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                {
                        MapInfo_Map_flags |= MAPINFO_FLAG_FRUSTRATING;
                }
-               else if(t == "noautomaplist")
+               else if(t == "donotwant" || t == "noautomaplist")
                {
-                       MapInfo_Map_flags |= MAPINFO_FLAG_NOAUTOMAPLIST;
+                       MapInfo_Map_flags |= MAPINFO_FLAG_DONOTWANT;
                }
                else if(t == "gameversion_min")
                {
                        if (cvar("gameversion") < stof(s))
-                               MapInfo_Map_flags |= MAPINFO_FLAG_NOAUTOMAPLIST;
+                               MapInfo_Map_flags |= MAPINFO_FLAG_DONOTWANT;
                }
                else if(t == "type")
                {
index b8eefcea3a6f163a6f365f65d0a6c4ef3535c603..4d65695ae41a9391d19b1f145440c1942bfc5e70 100644 (file)
@@ -143,7 +143,7 @@ const int MAPINFO_FEATURE_MONSTERS      = 8;
 const int MAPINFO_FLAG_HIDDEN           = 1; // not in lsmaps/menu/vcall/etc., can just be changed to manually
 const int MAPINFO_FLAG_FORBIDDEN        = 2; // don't even allow the map by a cvar setting that allows hidden maps
 const int MAPINFO_FLAG_FRUSTRATING      = 4; // this map is near impossible to play, enable at your own risk
-const int MAPINFO_FLAG_NOAUTOMAPLIST    = 8; // do not include when automatically building maplist (counts as hidden for maplist building purposes)
+const int MAPINFO_FLAG_DONOTWANT        = 8; // do not include in GUI voting screen or select in GotoNextMap()/GetNextMap(), unless added with `suggestmap` or required as a fallback
 
 float MapInfo_count;
 
index f89ab21e2f79ab1903dabc12c10da0cbcefac9ef..09ceba21f0bb4caee58bc093bfb1ea6a11b5e8a6 100644 (file)
@@ -298,6 +298,11 @@ void SUB_CalcMove (entity this, vector tdest, float tspeedtype, float tspeed, vo
                        break;
        }
 
+       // Q3 implements this fallback for all movers at the end of its InitMover()
+       // If .speed is negative this applies, instead of the mover-specific default speed.
+       if (traveltime <= 0)
+               traveltime = 0.001;
+
        // Very short animations don't really show off the effect
        // of controlled animation, so let's just use linear movement.
        // Alternatively entities can choose to specify non-controlled movement.
index f05edfcb5a670225986eb18ae6f679645d540c9b..3fdb1f968c5b75b96363643c1286837850d67ab4 100644 (file)
@@ -21,6 +21,7 @@
 #include <server/command/radarmap.qh>
 #include <server/intermission.qh>
 #include <server/ipban.qh>
+#include <server/mapvoting.qh>
 #include <server/mutators/_mod.qh>
 #include <server/player.qh>
 #include <server/scores_rules.qh>
@@ -774,30 +775,12 @@ void GameCommand_gametype(int request, int argc)
                        if (argv(1) != "")
                        {
                                string s = argv(1);
-                               Gametype t = MapInfo_Type_FromString(s, false, false), tsave = MapInfo_CurrentGametype();
+                               Gametype t = MapInfo_Type_FromString(s, false, false);
 
                                if (t)
-                               {
-                                       MapInfo_SwitchGameType(t);
-                                       MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
-                                       if (MapInfo_count > 0)
-                                       {
-                                               // update lsmaps in case the gametype changed, this way people can easily list maps for it
-                                               if (lsmaps_reply != "")   strunzone(lsmaps_reply);
-                                               lsmaps_reply = strzone(getlsmaps());
-                                               bprint("Game type successfully switched to ", s, "\n");
-                                       }
-                                       else
-                                       {
-                                               bprint("Cannot use this game type: no map for it found\n");
-                                               MapInfo_SwitchGameType(tsave);
-                                               MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
-                                       }
-                               }
+                                       GameTypeVote_SetGametype(t);
                                else
-                               {
                                        bprint("Failed to switch to ", s, ": this game type does not exist!\n");
-                               }
 
                                return;
                        }
index 9392c2399f3942aac3a2598568b4e7111be6971e..917eb8ce44b18901b3704e7226cf3bfaf99ea1dd 100644 (file)
@@ -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()
@@ -130,6 +129,9 @@ bool Map_Check(int position, float pass)
        {
                if(pass == 2)
                        return true;
+               // MapInfo_Map_flags was set by MapInfo_CheckMap()
+               if (MapInfo_Map_flags & MAPINFO_FLAG_DONOTWANT)
+                       return false;
                if(MapHasRightSize(map_next))
                        return true;
                return false;
@@ -150,8 +152,9 @@ void Map_Goto_SetStr(string nextmapname)
                getmapname_stored = strzone(nextmapname);
 }
 
-void Map_Goto_SetFloat(float position)
+void Map_Goto_SetIndex(int position)
 {
+       Map_Current = position;
        cvar_set("g_maplist_index", ftos(position));
        Map_Goto_SetStr(argv(position));
 }
@@ -164,9 +167,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");
 
@@ -174,7 +177,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;
@@ -183,7 +186,7 @@ float MaplistMethod_Iterate() // usual method
        return -1;
 }
 
-float MaplistMethod_Repeat() // fallback method
+int MaplistMethod_Repeat(void) // fallback method
 {
        LOG_TRACE("Trying MaplistMethod_Repeat");
 
@@ -192,9 +195,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");
 
@@ -202,7 +205,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;
@@ -212,7 +215,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;
 
@@ -252,57 +255,57 @@ float MaplistMethod_Shuffle(float exponent) // more clever shuffling
                Map_Count = tokenizebyseparator(autocvar_g_maplist, " ");
 
                // NOTE: the selected map has just been inserted at (insertpos-1)th position
-               Map_Current = insertpos - 1; // this is not really valid, but this way the fallback has a chance of working
-               if(Map_Check(Map_Current, 1))
-                       return Map_Current;
+               if (Map_Check(insertpos - 1, 1))
+                       return insertpos - 1;
        }
        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() | MAPINFO_FLAG_NOAUTOMAPLIST));
-               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();
@@ -312,7 +315,7 @@ string GetNextMap()
 
        if(nextMap >= 0)
        {
-               Map_Goto_SetFloat(nextMap);
+               Map_Goto_SetIndex(nextMap);
                return getmapname_stored;
        }
 
@@ -389,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);
index e3504829b57cdb27b11049c590432b336a240dbe..67413147c18bc3e231e57619dced90864cc1521e 100644 (file)
@@ -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);
 
index 051968eb00c488cbef6ebc9d53f2dcca818a9fca..5ac9b0472f7bc9844cf5eb5cd4e99672c5714461 100644 (file)
@@ -12,7 +12,6 @@
 #include <server/command/cmd.qh>
 #include <server/command/getreplies.qh>
 #include <server/gamelog.qh>
-#include <server/intermission.qh>
 #include <server/world.qh>
 
 // 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);
@@ -772,11 +752,7 @@ bool GameTypeVote_SetGametype(Gametype type)
                return false;
        }
 
-       //localcmd("gametype ", MapInfo_Type_ToString(type), "\n");
-
        cvar_set("g_maplist", MapInfo_ListAllowedMaps(type, MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags()) );
-       if(autocvar_g_maplist_shuffle)
-               ShuffleMaplist();
 
        return true;
 }
index ed8ef6ca1e206f85a9c0648045098b3b0ad74d53..c33dd5242f9614d515bfa71b8b287a262ae25164 100644 (file)
@@ -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);
index 6e79c73ef1c014d1de388729a8de6f15fdbffd1f..04706f615444d6dd93799473a4ef066b94b30c15 100644 (file)
@@ -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);
index 254e44be10e50ce22f959b3282085ce0489f6786..e38ce52f96db5f5b4ec87751a8998337a0895198 100644 (file)
@@ -226,7 +226,7 @@ set g_maplist_mostrecent "" "contains the name of the maps that were most recent
 set g_maplist_mostrecent_count 3 "number of most recent maps that are blocked from being played again"
 set g_maplist_index 0 "this is used internally for saving position in maplist cycle"
 set g_maplist_selectrandom 0 "if 1, a random map will be chosen as next map - DEPRECATED in favor of g_maplist_shuffle"
-set g_maplist_shuffle 1 "new randomization method: like selectrandom, but avoid playing the same maps in short succession. This works by taking out the first element and inserting it into g_maplist with a bias to the end of the list"
+set g_maplist_shuffle 1 "1: shuffling method which avoids playing the same maps in short succession by taking out the first element and inserting it into g_maplist with a bias to the end of the list. -1: a simpler shuffling method which should be adequate if g_maplist_mostrecent_count is large enough."
 set g_maplist_check_waypoints 0 "when 1, maps are skipped if there currently are bots, but the map has no waypoints"
 set g_maplist_ignore_sizes 0 "when 1, all maps are shown in the map list regardless of player count"
 set g_maplist_sizes_count_maxplayers 1 "check the player limit when getting the player count so forced spectators don't affect the size restrictions"