Add delaystart and forcepreset commands (#1163)
* Add extendroundstart message to extend lobby start timer * Rename StartExtend to DelayStart * Fix delaystart amounts above 59 not working * Change delaystart seconds type from int to uint * Change delaystart wrong args amount message * Add forcegamepreset command * Rename forcegamepreset to forcepreset and merged start and forcestart preset methods * Fix index out of bounds exception when forcing suspicion to start * Change game preset to match regardless of casing * Add forcepreset unknown preset message * Add and move in lobby checks * Remove testing changes * Change delaystart to pause/resume the timer when no seconds are specified * Change pause message * Remove testing code * Change 0 seconds to not be a valid amount of seconds * Replace MsgTickerLobbyCountdown Seconds with DateTime instead of uint * Add one entire dot * Replace Math.Min + Math.Max with Math.Clamp Co-authored-by: ComicIronic <comicironic@gmail.com> Co-authored-by: ComicIronic <comicironic@gmail.com>
This commit is contained in:
@@ -81,6 +81,7 @@ namespace Content.Server.GameTicking
|
||||
|
||||
[ViewVariables] private Type _presetType;
|
||||
|
||||
[ViewVariables] private DateTime _pauseTime;
|
||||
[ViewVariables] private bool _roundStartCountdownHasNotStartedYetDueToNoPlayers;
|
||||
private DateTime _roundStartTimeUtc;
|
||||
[ViewVariables] private GameRunLevel _runLevel;
|
||||
@@ -92,6 +93,8 @@ namespace Content.Server.GameTicking
|
||||
private CancellationTokenSource _updateShutdownCts;
|
||||
|
||||
|
||||
[ViewVariables] public bool Paused { get; private set; }
|
||||
|
||||
[ViewVariables]
|
||||
public GameRunLevel RunLevel
|
||||
{
|
||||
@@ -128,6 +131,7 @@ namespace Content.Server.GameTicking
|
||||
_netManager.RegisterNetMessage<MsgTickerJoinGame>(nameof(MsgTickerJoinGame));
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyStatus>(nameof(MsgTickerLobbyStatus));
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyInfo>(nameof(MsgTickerLobbyInfo));
|
||||
_netManager.RegisterNetMessage<MsgTickerLobbyCountdown>(nameof(MsgTickerLobbyCountdown));
|
||||
_netManager.RegisterNetMessage<MsgRoundEndMessage>(nameof(MsgRoundEndMessage));
|
||||
|
||||
SetStartPreset(_configurationManager.GetCVar<string>("game.defaultpreset"));
|
||||
@@ -156,9 +160,13 @@ namespace Content.Server.GameTicking
|
||||
RoundLengthMetric.Inc(frameEventArgs.DeltaSeconds);
|
||||
}
|
||||
|
||||
if (RunLevel != GameRunLevel.PreRoundLobby || _roundStartTimeUtc > DateTime.UtcNow ||
|
||||
if (RunLevel != GameRunLevel.PreRoundLobby ||
|
||||
Paused ||
|
||||
_roundStartTimeUtc > DateTime.UtcNow ||
|
||||
_roundStartCountdownHasNotStartedYetDueToNoPlayers)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StartRound();
|
||||
}
|
||||
@@ -197,7 +205,7 @@ namespace Content.Server.GameTicking
|
||||
}
|
||||
}
|
||||
|
||||
public void StartRound()
|
||||
public void StartRound(bool force = false)
|
||||
{
|
||||
DebugTools.Assert(RunLevel == GameRunLevel.PreRoundLobby);
|
||||
Logger.InfoS("ticker", "Starting round!");
|
||||
@@ -247,13 +255,15 @@ namespace Content.Server.GameTicking
|
||||
// Time to start the preset.
|
||||
var preset = MakeGamePreset();
|
||||
|
||||
if (!preset.Start(assignedJobs.Keys.ToList()))
|
||||
if (!preset.Start(assignedJobs.Keys.ToList(), force))
|
||||
{
|
||||
SetStartPreset(_configurationManager.GetCVar<string>("game.fallbackpreset"));
|
||||
var newPreset = MakeGamePreset();
|
||||
_chatManager.DispatchServerAnnouncement($"Failed to start {preset.ModeTitle} mode! Defaulting to {newPreset.ModeTitle}...");
|
||||
if(!newPreset.Start(readyPlayers))
|
||||
if (!newPreset.Start(readyPlayers, force))
|
||||
{
|
||||
throw new ApplicationException("Fallback preset failed to start!");
|
||||
}
|
||||
}
|
||||
|
||||
_roundStartTimeSpan = IoCManager.Resolve<IGameTiming>().RealTime;
|
||||
@@ -297,7 +307,7 @@ namespace Content.Server.GameTicking
|
||||
{
|
||||
PlayerOOCName = ply.Name,
|
||||
PlayerICName = mind.CurrentEntity.Name,
|
||||
Role = antag ? mind.AllRoles.First(role => role.Antag).Name : mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unkown"),
|
||||
Role = antag ? mind.AllRoles.First(role => role.Antag).Name : mind.AllRoles.FirstOrDefault()?.Name ?? Loc.GetString("Unknown"),
|
||||
Antag = antag
|
||||
};
|
||||
listOfPlayerInfo.Add(playerEndRoundInfo);
|
||||
@@ -377,22 +387,90 @@ namespace Content.Server.GameTicking
|
||||
|
||||
public IEnumerable<GameRule> ActiveGameRules => _gameRules;
|
||||
|
||||
public void SetStartPreset(Type type)
|
||||
public bool TryGetPreset(string name, out Type type)
|
||||
{
|
||||
type = name.ToLower() switch
|
||||
{
|
||||
"sandbox" => typeof(PresetSandbox),
|
||||
"deathmatch" => typeof(PresetDeathMatch),
|
||||
"suspicion" => typeof(PresetSuspicion),
|
||||
_ => default
|
||||
};
|
||||
|
||||
return type != default;
|
||||
}
|
||||
|
||||
public void SetStartPreset(Type type, bool force = false)
|
||||
{
|
||||
if (!typeof(GamePreset).IsAssignableFrom(type)) throw new ArgumentException("type must inherit GamePreset");
|
||||
|
||||
_presetType = type;
|
||||
UpdateInfoText();
|
||||
|
||||
if (force)
|
||||
{
|
||||
StartRound(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStartPreset(string type) =>
|
||||
SetStartPreset(type switch
|
||||
public void SetStartPreset(string name, bool force = false)
|
||||
{
|
||||
if (!TryGetPreset(name, out var type))
|
||||
{
|
||||
"Sandbox" => typeof(PresetSandbox),
|
||||
"DeathMatch" => typeof(PresetDeathMatch),
|
||||
"Suspicion" => typeof(PresetSuspicion),
|
||||
_ => throw new NotSupportedException()
|
||||
});
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
SetStartPreset(type, force);
|
||||
}
|
||||
|
||||
public bool DelayStart(TimeSpan time)
|
||||
{
|
||||
if (_runLevel != GameRunLevel.PreRoundLobby)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_roundStartTimeUtc += time;
|
||||
|
||||
var lobbyCountdownMessage = _netManager.CreateNetMessage<MsgTickerLobbyCountdown>();
|
||||
lobbyCountdownMessage.StartTime = _roundStartTimeUtc;
|
||||
lobbyCountdownMessage.Paused = Paused;
|
||||
_netManager.ServerSendToAll(lobbyCountdownMessage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool PauseStart(bool pause = true)
|
||||
{
|
||||
if (Paused == pause)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Paused = pause;
|
||||
|
||||
if (pause)
|
||||
{
|
||||
_pauseTime = DateTime.UtcNow;
|
||||
}
|
||||
else if (_pauseTime != default)
|
||||
{
|
||||
_roundStartTimeUtc += DateTime.UtcNow - _pauseTime;
|
||||
}
|
||||
|
||||
var lobbyCountdownMessage = _netManager.CreateNetMessage<MsgTickerLobbyCountdown>();
|
||||
lobbyCountdownMessage.StartTime = _roundStartTimeUtc;
|
||||
lobbyCountdownMessage.Paused = Paused;
|
||||
_netManager.ServerSendToAll(lobbyCountdownMessage);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TogglePause()
|
||||
{
|
||||
PauseStart(!Paused);
|
||||
return Paused;
|
||||
}
|
||||
|
||||
private IEntity _spawnPlayerMob(Job job, bool lateJoin = true)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user