Adds support for a map rotation system. (#7162)

* Adds support for a map rotation system.
It is now the default way of selecting a map, map votes have been disabled.

* whoops

* Randomize the map it starts off with, too.
(it'd pick bagel every time otherwise)

* Address review

* remove knight from rotation due to it being an unmaintained map.

* minor cleanup
This commit is contained in:
Moony
2022-03-17 13:59:53 -05:00
committed by GitHub
parent afc0e3708e
commit 3721b3303b
5 changed files with 84 additions and 8 deletions

View File

@@ -22,8 +22,11 @@ public sealed class GameMapManager : IGameMapManager
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
private readonly Queue<string> _previousMaps = new Queue<string>();
private GameMapPrototype _currentMap = default!;
private bool _currentMapForced;
private bool _mapRotationEnabled;
private int _mapQueueDepth = 1;
public void Initialize()
{
@@ -35,6 +38,25 @@ public sealed class GameMapManager : IGameMapManager
throw new ArgumentException($"Unknown map prototype {value} was selected!");
}, true);
_configurationManager.OnValueChanged(CCVars.GameMapForced, value => _currentMapForced = value, true);
_configurationManager.OnValueChanged(CCVars.GameMapRotation, value => _mapRotationEnabled = value, true);
_configurationManager.OnValueChanged(CCVars.GameMapMemoryDepth, value =>
{
_mapQueueDepth = value;
// Drain excess.
while (_previousMaps.Count > _mapQueueDepth)
{
_previousMaps.Dequeue();
}
}, true);
var maps = AllVotableMaps().ToArray();
_random.Shuffle(maps);
foreach (var map in maps)
{
if (_previousMaps.Count >= _mapQueueDepth)
break;
_previousMaps.Enqueue(map.ID);
}
}
public IEnumerable<GameMapPrototype> CurrentlyEligibleMaps()
@@ -75,17 +97,18 @@ public sealed class GameMapManager : IGameMapManager
public void SelectRandomMap()
{
var maps = CurrentlyEligibleMaps().ToList();
_random.Shuffle(maps);
_currentMap = maps[0];
_currentMap = _random.Pick(maps);
_currentMapForced = false;
}
public GameMapPrototype GetSelectedMap()
{
return _currentMap;
if (!_mapRotationEnabled || _currentMapForced)
return _currentMap;
return SelectMapInQueue() ?? CurrentlyEligibleMaps().First();
}
public GameMapPrototype GetSelectedMapChecked(bool loud = false)
public GameMapPrototype GetSelectedMapChecked(bool loud = false, bool markAsPlayed = false)
{
if (!_currentMapForced && !IsMapEligible(GetSelectedMap()))
{
@@ -100,7 +123,11 @@ public sealed class GameMapManager : IGameMapManager
}
}
return GetSelectedMap();
var map = GetSelectedMap();
if (markAsPlayed)
_previousMaps.Enqueue(map.ID);
return map;
}
public bool CheckMapExists(string gameMap)
@@ -127,4 +154,39 @@ public sealed class GameMapManager : IGameMapManager
else
return gameMap.MapName;
}
public int GetMapQueuePriority(string gameMapProtoName)
{
var i = 0;
foreach (var map in _previousMaps.Reverse())
{
if (map == gameMapProtoName)
return i;
i++;
}
return _mapQueueDepth;
}
public GameMapPrototype? SelectMapInQueue()
{
var eligible = CurrentlyEligibleMaps()
.Where(x => x.Votable)
.Select(x => (proto: x, weight: GetMapQueuePriority(x.ID)))
.OrderByDescending(x => x.weight).ToArray();
if (eligible.Length is 0)
return null;
var weight = eligible[0].weight;
return eligible.Where(x => x.Item2 == weight).OrderBy(x => x.proto.ID).First().proto;
}
private void EnqueueMap(string mapProtoName)
{
_previousMaps.Enqueue(mapProtoName);
while (_previousMaps.Count > _mapQueueDepth)
{
_previousMaps.Dequeue();
}
}
}