diff --git a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs index 4ac83b354e..5bd77c48aa 100644 --- a/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/ZombieRuleSystem.cs @@ -61,17 +61,17 @@ public sealed class ZombieRuleSystem : GameRuleSystem { foreach (var zombie in EntityQuery()) { - //this is just the general condition thing used for determining the win/lose text - var percent = GetInfectedPercentage(out var livingHumans); + // This is just the general condition thing used for determining the win/lose text + var fraction = GetInfectedFraction(); - if (percent <= 0) + if (fraction <= 0) ev.AddLine(Loc.GetString("zombie-round-end-amount-none")); - else if (percent <= 0.25) + else if (fraction <= 0.25) ev.AddLine(Loc.GetString("zombie-round-end-amount-low")); - else if (percent <= 0.5) - ev.AddLine(Loc.GetString("zombie-round-end-amount-medium", ("percent", Math.Round((percent * 100), 2).ToString(CultureInfo.InvariantCulture)))); - else if (percent < 1) - ev.AddLine(Loc.GetString("zombie-round-end-amount-high", ("percent", Math.Round((percent * 100), 2).ToString(CultureInfo.InvariantCulture)))); + else if (fraction <= 0.5) + ev.AddLine(Loc.GetString("zombie-round-end-amount-medium", ("percent", Math.Round((fraction * 100), 2).ToString(CultureInfo.InvariantCulture)))); + else if (fraction < 1) + ev.AddLine(Loc.GetString("zombie-round-end-amount-high", ("percent", Math.Round((fraction * 100), 2).ToString(CultureInfo.InvariantCulture)))); else ev.AddLine(Loc.GetString("zombie-round-end-amount-all")); @@ -83,13 +83,14 @@ public sealed class ZombieRuleSystem : GameRuleSystem ("username", player.Value))); } - //Gets a bunch of the living players and displays them if they're under a threshold. - //InitialInfected is used for the threshold because it scales with the player count well. - if (livingHumans.Count > 0 && livingHumans.Count <= zombie.InitialInfectedNames.Count) + var healthy = GetHealthyHumans(); + // Gets a bunch of the living players and displays them if they're under a threshold. + // InitialInfected is used for the threshold because it scales with the player count well. + if (healthy.Count > 0 && healthy.Count <= 2 * zombie.InitialInfectedNames.Count) { ev.AddLine(""); - ev.AddLine(Loc.GetString("zombie-round-end-survivor-count", ("count", livingHumans.Count))); - foreach (var survivor in livingHumans) + ev.AddLine(Loc.GetString("zombie-round-end-survivor-count", ("count", healthy.Count))); + foreach (var survivor in healthy) { var meta = MetaData(survivor); var username = string.Empty; @@ -142,14 +143,15 @@ public sealed class ZombieRuleSystem : GameRuleSystem if (GameTicker.IsGameRuleActive(uid, gameRule)) continue; - //we only care about players, not monkeys and such. + // We only care about players, not monkeys and such. if (!HasComp(target)) continue; - var percent = GetInfectedPercentage(out var num); - if (num.Count == 1) //only one human left. spooky - _popup.PopupEntity(Loc.GetString("zombie-alone"), num[0], num[0]); - if (percent >= 1) //oops, all zombies + var fraction = GetInfectedFraction(); + var healthy = GetHealthyHumans(); + if (healthy.Count == 1) // Only one human left. spooky + _popup.PopupEntity(Loc.GetString("zombie-alone"), healthy[0], healthy[0]); + if (fraction >= 1) // Oops, all zombies _roundEndSystem.EndRound(); } } @@ -192,29 +194,27 @@ public sealed class ZombieRuleSystem : GameRuleSystem _action.RemoveAction(uid, action); } - private float GetInfectedPercentage(out List livingHumans) + private float GetInfectedFraction() { - var allPlayers = EntityQuery(true); - var allZombers = GetEntityQuery(); + var players = EntityQuery(true); + var zombers = EntityQuery(true); - var totalPlayers = new List(); - var livingZombies = new List(); + return zombers.Count() / (float) players.Count(); + } - livingHumans = new(); - - foreach (var (_, mob) in allPlayers) + private List GetHealthyHumans() + { + var healthy = new List(); + var players = AllEntityQuery(); + var zombers = GetEntityQuery(); + while (players.MoveNext(out var uid, out _, out var mob)) { - if (_mobState.IsAlive(mob.Owner, mob)) + if (_mobState.IsAlive(uid, mob) && !zombers.HasComponent(uid)) { - totalPlayers.Add(mob.Owner); - - if (allZombers.HasComponent(mob.Owner)) - livingZombies.Add(mob.Owner); - else - livingHumans.Add(mob.Owner); + healthy.Add(uid); } } - return livingZombies.Count / (float) totalPlayers.Count; + return healthy; } ///