using Content.Shared.Access; using Content.Shared.Access.Systems; using JetBrains.Annotations; using Robust.Shared.Prototypes; namespace Content.Shared.Turrets; /// /// This system is used for validating potential targets for NPCs with a (i.e., turrets). /// A turret will consider an entity a valid target if the entity does not possess any access tags which appear on the /// turret's list. /// public sealed partial class TurretTargetSettingsSystem : EntitySystem { [Dependency] private readonly AccessReaderSystem _accessReader = default!; private ProtoId _accessLevelBorg = "Borg"; private ProtoId _accessLevelBasicSilicon = "BasicSilicon"; /// /// Adds or removes access levels from a list. /// /// The entity and its /// The proto ID for the access level /// Set 'true' to add the exemption, or 'false' to remove it [PublicAPI] public void SetAccessLevelExemption(Entity ent, ProtoId exemption, bool enabled) { if (enabled) ent.Comp.ExemptAccessLevels.Add(exemption); else ent.Comp.ExemptAccessLevels.Remove(exemption); } /// /// Adds or removes a collection of access levels from a list. /// /// The entity and its /// The collection of access level proto IDs to add or remove /// Set 'true' to add the collection as exemptions, or 'false' to remove them [PublicAPI] public void SetAccessLevelExemptions(Entity ent, ICollection> exemptions, bool enabled) { foreach (var exemption in exemptions) SetAccessLevelExemption(ent, exemption, enabled); } /// /// Sets a list to contain only a supplied collection of access levels. /// /// The entity and its /// The supplied collection of access level proto IDs [PublicAPI] public void SyncAccessLevelExemptions(Entity ent, ICollection> exemptions) { ent.Comp.ExemptAccessLevels.Clear(); SetAccessLevelExemptions(ent, exemptions, true); } /// /// Sets a list to match that of another. /// /// The entity this is having its exemption list updated /// The entity that is being used as a template for the target [PublicAPI] public void SyncAccessLevelExemptions(Entity target, Entity source) { SyncAccessLevelExemptions(target, source.Comp.ExemptAccessLevels); } /// /// Returns whether a list contains a specific access level. /// /// The entity and its /// The access level proto ID being checked [PublicAPI] public bool HasAccessLevelExemption(Entity ent, ProtoId exemption) { if (ent.Comp.ExemptAccessLevels.Count == 0) return false; return ent.Comp.ExemptAccessLevels.Contains(exemption); } /// /// Returns whether a list contains one or more access levels from another collection. /// /// The entity and its /// [PublicAPI] public bool HasAnyAccessLevelExemption(Entity ent, ICollection> exemptions) { if (ent.Comp.ExemptAccessLevels.Count == 0) return false; foreach (var exemption in exemptions) { if (HasAccessLevelExemption(ent, exemption)) return true; } return false; } /// /// Returns whether an entity is a valid target for a turret. /// /// /// Returns false if the target possesses one or more access tags that are present on the entity's list. /// /// The entity and its /// The target entity [PublicAPI] public bool EntityIsTargetForTurret(Entity ent, EntityUid target) { var accessLevels = _accessReader.FindAccessTags(target); if (accessLevels.Contains(_accessLevelBorg)) return !HasAccessLevelExemption(ent, _accessLevelBorg); if (accessLevels.Contains(_accessLevelBasicSilicon)) return !HasAccessLevelExemption(ent, _accessLevelBasicSilicon); return !HasAnyAccessLevelExemption(ent, accessLevels); } }