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.
This commit is contained in:
Super
2025-05-18 12:34:33 +01:00
committed by GitHub
parent 93cc4dc90d
commit 921c6dea30
2 changed files with 37 additions and 10 deletions

View File

@@ -44,6 +44,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
[ValidatePrototypeId<TagPrototype>]
private const string NukeOpsUplinkTagPrototype = "NukeOpsUplink";
public override void Initialize()
{
base.Initialize();
@@ -104,7 +105,7 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
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<NukeopsRuleComponent>
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<NukeopsRuleComponent>
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<NukeopsRuleComponent>
{
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<NukeComponent>())
{
@@ -462,11 +484,16 @@ public sealed class NukeopsRuleSystem : GameRuleSystem<NukeopsRuleComponent>
: 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;