using Content.Shared.Access; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Robust.Shared.Prototypes; namespace Content.Shared.Random.Rules; /// /// Checks for an entity nearby with the specified access. /// public sealed partial class NearbyAccessRule : RulesRule { // This exists because of door electronics contained inside doors. /// /// Does the access entity need to be anchored. /// [DataField] public bool Anchored = true; /// /// Count of entities that need to be nearby. /// [DataField] public int Count = 1; [DataField(required: true)] public List> Access = new(); [DataField] public float Range = 10f; public override bool Check(EntityManager entManager, EntityUid uid) { var xformQuery = entManager.GetEntityQuery(); if (!xformQuery.TryGetComponent(uid, out var xform) || xform.MapUid == null) { return false; } var transform = entManager.System(); var lookup = entManager.System(); var reader = entManager.System(); var found = false; var worldPos = transform.GetWorldPosition(xform, xformQuery); var count = 0; // TODO: Update this when we get the callback version var entities = new HashSet>(); lookup.GetEntitiesInRange(xform.MapID, worldPos, Range, entities); foreach (var comp in entities) { if (!reader.AreAccessTagsAllowed(Access, comp) || Anchored && (!xformQuery.TryGetComponent(comp, out var compXform) || !compXform.Anchored)) { continue; } count++; if (count < Count) continue; found = true; break; } if (!found) return Inverted; return !Inverted; } }