From 20756abcfbdce8f605204dda58f80ead4e641b1e Mon Sep 17 00:00:00 2001
From: Samuka <47865393+Samuka-C@users.noreply.github.com>
Date: Tue, 2 Dec 2025 11:28:33 -0300
Subject: [PATCH] Fix xenoborg evac calling announcment (#41437)
* no longer calls evac if evac is called or if the round is over
* can't recall shuttle
* some commentary
* can recall next round
* cancel evac recalling
* add this back
* only call once
* admins can recall anyway now
* 1 bool is better than 2 i guess
* some cleanup
---------
Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
---
.../Commands/ShuttleCommands.cs | 2 +-
.../Components/XenoborgsRuleComponent.cs | 7 +++
.../GameTicking/Rules/XenoborgsRuleSystem.cs | 15 +++---
Content.Server/RoundEnd/RoundEndSystem.cs | 46 +++++++++++++++----
4 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/Content.Server/Administration/Commands/ShuttleCommands.cs b/Content.Server/Administration/Commands/ShuttleCommands.cs
index 677c38ac4e..6dffe1f52c 100644
--- a/Content.Server/Administration/Commands/ShuttleCommands.cs
+++ b/Content.Server/Administration/Commands/ShuttleCommands.cs
@@ -35,7 +35,7 @@ namespace Content.Server.Administration.Commands
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
- _roundEndSystem.CancelRoundEndCountdown(shell.Player?.AttachedEntity, false);
+ _roundEndSystem.CancelRoundEndCountdown(shell.Player?.AttachedEntity, forceRecall: true);
}
}
}
diff --git a/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs b/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs
index c7496bb0fb..4a018d7e6c 100644
--- a/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs
+++ b/Content.Server/GameTicking/Rules/Components/XenoborgsRuleComponent.cs
@@ -36,4 +36,11 @@ public sealed partial class XenoborgsRuleComponent : Component
///
[DataField]
public bool MothershipCoreDeathAnnouncmentSent = false;
+
+ ///
+ /// If the emergency shuttle trigged by was already called.
+ /// Will only call once. if a admin recalls it. it won't call again unless this is set to false by a admin
+ ///
+ [DataField]
+ public bool XenoborgShuttleCalled = false;
}
diff --git a/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs b/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs
index 97a6efb471..cda1bce258 100644
--- a/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs
+++ b/Content.Server/GameTicking/Rules/XenoborgsRuleSystem.cs
@@ -100,14 +100,17 @@ public sealed class XenoborgsRuleSystem : GameRuleSystem
xenoborgsRuleComponent.MaxNumberXenoborgs = Math.Max(xenoborgsRuleComponent.MaxNumberXenoborgs, numXenoborgs);
- if ((float)numXenoborgs / (numHumans + numXenoborgs) > xenoborgsRuleComponent.XenoborgShuttleCallPercentage)
+ if (xenoborgsRuleComponent.XenoborgShuttleCalled
+ || (float)numXenoborgs / (numHumans + numXenoborgs) <= xenoborgsRuleComponent.XenoborgShuttleCallPercentage
+ || _roundEnd.IsRoundEndRequested())
+ return;
+
+ foreach (var station in _station.GetStations())
{
- foreach (var station in _station.GetStations())
- {
- _chatSystem.DispatchStationAnnouncement(station, Loc.GetString("xenoborg-shuttle-call"), colorOverride: Color.BlueViolet);
- }
- _roundEnd.RequestRoundEnd(null, false);
+ _chatSystem.DispatchStationAnnouncement(station, Loc.GetString("xenoborg-shuttle-call"), colorOverride: Color.BlueViolet);
}
+ _roundEnd.RequestRoundEnd(null, false, cantRecall: true);
+ xenoborgsRuleComponent.XenoborgShuttleCalled = true;
}
protected override void Started(EntityUid uid, XenoborgsRuleComponent component, GameRuleComponent gameRule, GameRuleStartedEvent args)
diff --git a/Content.Server/RoundEnd/RoundEndSystem.cs b/Content.Server/RoundEnd/RoundEndSystem.cs
index a464796a74..9419d4b01c 100644
--- a/Content.Server/RoundEnd/RoundEndSystem.cs
+++ b/Content.Server/RoundEnd/RoundEndSystem.cs
@@ -56,6 +56,11 @@ namespace Content.Server.RoundEnd
public TimeSpan? ExpectedShuttleLength => ExpectedCountdownEnd - LastCountdownStart;
public TimeSpan? ShuttleTimeLeft => ExpectedCountdownEnd - _gameTiming.CurTime;
+ ///
+ /// If the shuttle can't be recalled. if set to true, the station wont be able to recall
+ ///
+ public bool CantRecall = false;
+
public TimeSpan AutoCallStartTime;
private bool _autoCalledBefore = false;
@@ -85,6 +90,8 @@ namespace Content.Server.RoundEnd
_cooldownTokenSource = null;
}
+ CantRecall = false;
+
LastCountdownStart = null;
ExpectedCountdownEnd = null;
SetAutoCallTime();
@@ -116,7 +123,7 @@ namespace Content.Server.RoundEnd
public bool CanCallOrRecall()
{
- return _cooldownTokenSource == null;
+ return _cooldownTokenSource == null && !CantRecall;
}
public bool IsRoundEndRequested()
@@ -124,7 +131,15 @@ namespace Content.Server.RoundEnd
return _countdownTokenSource != null;
}
- public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement")
+ ///
+ /// Starts the process of ending the round by calling evac
+ ///
+ ///
+ ///
+ /// text in the announcement of shuttle calling
+ /// name in the announcement of shuttle calling
+ /// if the station shouldn't be able to recall the shuttle
+ public void RequestRoundEnd(EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement", bool cantRecall = false)
{
var duration = DefaultCountdownDuration;
@@ -139,10 +154,19 @@ namespace Content.Server.RoundEnd
}
}
- RequestRoundEnd(duration, requester, checkCooldown, text, name);
+ RequestRoundEnd(duration, requester, checkCooldown, text, name, cantRecall);
}
- public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement")
+ ///
+ /// Starts the process of ending the round by calling evac
+ ///
+ /// time for evac to arrive
+ ///
+ ///
+ /// text in the announcement of shuttle calling
+ /// name in the announcement of shuttle calling
+ /// if the station shouldn't be able to recall the shuttle
+ public void RequestRoundEnd(TimeSpan countdownTime, EntityUid? requester = null, bool checkCooldown = true, string text = "round-end-system-shuttle-called-announcement", string name = "round-end-system-shuttle-sender-announcement", bool cantRecall = false)
{
if (_gameTicker.RunLevel != GameRunLevel.InRound)
return;
@@ -154,6 +178,7 @@ namespace Content.Server.RoundEnd
return;
_countdownTokenSource = new();
+ CantRecall = cantRecall;
if (requester != null)
{
@@ -214,12 +239,17 @@ namespace Content.Server.RoundEnd
}
}
- public void CancelRoundEndCountdown(EntityUid? requester = null, bool checkCooldown = true)
+ public void CancelRoundEndCountdown(EntityUid? requester = null, bool forceRecall = false)
{
- if (_gameTicker.RunLevel != GameRunLevel.InRound) return;
- if (checkCooldown && _cooldownTokenSource != null) return;
+ if (_gameTicker.RunLevel != GameRunLevel.InRound)
+ return;
+
+ if (!forceRecall && (CantRecall || _cooldownTokenSource != null))
+ return;
+
+ if (_countdownTokenSource == null)
+ return;
- if (_countdownTokenSource == null) return;
_countdownTokenSource.Cancel();
_countdownTokenSource = null;
--
2.52.0