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