Add automatic emergency shuttle call (#12473)

* Add automatic emergency shuttle call

This adds a cvar shuttle.auto_call_time which is an integer N, that
calls the emergency shuttle automatically without intervention after N
minutes. This can be disabled by setting N to 0.

After a vote to extend, the shuttle will be called automatically every
shuttle.auto_call_extension_time minutes.

* Update Resources/Locale/en-US/round-end/round-end-system.ftl

Co-authored-by: theashtronaut <112137107+theashtronaut@users.noreply.github.com>

Co-authored-by: Moony <moony@hellomouse.net>
Co-authored-by: theashtronaut <112137107+theashtronaut@users.noreply.github.com>
This commit is contained in:
Kevin Zheng
2022-11-09 20:20:36 -08:00
committed by GitHub
parent f2363b4bab
commit 5ba034ad36
3 changed files with 69 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
using System.Threading;
using Content.Server.Administration.Logs;
using Content.Server.AlertLevel;
using Content.Shared.CCVar;
using Content.Server.Chat;
using Content.Server.Chat.Managers;
using Content.Server.Chat.Systems;
@@ -10,6 +11,7 @@ using Content.Server.Station.Systems;
using Content.Shared.Database;
using Content.Shared.GameTicking;
using Robust.Shared.Audio;
using Robust.Shared.Configuration;
using Robust.Shared.Player;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
@@ -24,6 +26,7 @@ namespace Content.Server.RoundEnd
public sealed class RoundEndSystem : EntitySystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IPrototypeManager _protoManager = default!;
@@ -47,10 +50,19 @@ namespace Content.Server.RoundEnd
public TimeSpan? ExpectedShuttleLength => ExpectedCountdownEnd - LastCountdownStart;
public TimeSpan? ShuttleTimeLeft => ExpectedCountdownEnd - _gameTiming.CurTime;
public TimeSpan AutoCallStartTime;
private bool AutoCalledBefore = false;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundRestartCleanupEvent>(_ => Reset());
SetAutoCallTime();
}
private void SetAutoCallTime()
{
AutoCallStartTime = _gameTiming.CurTime;
}
private void Reset()
@@ -69,6 +81,8 @@ namespace Content.Server.RoundEnd
LastCountdownStart = null;
ExpectedCountdownEnd = null;
SetAutoCallTime();
AutoCalledBefore = false;
RaiseLocalEvent(RoundEndSystemChangedEvent.Default);
}
@@ -77,7 +91,7 @@ namespace Content.Server.RoundEnd
return _cooldownTokenSource == null;
}
public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true)
public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, bool autoCall = false)
{
var duration = DefaultCountdownDuration;
@@ -92,10 +106,10 @@ namespace Content.Server.RoundEnd
}
}
RequestRoundEnd(duration, requester, checkCooldown);
RequestRoundEnd(duration, requester, checkCooldown, autoCall);
}
public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true)
public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, bool autoCall = false)
{
if (_gameTicker.RunLevel != GameRunLevel.InRound) return;
@@ -128,13 +142,26 @@ namespace Content.Server.RoundEnd
units = "eta-units-minutes";
}
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString("round-end-system-shuttle-called-announcement",
("time", time),
("units", Loc.GetString(units))),
Loc.GetString("Station"),
false,
null,
Color.Gold);
if (autoCall)
{
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString("round-end-system-shuttle-auto-called-announcement",
("time", time),
("units", Loc.GetString(units))),
Loc.GetString("Station"),
false,
null,
Color.Gold);
}
else
{
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString("round-end-system-shuttle-called-announcement",
("time", time),
("units", Loc.GetString(units))),
Loc.GetString("Station"),
false,
null,
Color.Gold);
}
SoundSystem.Play("/Audio/Announcements/shuttlecalled.ogg", Filter.Broadcast());
@@ -206,6 +233,24 @@ namespace Content.Server.RoundEnd
RaiseLocalEvent(RoundEndSystemChangedEvent.Default);
}, _cooldownTokenSource.Token);
}
public override void Update(float frameTime)
{
// Check if we should auto-call.
int mins = AutoCalledBefore ? _cfg.GetCVar(CCVars.EmergencyShuttleAutoCallExtensionTime)
: _cfg.GetCVar(CCVars.EmergencyShuttleAutoCallTime);
if (mins != 0 && _gameTiming.CurTime - AutoCallStartTime > TimeSpan.FromMinutes(mins))
{
if (!_shuttle.EmergencyShuttleArrived && ExpectedCountdownEnd is null)
{
RequestRoundEnd(null, false, true);
AutoCalledBefore = true;
}
// Always reset auto-call in case of a recall.
SetAutoCallTime();
}
}
}
public sealed class RoundEndSystemChangedEvent : EntityEventArgs

View File

@@ -1028,6 +1028,19 @@ namespace Content.Shared.CCVar
public static readonly CVarDef<float> EmergencyRecallTurningPoint =
CVarDef.Create("shuttle.recall_turning_point", 0.5f, CVar.SERVERONLY);
/// <summary>
/// Time in minutes after round start to auto-call the shuttle. Set to zero to disable.
/// </summary>
public static readonly CVarDef<int> EmergencyShuttleAutoCallTime =
CVarDef.Create("shuttle.auto_call_time", 90, CVar.SERVERONLY);
/// <summary>
/// Time in minutes after the round was extended (by recalling the shuttle) to call
/// the shuttle again.
/// </summary>
public static readonly CVarDef<int> EmergencyShuttleAutoCallExtensionTime =
CVarDef.Create("shuttle.auto_call_extension_time", 45, CVar.SERVERONLY);
/// <summary>
/// The map to load for CentCom for the emergency shuttle to dock to.
/// </summary>

View File

@@ -1,6 +1,7 @@
## RoundEndSystem
round-end-system-shuttle-called-announcement = An emergency shuttle has been sent. ETA: {$time} {$units}.
round-end-system-shuttle-auto-called-announcement = An automatic crew shift change shuttle has been sent. ETA: {$time} {$units}. Recall the shuttle to extend the shift.
round-end-system-shuttle-recalled-announcement = The emergency shuttle has been recalled.
round-end-system-round-restart-eta-announcement = Restarting the round in {$minutes} minutes...