using Content.Shared.Humanoid; using Content.Shared.Mind; using Content.Shared.Mind.Filters; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; using Robust.Shared.Random; namespace Content.Shared.Objectives.Systems; /// /// This system stores enumerators to find valid Targets, typically searching for minds. /// Typically used in conjunction with a or an Objective. /// public sealed partial class TargetSystem : EntitySystem { [Dependency] private IRobustRandom _random = default!; [Dependency] private MobStateSystem _mobState = default!; [Dependency] private SharedMindSystem _mind = default!; private HashSet> _pickingMinds = new(); /// /// Returns a list of every living humanoid player's minds, except for a single one which is exluded. /// A new hashset is allocated for every call, consider using instead. /// public HashSet> GetAliveHumans(EntityUid? exclude = null) { var allHumans = new HashSet>(); AddAliveHumans(allHumans, exclude); return allHumans; } /// /// Adds to a hashset every living humanoid player's minds, except for a single one which is exluded. /// public void AddAliveHumans(HashSet> allHumans, EntityUid? exclude = null) { // HumanoidProfileComponent is used to prevent mice, pAIs, etc from being chosen var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out _, out var mobState)) { // the player needs to have a mind and not be the excluded one + // the player has to be alive if (!_mind.TryGetMind(uid, out var mind, out var mindComp) || mind == exclude || !_mobState.IsAlive(uid, mobState)) continue; allHumans.Add((mind, mindComp)); } } /// /// Picks a random mind from a pool after applying a list of filters. /// Returns null if no valid mind could be found. /// public Entity? PickFromPool(MindPool pool, List filters, EntityUid? exclude = null) { _pickingMinds.Clear(); pool.FindMinds(_pickingMinds, exclude, EntityManager, this); _mind.FilterMinds(_pickingMinds, filters, exclude); if (_pickingMinds.Count == 0) return null; return _random.Pick(_pickingMinds); } }