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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user