using System.Threading; using Content.Server.Chat.Managers; using Content.Server.GameTicking.Rules.Components; using Timer = Robust.Shared.Timing.Timer; namespace Content.Server.GameTicking.Rules; public sealed class MaxTimeRestartRuleSystem : GameRuleSystem { [Dependency] private readonly IChatManager _chatManager = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(RunLevelChanged); } protected override void Started(EntityUid uid, MaxTimeRestartRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args) { base.Started(uid, component, gameRule, args); if(GameTicker.RunLevel == GameRunLevel.InRound) RestartTimer(component); } protected override void Ended(EntityUid uid, MaxTimeRestartRuleComponent component, GameRuleComponent gameRule, GameRuleEndedEvent args) { base.Ended(uid, component, gameRule, args); StopTimer(component); } public void RestartTimer(MaxTimeRestartRuleComponent component) { // TODO FULL GAME SAVE component.TimerCancel.Cancel(); component.TimerCancel = new CancellationTokenSource(); Timer.Spawn(component.RoundMaxTime, () => TimerFired(component), component.TimerCancel.Token); } public void StopTimer(MaxTimeRestartRuleComponent component) { component.TimerCancel.Cancel(); } private void TimerFired(MaxTimeRestartRuleComponent component) { GameTicker.EndRound(Loc.GetString("rule-time-has-run-out")); _chatManager.DispatchServerAnnouncement(Loc.GetString("rule-restarting-in-seconds",("seconds", (int) component.RoundEndDelay.TotalSeconds))); // TODO FULL GAME SAVE Timer.Spawn(component.RoundEndDelay, () => GameTicker.RestartRound()); } private void RunLevelChanged(GameRunLevelChangedEvent args) { var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var timer, out var gameRule)) { if (!GameTicker.IsGameRuleActive(uid, gameRule)) return; switch (args.New) { case GameRunLevel.InRound: RestartTimer(timer); break; case GameRunLevel.PreRoundLobby: case GameRunLevel.PostRound: StopTimer(timer); break; } } } }