From 921c6dea30fb35d1ce4143ef96a15c3fd058c908 Mon Sep 17 00:00:00 2001 From: Super <84590915+SuperGDPWYL@users.noreply.github.com> Date: Sun, 18 May 2025 12:34:33 +0100 Subject: [PATCH] A lone operative successfully nuking the station now actually ends the round. (#36498) LoneOpsSpawn is now of an indefinite duration -- it lasts until either the LoneOp dies or the nuke detonates. This means a few things. --- .../GameTicking/Rules/NukeopsRuleSystem.cs | 45 +++++++++++++++---- Resources/Prototypes/GameRules/events.yml | 2 +- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs index e22626594f..616a1e48ff 100644 --- a/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs @@ -44,6 +44,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem [ValidatePrototypeId] private const string NukeOpsUplinkTagPrototype = "NukeOpsUplink"; + public override void Initialize() { base.Initialize(); @@ -104,7 +105,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem args.AddLine(Loc.GetString("nukeops-list-start")); - var antags =_antag.GetAntagIdentifiers(uid); + var antags = _antag.GetAntagIdentifiers(uid); foreach (var (_, sessionData, name) in antags) { @@ -122,7 +123,9 @@ public sealed class NukeopsRuleSystem : GameRuleSystem if (ev.OwningStation == GetOutpost(uid)) { nukeops.WinConditions.Add(WinCondition.NukeExplodedOnNukieOutpost); - SetWinType((uid, nukeops), WinType.CrewMajor); + SetWinType((uid, nukeops), WinType.CrewMajor, GameTicker.IsGameRuleActive("Nukeops")); // End the round ONLY if the actual gamemode is NukeOps. + if (!GameTicker.IsGameRuleActive("Nukeops")) // End the rule if the LoneOp shuttle got nuked, because that particular LoneOp clearly failed, and should not be considered a Syndie victory even if a future LoneOp wins. + GameTicker.EndGameRule(uid); continue; } @@ -152,7 +155,27 @@ public sealed class NukeopsRuleSystem : GameRuleSystem nukeops.WinConditions.Add(WinCondition.NukeExplodedOnIncorrectLocation); } - _roundEndSystem.EndRound(); + if (GameTicker.IsGameRuleActive("Nukeops")) // If it's Nukeops then end the round on any detonation + { + _roundEndSystem.EndRound(); + } + else + { // It's a LoneOp. Only end the round if the station was destroyed + var handled = false; + foreach (var cond in nukeops.WinConditions) + { + if (cond.ToString().ToLower() == "NukeExplodedOnCorrectStation") // If this is true, then the nuke destroyed the station! It's likely everyone is very dead so keeping the round going is pointless. + { + _roundEndSystem.EndRound(); // end the round! + handled = true; + break; + } + } + if (!handled) // The round didn't end, so end the rule so it doesn't get overridden by future LoneOps. + { + GameTicker.EndGameRule(uid); + } + } } } @@ -411,10 +434,9 @@ public sealed class NukeopsRuleSystem : GameRuleSystem { var nukeops = ent.Comp; - if (nukeops.RoundEndBehavior == RoundEndBehavior.Nothing || nukeops.WinType == WinType.CrewMajor || nukeops.WinType == WinType.OpsMajor) + if (nukeops.WinType == WinType.CrewMajor || nukeops.WinType == WinType.OpsMajor) // Skip this if the round's victor has already been decided. return; - // If there are any nuclear bombs that are active, immediately return. We're not over yet. foreach (var nuke in EntityQuery()) { @@ -462,11 +484,16 @@ public sealed class NukeopsRuleSystem : GameRuleSystem : WinCondition.AllNukiesDead); SetWinType(ent, WinType.CrewMajor, false); + + if (nukeops.RoundEndBehavior == RoundEndBehavior.Nothing) // It's still worth checking if operatives have all died, even if the round-end behaviour is nothing. + return; // Shouldn't actually try to end the round in the case of nothing though. + _roundEndSystem.DoRoundEndBehavior(nukeops.RoundEndBehavior, - nukeops.EvacShuttleTime, - nukeops.RoundEndTextSender, - nukeops.RoundEndTextShuttleCall, - nukeops.RoundEndTextAnnouncement); + nukeops.EvacShuttleTime, + nukeops.RoundEndTextSender, + nukeops.RoundEndTextShuttleCall, + nukeops.RoundEndTextAnnouncement); + // prevent it called multiple times nukeops.RoundEndBehavior = RoundEndBehavior.Nothing; diff --git a/Resources/Prototypes/GameRules/events.yml b/Resources/Prototypes/GameRules/events.yml index c369b10949..78602f97b9 100644 --- a/Resources/Prototypes/GameRules/events.yml +++ b/Resources/Prototypes/GameRules/events.yml @@ -529,7 +529,7 @@ earliestStart: 35 weight: 5.5 minimumPlayers: 20 - duration: 1 + duration: null # LoneOpsSpawn needs an infinite duration so that it inherits the NukeOpsRule things of an actually appropriate end scrreen (not always "Neutral outcome!") and... ending the game if the station is nuked. - type: RuleGrids - type: LoadMapRule gridPath: /Maps/Shuttles/ShuttleEvent/striker.yml