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);
}
}