After killing all nuclear operatives, shuttle will be called instead of instant round end (#19850)

* ☢️🕵️💀🚫📄🚀

* 🚀📢📥📜

* 🔧🐛📢🚹🚉👑👑

* 😪

* 🧱

* 🚀🛬🕔➡️🕙

* ☢️⚙️🔵🔚🔨➡️🔵🔚⚙️

these commit names are literally evil who tf does this
This commit is contained in:
csqrb
2023-09-25 02:16:33 +06:00
committed by GitHub
parent 4a263952cf
commit 7bb3dd09c7
5 changed files with 100 additions and 33 deletions

View File

@@ -1,4 +1,5 @@
using Content.Server.NPC.Components;
using Content.Server.RoundEnd;
using Content.Server.StationEvents.Events;
using Content.Shared.Dataset;
using Content.Shared.Roles;
@@ -31,10 +32,34 @@ public sealed partial class NukeopsRuleComponent : Component
public int MaxOperatives = 5;
/// <summary>
/// Whether or not all of the nuclear operatives dying will end the round. Used by LoneOpsSpawn event.
/// What will happen if all of the nuclear operatives will die. Used by LoneOpsSpawn event.
/// </summary>
[DataField("endsRound")]
public bool EndsRound = true;
[DataField("roundEndBehavior")]
public RoundEndBehavior RoundEndBehavior = RoundEndBehavior.ShuttleCall;
/// <summary>
/// Text for shuttle call if RoundEndBehavior is ShuttleCall.
/// </summary>
[DataField("roundEndTextSender")]
public string RoundEndTextSender = "comms-console-announcement-title-centcom";
/// <summary>
/// Text for shuttle call if RoundEndBehavior is ShuttleCall.
/// </summary>
[DataField("roundEndTextShuttleCall")]
public string RoundEndTextShuttleCall = "nuke-ops-no-more-threat-announcement-shuttle-call";
/// <summary>
/// Text for announcement if RoundEndBehavior is ShuttleCall. Used if shuttle is already called
/// </summary>
[DataField("roundEndTextAnnouncement")]
public string RoundEndTextAnnouncement = "nuke-ops-no-more-threat-announcement";
/// <summary>
/// Time to emergency shuttle to arrive if RoundEndBehavior is ShuttleCall.
/// </summary>
[DataField("evacShuttleTime")]
public TimeSpan EvacShuttleTime = TimeSpan.FromMinutes(10);
/// <summary>
/// Whether or not to spawn the nuclear operative outpost. Used by LoneOpsSpawn event.

View File

@@ -487,14 +487,14 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
}
}
private void SetWinType(EntityUid uid, WinType type, NukeopsRuleComponent? component = null)
private void SetWinType(EntityUid uid, WinType type, NukeopsRuleComponent? component = null, bool endRound = true)
{
if (!Resolve(uid, ref component))
return;
component.WinType = type;
if (type == WinType.CrewMajor || type == WinType.OpsMajor)
if (endRound && (type == WinType.CrewMajor || type == WinType.OpsMajor))
_roundEndSystem.EndRound();
}
@@ -506,7 +506,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
if (!GameTicker.IsGameRuleAdded(uid, gameRule))
continue;
if (!nukeops.EndsRound || nukeops.WinType == WinType.CrewMajor || nukeops.WinType == WinType.OpsMajor)
if (nukeops.RoundEndBehavior == RoundEndBehavior.Nothing || nukeops.WinType == WinType.CrewMajor || nukeops.WinType == WinType.OpsMajor)
continue;
// If there are any nuclear bombs that are active, immediately return. We're not over yet.
@@ -559,7 +559,12 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
? WinCondition.NukiesAbandoned
: WinCondition.AllNukiesDead);
SetWinType(uid, WinType.CrewMajor, nukeops);
SetWinType(uid, WinType.CrewMajor, nukeops, false);
_roundEndSystem.DoRoundEndBehavior(
nukeops.RoundEndBehavior, nukeops.EvacShuttleTime, nukeops.RoundEndTextSender, nukeops.RoundEndTextShuttleCall, nukeops.RoundEndTextAnnouncement);
// prevent it called multiple times
nukeops.RoundEndBehavior = RoundEndBehavior.Nothing;
}
}
@@ -763,7 +768,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
foreach (var (nukeops, gameRule) in EntityQuery<NukeopsRuleComponent, GameRuleComponent>())
{
if (nukeops.OperativeMindPendingData.TryGetValue(uid, out var role) || !nukeops.SpawnOutpost || !nukeops.EndsRound)
if (nukeops.OperativeMindPendingData.TryGetValue(uid, out var role) || !nukeops.SpawnOutpost || nukeops.RoundEndBehavior == RoundEndBehavior.Nothing)
{
role ??= nukeops.OperativeRoleProto;
_roles.MindAddRole(mindId, new NukeopsRoleComponent { PrototypeId = role });

View File

@@ -90,7 +90,12 @@ namespace Content.Server.RoundEnd
return _cooldownTokenSource == null;
}
public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, bool autoCall = false)
public bool IsRoundEndRequested()
{
return _countdownTokenSource != null;
}
public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "Station")
{
var duration = DefaultCountdownDuration;
@@ -105,10 +110,10 @@ namespace Content.Server.RoundEnd
}
}
RequestRoundEnd(duration, requester, checkCooldown, autoCall);
RequestRoundEnd(duration, requester, checkCooldown, text, name);
}
public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, bool autoCall = false)
public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "Station")
{
if (_gameTicker.RunLevel != GameRunLevel.InRound) return;
@@ -141,26 +146,13 @@ namespace Content.Server.RoundEnd
units = "eta-units-minutes";
}
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);
}
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString(text,
("time", time),
("units", Loc.GetString(units))),
name,
false,
null,
Color.Gold);
SoundSystem.Play("/Audio/Announcements/shuttlecalled.ogg", Filter.Broadcast());
@@ -232,6 +224,30 @@ namespace Content.Server.RoundEnd
Timer.Spawn(countdownTime.Value, AfterEndRoundRestart, _countdownTokenSource.Token);
}
public void DoRoundEndBehavior(RoundEndBehavior behavior, TimeSpan time, string sender, string textCall, string textAnnounce)
{
switch (behavior)
{
case RoundEndBehavior.InstantEnd:
EndRound();
break;
case RoundEndBehavior.ShuttleCall:
// Check is shuttle called or not. We should only dispatch announcement if it's already called
if (IsRoundEndRequested())
{
_chatSystem.DispatchGlobalAnnouncement(Loc.GetString(textAnnounce),
Loc.GetString(sender),
colorOverride: Color.Gold);
}
else
{
RequestRoundEnd(time, null, false, textCall,
Loc.GetString(sender));
}
break;
}
}
private void AfterEndRoundRestart()
{
if (_gameTicker.RunLevel != GameRunLevel.PostRound) return;
@@ -260,7 +276,7 @@ namespace Content.Server.RoundEnd
{
if (!_shuttle.EmergencyShuttleArrived && ExpectedCountdownEnd is null)
{
RequestRoundEnd(null, false, true);
RequestRoundEnd(null, false, "round-end-system-shuttle-auto-called-announcement");
AutoCalledBefore = true;
}
@@ -274,4 +290,22 @@ namespace Content.Server.RoundEnd
{
public static RoundEndSystemChangedEvent Default { get; } = new();
}
public enum RoundEndBehavior : byte
{
/// <summary>
/// Instantly end round
/// </summary>
InstantEnd,
/// <summary>
/// Call shuttle with custom announcement
/// </summary>
ShuttleCall,
/// <summary>
/// Do nothing
/// </summary>
Nothing
}
}

View File

@@ -5,6 +5,7 @@ using Content.Server.GameTicking;
using Content.Server.GameTicking.Rules;
using Content.Server.GameTicking.Rules.Components;
using Content.Server.StationEvents.Components;
using Content.Server.RoundEnd;
namespace Content.Server.StationEvents.Events;
@@ -37,7 +38,7 @@ public sealed class LoneOpsSpawnRule : StationEventSystem<LoneOpsSpawnRuleCompon
component.AdditionalRule = nukeopsEntity;
var nukeopsComp = EntityManager.GetComponent<NukeopsRuleComponent>(nukeopsEntity);
nukeopsComp.SpawnOutpost = false;
nukeopsComp.EndsRound = false;
nukeopsComp.RoundEndBehavior = RoundEndBehavior.Nothing;
_gameTicker.StartGameRule(nukeopsEntity);
}

View File

@@ -0,0 +1,2 @@
nuke-ops-no-more-threat-announcement-shuttle-call = Based on our scans from our long-range sensors, the nuclear threat is now eliminated. We will call emergency shuttle that will arrive shortly. ETA: {$time} {$units}. You can recall the shuttle to extend the shift.
nuke-ops-no-more-threat-announcement = Based on our scans from our long-range sensors, the nuclear threat is now eliminated. Shuttle is already called.