TurretTargetSettingsSystem.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using Content.Shared.Access;
  2. using Content.Shared.Access.Systems;
  3. using JetBrains.Annotations;
  4. using Robust.Shared.Prototypes;
  5. namespace Content.Shared.Turrets;
  6. /// <summary>
  7. /// This system is used for validating potential targets for NPCs with a <see cref="TurretTargetSettingsComponent"/> (i.e., turrets).
  8. /// A turret will consider an entity a valid target if the entity does not possess any access tags which appear on the
  9. /// turret's <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list.
  10. /// </summary>
  11. public sealed partial class TurretTargetSettingsSystem : EntitySystem
  12. {
  13. [Dependency] private readonly AccessReaderSystem _accessReader = default!;
  14. private ProtoId<AccessLevelPrototype> _accessLevelBorg = "Borg";
  15. private ProtoId<AccessLevelPrototype> _accessLevelBasicSilicon = "BasicSilicon";
  16. /// <summary>
  17. /// Adds or removes access levels from a <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list.
  18. /// </summary>
  19. /// <param name="ent">The entity and its <see cref="TurretTargetSettingsComponent"/></param>
  20. /// <param name="exemption">The proto ID for the access level</param>
  21. /// <param name="enabled">Set 'true' to add the exemption, or 'false' to remove it</param>
  22. [PublicAPI]
  23. public void SetAccessLevelExemption(Entity<TurretTargetSettingsComponent> ent, ProtoId<AccessLevelPrototype> exemption, bool enabled)
  24. {
  25. if (enabled)
  26. ent.Comp.ExemptAccessLevels.Add(exemption);
  27. else
  28. ent.Comp.ExemptAccessLevels.Remove(exemption);
  29. }
  30. /// <summary>
  31. /// Adds or removes a collection of access levels from a <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list.
  32. /// </summary>
  33. /// <param name="ent">The entity and its <see cref="TurretTargetSettingsComponent"/></param>
  34. /// <param name="exemption">The collection of access level proto IDs to add or remove</param>
  35. /// <param name="enabled">Set 'true' to add the collection as exemptions, or 'false' to remove them</param>
  36. [PublicAPI]
  37. public void SetAccessLevelExemptions(Entity<TurretTargetSettingsComponent> ent, ICollection<ProtoId<AccessLevelPrototype>> exemptions, bool enabled)
  38. {
  39. foreach (var exemption in exemptions)
  40. SetAccessLevelExemption(ent, exemption, enabled);
  41. }
  42. /// <summary>
  43. /// Sets a <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list to contain only a supplied collection of access levels.
  44. /// </summary>
  45. /// <param name="ent">The entity and its <see cref="TurretTargetSettingsComponent"/></param>
  46. /// <param name="exemptions">The supplied collection of access level proto IDs</param>
  47. [PublicAPI]
  48. public void SyncAccessLevelExemptions(Entity<TurretTargetSettingsComponent> ent, ICollection<ProtoId<AccessLevelPrototype>> exemptions)
  49. {
  50. ent.Comp.ExemptAccessLevels.Clear();
  51. SetAccessLevelExemptions(ent, exemptions, true);
  52. }
  53. /// <summary>
  54. /// Sets a <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list to match that of another.
  55. /// </summary>
  56. /// <param name="target">The entity this is having its exemption list updated <see cref="TurretTargetSettingsComponent"/></param>
  57. /// <param name="source">The entity that is being used as a template for the target</param>
  58. [PublicAPI]
  59. public void SyncAccessLevelExemptions(Entity<TurretTargetSettingsComponent> target, Entity<TurretTargetSettingsComponent> source)
  60. {
  61. SyncAccessLevelExemptions(target, source.Comp.ExemptAccessLevels);
  62. }
  63. /// <summary>
  64. /// Returns whether a <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list contains a specific access level.
  65. /// </summary>
  66. /// <param name="ent">The entity and its <see cref="TurretTargetSettingsComponent"/></param>
  67. /// <param name="exemption">The access level proto ID being checked</param>
  68. [PublicAPI]
  69. public bool HasAccessLevelExemption(Entity<TurretTargetSettingsComponent> ent, ProtoId<AccessLevelPrototype> exemption)
  70. {
  71. if (ent.Comp.ExemptAccessLevels.Count == 0)
  72. return false;
  73. return ent.Comp.ExemptAccessLevels.Contains(exemption);
  74. }
  75. /// <summary>
  76. /// Returns whether a <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list contains one or more access levels from another collection.
  77. /// </summary>
  78. /// <param name="ent">The entity and its <see cref="TurretTargetSettingsComponent"/></param>
  79. /// <param name="exemptions"></param>
  80. [PublicAPI]
  81. public bool HasAnyAccessLevelExemption(Entity<TurretTargetSettingsComponent> ent, ICollection<ProtoId<AccessLevelPrototype>> exemptions)
  82. {
  83. if (ent.Comp.ExemptAccessLevels.Count == 0)
  84. return false;
  85. foreach (var exemption in exemptions)
  86. {
  87. if (HasAccessLevelExemption(ent, exemption))
  88. return true;
  89. }
  90. return false;
  91. }
  92. /// <summary>
  93. /// Returns whether an entity is a valid target for a turret.
  94. /// </summary>
  95. /// <remarks>
  96. /// Returns false if the target possesses one or more access tags that are present on the entity's <see cref="TurretTargetSettingsComponent.ExemptAccessLevels"/> list.
  97. /// </remarks>
  98. /// <param name="ent">The entity and its <see cref="TurretTargetSettingsComponent"/></param>
  99. /// <param name="target">The target entity</param>
  100. [PublicAPI]
  101. public bool EntityIsTargetForTurret(Entity<TurretTargetSettingsComponent> ent, EntityUid target)
  102. {
  103. var accessLevels = _accessReader.FindAccessTags(target);
  104. if (accessLevels.Contains(_accessLevelBorg))
  105. return !HasAccessLevelExemption(ent, _accessLevelBorg);
  106. if (accessLevels.Contains(_accessLevelBasicSilicon))
  107. return !HasAccessLevelExemption(ent, _accessLevelBasicSilicon);
  108. return !HasAnyAccessLevelExemption(ent, accessLevels);
  109. }
  110. }