NearbyAccess.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using Content.Shared.Access;
  2. using Content.Shared.Access.Components;
  3. using Content.Shared.Access.Systems;
  4. using Robust.Shared.Prototypes;
  5. namespace Content.Shared.Random.Rules;
  6. /// <summary>
  7. /// Checks for an entity nearby with the specified access.
  8. /// </summary>
  9. public sealed partial class NearbyAccessRule : RulesRule
  10. {
  11. // This exists because of door electronics contained inside doors.
  12. /// <summary>
  13. /// Does the access entity need to be anchored.
  14. /// </summary>
  15. [DataField]
  16. public bool Anchored = true;
  17. /// <summary>
  18. /// Count of entities that need to be nearby.
  19. /// </summary>
  20. [DataField]
  21. public int Count = 1;
  22. [DataField(required: true)]
  23. public List<ProtoId<AccessLevelPrototype>> Access = new();
  24. [DataField]
  25. public float Range = 10f;
  26. public override bool Check(EntityManager entManager, EntityUid uid)
  27. {
  28. var xformQuery = entManager.GetEntityQuery<TransformComponent>();
  29. if (!xformQuery.TryGetComponent(uid, out var xform) ||
  30. xform.MapUid == null)
  31. {
  32. return false;
  33. }
  34. var transform = entManager.System<SharedTransformSystem>();
  35. var lookup = entManager.System<EntityLookupSystem>();
  36. var reader = entManager.System<AccessReaderSystem>();
  37. var found = false;
  38. var worldPos = transform.GetWorldPosition(xform, xformQuery);
  39. var count = 0;
  40. // TODO: Update this when we get the callback version
  41. var entities = new HashSet<Entity<AccessReaderComponent>>();
  42. lookup.GetEntitiesInRange(xform.MapID, worldPos, Range, entities);
  43. foreach (var comp in entities)
  44. {
  45. if (!reader.AreAccessTagsAllowed(Access, comp) ||
  46. Anchored &&
  47. (!xformQuery.TryGetComponent(comp, out var compXform) ||
  48. !compXform.Anchored))
  49. {
  50. continue;
  51. }
  52. count++;
  53. if (count < Count)
  54. continue;
  55. found = true;
  56. break;
  57. }
  58. if (!found)
  59. return Inverted;
  60. return !Inverted;
  61. }
  62. }