]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
After killing all nuclear operatives, shuttle will be called instead of instant round...
authorcsqrb <56765288+CaptainSqrBeard@users.noreply.github.com>
Sun, 24 Sep 2023 20:16:33 +0000 (02:16 +0600)
committerGitHub <noreply@github.com>
Sun, 24 Sep 2023 20:16:33 +0000 (16:16 -0400)
* β˜’οΈπŸ•΅οΈπŸ’€πŸš«πŸ“„πŸš€

* πŸš€πŸ“’❌πŸ“₯πŸ“œ

* πŸ”§πŸ›πŸ“’πŸšΉπŸš‰βž‘πŸ‘‘πŸ‘‘

* πŸ˜ͺ

* πŸ§±

* πŸš€πŸ›¬πŸ•”βž‘οΈπŸ•™

* β˜’οΈβš™οΈπŸ”΅πŸ”šπŸ”¨βž‘οΈπŸ”΅πŸ”šβš™οΈ

these commit names are literally evil who tf does this

Content.Server/GameTicking/Rules/Components/NukeopsRuleComponent.cs
Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs
Content.Server/RoundEnd/RoundEndSystem.cs
Content.Server/StationEvents/Events/LoneOpsSpawnRule.cs
Resources/Locale/en-US/nukeops/nuke-ops.ftl [new file with mode: 0644]

index 760b684e1ade604b227c2e2f874575d4f5b80b99..8ddfd9c14bb771b46039d62f454287c4e21a3322 100644 (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.
index d94c9dae48ffef5378bb861afdd06df81e870ad8..df9fbcc13017ea919fad11b0a24c3a943febf5ba 100644 (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 });
index 4681acc227b6d47ba2850aef0345ab6982212230..12cfb0e6667d0e8b13d1b18bc5118685f0fe89f3 100644 (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
+}
 }
index 8e1a2f3b3b06ca4269a0bab339acca721446a55b..ce5f826d0cded96a0927fc5b120c5888fdb2987b 100644 (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);
     }
 
diff --git a/Resources/Locale/en-US/nukeops/nuke-ops.ftl b/Resources/Locale/en-US/nukeops/nuke-ops.ftl
new file mode 100644 (file)
index 0000000..b4f2238
--- /dev/null
@@ -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.
\ No newline at end of file