diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml b/Content.Client/Access/UI/AccessLevelControl.xaml
new file mode 100644
index 0000000000..56968d8983
--- /dev/null
+++ b/Content.Client/Access/UI/AccessLevelControl.xaml
@@ -0,0 +1,4 @@
+
+
diff --git a/Content.Client/Access/UI/AccessLevelControl.xaml.cs b/Content.Client/Access/UI/AccessLevelControl.xaml.cs
new file mode 100644
index 0000000000..34db80b7af
--- /dev/null
+++ b/Content.Client/Access/UI/AccessLevelControl.xaml.cs
@@ -0,0 +1,52 @@
+using System.Linq;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Prototypes;
+using Content.Shared.Access;
+using Content.Shared.Access.Systems;
+
+namespace Content.Client.Access.UI;
+
+[GenerateTypedNameReferences]
+public sealed partial class AccessLevelControl : GridContainer
+{
+ public readonly Dictionary, Button> ButtonsList = new();
+
+ public AccessLevelControl()
+ {
+ RobustXamlLoader.Load(this);
+ }
+
+ public void Populate(List> accessLevels, IPrototypeManager prototypeManager)
+ {
+ foreach (var access in accessLevels)
+ {
+ if (!prototypeManager.TryIndex(access, out var accessLevel))
+ {
+ Logger.Error($"Unable to find accesslevel for {access}");
+ continue;
+ }
+
+ var newButton = new Button
+ {
+ Text = accessLevel.GetAccessLevelName(),
+ ToggleMode = true,
+ };
+ AddChild(newButton);
+ ButtonsList.Add(accessLevel.ID, newButton);
+ }
+ }
+
+ public void UpdateState(
+ List> pressedList,
+ List>? enabledList = null)
+ {
+ foreach (var (accessName, button) in ButtonsList)
+ {
+ button.Pressed = pressedList.Contains(accessName);
+ button.Disabled = !(enabledList?.Contains(accessName) ?? true);
+ }
+ }
+}
diff --git a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs
index 0c23542f79..c1b63dc4d0 100644
--- a/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs
+++ b/Content.Client/Access/UI/AccessOverriderBoundUserInterface.cs
@@ -64,7 +64,7 @@ namespace Content.Client.Access.UI
_window?.UpdateState(castState);
}
- public void SubmitData(List newAccessList)
+ public void SubmitData(List> newAccessList)
{
SendMessage(new WriteToTargetAccessReaderIdMessage(newAccessList));
}
diff --git a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs
index 2fd0057121..6025c3b551 100644
--- a/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs
+++ b/Content.Client/Access/UI/AccessOverriderWindow.xaml.cs
@@ -16,7 +16,6 @@ namespace Content.Client.Access.UI
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- private readonly ISawmill _logMill = default!;
private readonly AccessOverriderBoundUserInterface _owner;
private readonly Dictionary _accessButtons = new();
@@ -25,7 +24,7 @@ namespace Content.Client.Access.UI
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
- _logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill);
+ var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill);
_owner = owner;
@@ -33,13 +32,13 @@ namespace Content.Client.Access.UI
{
if (!prototypeManager.TryIndex(access, out var accessLevel))
{
- _logMill.Error($"Unable to find accesslevel for {access}");
+ logMill.Error($"Unable to find accesslevel for {access}");
continue;
}
var newButton = new Button
{
- Text = GetAccessLevelName(accessLevel),
+ Text = accessLevel.GetAccessLevelName(),
ToggleMode = true,
};
@@ -49,14 +48,6 @@ namespace Content.Client.Access.UI
}
}
- private static string GetAccessLevelName(AccessLevelPrototype prototype)
- {
- if (prototype.Name is { } name)
- return Loc.GetString(name);
-
- return prototype.ID;
- }
-
public void UpdateState(AccessOverriderBoundUserInterfaceState state)
{
PrivilegedIdLabel.Text = state.PrivilegedIdName;
@@ -105,7 +96,7 @@ namespace Content.Client.Access.UI
_owner.SubmitData(
// Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair
- _accessButtons.Where(x => x.Value.Pressed).Select(x => x.Key).ToList());
+ _accessButtons.Where(x => x.Value.Pressed).Select(x => new ProtoId(x.Key)).ToList());
}
}
}
diff --git a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs
index 898792aa03..5b7011c195 100644
--- a/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs
+++ b/Content.Client/Access/UI/IdCardConsoleBoundUserInterface.cs
@@ -1,5 +1,6 @@
using Content.Shared.Access;
using Content.Shared.Access.Components;
+using Content.Shared.Access;
using Content.Shared.Access.Systems;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.CrewManifest;
@@ -28,7 +29,6 @@ namespace Content.Client.Access.UI
if (EntMan.TryGetComponent(Owner, out var idCard))
{
accessLevels = idCard.AccessLevels;
- accessLevels.Sort();
}
else
{
@@ -65,7 +65,7 @@ namespace Content.Client.Access.UI
_window?.UpdateState(castState);
}
- public void SubmitData(string newFullName, string newJobTitle, List newAccessList, string newJobPrototype)
+ public void SubmitData(string newFullName, string newJobTitle, List> newAccessList, string newJobPrototype)
{
if (newFullName.Length > MaxFullNameLength)
newFullName = newFullName[..MaxFullNameLength];
diff --git a/Content.Client/Access/UI/IdCardConsoleWindow.xaml b/Content.Client/Access/UI/IdCardConsoleWindow.xaml
index c29adc8ebd..a2f5f3382b 100644
--- a/Content.Client/Access/UI/IdCardConsoleWindow.xaml
+++ b/Content.Client/Access/UI/IdCardConsoleWindow.xaml
@@ -30,10 +30,6 @@
-
-
-
-
-
+
diff --git a/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs b/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
index bf5984e809..298912e7d5 100644
--- a/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
+++ b/Content.Client/Access/UI/IdCardConsoleWindow.xaml.cs
@@ -20,7 +20,7 @@ namespace Content.Client.Access.UI
private readonly IdCardConsoleBoundUserInterface _owner;
- private readonly Dictionary _accessButtons = new();
+ private AccessLevelControl _accessButtons = new();
private readonly List _jobPrototypeIds = new();
private string? _lastFullName;
@@ -66,36 +66,18 @@ namespace Content.Client.Access.UI
JobPresetOptionButton.OnItemSelected += SelectJobPreset;
- foreach (var access in accessLevels)
+ _accessButtons.Populate(accessLevels, prototypeManager);
+ AccessLevelControlContainer.AddChild(_accessButtons);
+
+ foreach (var (id, button) in _accessButtons.ButtonsList)
{
- if (!prototypeManager.TryIndex(access, out var accessLevel))
- {
- _logMill.Error($"Unable to find accesslevel for {access}");
- continue;
- }
-
- var newButton = new Button
- {
- Text = GetAccessLevelName(accessLevel),
- ToggleMode = true,
- };
- AccessLevelGrid.AddChild(newButton);
- _accessButtons.Add(accessLevel.ID, newButton);
- newButton.OnPressed += _ => SubmitData();
+ button.OnPressed += _ => SubmitData();
}
}
- private static string GetAccessLevelName(AccessLevelPrototype prototype)
- {
- if (prototype.Name is { } name)
- return Loc.GetString(name);
-
- return prototype.ID;
- }
-
private void ClearAllAccess()
{
- foreach (var button in _accessButtons.Values)
+ foreach (var button in _accessButtons.ButtonsList.Values)
{
if (button.Pressed)
{
@@ -119,7 +101,7 @@ namespace Content.Client.Access.UI
// this is a sussy way to do this
foreach (var access in job.Access)
{
- if (_accessButtons.TryGetValue(access, out var button) && !button.Disabled)
+ if (_accessButtons.ButtonsList.TryGetValue(access, out var button) && !button.Disabled)
{
button.Pressed = true;
}
@@ -134,7 +116,7 @@ namespace Content.Client.Access.UI
foreach (var access in groupPrototype.Tags)
{
- if (_accessButtons.TryGetValue(access, out var button) && !button.Disabled)
+ if (_accessButtons.ButtonsList.TryGetValue(access, out var button) && !button.Disabled)
{
button.Pressed = true;
}
@@ -184,15 +166,10 @@ namespace Content.Client.Access.UI
JobPresetOptionButton.Disabled = !interfaceEnabled;
- foreach (var (accessName, button) in _accessButtons)
- {
- button.Disabled = !interfaceEnabled;
- if (interfaceEnabled)
- {
- button.Pressed = state.TargetIdAccessList?.Contains(accessName) ?? false;
- button.Disabled = (!state.AllowedModifyAccessList?.Contains(accessName)) ?? true;
- }
- }
+ _accessButtons.UpdateState(state.TargetIdAccessList?.ToList() ??
+ new List>(),
+ state.AllowedModifyAccessList?.ToList() ??
+ new List>());
var jobIndex = _jobPrototypeIds.IndexOf(state.TargetIdJobPrototype);
if (jobIndex >= 0)
@@ -215,7 +192,7 @@ namespace Content.Client.Access.UI
FullNameLineEdit.Text,
JobTitleLineEdit.Text,
// Iterate over the buttons dictionary, filter by `Pressed`, only get key from the key/value pair
- _accessButtons.Where(x => x.Value.Pressed).Select(x => x.Key).ToList(),
+ _accessButtons.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList(),
jobProtoDirty ? _jobPrototypeIds[JobPresetOptionButton.SelectedId] : string.Empty);
}
}
diff --git a/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs
new file mode 100644
index 0000000000..cd7ea717ce
--- /dev/null
+++ b/Content.Client/Doors/Electronics/DoorElectronicsBoundUserInterface.cs
@@ -0,0 +1,59 @@
+using Content.Shared.Access;
+using Content.Shared.Doors.Electronics;
+using Robust.Client.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.Client.Doors.Electronics;
+
+public sealed class DoorElectronicsBoundUserInterface : BoundUserInterface
+{
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+
+ private DoorElectronicsConfigurationMenu? _window;
+
+ public DoorElectronicsBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
+ {
+ }
+
+ protected override void Open()
+ {
+ base.Open();
+ List> accessLevels = new();
+
+ foreach (var accessLevel in _prototypeManager.EnumeratePrototypes())
+ {
+ if (accessLevel.Name != null)
+ {
+ accessLevels.Add(accessLevel.ID);
+ }
+ }
+
+ accessLevels.Sort();
+
+ _window = new DoorElectronicsConfigurationMenu(this, accessLevels, _prototypeManager);
+ _window.OnClose += Close;
+ _window.OpenCentered();
+ }
+
+ protected override void UpdateState(BoundUserInterfaceState state)
+ {
+ base.UpdateState(state);
+
+ var castState = (DoorElectronicsConfigurationState) state;
+
+ _window?.UpdateState(castState);
+ }
+
+ protected override void Dispose(bool disposing)
+ {
+ base.Dispose(disposing);
+ if (!disposing) return;
+
+ _window?.Dispose();
+ }
+
+ public void UpdateConfiguration(List> newAccessList)
+ {
+ SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList));
+ }
+}
diff --git a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml
new file mode 100644
index 0000000000..4cd59f38b2
--- /dev/null
+++ b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs
new file mode 100644
index 0000000000..c01f13a462
--- /dev/null
+++ b/Content.Client/Doors/Electronics/DoorElectronicsConfigurationMenu.xaml.cs
@@ -0,0 +1,41 @@
+using System.Linq;
+using Robust.Client.AutoGenerated;
+using Robust.Client.UserInterface.Controls;
+using Robust.Client.UserInterface.CustomControls;
+using Robust.Client.UserInterface.XAML;
+using Robust.Shared.Prototypes;
+using Content.Client.Access.UI;
+using Content.Client.Doors.Electronics;
+using Content.Shared.Access;
+using Content.Shared.Doors.Electronics;
+using FancyWindow = Content.Client.UserInterface.Controls.FancyWindow;
+
+namespace Content.Client.Doors.Electronics;
+
+[GenerateTypedNameReferences]
+public sealed partial class DoorElectronicsConfigurationMenu : FancyWindow
+{
+ private readonly DoorElectronicsBoundUserInterface _owner;
+ private AccessLevelControl _buttonsList = new();
+
+ public DoorElectronicsConfigurationMenu(DoorElectronicsBoundUserInterface ui, List> accessLevels, IPrototypeManager prototypeManager)
+ {
+ RobustXamlLoader.Load(this);
+
+ _owner = ui;
+
+ _buttonsList.Populate(accessLevels, prototypeManager);
+ AccessLevelControlContainer.AddChild(_buttonsList);
+
+ foreach (var (id, button) in _buttonsList.ButtonsList)
+ {
+ button.OnPressed += _ => _owner.UpdateConfiguration(
+ _buttonsList.ButtonsList.Where(x => x.Value.Pressed).Select(x => x.Key).ToList());
+ }
+ }
+
+ public void UpdateState(DoorElectronicsConfigurationState state)
+ {
+ _buttonsList.UpdateState(state.AccessList);
+ }
+}
diff --git a/Content.IntegrationTests/Tests/Access/AccessReaderTest.cs b/Content.IntegrationTests/Tests/Access/AccessReaderTest.cs
index 7d86fc2f6c..895bb2cf87 100644
--- a/Content.IntegrationTests/Tests/Access/AccessReaderTest.cs
+++ b/Content.IntegrationTests/Tests/Access/AccessReaderTest.cs
@@ -57,9 +57,9 @@ namespace Content.IntegrationTests.Tests.Access
var reader = new AccessReaderComponent();
Assert.Multiple(() =>
{
- Assert.That(system.AreAccessTagsAllowed(new[] { "Foo" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "Bar" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(Array.Empty(), reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "Foo" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "Bar" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty>(), reader), Is.True);
});
// test deny
@@ -67,58 +67,58 @@ namespace Content.IntegrationTests.Tests.Access
reader.DenyTags.Add("A");
Assert.Multiple(() =>
{
- Assert.That(system.AreAccessTagsAllowed(new[] { "Foo" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(new[] { "A", "Foo" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(Array.Empty(), reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "Foo" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A", "Foo" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty>(), reader), Is.True);
});
// test one list
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet { "A" });
+ reader.AccessLists.Add(new HashSet> { "A" });
Assert.Multiple(() =>
{
- Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(Array.Empty(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty>(), reader), Is.False);
});
// test one list - two items
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet { "A", "B" });
+ reader.AccessLists.Add(new HashSet> { "A", "B" });
Assert.Multiple(() =>
{
- Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(Array.Empty(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty>(), reader), Is.False);
});
// test two list
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet { "A" });
- reader.AccessLists.Add(new HashSet { "B", "C" });
+ reader.AccessLists.Add(new HashSet> { "A" });
+ reader.AccessLists.Add(new HashSet> { "B", "C" });
Assert.Multiple(() =>
{
- Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "C", "B" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "C", "B", "A" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(Array.Empty(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "C", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "C", "B", "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty>(), reader), Is.False);
});
// test deny list
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet { "A" });
+ reader.AccessLists.Add(new HashSet> { "A" });
reader.DenyTags.Add("B");
Assert.Multiple(() =>
{
- Assert.That(system.AreAccessTagsAllowed(new[] { "A" }, reader), Is.True);
- Assert.That(system.AreAccessTagsAllowed(new[] { "B" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(new[] { "A", "B" }, reader), Is.False);
- Assert.That(system.AreAccessTagsAllowed(Array.Empty(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List> { "A", "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty>(), reader), Is.False);
});
});
await pair.CleanReturnAsync();
diff --git a/Content.Server/Access/Systems/AccessOverriderSystem.cs b/Content.Server/Access/Systems/AccessOverriderSystem.cs
index 684312c7c1..25f2e4c1b0 100644
--- a/Content.Server/Access/Systems/AccessOverriderSystem.cs
+++ b/Content.Server/Access/Systems/AccessOverriderSystem.cs
@@ -1,5 +1,6 @@
using System.Linq;
using Content.Server.Popups;
+using Content.Shared.Access;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Administration.Logs;
@@ -12,6 +13,7 @@ using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
using static Content.Shared.Access.Components.AccessOverriderComponent;
namespace Content.Server.Access.Systems;
@@ -26,6 +28,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
+ [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
public override void Initialize()
{
@@ -108,17 +111,20 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
var targetLabel = Loc.GetString("access-overrider-window-no-target");
var targetLabelColor = Color.Red;
- string[]? possibleAccess = null;
- string[]? currentAccess = null;
- string[]? missingAccess = null;
+ ProtoId[]? possibleAccess = null;
+ ProtoId[]? currentAccess = null;
+ ProtoId[]? missingAccess = null;
if (component.TargetAccessReaderId is { Valid: true } accessReader)
{
targetLabel = Loc.GetString("access-overrider-window-target-label") + " " + EntityManager.GetComponent(component.TargetAccessReaderId).EntityName;
targetLabelColor = Color.White;
- List> currentAccessHashsets = EntityManager.GetComponent(accessReader).AccessLists;
- currentAccess = ConvertAccessHashSetsToList(currentAccessHashsets)?.ToArray();
+ if (!_accessReader.GetMainAccessReader(accessReader, out var accessReaderComponent))
+ return;
+
+ var currentAccessHashsets = accessReaderComponent.AccessLists;
+ currentAccess = ConvertAccessHashSetsToList(currentAccessHashsets).ToArray();
}
if (component.PrivilegedIdSlot.Item is { Valid: true } idCard)
@@ -151,15 +157,15 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
_userInterface.TrySetUiState(uid, AccessOverriderUiKey.Key, newState);
}
- private List ConvertAccessHashSetsToList(List> accessHashsets)
+ private List> ConvertAccessHashSetsToList(List>> accessHashsets)
{
- List accessList = new List();
+ List> accessList = new List>();
if (accessHashsets != null && accessHashsets.Any())
{
- foreach (HashSet hashSet in accessHashsets)
+ foreach (HashSet> hashSet in accessHashsets)
{
- foreach (string hash in hashSet.ToArray())
+ foreach (ProtoId hash in hashSet.ToArray())
{
accessList.Add(hash);
}
@@ -169,15 +175,15 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
return accessList;
}
- private List> ConvertAccessListToHashSet(List accessList)
+ private List>> ConvertAccessListToHashSet(List> accessList)
{
- List> accessHashsets = new List>();
+ List>> accessHashsets = new List>>();
if (accessList != null && accessList.Any())
{
- foreach (string access in accessList)
+ foreach (ProtoId access in accessList)
{
- accessHashsets.Add(new HashSet() { access });
+ accessHashsets.Add(new HashSet>() { access });
}
}
@@ -188,7 +194,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
/// Called whenever an access button is pressed, adding or removing that access requirement from the target access reader.
///
private void TryWriteToTargetAccessReaderId(EntityUid uid,
- List newAccessList,
+ List> newAccessList,
EntityUid player,
AccessOverriderComponent? component = null)
{
@@ -211,9 +217,7 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
return;
}
- TryComp(component.TargetAccessReaderId, out AccessReaderComponent? accessReader);
-
- if (accessReader == null)
+ if (!_accessReader.GetMainAccessReader(component.TargetAccessReaderId, out var accessReader))
return;
var oldTags = ConvertAccessHashSetsToList(accessReader.AccessLists);
@@ -262,10 +266,10 @@ public sealed class AccessOverriderSystem : SharedAccessOverriderSystem
if (!Resolve(uid, ref component))
return true;
- if (!EntityManager.TryGetComponent(uid, out var reader))
+ if (_accessReader.GetMainAccessReader(uid, out var accessReader))
return true;
var privilegedId = component.PrivilegedIdSlot.Item;
- return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, uid, reader);
+ return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, uid, accessReader);
}
}
diff --git a/Content.Server/Access/Systems/IdCardConsoleSystem.cs b/Content.Server/Access/Systems/IdCardConsoleSystem.cs
index 791159f972..db8b9d036e 100644
--- a/Content.Server/Access/Systems/IdCardConsoleSystem.cs
+++ b/Content.Server/Access/Systems/IdCardConsoleSystem.cs
@@ -12,6 +12,7 @@ using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
using System.Linq;
using static Content.Shared.Access.Components.IdCardConsoleComponent;
+using Content.Shared.Access;
namespace Content.Server.Access.Systems;
@@ -54,11 +55,11 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
return;
var privilegedIdName = string.Empty;
- string[]? possibleAccess = null;
+ List>? possibleAccess = null;
if (component.PrivilegedIdSlot.Item is { Valid: true } item)
{
privilegedIdName = EntityManager.GetComponent(item).EntityName;
- possibleAccess = _accessReader.FindAccessTags(item).ToArray();
+ possibleAccess = _accessReader.FindAccessTags(item).ToList();
}
IdCardConsoleBoundUserInterfaceState newState;
@@ -82,7 +83,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
var targetIdComponent = EntityManager.GetComponent(targetId);
var targetAccessComponent = EntityManager.GetComponent(targetId);
- var jobProto = string.Empty;
+ var jobProto = new ProtoId(string.Empty);
if (TryComp(targetId, out var keyStorage)
&& keyStorage.Key is {} key
&& _record.TryGetRecord(key, out var record))
@@ -96,7 +97,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
true,
targetIdComponent.FullName,
targetIdComponent.JobTitle,
- targetAccessComponent.Tags.ToArray(),
+ targetAccessComponent.Tags.ToList(),
possibleAccess,
jobProto,
privilegedIdName,
@@ -113,8 +114,8 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
private void TryWriteToTargetId(EntityUid uid,
string newFullName,
string newJobTitle,
- List newAccessList,
- string newJobProto,
+ List> newAccessList,
+ ProtoId newJobProto,
EntityUid player,
IdCardConsoleComponent? component = null)
{
@@ -140,7 +141,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
return;
}
- var oldTags = _access.TryGetTags(targetId) ?? new List();
+ var oldTags = _access.TryGetTags(targetId) ?? new List>();
oldTags = oldTags.ToList();
var privilegedId = component.PrivilegedIdSlot.Item;
@@ -189,7 +190,7 @@ public sealed class IdCardConsoleSystem : SharedIdCardConsoleSystem
return privilegedId != null && _accessReader.IsAllowed(privilegedId.Value, uid, reader);
}
- private void UpdateStationRecord(EntityUid uid, EntityUid targetId, string newFullName, string newJobTitle, JobPrototype? newJobProto)
+ private void UpdateStationRecord(EntityUid uid, EntityUid targetId, string newFullName, ProtoId newJobTitle, JobPrototype? newJobProto)
{
if (!TryComp(targetId, out var keyStorage)
|| keyStorage.Key is not { } key
diff --git a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs
index 9d66338c8b..328fa74484 100644
--- a/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs
+++ b/Content.Server/Administration/Systems/AdminVerbSystem.Tools.cs
@@ -35,6 +35,7 @@ using Robust.Shared.Map.Components;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Administration.Systems;
@@ -844,14 +845,14 @@ public sealed partial class AdminVerbSystem
{
var allAccess = _prototypeManager
.EnumeratePrototypes()
- .Select(p => p.ID).ToArray();
+ .Select(p => new ProtoId(p.ID)).ToArray();
_accessSystem.TrySetTags(entity, allAccess);
}
private void RevokeAllAccess(EntityUid entity)
{
- _accessSystem.TrySetTags(entity, Array.Empty());
+ _accessSystem.TrySetTags(entity, new List>());
}
public enum TricksVerbPriorities
diff --git a/Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs b/Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs
new file mode 100644
index 0000000000..56e8bd50b3
--- /dev/null
+++ b/Content.Server/Doors/Electronics/Systems/DoorElectronicsSystem.cs
@@ -0,0 +1,69 @@
+using System.Linq;
+using Content.Server.Doors.Electronics;
+using Content.Shared.Access;
+using Content.Shared.Access.Components;
+using Content.Shared.Access.Systems;
+using Content.Shared.DeviceNetwork.Components;
+using Content.Shared.Doors.Electronics;
+using Content.Shared.Doors;
+using Content.Shared.Interaction;
+using Robust.Server.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.Server.Doors.Electronics;
+
+public sealed class DoorElectronicsSystem : EntitySystem
+{
+ [Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
+ [Dependency] private readonly AccessReaderSystem _accessReader = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnChangeConfiguration);
+ SubscribeLocalEvent(OnAccessReaderChanged);
+ SubscribeLocalEvent(OnBoundUIOpened);
+ }
+
+ public void UpdateUserInterface(EntityUid uid, DoorElectronicsComponent component)
+ {
+ var accesses = new List>();
+
+ if (TryComp(uid, out var accessReader))
+ {
+ foreach (var accessList in accessReader.AccessLists)
+ {
+ var access = accessList.FirstOrDefault();
+ accesses.Add(access);
+ }
+ }
+
+ var state = new DoorElectronicsConfigurationState(accesses);
+ _uiSystem.TrySetUiState(uid, DoorElectronicsConfigurationUiKey.Key, state);
+ }
+
+ private void OnChangeConfiguration(
+ EntityUid uid,
+ DoorElectronicsComponent component,
+ DoorElectronicsUpdateConfigurationMessage args)
+ {
+ var accessReader = EnsureComp(uid);
+ _accessReader.SetAccesses(uid, accessReader, args.AccessList);
+ }
+
+ private void OnAccessReaderChanged(
+ EntityUid uid,
+ DoorElectronicsComponent component,
+ AccessReaderConfigurationChangedEvent args)
+ {
+ UpdateUserInterface(uid, component);
+ }
+
+ private void OnBoundUIOpened(
+ EntityUid uid,
+ DoorElectronicsComponent component,
+ BoundUIOpenedEvent args)
+ {
+ UpdateUserInterface(uid, component);
+ }
+}
diff --git a/Content.Server/Sandbox/SandboxSystem.cs b/Content.Server/Sandbox/SandboxSystem.cs
index b8bf123090..30fe4e0fe9 100644
--- a/Content.Server/Sandbox/SandboxSystem.cs
+++ b/Content.Server/Sandbox/SandboxSystem.cs
@@ -14,6 +14,7 @@ using Robust.Server.Placement;
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
namespace Content.Server.Sandbox
{
@@ -121,7 +122,7 @@ namespace Content.Server.Sandbox
var allAccess = PrototypeManager
.EnumeratePrototypes()
- .Select(p => p.ID).ToArray();
+ .Select(p => new ProtoId(p.ID)).ToList();
if (_inventory.TryGetSlotEntity(attached, "id", out var slotEntity))
{
diff --git a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs
index 356768769b..838311c1aa 100644
--- a/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs
+++ b/Content.Server/Storage/EntitySystems/BluespaceLockerSystem.cs
@@ -3,6 +3,7 @@ using Content.Server.Explosion.EntitySystems;
using Content.Server.Resist;
using Content.Server.Station.Components;
using Content.Server.Storage.Components;
+using Content.Shared.Access;
using Content.Shared.Access.Components;
using Content.Shared.Coordinates;
using Content.Shared.DoAfter;
@@ -14,6 +15,7 @@ using Content.Shared.Tools.Systems;
using Robust.Shared.Containers;
using Robust.Shared.Random;
using Robust.Shared.Timing;
+using Robust.Shared.Prototypes;
namespace Content.Server.Storage.EntitySystems;
@@ -138,7 +140,7 @@ public sealed class BluespaceLockerSystem : EntitySystem
}
/// True if any HashSet in would grant access to
- private bool AccessMatch(IReadOnlyCollection>? a, IReadOnlyCollection>? b)
+ private bool AccessMatch(IReadOnlyCollection>>? a, IReadOnlyCollection>>? b)
{
if ((a == null || a.Count == 0) && (b == null || b.Count == 0))
return true;
diff --git a/Content.Server/UserInterface/ActivatableUIComponent.cs b/Content.Server/UserInterface/ActivatableUIComponent.cs
index 54639dd2b0..cc0e5008e4 100644
--- a/Content.Server/UserInterface/ActivatableUIComponent.cs
+++ b/Content.Server/UserInterface/ActivatableUIComponent.cs
@@ -1,3 +1,6 @@
+using Content.Shared.Whitelist;
+using Robust.Server.GameObjects;
+using Robust.Server.Player;
using Robust.Shared.Player;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
@@ -34,12 +37,19 @@ namespace Content.Server.UserInterface
[DataField]
public bool RequireHands = true;
+ ///
+ /// Entities that are required to open this UI.
+ ///
+ [DataField("allowedItems")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public EntityWhitelist? AllowedItems = null;
+
///
/// Whether you can activate this ui with activateinhand or not
///
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
- public bool rightClickOnly = false;
+ public bool RightClickOnly;
///
/// Whether spectators (non-admin ghosts) should be allowed to view this UI.
@@ -63,4 +73,3 @@ namespace Content.Server.UserInterface
public ICommonSession? CurrentSingleUser;
}
}
-
diff --git a/Content.Server/UserInterface/ActivatableUISystem.cs b/Content.Server/UserInterface/ActivatableUISystem.cs
index 387221e00c..e3a11af429 100644
--- a/Content.Server/UserInterface/ActivatableUISystem.cs
+++ b/Content.Server/UserInterface/ActivatableUISystem.cs
@@ -26,6 +26,7 @@ public sealed partial class ActivatableUISystem : EntitySystem
SubscribeLocalEvent(OnActivate);
SubscribeLocalEvent(OnUseInHand);
+ SubscribeLocalEvent(OnInteractUsing);
SubscribeLocalEvent(OnHandDeselected);
SubscribeLocalEvent((uid, aui, _) => CloseAll(uid, aui));
// *THIS IS A BLATANT WORKAROUND!* RATIONALE: Microwaves need it
@@ -100,12 +101,20 @@ public sealed partial class ActivatableUISystem : EntitySystem
if (args.Handled)
return;
- if (component.rightClickOnly)
+ if (component.RightClickOnly)
return;
args.Handled = InteractUI(args.User, uid, component);
}
+ private void OnInteractUsing(EntityUid uid, ActivatableUIComponent component, InteractUsingEvent args)
+ {
+ if (args.Handled) return;
+ if (component.AllowedItems == null) return;
+ if (!component.AllowedItems.IsValid(args.Used, EntityManager)) return;
+ args.Handled = InteractUI(args.User, uid, component);
+ }
+
private void OnParentChanged(EntityUid uid, ActivatableUIComponent aui, ref EntParentChangedMessage args)
{
CloseAll(uid, aui);
diff --git a/Content.Shared/Access/AccessGroupPrototype.cs b/Content.Shared/Access/AccessGroupPrototype.cs
index 8d3ed8feea..323fdb91ed 100644
--- a/Content.Shared/Access/AccessGroupPrototype.cs
+++ b/Content.Shared/Access/AccessGroupPrototype.cs
@@ -14,6 +14,6 @@ public sealed partial class AccessGroupPrototype : IPrototype
[IdDataField]
public string ID { get; private set; } = default!;
- [DataField("tags", required: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
- public HashSet Tags = default!;
+ [DataField("tags", required: true)]
+ public HashSet> Tags = default!;
}
diff --git a/Content.Shared/Access/AccessLevelPrototype.cs b/Content.Shared/Access/AccessLevelPrototype.cs
index 8cc5927158..e3a3b426b0 100644
--- a/Content.Shared/Access/AccessLevelPrototype.cs
+++ b/Content.Shared/Access/AccessLevelPrototype.cs
@@ -17,5 +17,13 @@ namespace Content.Shared.Access
///
[DataField("name")]
public string? Name { get; set; }
+
+ public string GetAccessLevelName()
+ {
+ if (Name is { } name)
+ return Loc.GetString(name);
+
+ return ID;
+ }
}
}
diff --git a/Content.Shared/Access/Components/AccessComponent.cs b/Content.Shared/Access/Components/AccessComponent.cs
index 2eacf2aa67..00ee87b3b6 100644
--- a/Content.Shared/Access/Components/AccessComponent.cs
+++ b/Content.Shared/Access/Components/AccessComponent.cs
@@ -20,17 +20,17 @@ public sealed partial class AccessComponent : Component
[AutoNetworkedField]
public bool Enabled = true;
- [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ [DataField]
[Access(typeof(SharedAccessSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
[AutoNetworkedField]
- public HashSet Tags = new();
+ public HashSet> Tags = new();
///
/// Access Groups. These are added to the tags during map init. After map init this will have no effect.
///
- [DataField(readOnly: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
+ [DataField(readOnly: true)]
[AutoNetworkedField]
- public HashSet Groups = new();
+ public HashSet> Groups = new();
}
///
@@ -47,9 +47,9 @@ public struct GetAdditionalAccessEvent
}
[ByRefEvent]
-public record struct GetAccessTagsEvent(HashSet Tags, IPrototypeManager PrototypeManager)
+public record struct GetAccessTagsEvent(HashSet> Tags, IPrototypeManager PrototypeManager)
{
- public void AddGroup(string group)
+ public void AddGroup(ProtoId group)
{
if (!PrototypeManager.TryIndex(group, out var groupPrototype))
return;
diff --git a/Content.Shared/Access/Components/AccessOverriderComponent.cs b/Content.Shared/Access/Components/AccessOverriderComponent.cs
index 92c09f1ab7..6a1bf2c831 100644
--- a/Content.Shared/Access/Components/AccessOverriderComponent.cs
+++ b/Content.Shared/Access/Components/AccessOverriderComponent.cs
@@ -25,9 +25,9 @@ public sealed partial class AccessOverriderComponent : Component
[Serializable, NetSerializable]
public sealed class WriteToTargetAccessReaderIdMessage : BoundUserInterfaceMessage
{
- public readonly List AccessList;
+ public readonly List> AccessList;
- public WriteToTargetAccessReaderIdMessage(List accessList)
+ public WriteToTargetAccessReaderIdMessage(List> accessList)
{
AccessList = accessList;
}
@@ -48,15 +48,15 @@ public sealed partial class AccessOverriderComponent : Component
public readonly string PrivilegedIdName;
public readonly bool IsPrivilegedIdPresent;
public readonly bool IsPrivilegedIdAuthorized;
- public readonly string[]? TargetAccessReaderIdAccessList;
- public readonly string[]? AllowedModifyAccessList;
- public readonly string[]? MissingPrivilegesList;
+ public readonly ProtoId[]? TargetAccessReaderIdAccessList;
+ public readonly ProtoId[]? AllowedModifyAccessList;
+ public readonly ProtoId[]? MissingPrivilegesList;
public AccessOverriderBoundUserInterfaceState(bool isPrivilegedIdPresent,
bool isPrivilegedIdAuthorized,
- string[]? targetAccessReaderIdAccessList,
- string[]? allowedModifyAccessList,
- string[]? missingPrivilegesList,
+ ProtoId[]? targetAccessReaderIdAccessList,
+ ProtoId[]? allowedModifyAccessList,
+ ProtoId[]? missingPrivilegesList,
string privilegedIdName,
string targetLabel,
Color targetLabelColor)
diff --git a/Content.Shared/Access/Components/AccessReaderComponent.cs b/Content.Shared/Access/Components/AccessReaderComponent.cs
index b157797922..cbd3f5acd6 100644
--- a/Content.Shared/Access/Components/AccessReaderComponent.cs
+++ b/Content.Shared/Access/Components/AccessReaderComponent.cs
@@ -1,5 +1,6 @@
using Content.Shared.StationRecords;
using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
@@ -23,15 +24,15 @@ public sealed partial class AccessReaderComponent : Component
/// The set of tags that will automatically deny an allowed check, if any of them are present.
///
[ViewVariables(VVAccess.ReadWrite)]
- [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer))]
- public HashSet DenyTags = new();
+ [DataField]
+ public HashSet> DenyTags = new();
///
/// List of access groups that grant access to this reader. Only a single matching group is required to gain access.
/// A group matches if it is a subset of the set being checked against.
///
[DataField("access")] [ViewVariables(VVAccess.ReadWrite)]
- public List> AccessLists = new();
+ public List>> AccessLists = new();
///
/// A list of s that grant access. Only a single matching key is required to gain
@@ -88,9 +89,9 @@ public sealed class AccessReaderComponentState : ComponentState
{
public bool Enabled;
- public HashSet DenyTags;
+ public HashSet> DenyTags;
- public List> AccessLists;
+ public List>> AccessLists;
public List<(NetEntity, uint)> AccessKeys;
@@ -98,7 +99,7 @@ public sealed class AccessReaderComponentState : ComponentState
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, List<(NetEntity, uint)> accessKeys, Queue accessLog, int accessLogLimit)
{
Enabled = enabled;
DenyTags = denyTags;
@@ -108,3 +109,10 @@ public sealed class AccessReaderComponentState : ComponentState
AccessLogLimit = accessLogLimit;
}
}
+
+public sealed class AccessReaderConfigurationChangedEvent : EntityEventArgs
+{
+ public AccessReaderConfigurationChangedEvent()
+ {
+ }
+}
diff --git a/Content.Shared/Access/Components/IdCardConsoleComponent.cs b/Content.Shared/Access/Components/IdCardConsoleComponent.cs
index 387ca8a013..deeafe2793 100644
--- a/Content.Shared/Access/Components/IdCardConsoleComponent.cs
+++ b/Content.Shared/Access/Components/IdCardConsoleComponent.cs
@@ -3,6 +3,8 @@ using Content.Shared.Containers.ItemSlots;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
+using Robust.Shared.Prototypes;
namespace Content.Shared.Access.Components;
@@ -27,10 +29,10 @@ public sealed partial class IdCardConsoleComponent : Component
{
public readonly string FullName;
public readonly string JobTitle;
- public readonly List AccessList;
- public readonly string JobPrototype;
+ public readonly List> AccessList;
+ public readonly ProtoId JobPrototype;
- public WriteToTargetIdMessage(string fullName, string jobTitle, List accessList, string jobPrototype)
+ public WriteToTargetIdMessage(string fullName, string jobTitle, List> accessList, ProtoId jobPrototype)
{
FullName = fullName;
JobTitle = jobTitle;
@@ -86,18 +88,18 @@ public sealed partial class IdCardConsoleComponent : Component
public readonly string TargetIdName;
public readonly string? TargetIdFullName;
public readonly string? TargetIdJobTitle;
- public readonly string[]? TargetIdAccessList;
- public readonly string[]? AllowedModifyAccessList;
- public readonly string TargetIdJobPrototype;
+ public readonly List>? TargetIdAccessList;
+ public readonly List>? AllowedModifyAccessList;
+ public readonly ProtoId TargetIdJobPrototype;
public IdCardConsoleBoundUserInterfaceState(bool isPrivilegedIdPresent,
bool isPrivilegedIdAuthorized,
bool isTargetIdPresent,
string? targetIdFullName,
string? targetIdJobTitle,
- string[]? targetIdAccessList,
- string[]? allowedModifyAccessList,
- string targetIdJobPrototype,
+ List>? targetIdAccessList,
+ List>? allowedModifyAccessList,
+ ProtoId targetIdJobPrototype,
string privilegedIdName,
string targetIdName)
{
diff --git a/Content.Shared/Access/Systems/AccessReaderSystem.cs b/Content.Shared/Access/Systems/AccessReaderSystem.cs
index 812a8e0487..4c12622ab5 100644
--- a/Content.Shared/Access/Systems/AccessReaderSystem.cs
+++ b/Content.Shared/Access/Systems/AccessReaderSystem.cs
@@ -112,11 +112,36 @@ public sealed class AccessReaderSystem : EntitySystem
return false;
}
+ public bool GetMainAccessReader(EntityUid uid, [NotNullWhen(true)] out AccessReaderComponent? component)
+ {
+ component = null;
+ if (!TryComp(uid, out AccessReaderComponent? accessReader))
+ return false;
+
+ component = accessReader;
+
+ if (component.ContainerAccessProvider == null)
+ return true;
+
+ if (!_containerSystem.TryGetContainer(uid, component.ContainerAccessProvider, out var container))
+ return true;
+
+ foreach (var entity in container.ContainedEntities)
+ {
+ if (TryComp(entity, out AccessReaderComponent? containedReader))
+ {
+ component = containedReader;
+ return true;
+ }
+ }
+ return true;
+ }
+
///
/// Check whether the given access permissions satisfy an access reader's requirements.
///
public bool IsAllowed(
- ICollection access,
+ ICollection> access,
ICollection stationKeys,
EntityUid target,
AccessReaderComponent reader)
@@ -142,7 +167,7 @@ public sealed class AccessReaderSystem : EntitySystem
return false;
}
- private bool IsAllowedInternal(ICollection access, ICollection stationKeys, AccessReaderComponent reader)
+ private bool IsAllowedInternal(ICollection> access, ICollection stationKeys, AccessReaderComponent reader)
{
return !reader.Enabled
|| AreAccessTagsAllowed(access, reader)
@@ -154,7 +179,7 @@ public sealed class AccessReaderSystem : EntitySystem
///
/// A list of access tags
/// An access reader to check against
- public bool AreAccessTagsAllowed(ICollection accessTags, AccessReaderComponent reader)
+ public bool AreAccessTagsAllowed(ICollection> accessTags, AccessReaderComponent reader)
{
if (reader.DenyTags.Overlaps(accessTags))
{
@@ -218,9 +243,9 @@ public sealed class AccessReaderSystem : EntitySystem
///
/// The entity that is being searched.
/// All of the items to search for access. If none are passed in, will be used.
- public ICollection FindAccessTags(EntityUid uid, HashSet? items = null)
+ public ICollection> FindAccessTags(EntityUid uid, HashSet? items = null)
{
- HashSet? tags = null;
+ HashSet>? tags = null;
var owned = false;
items ??= FindPotentialAccessItems(uid);
@@ -230,7 +255,7 @@ public sealed class AccessReaderSystem : EntitySystem
FindAccessTagsItem(ent, ref tags, ref owned);
}
- return (ICollection?) tags ?? Array.Empty();
+ return (ICollection>?) tags ?? Array.Empty>();
}
///
@@ -260,7 +285,7 @@ public sealed class AccessReaderSystem : EntitySystem
/// This version merges into a set or replaces the set.
/// If owned is false, the existing tag-set "isn't ours" and can't be merged with (is read-only).
///
- private void FindAccessTagsItem(EntityUid uid, ref HashSet? tags, ref bool owned)
+ private void FindAccessTagsItem(EntityUid uid, ref HashSet>? tags, ref bool owned)
{
if (!FindAccessTagsItem(uid, out var targetTags))
{
@@ -286,6 +311,16 @@ public sealed class AccessReaderSystem : EntitySystem
}
}
+ public void SetAccesses(EntityUid uid, AccessReaderComponent component, List> accesses)
+ {
+ component.AccessLists.Clear();
+ foreach (var access in accesses)
+ {
+ component.AccessLists.Add(new HashSet>(){access});
+ }
+ RaiseLocalEvent(uid, new AccessReaderConfigurationChangedEvent());
+ }
+
public bool FindAccessItemsInventory(EntityUid uid, out HashSet items)
{
items = new();
@@ -308,7 +343,7 @@ public sealed class AccessReaderSystem : EntitySystem
/// Try to find on this item
/// or inside this item (if it's pda)
///
- private bool FindAccessTagsItem(EntityUid uid, out HashSet tags)
+ private bool FindAccessTagsItem(EntityUid uid, out HashSet> tags)
{
tags = new();
var ev = new GetAccessTagsEvent(tags, _prototype);
diff --git a/Content.Shared/Access/Systems/SharedAccessSystem.cs b/Content.Shared/Access/Systems/SharedAccessSystem.cs
index 965ccb2412..a4b04c3559 100644
--- a/Content.Shared/Access/Systems/SharedAccessSystem.cs
+++ b/Content.Shared/Access/Systems/SharedAccessSystem.cs
@@ -51,7 +51,7 @@ namespace Content.Shared.Access.Systems
/// Replaces the set of access tags we have with the provided set.
///
/// The new access tags
- public bool TrySetTags(EntityUid uid, IEnumerable newTags, AccessComponent? access = null)
+ public bool TrySetTags(EntityUid uid, IEnumerable> newTags, AccessComponent? access = null)
{
if (!Resolve(uid, ref access))
return false;
@@ -67,12 +67,12 @@ namespace Content.Shared.Access.Systems
/// Gets the set of access tags.
///
/// The new access tags
- public IEnumerable? TryGetTags(EntityUid uid, AccessComponent? access = null)
+ public IEnumerable>? TryGetTags(EntityUid uid, AccessComponent? access = null)
{
return !Resolve(uid, ref access) ? null : access.Tags;
}
- public bool TryAddGroups(EntityUid uid, IEnumerable newGroups, AccessComponent? access = null)
+ public bool TryAddGroups(EntityUid uid, IEnumerable> newGroups, AccessComponent? access = null)
{
if (!Resolve(uid, ref access))
return false;
diff --git a/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs b/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs
index 12e25e1e22..81843b5e2d 100644
--- a/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs
+++ b/Content.Shared/Access/Systems/SharedIdCardConsoleSystem.cs
@@ -1,6 +1,9 @@
using Content.Shared.Access.Components;
using Content.Shared.Containers.ItemSlots;
using JetBrains.Annotations;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+using Robust.Shared.Prototypes;
namespace Content.Shared.Access.Systems
{
@@ -33,5 +36,16 @@ namespace Content.Shared.Access.Systems
_itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot);
_itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot);
}
+
+ [Serializable, NetSerializable]
+ private sealed class IdCardConsoleComponentState : ComponentState
+ {
+ public List AccessLevels;
+
+ public IdCardConsoleComponentState(List accessLevels)
+ {
+ AccessLevels = accessLevels;
+ }
+ }
}
}
diff --git a/Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs b/Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs
new file mode 100644
index 0000000000..3e9f279ee5
--- /dev/null
+++ b/Content.Shared/Doors/Electronics/DoorElectronicsComponent.cs
@@ -0,0 +1,42 @@
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+using Robust.Shared.Prototypes;
+using Content.Shared.Access;
+
+namespace Content.Shared.Doors.Electronics;
+
+///
+/// Allows an entity's AccessReader to be configured via UI.
+///
+[RegisterComponent, NetworkedComponent]
+public sealed partial class DoorElectronicsComponent : Component
+{
+}
+
+[Serializable, NetSerializable]
+public sealed class DoorElectronicsUpdateConfigurationMessage : BoundUserInterfaceMessage
+{
+ public List> AccessList;
+
+ public DoorElectronicsUpdateConfigurationMessage(List> accessList)
+ {
+ AccessList = accessList;
+ }
+}
+
+[Serializable, NetSerializable]
+public sealed class DoorElectronicsConfigurationState : BoundUserInterfaceState
+{
+ public List> AccessList;
+
+ public DoorElectronicsConfigurationState(List> accessList)
+ {
+ AccessList = accessList;
+ }
+}
+
+[Serializable, NetSerializable]
+public enum DoorElectronicsConfigurationUiKey : byte
+{
+ Key
+}
diff --git a/Content.Shared/Random/RulesPrototype.cs b/Content.Shared/Random/RulesPrototype.cs
index 6bbc3a68f8..20961af8e7 100644
--- a/Content.Shared/Random/RulesPrototype.cs
+++ b/Content.Shared/Random/RulesPrototype.cs
@@ -116,8 +116,8 @@ public sealed partial class NearbyAccessRule : RulesRule
[DataField("count")]
public int Count = 1;
- [DataField("access", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer))]
- public List Access = new();
+ [DataField("access", required: true)]
+ public List> Access = new();
[DataField("range")]
public float Range = 10f;
diff --git a/Content.Shared/Roles/JobPrototype.cs b/Content.Shared/Roles/JobPrototype.cs
index 0064fcdf17..34a8ce64bf 100644
--- a/Content.Shared/Roles/JobPrototype.cs
+++ b/Content.Shared/Roles/JobPrototype.cs
@@ -105,17 +105,17 @@ namespace Content.Shared.Roles
[DataField("special", serverOnly: true)]
public JobSpecial[] Special { get; private set; } = Array.Empty();
- [DataField("access", customTypeSerializer: typeof(PrototypeIdListSerializer))]
- public IReadOnlyCollection Access { get; private set; } = Array.Empty();
+ [DataField("access")]
+ public IReadOnlyCollection> Access { get; private set; } = Array.Empty>();
- [DataField("accessGroups", customTypeSerializer: typeof(PrototypeIdListSerializer))]
- public IReadOnlyCollection AccessGroups { get; private set; } = Array.Empty();
+ [DataField("accessGroups")]
+ public IReadOnlyCollection> AccessGroups { get; private set; } = Array.Empty>();
- [DataField("extendedAccess", customTypeSerializer: typeof(PrototypeIdListSerializer))]
- public IReadOnlyCollection ExtendedAccess { get; private set; } = Array.Empty();
+ [DataField("extendedAccess")]
+ public IReadOnlyCollection> ExtendedAccess { get; private set; } = Array.Empty>();
- [DataField("extendedAccessGroups", customTypeSerializer: typeof(PrototypeIdListSerializer))]
- public IReadOnlyCollection ExtendedAccessGroups { get; private set; } = Array.Empty();
+ [DataField("extendedAccessGroups")]
+ public IReadOnlyCollection> ExtendedAccessGroups { get; private set; } = Array.Empty>();
}
///
diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
index 275a61d821..16713a6692 100644
--- a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
+++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door.yml
@@ -7,9 +7,19 @@
- type: Sprite
sprite: Objects/Misc/module.rsi
state: door_electronics
- - type: AccessReader
- type: Tag
tags:
- DoorElectronics
+ - type: DoorElectronics
- type: StaticPrice
price: 55
+ - type: AccessReader
+ - type: ActivatableUI
+ key: enum.DoorElectronicsConfigurationUiKey.Key
+ allowedItems:
+ tags:
+ - Multitool
+ - type: UserInterface
+ interfaces:
+ - key: enum.DoorElectronicsConfigurationUiKey.Key
+ type: DoorElectronicsBoundUserInterface
diff --git a/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml
new file mode 100644
index 0000000000..fc6d8e2697
--- /dev/null
+++ b/Resources/Prototypes/Entities/Objects/Devices/Electronics/door_access.yml
@@ -0,0 +1,264 @@
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsService
+ suffix: Service, Locked
+ components:
+ - type: AccessReader
+ access: [["Service"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsTheatre
+ suffix: Theatre, Locked
+ components:
+ - type: AccessReader
+ access: [["Theatre"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsChapel
+ suffix: Chapel, Locked
+ components:
+ - type: AccessReader
+ access: [["Chapel"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsJanitor
+ suffix: Janitor, Locked
+ components:
+ - type: AccessReader
+ access: [["Janitor"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsKitchen
+ suffix: Kitchen, Locked
+ components:
+ - type: AccessReader
+ access: [["Kitchen"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsBar
+ suffix: Bar, Locked
+ components:
+ - type: AccessReader
+ access: [["Bar"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsHydroponics
+ suffix: Hydroponics, Locked
+ components:
+ - type: AccessReader
+ access: [["Hydroponics"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsCaptain
+ suffix: Captain, Locked
+ components:
+ - type: AccessReader
+ access: [["Captain"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsExternal
+ suffix: External, Locked
+ components:
+ - type: AccessReader
+ access: [["External"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsCargo
+ suffix: Cargo, Locked
+ components:
+ - type: AccessReader
+ access: [["Cargo"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsEngineering
+ suffix: Engineering, Locked
+ components:
+ - type: AccessReader
+ access: [["Engineering"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsAtmospherics
+ suffix: Atmospherics, Locked
+ components:
+ - type: AccessReader
+ access: [["Atmospherics"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsFreezer
+ suffix: Freezer, Locked
+ components:
+ - type: AccessReader
+ access: [["Kitchen"], ["Hydroponics"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsSalvage
+ suffix: Salvage, Locked
+ components:
+ - type: AccessReader
+ access: [["Salvage"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsMedical
+ suffix: Medical, Locked
+ components:
+ - type: AccessReader
+ access: [["Medical"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsChemistry
+ suffix: Chemistry, Locked
+ components:
+ - type: AccessReader
+ access: [["Chemistry"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsResearch
+ suffix: Research, Locked
+ components:
+ - type: AccessReader
+ access: [["Research"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsScience
+ suffix: Science, Locked
+ components:
+ - type: AccessReader
+ access: [["Research"], ["Medical"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsCommand
+ suffix: Command, Locked
+ components:
+ - type: AccessReader
+ access: [["Command"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsChiefMedicalOfficer
+ suffix: ChiefMedicalOfficer, Locked
+ components:
+ - type: AccessReader
+ access: [["ChiefMedicalOfficer"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsChiefEngineer
+ suffix: ChiefEngineer, Locked
+ components:
+ - type: AccessReader
+ access: [["ChiefEngineer"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsHeadOfSecurity
+ suffix: HeadOfSecurity, Locked
+ components:
+ - type: AccessReader
+ access: [["HeadOfSecurity"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsResearchDirector
+ suffix: ResearchDirector, Locked
+ components:
+ - type: AccessReader
+ access: [["ResearchDirector"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsHeadOfPersonnel
+ suffix: HeadOfPersonnel, Locked
+ components:
+ - type: AccessReader
+ access: [["HeadOfPersonnel"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsQuartermaster
+ suffix: Quartermaster, Locked
+ components:
+ - type: AccessReader
+ access: [["Quartermaster"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsSecurity
+ suffix: Security, Locked
+ components:
+ - type: AccessReader
+ access: [["Security"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsDetective
+ suffix: Detective, Locked
+ components:
+ - type: AccessReader
+ access: [["Detective"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsBrig
+ suffix: Brig, Locked
+ components:
+ - type: AccessReader
+ access: [["Brig"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsArmory
+ suffix: Armory, Locked
+ components:
+ - type: AccessReader
+ access: [["Armory"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsVault
+ suffix: Vault, Locked
+ components:
+ - type: AccessReader
+ access: [["Security", "Command"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsMaintenance
+ suffix: Maintenance, Locked
+ components:
+ - type: AccessReader
+ access: [["Maintenance"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsSyndicateAgent
+ suffix: SyndicateAgent, Locked
+ components:
+ - type: AccessReader
+ access: [["SyndicateAgent"]]
+
+- type: entity
+ parent: DoorElectronics
+ id: DoorElectronicsRnDMed
+ suffix: Medical/Science, Locked
+ components:
+ - type: AccessReader
+ access: [["Research"], ["Medical"]]
diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
index 7eed29ad56..8ffd18e7e2 100644
--- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
+++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/access.yml
@@ -4,10 +4,9 @@
id: AirlockServiceLocked
suffix: Service, Locked
components:
- - type: AccessReader
- access: [["Service"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsService ]
- type: entity
parent: Airlock
@@ -24,108 +23,99 @@
id: AirlockTheatreLocked
suffix: Theatre, Locked
components:
- - type: AccessReader
- access: [["Theatre"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsTheatre ]
- type: entity
parent: Airlock
id: AirlockChapelLocked
suffix: Chapel, Locked
components:
- - type: AccessReader
- access: [["Chapel"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChapel ]
- type: entity
parent: Airlock
id: AirlockJanitorLocked
suffix: Janitor, Locked
components:
- - type: AccessReader
- access: [["Janitor"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsJanitor ]
- type: entity
parent: Airlock
id: AirlockKitchenLocked
suffix: Kitchen, Locked
components:
- - type: AccessReader
- access: [["Kitchen"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsKitchen ]
- type: entity
parent: Airlock
id: AirlockBarLocked
suffix: Bar, Locked
components:
- - type: AccessReader
- access: [["Bar"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsBar ]
- type: entity
parent: Airlock
id: AirlockHydroponicsLocked
suffix: Hydroponics, Locked
components:
- - type: AccessReader
- access: [["Hydroponics"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHydroponics ]
- type: entity
parent: Airlock
id: AirlockServiceCaptainLocked
suffix: Captain, Locked
components:
- - type: AccessReader
- access: [["Captain"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCaptain ]
- type: entity
parent: AirlockExternal
id: AirlockExternalLocked
suffix: External, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockExternal
id: AirlockExternalCargoLocked
suffix: External, Cargo, Locked
components:
- - type: AccessReader
- access: [["Cargo"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCargo ]
- type: entity
parent: AirlockExternal
id: AirlockExternalEngineeringLocked
suffix: External, Engineering, Locked
components:
- - type: AccessReader
- access: [["Engineering"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsEngineering ]
- type: entity
parent: AirlockExternal
id: AirlockExternalAtmosphericsLocked
suffix: External, Atmospherics, Locked
components:
- - type: AccessReader
- access: [["Atmospherics"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockExternal
@@ -148,20 +138,18 @@
id: AirlockFreezerLocked
suffix: Kitchen, Locked
components:
- - type: AccessReader
- access: [["Kitchen"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsKitchen ]
- type: entity
parent: AirlockFreezer
id: AirlockFreezerKitchenHydroLocked
suffix: Kitchen/Hydroponics, Locked
components:
- - type: AccessReader
- access: [["Kitchen"], ["Hydroponics"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsFreezer ]
- type: entity
parent: AirlockFreezer
@@ -178,40 +166,36 @@
id: AirlockEngineeringLocked
suffix: Engineering, Locked
components:
- - type: AccessReader
- access: [["Engineering"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsEngineering ]
- type: entity
parent: AirlockAtmospherics
id: AirlockAtmosphericsLocked
suffix: Atmospherics, Locked
components:
- - type: AccessReader
- access: [["Atmospherics"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockCargo
id: AirlockCargoLocked
suffix: Cargo, Locked
components:
- - type: AccessReader
- access: [["Cargo"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCargo ]
- type: entity
parent: AirlockCargo
id: AirlockSalvageLocked
suffix: Salvage, Locked
components:
- - type: AccessReader
- access: [["Salvage"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSalvage ]
- type: entity
parent: AirlockMining
@@ -228,50 +212,45 @@
id: AirlockMedicalLocked
suffix: Medical, Locked
components:
- - type: AccessReader
- access: [["Medical"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMedical ]
- type: entity
parent: AirlockVirology
id: AirlockVirologyLocked
suffix: Virology, Locked
components:
- - type: AccessReader
- access: [["Medical"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMedical ]
- type: entity
parent: AirlockChemistry
id: AirlockChemistryLocked
suffix: Chemistry, Locked
components:
- - type: AccessReader
- access: [["Chemistry"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChemistry ]
- type: entity
parent: AirlockScience
id: AirlockScienceLocked
suffix: Science, Locked
components:
- - type: AccessReader
- access: [["Research"]]
- - type: Wires
- layoutId: AirlockScience
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsResearch ]
- type: entity
parent: AirlockScience
id: AirlockMedicalScienceLocked
suffix: Medical/Science, Locked
components:
- - type: AccessReader
- access: [["Research"], ["Medical"]]
- - type: Wires
- layoutId: AirlockScience
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsScience ]
- type: entity
parent: AirlockCentralCommand
@@ -288,8 +267,9 @@
id: AirlockCommandLocked
suffix: Command, Locked
components:
- - type: AccessReader
- access: [["Command"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCommand ]
- type: Wires
layoutId: AirlockCommand
@@ -298,78 +278,72 @@
id: AirlockCaptainLocked
suffix: Captain, Locked
components:
- - type: AccessReader
- access: [["Captain"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCaptain ]
- type: entity
parent: AirlockCommand
id: AirlockChiefMedicalOfficerLocked
suffix: ChiefMedicalOfficer, Locked
components:
- - type: AccessReader
- access: [["ChiefMedicalOfficer"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChiefMedicalOfficer ]
- type: entity
parent: AirlockCommand
id: AirlockChiefEngineerLocked
suffix: ChiefEngineer, Locked
components:
- - type: AccessReader
- access: [["ChiefEngineer"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChiefEngineer ]
- type: entity
parent: AirlockCommand
id: AirlockHeadOfSecurityLocked
suffix: HeadOfSecurity, Locked
components:
- - type: AccessReader
- access: [["HeadOfSecurity"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHeadOfSecurity ]
- type: entity
parent: AirlockCommand
id: AirlockResearchDirectorLocked
suffix: ResearchDirector, Locked
components:
- - type: AccessReader
- access: [["ResearchDirector"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsResearchDirector ]
- type: entity
parent: AirlockCommand
id: AirlockHeadOfPersonnelLocked
suffix: HeadOfPersonnel, Locked
components:
- - type: AccessReader
- access: [["HeadOfPersonnel"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHeadOfPersonnel ]
- type: entity
parent: AirlockCommand
id: AirlockQuartermasterLocked
suffix: Quartermaster, Locked
components:
- - type: AccessReader
- access: [["Quartermaster"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsQuartermaster ]
- type: entity
parent: AirlockSecurity
id: AirlockSecurityLocked
suffix: Security, Locked
components:
- - type: AccessReader
- access: [["Security"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSecurity ]
- type: Wires
layoutId: AirlockSecurity
@@ -378,8 +352,9 @@
id: AirlockDetectiveLocked
suffix: Detective, Locked
components:
- - type: AccessReader
- access: [["Detective"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsDetective ]
- type: Wires
layoutId: AirlockSecurity
@@ -388,8 +363,9 @@
id: AirlockBrigLocked
suffix: Brig, Locked
components:
- - type: AccessReader
- access: [["Brig"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsBrig ]
- type: Wires
layoutId: AirlockSecurity
@@ -408,8 +384,9 @@
id: AirlockArmoryLocked
suffix: Armory, Locked
components:
- - type: AccessReader
- access: [["Armory"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsArmory ]
- type: Wires
layoutId: AirlockArmory
@@ -418,20 +395,18 @@
id: AirlockVaultLocked
suffix: Vault, Locked
components:
- - type: AccessReader
- access: [["Security", "Command"]]
- - type: Wires
- layoutId: AirlockSecurity
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsVault ]
- type: entity
parent: AirlockCommand
id: AirlockEVALocked
suffix: EVA, Locked
components:
- - type: AccessReader
- access: [["External"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
# Glass Airlocks
- type: entity
@@ -439,10 +414,9 @@
id: AirlockServiceGlassLocked
suffix: Service, Locked
components:
- - type: AccessReader
- access: [["Service"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsService ]
- type: entity
parent: AirlockGlass
@@ -469,28 +443,27 @@
id: AirlockBarGlassLocked
suffix: Bar, Locked
components:
- - type: AccessReader
- access: [["Bar"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsBar ]
- type: entity
parent: AirlockExternalGlass
id: AirlockExternalGlassLocked
suffix: External, Glass, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockExternalGlass
id: AirlockExternalGlassCargoLocked
suffix: External, Glass, Cargo, Locked
components:
- - type: AccessReader
- access: [["Cargo"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCargo ]
- type: entity
parent: AirlockExternalGlass
@@ -513,30 +486,27 @@
id: AirlockExternalGlassEngineeringLocked
suffix: External, Glass, Engineering, Locked
components:
- - type: AccessReader
- access: [["Engineering"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsEngineering ]
- type: entity
parent: AirlockExternalGlass
id: AirlockExternalGlassAtmosphericsLocked
suffix: External, Glass, Atmospherics, Locked
components:
- - type: AccessReader
- access: [["Atmospherics"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockGlass
id: AirlockKitchenGlassLocked
suffix: Kitchen, Locked
components:
- - type: AccessReader
- access: [["Kitchen"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsKitchen ]
- type: entity
parent: AirlockGlass
@@ -553,60 +523,54 @@
id: AirlockHydroGlassLocked
suffix: Hydroponics, Locked
components:
- - type: AccessReader
- access: [["Hydroponics"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHydroponics ]
- type: entity
parent: AirlockGlass
id: AirlockChapelGlassLocked
suffix: Chapel, Locked
components:
- - type: AccessReader
- access: [["Chapel"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChapel ]
- type: entity
parent: AirlockEngineeringGlass
id: AirlockEngineeringGlassLocked
suffix: Engineering, Locked
components:
- - type: AccessReader
- access: [["Engineering"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsEngineering ]
- type: entity
parent: AirlockAtmosphericsGlass
id: AirlockAtmosphericsGlassLocked
suffix: Atmospherics, Locked
components:
- - type: AccessReader
- access: [["Atmospherics"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockCargoGlass
id: AirlockCargoGlassLocked
suffix: Cargo, Locked
components:
- - type: AccessReader
- access: [["Cargo"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCargo ]
- type: entity
parent: AirlockCargoGlass
id: AirlockSalvageGlassLocked
suffix: Salvage, Locked
components:
- - type: AccessReader
- access: [["Salvage"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSalvage ]
- type: entity
parent: AirlockMiningGlass
@@ -633,40 +597,36 @@
id: AirlockMedicalGlassLocked
suffix: Medical, Locked
components:
- - type: AccessReader
- access: [["Medical"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMedical ]
- type: entity
parent: AirlockVirologyGlass
id: AirlockVirologyGlassLocked
suffix: Virology, Locked
components:
- - type: AccessReader
- access: [["Medical"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMedical ]
- type: entity
parent: AirlockScienceGlass
id: AirlockScienceGlassLocked
suffix: Science, Locked
components:
- - type: AccessReader
- access: [["Research"]]
- - type: Wires
- layoutId: AirlockScience
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsResearch ]
- type: entity
parent: AirlockScienceGlass
id: AirlockMedicalScienceGlassLocked
suffix: Medical/Science, Locked
components:
- - type: AccessReader
- access: [["Research"], ["Medical"]]
- - type: Wires
- layoutId: AirlockScience
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsScience ]
- type: entity
parent: AirlockCentralCommandGlass
@@ -683,110 +643,99 @@
id: AirlockCommandGlassLocked
suffix: Command, Locked
components:
- - type: AccessReader
- access: [["Command"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCommand ]
- type: entity
parent: AirlockCommandGlass
id: AirlockCaptainGlassLocked
suffix: Captain, Locked
components:
- - type: AccessReader
- access: [["Captain"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCaptain ]
- type: entity
parent: AirlockCommandGlass
id: AirlockChiefMedicalOfficerGlassLocked
suffix: ChiefMedicalOfficer, Locked
components:
- - type: AccessReader
- access: [["ChiefMedicalOfficer"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChiefMedicalOfficer ]
- type: entity
parent: AirlockCommandGlass
id: AirlockChiefEngineerGlassLocked
suffix: ChiefEngineer, Locked
components:
- - type: AccessReader
- access: [["ChiefEngineer"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChiefEngineer ]
- type: entity
parent: AirlockCommandGlass
id: AirlockHeadOfSecurityGlassLocked
suffix: HeadOfSecurity, Locked
components:
- - type: AccessReader
- access: [["HeadOfSecurity"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHeadOfSecurity ]
- type: entity
parent: AirlockCommandGlass
id: AirlockResearchDirectorGlassLocked
suffix: ResearchDirector, Locked
components:
- - type: AccessReader
- access: [["ResearchDirector"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsResearchDirector ]
- type: entity
parent: AirlockCommandGlass
id: AirlockHeadOfPersonnelGlassLocked
suffix: HeadOfPersonnel, Locked
components:
- - type: AccessReader
- access: [["HeadOfPersonnel"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHeadOfPersonnel ]
- type: entity
parent: AirlockCommandGlass
id: AirlockQuartermasterGlassLocked
suffix: Quartermaster, Locked
components:
- - type: AccessReader
- access: [["Quartermaster"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsQuartermaster ]
- type: entity
parent: AirlockSecurityGlass
id: AirlockSecurityGlassLocked
suffix: Security, Locked
components:
- - type: AccessReader
- access: [["Security"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSecurity ]
- type: entity
parent: AirlockSecurityGlass
id: AirlockDetectiveGlassLocked
suffix: Detective, Locked
components:
- - type: AccessReader
- access: [["Detective"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsDetective ]
- type: entity
parent: AirlockSecurityGlass
id: AirlockBrigGlassLocked
suffix: Brig, Locked
components:
- - type: AccessReader
- access: [["Brig"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsBrig ]
- type: entity
parent: AirlockSecurityGlass
@@ -803,18 +752,18 @@
id: AirlockArmoryGlassLocked
suffix: Armory, Locked
components:
- - type: AccessReader
- access: [["Armory"]]
- - type: Wires
- layoutId: AirlockSecurity
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsArmory ]
- type: entity
parent: AirlockCommandGlassLocked
id: AirlockEVAGlassLocked
suffix: EVA, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockSyndicateGlass
@@ -838,114 +787,108 @@
id: AirlockMaintLocked
suffix: Locked
components:
- - type: AccessReader
- access: [["Maintenance"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMaintenance ]
- type: entity
parent: AirlockMaintGlass
id: AirlockMaintGlassLocked
suffix: Locked
components:
- - type: AccessReader
- access: [["Maintenance"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMaintenance ]
- type: entity
parent: AirlockMaint
id: AirlockMaintSalvageLocked
suffix: Salvage, Locked
components:
- - type: AccessReader
- access: [["Salvage"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSalvage ]
- type: entity
parent: AirlockMaint
id: AirlockMaintCargoLocked
suffix: Cargo, Locked
components:
- - type: AccessReader
- access: [["Cargo"]]
- - type: Wires
- layoutId: AirlockCargo
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCargo ]
- type: entity
parent: AirlockMaint
id: AirlockMaintCommandLocked
suffix: Command, Locked
components:
- - type: AccessReader
- access: [["Command"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCommand ]
- type: entity
parent: AirlockMaint
id: AirlockMaintCommonLocked
suffix: Common, Locked
components:
- - type: AccessReader
- access: [["Maintenance"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMaintenance ]
- type: entity
parent: AirlockMaint
id: AirlockMaintEngiLocked
suffix: Engineering, Locked
components:
- - type: AccessReader
- access: [["Engineering"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsEngineering ]
- type: entity
parent: AirlockMaint
id: AirlockMaintAtmoLocked
suffix: Atmospherics, Locked
components:
- - type: AccessReader
- access: [["Atmospherics"]]
- - type: Wires
- layoutId: AirlockEngineering
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsAtmospherics ]
- type: entity
parent: AirlockMaint
id: AirlockMaintBarLocked
suffix: Bar, Locked
components:
- - type: AccessReader
- access: [["Bar"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsBar ]
- type: entity
parent: AirlockMaint
id: AirlockMaintChapelLocked
suffix: Chapel, Locked
components:
- - type: AccessReader
- access: [["Chapel"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChapel ]
- type: entity
parent: AirlockMaint
id: AirlockMaintHydroLocked
suffix: Hydroponics, Locked
components:
- - type: AccessReader
- access: [["Hydroponics"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHydroponics ]
- type: entity
parent: AirlockMaint
id: AirlockMaintJanitorLocked
suffix: Janitor, Locked
components:
- - type: AccessReader
- access: [["Janitor"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsJanitor ]
- type: entity
parent: AirlockMaint
@@ -972,108 +915,99 @@
id: AirlockMaintTheatreLocked
suffix: Theatre, Locked
components:
- - type: AccessReader
- access: [["Theatre"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsTheatre ]
- type: entity
parent: AirlockMaint
id: AirlockMaintKitchenLocked
suffix: Kitchen, Locked
components:
- - type: AccessReader
- access: [["Kitchen"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsKitchen ]
- type: entity
parent: AirlockMaint
id: AirlockMaintIntLocked
suffix: Interior, Locked
components:
- - type: AccessReader
- access: [["Maintenance"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMaintenance ]
- type: entity
parent: AirlockMaint
id: AirlockMaintMedLocked
suffix: Medical, Locked
components:
- - type: AccessReader
- access: [["Medical"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsMedical ]
- type: entity
parent: AirlockMaint
id: AirlockMaintChemLocked
suffix: Chemistry, Locked
components:
- - type: AccessReader
- access: [["Chemistry"]]
- - type: Wires
- layoutId: AirlockMedical
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsChemistry ]
- type: entity
parent: AirlockMaint
id: AirlockMaintRnDLocked
suffix: Science, Locked
components:
- - type: AccessReader
- access: [["Research"]]
- - type: Wires
- layoutId: AirlockScience
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsResearch ]
- type: entity
parent: AirlockMaint
id: AirlockMaintRnDMedLocked
suffix: Medical/Science, Locked
components:
- - type: AccessReader
- access: [["Research"], ["Medical"]]
- - type: Wires
- layoutId: AirlockScience
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsRnDMed ]
- type: entity
parent: AirlockMaint
id: AirlockMaintSecLocked
suffix: Security, Locked
components:
- - type: AccessReader
- access: [["Security"]]
- - type: Wires
- layoutId: AirlockSecurity
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSecurity ]
- type: entity
parent: AirlockMaint
id: AirlockMaintDetectiveLocked
suffix: Detective, Locked
components:
- - type: AccessReader
- access: [["Detective"]]
- - type: Wires
- layoutId: AirlockSecurity
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsDetective ]
- type: entity
parent: AirlockMaint
id: AirlockMaintHOPLocked
suffix: HeadOfPersonnel, Locked
components:
- - type: AccessReader
- access: [["HeadOfPersonnel"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsHeadOfPersonnel ]
- type: entity
parent: AirlockMaint
id: AirlockMaintCaptainLocked
suffix: Captain, Locked
components:
- - type: AccessReader
- access: [["Captain"]]
- - type: Wires
- layoutId: AirlockCommand
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCaptain ]
- type: entity
parent: AirlockMaint
@@ -1147,8 +1081,9 @@
id: AirlockExternalShuttleLocked
suffix: External, Docking, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockShuttleSyndicate
@@ -1171,8 +1106,9 @@
id: AirlockExternalGlassShuttleLocked
suffix: External, Glass, Docking, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockGlassShuttleSyndicate
@@ -1197,8 +1133,9 @@
components:
- type: PriorityDock
tag: DockEmergency
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockGlassShuttle
@@ -1229,24 +1166,27 @@
id: HighSecCommandLocked
suffix: Command, Locked
components:
- - type: AccessReader
- access: [["Command"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCommand ]
- type: entity
parent: HighSecDoor
id: HighSecCaptainLocked
suffix: Captain, Locked
components:
- - type: AccessReader
- access: [["Captain"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCaptain ]
- type: entity
parent: HighSecDoor
id: HighSecArmoryLocked
suffix: Armory, Locked
components:
- - type: AccessReader
- access: [["Armory"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsArmory ]
#Airtight hatch
@@ -1255,6 +1195,6 @@
id: AirlockHatchSyndicate
suffix: Syndicate, Locked
components:
- - type: AccessReader
- access: [["SyndicateAgent"]]
-
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSyndicateAgent ]
diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml
index abc86b2be8..4ca7df6482 100644
--- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml
+++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/base_structureairlocks.yml
@@ -48,6 +48,8 @@
- type: ContainerFill
containers:
board: [ DoorElectronics ]
+ - type: AccessReader
+ containerAccessProvider: board
- type: Door
crushDamage:
types:
@@ -140,7 +142,6 @@
- type: PaintableAirlock
group: Standard
department: Civilian
- - type: AccessReader
- type: StaticPrice
price: 150
- type: LightningTarget
diff --git a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml
index a26226c957..e9ea05a1c3 100644
--- a/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml
+++ b/Resources/Prototypes/Entities/Structures/Doors/Airlocks/highsec.yml
@@ -60,6 +60,7 @@
- type: NavMapDoor
- type: DoorBolt
- type: AccessReader
+ containerAccessProvider: board
- type: Appearance
- type: WiresVisuals
- type: ApcPowerReceiver
diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml
index 3cd22bbfc7..5529514fdc 100644
--- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml
+++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/airlock.yml
@@ -46,7 +46,7 @@
conditions:
- !type:EntityAnchored {}
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon:
diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml
index 70d1c12d84..db53de288a 100644
--- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml
+++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shutter.yml
@@ -44,7 +44,7 @@
- !type:EntityAnchored
anchored: true
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
name: Door Electronics
icon:
sprite: "Objects/Misc/module.rsi"
diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml
index 457fbfede5..f29629043d 100644
--- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml
+++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/shuttle.yml
@@ -23,7 +23,7 @@
conditions:
- !type:EntityAnchored {}
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon:
diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml b/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml
index 64809ee1db..de89663467 100644
--- a/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml
+++ b/Resources/Prototypes/Recipes/Construction/Graphs/structures/windoor.yml
@@ -107,7 +107,7 @@
conditions:
- !type:EntityAnchored {}
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon:
@@ -378,7 +378,7 @@
conditions:
- !type:EntityAnchored { }
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon: