From 4ba5c2151ca4f68f2ec07eeef4dd8b5d01d25936 Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Tue, 10 Dec 2024 16:45:59 -0600 Subject: [PATCH 1/8] first steps --- Content.Server/Antag/AntagSelectionSystem.cs | 20 +++++++++++-------- .../Components/AntagSelectionComponent.cs | 6 ++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index af8c4b32eecf04..db87da7150cb23 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -89,15 +89,16 @@ private void OnPlayerSpawning(RulePlayerSpawningEvent args) var query = QueryActiveRules(); while (query.MoveNext(out var uid, out _, out var comp, out _)) { - if (comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn) - continue; if (comp.SelectionsComplete) continue; ChooseAntags((uid, comp), pool); - foreach (var session in comp.SelectedSessions) + if (comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn) + continue; + + foreach (var session in comp.ProcessedSessions) { args.PlayerPool.Remove(session); GameTicker.PlayerJoinGame(session); @@ -254,8 +255,10 @@ public void ChooseAntags(Entity ent, continue; } } - - MakeAntag(ent, session, def, playerPool); + if (!midround && ent.Comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn && session != null) // If it's Prespawn or midround we just want to go ahead and finish the process + ent.Comp.SelectedSessions.Add(session); + else + MakeAntag(ent, session, def, playerPool); } } @@ -284,7 +287,8 @@ public void MakeAntag(Entity ent, ICommonSession? sessi if (session != null) { - ent.Comp.SelectedSessions.Add(session); + ent.Comp.SelectedSessions.Remove(session); + ent.Comp.ProcessedSessions.Add(session); // we shouldn't be blocking the entity if they're just a ghost or smth. if (!HasComp(session.AttachedEntity)) @@ -307,7 +311,7 @@ public void MakeAntag(Entity ent, ICommonSession? sessi { Log.Error($"Attempted to make {session} antagonist in gamerule {ToPrettyString(ent)} but there was no valid entity for player."); if (session != null) - ent.Comp.SelectedSessions.Remove(session); + ent.Comp.ProcessedSessions.Remove(session); return; } @@ -413,7 +417,7 @@ public bool IsSessionValid(Entity ent, ICommonSession? if (session.Status is SessionStatus.Disconnected or SessionStatus.Zombie) return false; - if (ent.Comp.SelectedSessions.Contains(session)) + if (ent.Comp.ProcessedSessions.Contains(session)) return false; mind ??= session.GetMind(); diff --git a/Content.Server/Antag/Components/AntagSelectionComponent.cs b/Content.Server/Antag/Components/AntagSelectionComponent.cs index ac31c78d73d93c..9a5afb7f59dd93 100644 --- a/Content.Server/Antag/Components/AntagSelectionComponent.cs +++ b/Content.Server/Antag/Components/AntagSelectionComponent.cs @@ -43,6 +43,12 @@ public sealed partial class AntagSelectionComponent : Component /// public HashSet SelectedSessions = new(); + /// + /// Cached sessions of players who are chosen. Used so we don't have to rebuild the pool multiple times in a tick. + /// Is not serialized. + /// + public HashSet ProcessedSessions = new(); + /// /// Locale id for the name of the antag. /// If this is set then the antag is listed in the round-end summary. From 3b56abe99567793f4eca9b3dada88feb292f445c Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Wed, 11 Dec 2024 00:18:23 -0600 Subject: [PATCH 2/8] asdfg --- Content.Server/Antag/AntagSelectionSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index db87da7150cb23..60841d6210bef4 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -255,7 +255,7 @@ public void ChooseAntags(Entity ent, continue; } } - if (!midround && ent.Comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn && session != null) // If it's Prespawn or midround we just want to go ahead and finish the process + if (!midround && ent.Comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn && session != null) // If it's a prespawn antag or midround we just want to go ahead and finish the process ent.Comp.SelectedSessions.Add(session); else MakeAntag(ent, session, def, playerPool); From fac9c6783f353b2eb35410be75e5d41bf6c33c47 Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Fri, 13 Dec 2024 02:04:55 -0600 Subject: [PATCH 3/8] intermission to test a different thing --- Content.Server/Antag/AntagSelectionSystem.cs | 28 ++++++++++++++++++- .../Systems/StationJobsSystem.Roundstart.cs | 5 ++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 60841d6210bef4..d22e7fcc280100 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -19,6 +19,7 @@ using Content.Shared.Humanoid; using Content.Shared.Mind; using Content.Shared.Players; +using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Whitelist; using Robust.Server.Audio; @@ -26,6 +27,7 @@ using Robust.Server.Player; using Robust.Shared.Enums; using Robust.Shared.Map; +using Robust.Shared.Network; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -50,6 +52,8 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem QueuedAntags = []; + /// public override void Initialize() { @@ -85,6 +89,7 @@ private void OnTakeGhostRole(Entity ent, ref Tak private void OnPlayerSpawning(RulePlayerSpawningEvent args) { var pool = args.PlayerPool; + var playerNetIds = args.PlayerPool.Select(o => o.UserId).ToHashSet(); var query = QueryActiveRules(); while (query.MoveNext(out var uid, out _, out var comp, out _)) @@ -95,8 +100,21 @@ private void OnPlayerSpawning(RulePlayerSpawningEvent args) ChooseAntags((uid, comp), pool); + var selectedAntagNetIds = comp.SelectedSessions.Select(o => o.UserId).ToHashSet(); + + + if (comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn) + { + foreach (var (player, _) in args.Profiles) + { + if (selectedAntagNetIds.Contains(player)) + QueuedAntags.Add(player); + } + continue; + } + foreach (var session in comp.ProcessedSessions) { @@ -114,7 +132,15 @@ private void OnJobsAssigned(RulePlayerJobsAssignedEvent args) if (comp.SelectionTime != AntagSelectionTime.PostPlayerSpawn) continue; - ChooseAntags((uid, comp), args.Players); + if (!comp.SelectionsComplete) // Should never happen I think? + ChooseAntags((uid, comp), args.Players); + + foreach(var session in comp.ProcessedSessions){ + MakeAntag(ent, session, def, playerPool); // You left off here + } + + + } } diff --git a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs index 8a918bd2fd045d..c8df7ed593e17b 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Server.Antag; using Content.Server.Administration.Managers; using Content.Server.Players.PlayTimeTracking; using Content.Server.Station.Components; @@ -17,6 +18,7 @@ public sealed partial class StationJobsSystem { [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IBanManager _banManager = default!; + [Dependency] private readonly AntagSelectionSystem _antag = default!; private Dictionary> _jobsByWeight = default!; private List _orderedWeights = default!; @@ -361,6 +363,9 @@ private Dictionary> GetPlayersJobCandidates(int? weight, if (!_prototypeManager.TryIndex(jobId, out var job)) continue; + if (!job.CanBeAntag && _antag.QueuedAntags.Contains(player)) + continue; + if (weight is not null && job.Weight != weight.Value) continue; From bb404afe8ae0b37639c7bda90f53af3de1fcb153 Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Tue, 17 Dec 2024 22:13:37 -0600 Subject: [PATCH 4/8] this technically works --- Content.Server/Antag/AntagSelectionSystem.cs | 59 +++++++++++-------- .../GameTicking/Rules/TraitorRuleSystem.cs | 2 + .../Systems/StationJobsSystem.Roundstart.cs | 2 +- 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index d22e7fcc280100..7902b2a22143e8 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -19,7 +19,6 @@ using Content.Shared.Humanoid; using Content.Shared.Mind; using Content.Shared.Players; -using Content.Shared.Preferences; using Content.Shared.Roles; using Content.Shared.Whitelist; using Robust.Server.Audio; @@ -52,7 +51,7 @@ public sealed partial class AntagSelectionSystem : GameRuleSystem QueuedAntags = []; + public Dictionary)> QueuedAntags = []; /// public override void Initialize() @@ -91,8 +90,8 @@ private void OnPlayerSpawning(RulePlayerSpawningEvent args) var pool = args.PlayerPool; var playerNetIds = args.PlayerPool.Select(o => o.UserId).ToHashSet(); - var query = QueryActiveRules(); - while (query.MoveNext(out var uid, out _, out var comp, out _)) + var query = QueryAllRules(); + while (query.MoveNext(out var uid, out var comp, out _)) { if (comp.SelectionsComplete) @@ -100,22 +99,11 @@ private void OnPlayerSpawning(RulePlayerSpawningEvent args) ChooseAntags((uid, comp), pool); - var selectedAntagNetIds = comp.SelectedSessions.Select(o => o.UserId).ToHashSet(); - - - if (comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn) { - foreach (var (player, _) in args.Profiles) - { - if (selectedAntagNetIds.Contains(player)) - QueuedAntags.Add(player); - } - continue; } - foreach (var session in comp.ProcessedSessions) { args.PlayerPool.Remove(session); @@ -135,12 +123,12 @@ private void OnJobsAssigned(RulePlayerJobsAssignedEvent args) if (!comp.SelectionsComplete) // Should never happen I think? ChooseAntags((uid, comp), args.Players); - foreach(var session in comp.ProcessedSessions){ - MakeAntag(ent, session, def, playerPool); // You left off here + foreach ((var _, var antagData) in QueuedAntags) + { + if(antagData.Item3.Comp == comp) + MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2, null); } - - } } @@ -209,7 +197,18 @@ protected override void Started(EntityUid uid, AntagSelectionComponent component return; if (component.SelectionsComplete) - return; + { + if(QueuedAntags.Count != 0) + { + foreach ((var _, var antagData) in QueuedAntags) + { + if(antagData.Item3.Comp == component) + MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2, null); + } + } + else + return; + } var players = _playerManager.Sessions .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame) @@ -275,14 +274,17 @@ public void ChooseAntags(Entity ent, break; } - if (session != null && ent.Comp.SelectedSessions.Contains(session)) + if (session != null && QueuedAntags.ContainsKey(session.UserId)) { - Log.Warning($"Somehow picked {session} for an antag when this rule already selected them previously"); + Log.Warning($"Somehow picked {session} for an antag when another rule already selected them previously"); continue; } } - if (!midround && ent.Comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn && session != null) // If it's a prespawn antag or midround we just want to go ahead and finish the process + if (!midround && ent.Comp.SelectionTime != AntagSelectionTime.PrePlayerSpawn && session != null) //Midround rule additions, ghost roles, and prespawn activations should never be queued + { ent.Comp.SelectedSessions.Add(session); + QueuedAntags[session.UserId] = (session, def, ent); + } else MakeAntag(ent, session, def, playerPool); } @@ -314,6 +316,7 @@ public void MakeAntag(Entity ent, ICommonSession? sessi if (session != null) { ent.Comp.SelectedSessions.Remove(session); + QueuedAntags.Remove(session.UserId); ent.Comp.ProcessedSessions.Add(session); // we shouldn't be blocking the entity if they're just a ghost or smth. @@ -367,7 +370,15 @@ public void MakeAntag(Entity ent, ICommonSession? sessi return; } - var prereqEv = new AntagPrereqSetupEvent(session, ent, def, pool); + var validPool = GetPlayerPool( // This is probably stupid + ent, + _playerManager.Sessions + .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame) + .ToList(), + def + ); + + var prereqEv = new AntagPrereqSetupEvent(session, ent, def, validPool); RaiseLocalEvent(ent, ref prereqEv, true); // The following is where we apply components, equipment, and other changes to our antagonist entity. diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 92c070958447cf..12da0ce98aff70 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -17,6 +17,7 @@ using Content.Shared.Roles.RoleCodeword; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using Robust.Server.Player; using System.Linq; using System.Text; @@ -31,6 +32,7 @@ public sealed class TraitorRuleSystem : GameRuleSystem [Dependency] private readonly SharedJobSystem _jobs = default!; [Dependency] private readonly MindSystem _mindSystem = default!; [Dependency] private readonly NpcFactionSystem _npcFaction = default!; + [Dependency] private readonly IPlayerManager _playerManager = default!; [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedRoleCodewordSystem _roleCodewordSystem = default!; diff --git a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs index c8df7ed593e17b..5c7888c29cd81f 100644 --- a/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs +++ b/Content.Server/Station/Systems/StationJobsSystem.Roundstart.cs @@ -363,7 +363,7 @@ private Dictionary> GetPlayersJobCandidates(int? weight, if (!_prototypeManager.TryIndex(jobId, out var job)) continue; - if (!job.CanBeAntag && _antag.QueuedAntags.Contains(player)) + if (!job.CanBeAntag && _antag.QueuedAntags.ContainsKey(player)) continue; if (weight is not null && job.Weight != weight.Value) From b00a5456b62ad1cd3db80d5b147b015eb2f34dd2 Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:08:23 -0600 Subject: [PATCH 5/8] i think this works --- .../Antag/AntagSelectionSystem.API.cs | 2 +- Content.Server/Antag/AntagSelectionSystem.cs | 24 +++++++------------ .../GameTicking/Rules/TraitorRuleSystem.cs | 12 +++++++++- .../_Impstation/GameRules/roundstart.yml | 4 ++-- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.API.cs b/Content.Server/Antag/AntagSelectionSystem.API.cs index 19438958fc7981..bbb38f0155801c 100644 --- a/Content.Server/Antag/AntagSelectionSystem.API.cs +++ b/Content.Server/Antag/AntagSelectionSystem.API.cs @@ -348,7 +348,7 @@ public void ForceMakeAntag(ICommonSession? player, string defaultRule) where if (!TryGetNextAvailableDefinition(rule, out var def)) def = rule.Comp.Definitions.Last(); - MakeAntag(rule, player, def.Value, null); + MakeAntag(rule, player, def.Value); } /// diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 7902b2a22143e8..52f8ebd2f62045 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -80,7 +80,7 @@ private void OnTakeGhostRole(Entity ent, ref Tak if (!Exists(rule) || !TryComp(rule, out var select)) return; - MakeAntag((rule, select), args.Player, def, null, ignoreSpawner: true); + MakeAntag((rule, select), args.Player, def, ignoreSpawner: true); args.TookRole = true; _ghostRole.UnregisterGhostRole((ent, Comp(ent))); } @@ -126,7 +126,7 @@ private void OnJobsAssigned(RulePlayerJobsAssignedEvent args) foreach ((var _, var antagData) in QueuedAntags) { if(antagData.Item3.Comp == comp) - MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2, null); + MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2); } } @@ -203,7 +203,7 @@ protected override void Started(EntityUid uid, AntagSelectionComponent component foreach ((var _, var antagData) in QueuedAntags) { if(antagData.Item3.Comp == component) - MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2, null); + MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2); } } else @@ -286,7 +286,7 @@ public void ChooseAntags(Entity ent, QueuedAntags[session.UserId] = (session, def, ent); } else - MakeAntag(ent, session, def, playerPool); + MakeAntag(ent, session, def); } } @@ -301,14 +301,14 @@ public bool TryMakeAntag(Entity ent, ICommonSession? se if (!IsSessionValid(ent, session, def) || !IsEntityValid(session?.AttachedEntity, def)) return false; - MakeAntag(ent, session, def, null, ignoreSpawner); + MakeAntag(ent, session, def, ignoreSpawner); return true; } /// /// Makes a given player into the specified antagonist. /// - public void MakeAntag(Entity ent, ICommonSession? session, AntagSelectionDefinition def, AntagSelectionPlayerPool? pool, bool ignoreSpawner = false) + public void MakeAntag(Entity ent, ICommonSession? session, AntagSelectionDefinition def, bool ignoreSpawner = false) { EntityUid? antagEnt = null; var isSpawner = false; @@ -370,15 +370,7 @@ public void MakeAntag(Entity ent, ICommonSession? sessi return; } - var validPool = GetPlayerPool( // This is probably stupid - ent, - _playerManager.Sessions - .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame) - .ToList(), - def - ); - - var prereqEv = new AntagPrereqSetupEvent(session, ent, def, validPool); + var prereqEv = new AntagPrereqSetupEvent(session, ent, def); RaiseLocalEvent(ent, ref prereqEv, true); // The following is where we apply components, equipment, and other changes to our antagonist entity. @@ -560,7 +552,7 @@ public record struct AntagSelectLocationEvent(ICommonSession? Session, Entity [ByRefEvent] -public readonly record struct AntagPrereqSetupEvent(ICommonSession? Session, Entity GameRule, AntagSelectionDefinition Def, AntagSelectionPlayerPool? Pool); +public readonly record struct AntagPrereqSetupEvent(ICommonSession? Session, Entity GameRule, AntagSelectionDefinition Def); /// /// Event raised on a game rule entity after the setup logic for an antag is complete. diff --git a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs index 12da0ce98aff70..cf162ad9a95dec 100644 --- a/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs +++ b/Content.Server/GameTicking/Rules/TraitorRuleSystem.cs @@ -8,6 +8,7 @@ using Content.Server.Traitor.Uplink; using Content.Shared.Database; using Content.Shared.FixedPoint; +using Content.Shared.GameTicking; using Content.Shared.GameTicking.Components; using Content.Shared.Mind; using Content.Shared.NPC.Systems; @@ -61,8 +62,17 @@ protected override void Added(EntityUid uid, TraitorRuleComponent component, Gam private void AdditionalSetup(Entity ent, ref AntagPrereqSetupEvent args) { - CurrentAntagPool = args.Pool; ForceAllPossible = args.Def.ForceAllPossible; + if (args.Def.ForceAllPossible) + { + CurrentAntagPool = _antag.GetPlayerPool( // Get player pool of potential antags. Used for assigning objective targets + args.GameRule, + _playerManager.Sessions + .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame) + .ToList(), + args.Def + ); + } } private void AfterEntitySelected(Entity ent, ref AfterAntagEntitySelectedEvent args) diff --git a/Resources/Prototypes/_Impstation/GameRules/roundstart.yml b/Resources/Prototypes/_Impstation/GameRules/roundstart.yml index 2e09aa450a965a..fffbd2a2728da7 100644 --- a/Resources/Prototypes/_Impstation/GameRules/roundstart.yml +++ b/Resources/Prototypes/_Impstation/GameRules/roundstart.yml @@ -48,8 +48,8 @@ - type: GameRule minPlayers: 35 delay: - min: 2 - max: 4 + min: 240 + max: 420 - type: AntagObjectives objectives: - KillRandomTraitorSvSObjective From 3b2ae5fbb634d00ce832159635b91ad4f7f6117d Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Tue, 17 Dec 2024 23:20:48 -0600 Subject: [PATCH 6/8] this doesn't need to be there --- Content.Server/Antag/AntagSelectionSystem.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index 52f8ebd2f62045..f724ab5d27d647 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -88,7 +88,6 @@ private void OnTakeGhostRole(Entity ent, ref Tak private void OnPlayerSpawning(RulePlayerSpawningEvent args) { var pool = args.PlayerPool; - var playerNetIds = args.PlayerPool.Select(o => o.UserId).ToHashSet(); var query = QueryAllRules(); while (query.MoveNext(out var uid, out var comp, out _)) From 6afee5a88281c7e6f5bba5591c7fc06014fd2c39 Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Mon, 23 Dec 2024 09:48:49 -0600 Subject: [PATCH 7/8] sure ill commit like two spacing changes --- Content.Server/Antag/AntagSelectionSystem.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index f724ab5d27d647..b676762aa63c94 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -197,11 +197,11 @@ protected override void Started(EntityUid uid, AntagSelectionComponent component if (component.SelectionsComplete) { - if(QueuedAntags.Count != 0) + if (QueuedAntags.Count != 0) { foreach ((var _, var antagData) in QueuedAntags) { - if(antagData.Item3.Comp == component) + if (antagData.Item3.Comp == component) MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2); } } From b22eee36b6f28fd9532783caefd05743a766f6f1 Mon Sep 17 00:00:00 2001 From: V <97265903+formlessnameless@users.noreply.github.com> Date: Sat, 11 Jan 2025 21:49:40 -0600 Subject: [PATCH 8/8] still running tests but --- Content.Server/Antag/AntagSelectionSystem.cs | 28 ++++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Content.Server/Antag/AntagSelectionSystem.cs b/Content.Server/Antag/AntagSelectionSystem.cs index b676762aa63c94..766f12fb14a3e3 100644 --- a/Content.Server/Antag/AntagSelectionSystem.cs +++ b/Content.Server/Antag/AntagSelectionSystem.cs @@ -124,7 +124,7 @@ private void OnJobsAssigned(RulePlayerJobsAssignedEvent args) foreach ((var _, var antagData) in QueuedAntags) { - if(antagData.Item3.Comp == comp) + if (antagData.Item3.Comp == comp) MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2); } @@ -195,7 +195,7 @@ protected override void Started(EntityUid uid, AntagSelectionComponent component if (GameTicker.RunLevel != GameRunLevel.InRound) return; - if (component.SelectionsComplete) + if (component.SelectionsComplete) // Imp edit start { if (QueuedAntags.Count != 0) { @@ -203,11 +203,25 @@ protected override void Started(EntityUid uid, AntagSelectionComponent component { if (antagData.Item3.Comp == component) MakeAntag(antagData.Item3, antagData.Item1, antagData.Item2); + + } + // Checking if antag counts meet expectations and choosing additional antags if not + var existingAntags = GetAntagMinds((uid, component)).Count; + var targetCount = GetTargetAntagCount((uid, component), null); + if (existingAntags < targetCount) + { + var playerPool = _playerManager.Sessions + .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame) + .ToList(); + if (TryGetNextAvailableDefinition((uid, component), out var def)) // Given how we're getting here this should never be false but I'm wrapping it like this anyway Because + { + ChooseAntags((uid, component), playerPool, (AntagSelectionDefinition)def, midround: true, targetCount - existingAntags); + } } } else return; - } + } // Imp edit end var players = _playerManager.Sessions .Where(x => GameTicker.PlayerGameStatuses.TryGetValue(x.UserId, out var status) && status == PlayerGameStatus.JoinedGame) @@ -242,13 +256,17 @@ public void ChooseAntags(Entity ent, IListThe players to choose from /// The antagonist selection parameters and criteria /// Disable picking players for pre-spawn antags in the middle of a round + /// Override to choose a number of additional antags if there are not enough at the start of the gamerule. public void ChooseAntags(Entity ent, IList pool, AntagSelectionDefinition def, - bool midround = false) + bool midround = false, + int number = 0) { var playerPool = GetPlayerPool(ent, pool, def); - var count = GetTargetAntagCount(ent, GetTotalPlayerCount(pool), def); + var count = number; + if (count <= 0) + count = GetTargetAntagCount(ent, GetTotalPlayerCount(pool), def); // if there is both a spawner and players getting picked, let it fall back to a spawner. var noSpawner = def.SpawnerPrototype == null;