diff --git a/Content.Server/Access/Systems/AccessSystem.cs b/Content.Server/Access/Systems/AccessSystem.cs index f185d0ff980..81c7dca120a 100644 --- a/Content.Server/Access/Systems/AccessSystem.cs +++ b/Content.Server/Access/Systems/AccessSystem.cs @@ -1,7 +1,91 @@ using Content.Shared.Access.Systems; - +using Content.Shared.Access.Components; +using Content.Server.Station.Systems; +using Content.Server.AlertLevel; +using Content.Shared.Station.Components; namespace Content.Server.Access.Systems; public sealed class AccessSystem : SharedAccessSystem { + // + // Запускает обновление уровня аварийных доступов на всех сущностях с AccessReaderComponent + // + [Dependency] private readonly StationSystem _station = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAlertLevelChanged); + } + + private void OnAlertLevelChanged(AlertLevelChangedEvent ev) + { + if (!TryComp(ev.Station, out var alert)) + return; + + if (alert.AlertLevels == null) + return; + + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var reader, out var xform)) + { + if (CompOrNull(xform.GridUid)?.Station != ev.Station) + continue; + + if (alert.AlertLevels == null) + return; + + if (!TryComp(uid, out var comp)) + return; + + if (comp.AlertAccesses.Count == 0) + continue; + + Update((uid, reader)); + Dirty(uid, reader); + } + } + + // + // Устанавливает значение из прототипа в зависимости от кода + // + public void Update(Entity entity) + { + + if (!TryComp(_station.GetOwningStation(entity.Owner), out var alerts)) + return; + + if (entity.Comp.AlertAccesses.Count == 0) + return; + + if (alerts.AlertLevels == null) + return; + + if (alerts.CurrentLevel.Contains("blue")) + { + entity.Comp.AlertAccesses.TryGetValue(AccessReaderComponent.CurrentAlertLevel.blue, out var value); + entity.Comp.Group = value; + } + else if (alerts.CurrentLevel.Contains("red")) + { + entity.Comp.AlertAccesses.TryGetValue(AccessReaderComponent.CurrentAlertLevel.red, out var value); + entity.Comp.Group = value; + Dirty(entity); + } + else if (alerts.CurrentLevel.Contains("yellow")) + { + entity.Comp.AlertAccesses.TryGetValue(AccessReaderComponent.CurrentAlertLevel.yellow, out var value); + entity.Comp.Group = value; + } + else if (alerts.CurrentLevel.Contains("gamma")) + { + entity.Comp.AlertAccesses.TryGetValue(AccessReaderComponent.CurrentAlertLevel.gamma, out var value); + entity.Comp.Group = value; + } + else // Все остальные доступы + { + entity.Comp.Group = string.Empty; + } + } } diff --git a/Content.Shared/Access/Components/AccessReaderComponent.cs b/Content.Shared/Access/Components/AccessReaderComponent.cs index 804137e0fd6..e414146a017 100644 --- a/Content.Shared/Access/Components/AccessReaderComponent.cs +++ b/Content.Shared/Access/Components/AccessReaderComponent.cs @@ -1,8 +1,11 @@ +using System.Text.RegularExpressions; using Content.Shared.StationRecords; +using Content.Shared.Weapons.Melee; using Robust.Shared.GameStates; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set; +using Robust.Shared.Toolshed.Syntax; namespace Content.Shared.Access.Components; @@ -20,10 +23,20 @@ public sealed partial class AccessReaderComponent : Component [DataField] public bool Enabled = true; + // Sunrise-start + + /// + /// Именно от Group происходит проверка аварийных доступов + /// [ViewVariables(VVAccess.ReadWrite)] - [DataField("alertAccesses")] - public Dictionary> AlertAccesses = new(); + [DataField] + public ProtoId Group { get; set; } = string.Empty; + [ViewVariables(VVAccess.ReadWrite)] + [DataField] + public Dictionary> AlertAccesses { get; set; } = new(); + + [Flags] public enum CurrentAlertLevel : byte { blue, @@ -31,6 +44,8 @@ public enum CurrentAlertLevel : byte yellow, gamma } + // Sunrise-end + /// /// The set of tags that will automatically deny an allowed check, if any of them are present. /// @@ -111,13 +126,15 @@ public sealed class AccessReaderComponentState : ComponentState public List>> AccessLists; + public ProtoId Group; // Sunrise-alertAccesses + public List<(NetEntity, uint)> AccessKeys; public Queue AccessLog; public int AccessLogLimit; - public AccessReaderComponentState(bool enabled, HashSet> denyTags, List>> accessLists, List<(NetEntity, uint)> accessKeys, Queue accessLog, int accessLogLimit) + public AccessReaderComponentState(bool enabled, HashSet> denyTags, List>> accessLists, ProtoId group, List<(NetEntity, uint)> accessKeys, Queue accessLog, int accessLogLimit) { Enabled = enabled; DenyTags = denyTags; @@ -125,6 +142,7 @@ public AccessReaderComponentState(bool enabled, HashSet> acce public bool AreAccessTagsAllowedAlert(ICollection> access, AccessReaderComponent reader) { - foreach (var (stationCode, alertAccesses) in reader.AlertAccesses) - { - if (!_prototype.TryIndex(alertAccesses, out var accessTags)) - return false; + if (reader.Group == string.Empty) + return false; - if (accessTags == null) - return false; + if (!_prototype.TryIndex(reader.Group, out var accessTags)) + return false; - if (accessTags.Tags.Count == 0) - return false; + if (accessTags == null) + return false; - if (accessTags.Tags.IsSubsetOf(access)) + if (accessTags.Tags.Count == 0) + return false; + foreach (var ent in accessTags.Tags) + { + if (access.Contains(ent)) return true; } + return false; } diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml index c0bbb2e5275..0e2cf98938b 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml @@ -89,6 +89,10 @@ components: - type: AccessReader access: [["Janitor"]] + alertAccesses: + red: RedAlertAccesses + blue: BlueAlertAccesses + yellow: YellowAlertAccesses - type: entity parent: DoorElectronics @@ -105,6 +109,9 @@ components: - type: AccessReader access: [["Service"]] + alertAccess: + red: RedAlertAccesses + yellow: YellowAlertAccesses # Cargo - type: entity diff --git a/Resources/Prototypes/_Sunrise/Access/AccessGroup/access_group.yml b/Resources/Prototypes/_Sunrise/Access/AccessGroup/access_group.yml index 9a3526ea38a..3a2a0763c5d 100644 --- a/Resources/Prototypes/_Sunrise/Access/AccessGroup/access_group.yml +++ b/Resources/Prototypes/_Sunrise/Access/AccessGroup/access_group.yml @@ -2,21 +2,25 @@ id: RedAlertAccesses tags: - Security + - HeadOfSecurity - type: accessGroup - id: SecurityBlueAlertAccesses + id: BlueAlertAccesses tags: - - Maintance + - Security + - HeadOfSecurity - type: accessGroup - id: SecurityGammaAlertAccesses + id: YellowAlertAccesses tags: - - Command - - Captain - - HeadOfPersonnel - - Cryogenics - - BlueShield - - Ntrep + - Engineering + - HeadOfSecurity + +- type: accessGroup + id: GammaAlertAccesses + tags: + - Security + - HeadOfSecurity # Потом дополню доступы