--- /dev/null
+<GridContainer xmlns="https://spacestation14.io"
+ Columns="5"
+ HorizontalAlignment="Center">
+</GridContainer>
--- /dev/null
+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<ProtoId<AccessLevelPrototype>, Button> ButtonsList = new();
+
+ public AccessLevelControl()
+ {
+ RobustXamlLoader.Load(this);
+ }
+
+ public void Populate(List<ProtoId<AccessLevelPrototype>> 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<ProtoId<AccessLevelPrototype>> pressedList,
+ List<ProtoId<AccessLevelPrototype>>? enabledList = null)
+ {
+ foreach (var (accessName, button) in ButtonsList)
+ {
+ button.Pressed = pressedList.Contains(accessName);
+ button.Disabled = !(enabledList?.Contains(accessName) ?? true);
+ }
+ }
+}
_window?.UpdateState(castState);
}
- public void SubmitData(List<string> newAccessList)
+ public void SubmitData(List<ProtoId<AccessLevelPrototype>> newAccessList)
{
SendMessage(new WriteToTargetAccessReaderIdMessage(newAccessList));
}
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
- private readonly ISawmill _logMill = default!;
private readonly AccessOverriderBoundUserInterface _owner;
private readonly Dictionary<string, Button> _accessButtons = new();
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
- _logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill);
+ var logMill = _logManager.GetSawmill(SharedAccessOverriderSystem.Sawmill);
_owner = owner;
{
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,
};
}
}
- 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;
_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<AccessLevelPrototype>(x.Key)).ToList());
}
}
}
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;
if (EntMan.TryGetComponent<IdCardConsoleComponent>(Owner, out var idCard))
{
accessLevels = idCard.AccessLevels;
- accessLevels.Sort();
}
else
{
_window?.UpdateState(castState);
}
- public void SubmitData(string newFullName, string newJobTitle, List<string> newAccessList, string newJobPrototype)
+ public void SubmitData(string newFullName, string newJobTitle, List<ProtoId<AccessLevelPrototype>> newAccessList, string newJobPrototype)
{
if (newFullName.Length > MaxFullNameLength)
newFullName = newFullName[..MaxFullNameLength];
<Label Text="{Loc 'id-card-console-window-job-selection-label'}" />
<OptionButton Name="JobPresetOptionButton" />
</GridContainer>
- <GridContainer Name="AccessLevelGrid" Columns="5" HorizontalAlignment="Center">
-
- <!-- Access level buttons are added here by the C# code -->
-
- </GridContainer>
+ <Control Name="AccessLevelControlContainer" />
</BoxContainer>
</DefaultWindow>
private readonly IdCardConsoleBoundUserInterface _owner;
- private readonly Dictionary<string, Button> _accessButtons = new();
+ private AccessLevelControl _accessButtons = new();
private readonly List<string> _jobPrototypeIds = new();
private string? _lastFullName;
JobPresetOptionButton.OnItemSelected += SelectJobPreset;
- foreach (var access in accessLevels)
- {
- if (!prototypeManager.TryIndex<AccessLevelPrototype>(access, out var accessLevel))
- {
- _logMill.Error($"Unable to find accesslevel for {access}");
- continue;
- }
+ _accessButtons.Populate(accessLevels, prototypeManager);
+ AccessLevelControlContainer.AddChild(_accessButtons);
- var newButton = new Button
- {
- Text = GetAccessLevelName(accessLevel),
- ToggleMode = true,
- };
- AccessLevelGrid.AddChild(newButton);
- _accessButtons.Add(accessLevel.ID, newButton);
- newButton.OnPressed += _ => SubmitData();
+ foreach (var (id, button) in _accessButtons.ButtonsList)
+ {
+ 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)
{
// 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;
}
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;
}
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<ProtoId<AccessLevelPrototype>>(),
+ state.AllowedModifyAccessList?.ToList() ??
+ new List<ProtoId<AccessLevelPrototype>>());
var jobIndex = _jobPrototypeIds.IndexOf(state.TargetIdJobPrototype);
if (jobIndex >= 0)
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);
}
}
--- /dev/null
+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<ProtoId<AccessLevelPrototype>> accessLevels = new();
+
+ foreach (var accessLevel in _prototypeManager.EnumeratePrototypes<AccessLevelPrototype>())
+ {
+ 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<ProtoId<AccessLevelPrototype>> newAccessList)
+ {
+ SendMessage(new DoorElectronicsUpdateConfigurationMessage(newAccessList));
+ }
+}
--- /dev/null
+<controls:FancyWindow xmlns="https://spacestation14.io"
+ xmlns:ui="clr-namespace:Content.Client.UserInterface"
+ xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
+ <Control Name="AccessLevelControlContainer" />
+
+</controls:FancyWindow>
--- /dev/null
+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<ProtoId<AccessLevelPrototype>> 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);
+ }
+}
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<string>(), reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Bar" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
});
// test deny
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<string>(), reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "Foo" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "Foo" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.True);
});
// test one list
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet<string> { "A" });
+ reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "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<string>(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
// test one list - two items
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet<string> { "A", "B" });
+ reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "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<string>(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
// test two list
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet<string> { "A" });
- reader.AccessLists.Add(new HashSet<string> { "B", "C" });
+ reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "A" });
+ reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "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<string>(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "C", "B", "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
// test deny list
reader = new AccessReaderComponent();
- reader.AccessLists.Add(new HashSet<string> { "A" });
+ reader.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>> { "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<string>(), reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A" }, reader), Is.True);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(new List<ProtoId<AccessLevelPrototype>> { "A", "B" }, reader), Is.False);
+ Assert.That(system.AreAccessTagsAllowed(Array.Empty<ProtoId<AccessLevelPrototype>>(), reader), Is.False);
});
});
await pair.CleanReturnAsync();
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;
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;
[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()
{
var targetLabel = Loc.GetString("access-overrider-window-no-target");
var targetLabelColor = Color.Red;
- string[]? possibleAccess = null;
- string[]? currentAccess = null;
- string[]? missingAccess = null;
+ ProtoId<AccessLevelPrototype>[]? possibleAccess = null;
+ ProtoId<AccessLevelPrototype>[]? currentAccess = null;
+ ProtoId<AccessLevelPrototype>[]? missingAccess = null;
if (component.TargetAccessReaderId is { Valid: true } accessReader)
{
targetLabel = Loc.GetString("access-overrider-window-target-label") + " " + EntityManager.GetComponent<MetaDataComponent>(component.TargetAccessReaderId).EntityName;
targetLabelColor = Color.White;
- List<HashSet<string>> currentAccessHashsets = EntityManager.GetComponent<AccessReaderComponent>(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)
_userInterface.TrySetUiState(uid, AccessOverriderUiKey.Key, newState);
}
- private List<string> ConvertAccessHashSetsToList(List<HashSet<string>> accessHashsets)
+ private List<ProtoId<AccessLevelPrototype>> ConvertAccessHashSetsToList(List<HashSet<ProtoId<AccessLevelPrototype>>> accessHashsets)
{
- List<string> accessList = new List<string>();
+ List<ProtoId<AccessLevelPrototype>> accessList = new List<ProtoId<AccessLevelPrototype>>();
if (accessHashsets != null && accessHashsets.Any())
{
- foreach (HashSet<string> hashSet in accessHashsets)
+ foreach (HashSet<ProtoId<AccessLevelPrototype>> hashSet in accessHashsets)
{
- foreach (string hash in hashSet.ToArray())
+ foreach (ProtoId<AccessLevelPrototype> hash in hashSet.ToArray())
{
accessList.Add(hash);
}
return accessList;
}
- private List<HashSet<string>> ConvertAccessListToHashSet(List<string> accessList)
+ private List<HashSet<ProtoId<AccessLevelPrototype>>> ConvertAccessListToHashSet(List<ProtoId<AccessLevelPrototype>> accessList)
{
- List<HashSet<string>> accessHashsets = new List<HashSet<string>>();
+ List<HashSet<ProtoId<AccessLevelPrototype>>> accessHashsets = new List<HashSet<ProtoId<AccessLevelPrototype>>>();
if (accessList != null && accessList.Any())
{
- foreach (string access in accessList)
+ foreach (ProtoId<AccessLevelPrototype> access in accessList)
{
- accessHashsets.Add(new HashSet<string>() { access });
+ accessHashsets.Add(new HashSet<ProtoId<AccessLevelPrototype>>() { access });
}
}
/// Called whenever an access button is pressed, adding or removing that access requirement from the target access reader.
/// </summary>
private void TryWriteToTargetAccessReaderId(EntityUid uid,
- List<string> newAccessList,
+ List<ProtoId<AccessLevelPrototype>> newAccessList,
EntityUid player,
AccessOverriderComponent? component = null)
{
return;
}
- TryComp(component.TargetAccessReaderId, out AccessReaderComponent? accessReader);
-
- if (accessReader == null)
+ if (!_accessReader.GetMainAccessReader(component.TargetAccessReaderId, out var accessReader))
return;
var oldTags = ConvertAccessHashSetsToList(accessReader.AccessLists);
if (!Resolve(uid, ref component))
return true;
- if (!EntityManager.TryGetComponent<AccessReaderComponent>(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);
}
}
using Robust.Shared.Prototypes;
using System.Linq;
using static Content.Shared.Access.Components.IdCardConsoleComponent;
+using Content.Shared.Access;
namespace Content.Server.Access.Systems;
return;
var privilegedIdName = string.Empty;
- string[]? possibleAccess = null;
+ List<ProtoId<AccessLevelPrototype>>? possibleAccess = null;
if (component.PrivilegedIdSlot.Item is { Valid: true } item)
{
privilegedIdName = EntityManager.GetComponent<MetaDataComponent>(item).EntityName;
- possibleAccess = _accessReader.FindAccessTags(item).ToArray();
+ possibleAccess = _accessReader.FindAccessTags(item).ToList();
}
IdCardConsoleBoundUserInterfaceState newState;
var targetIdComponent = EntityManager.GetComponent<IdCardComponent>(targetId);
var targetAccessComponent = EntityManager.GetComponent<AccessComponent>(targetId);
- var jobProto = string.Empty;
+ var jobProto = new ProtoId<AccessLevelPrototype>(string.Empty);
if (TryComp<StationRecordKeyStorageComponent>(targetId, out var keyStorage)
&& keyStorage.Key is {} key
&& _record.TryGetRecord<GeneralStationRecord>(key, out var record))
true,
targetIdComponent.FullName,
targetIdComponent.JobTitle,
- targetAccessComponent.Tags.ToArray(),
+ targetAccessComponent.Tags.ToList(),
possibleAccess,
jobProto,
privilegedIdName,
private void TryWriteToTargetId(EntityUid uid,
string newFullName,
string newJobTitle,
- List<string> newAccessList,
- string newJobProto,
+ List<ProtoId<AccessLevelPrototype>> newAccessList,
+ ProtoId<AccessLevelPrototype> newJobProto,
EntityUid player,
IdCardConsoleComponent? component = null)
{
return;
}
- var oldTags = _access.TryGetTags(targetId) ?? new List<string>();
+ var oldTags = _access.TryGetTags(targetId) ?? new List<ProtoId<AccessLevelPrototype>>();
oldTags = oldTags.ToList();
var privilegedId = component.PrivilegedIdSlot.Item;
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<AccessLevelPrototype> newJobTitle, JobPrototype? newJobProto)
{
if (!TryComp<StationRecordKeyStorageComponent>(targetId, out var keyStorage)
|| keyStorage.Key is not { } key
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;
{
var allAccess = _prototypeManager
.EnumeratePrototypes<AccessLevelPrototype>()
- .Select(p => p.ID).ToArray();
+ .Select(p => new ProtoId<AccessLevelPrototype>(p.ID)).ToArray();
_accessSystem.TrySetTags(entity, allAccess);
}
private void RevokeAllAccess(EntityUid entity)
{
- _accessSystem.TrySetTags(entity, Array.Empty<string>());
+ _accessSystem.TrySetTags(entity, new List<ProtoId<AccessLevelPrototype>>());
}
public enum TricksVerbPriorities
--- /dev/null
+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<DoorElectronicsComponent, DoorElectronicsUpdateConfigurationMessage>(OnChangeConfiguration);
+ SubscribeLocalEvent<DoorElectronicsComponent, AccessReaderConfigurationChangedEvent>(OnAccessReaderChanged);
+ SubscribeLocalEvent<DoorElectronicsComponent, BoundUIOpenedEvent>(OnBoundUIOpened);
+ }
+
+ public void UpdateUserInterface(EntityUid uid, DoorElectronicsComponent component)
+ {
+ var accesses = new List<ProtoId<AccessLevelPrototype>>();
+
+ if (TryComp<AccessReaderComponent>(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<AccessReaderComponent>(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);
+ }
+}
using Robust.Server.Player;
using Robust.Shared.Enums;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes;
namespace Content.Server.Sandbox
{
var allAccess = PrototypeManager
.EnumeratePrototypes<AccessLevelPrototype>()
- .Select(p => p.ID).ToArray();
+ .Select(p => new ProtoId<AccessLevelPrototype>(p.ID)).ToList();
if (_inventory.TryGetSlotEntity(attached, "id", out var slotEntity))
{
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;
using Robust.Shared.Containers;
using Robust.Shared.Random;
using Robust.Shared.Timing;
+using Robust.Shared.Prototypes;
namespace Content.Server.Storage.EntitySystems;
}
/// <returns>True if any HashSet in <paramref name="a"/> would grant access to <paramref name="b"/></returns>
- private bool AccessMatch(IReadOnlyCollection<HashSet<string>>? a, IReadOnlyCollection<HashSet<string>>? b)
+ private bool AccessMatch(IReadOnlyCollection<HashSet<ProtoId<AccessLevelPrototype>>>? a, IReadOnlyCollection<HashSet<ProtoId<AccessLevelPrototype>>>? b)
{
if ((a == null || a.Count == 0) && (b == null || b.Count == 0))
return true;
+using Content.Shared.Whitelist;
+using Robust.Server.GameObjects;
+using Robust.Server.Player;
using Robust.Shared.Player;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
[DataField]
public bool RequireHands = true;
+ /// <summary>
+ /// Entities that are required to open this UI.
+ /// </summary>
+ [DataField("allowedItems")]
+ [ViewVariables(VVAccess.ReadWrite)]
+ public EntityWhitelist? AllowedItems = null;
+
/// <summary>
/// Whether you can activate this ui with activateinhand or not
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
[DataField]
- public bool rightClickOnly = false;
+ public bool RightClickOnly;
/// <summary>
/// Whether spectators (non-admin ghosts) should be allowed to view this UI.
public ICommonSession? CurrentSingleUser;
}
}
-
SubscribeLocalEvent<ActivatableUIComponent, ActivateInWorldEvent>(OnActivate);
SubscribeLocalEvent<ActivatableUIComponent, UseInHandEvent>(OnUseInHand);
+ SubscribeLocalEvent<ActivatableUIComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<ActivatableUIComponent, HandDeselectedEvent>(OnHandDeselected);
SubscribeLocalEvent<ActivatableUIComponent, GotUnequippedHandEvent>((uid, aui, _) => CloseAll(uid, aui));
// *THIS IS A BLATANT WORKAROUND!* RATIONALE: Microwaves need it
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);
[IdDataField]
public string ID { get; private set; } = default!;
- [DataField("tags", required: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessLevelPrototype>))]
- public HashSet<string> Tags = default!;
+ [DataField("tags", required: true)]
+ public HashSet<ProtoId<AccessLevelPrototype>> Tags = default!;
}
/// </summary>
[DataField("name")]
public string? Name { get; set; }
+
+ public string GetAccessLevelName()
+ {
+ if (Name is { } name)
+ return Loc.GetString(name);
+
+ return ID;
+ }
}
}
[AutoNetworkedField]
public bool Enabled = true;
- [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessLevelPrototype>))]
+ [DataField]
[Access(typeof(SharedAccessSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
[AutoNetworkedField]
- public HashSet<string> Tags = new();
+ public HashSet<ProtoId<AccessLevelPrototype>> Tags = new();
/// <summary>
/// Access Groups. These are added to the tags during map init. After map init this will have no effect.
/// </summary>
- [DataField(readOnly: true, customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessGroupPrototype>))]
+ [DataField(readOnly: true)]
[AutoNetworkedField]
- public HashSet<string> Groups = new();
+ public HashSet<ProtoId<AccessGroupPrototype>> Groups = new();
}
/// <summary>
}
[ByRefEvent]
-public record struct GetAccessTagsEvent(HashSet<string> Tags, IPrototypeManager PrototypeManager)
+public record struct GetAccessTagsEvent(HashSet<ProtoId<AccessLevelPrototype>> Tags, IPrototypeManager PrototypeManager)
{
- public void AddGroup(string group)
+ public void AddGroup(ProtoId<AccessGroupPrototype> group)
{
if (!PrototypeManager.TryIndex<AccessGroupPrototype>(group, out var groupPrototype))
return;
[Serializable, NetSerializable]
public sealed class WriteToTargetAccessReaderIdMessage : BoundUserInterfaceMessage
{
- public readonly List<string> AccessList;
+ public readonly List<ProtoId<AccessLevelPrototype>> AccessList;
- public WriteToTargetAccessReaderIdMessage(List<string> accessList)
+ public WriteToTargetAccessReaderIdMessage(List<ProtoId<AccessLevelPrototype>> accessList)
{
AccessList = accessList;
}
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<AccessLevelPrototype>[]? TargetAccessReaderIdAccessList;
+ public readonly ProtoId<AccessLevelPrototype>[]? AllowedModifyAccessList;
+ public readonly ProtoId<AccessLevelPrototype>[]? MissingPrivilegesList;
public AccessOverriderBoundUserInterfaceState(bool isPrivilegedIdPresent,
bool isPrivilegedIdAuthorized,
- string[]? targetAccessReaderIdAccessList,
- string[]? allowedModifyAccessList,
- string[]? missingPrivilegesList,
+ ProtoId<AccessLevelPrototype>[]? targetAccessReaderIdAccessList,
+ ProtoId<AccessLevelPrototype>[]? allowedModifyAccessList,
+ ProtoId<AccessLevelPrototype>[]? missingPrivilegesList,
string privilegedIdName,
string targetLabel,
Color targetLabelColor)
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;
/// The set of tags that will automatically deny an allowed check, if any of them are present.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
- [DataField(customTypeSerializer: typeof(PrototypeIdHashSetSerializer<AccessLevelPrototype>))]
- public HashSet<string> DenyTags = new();
+ [DataField]
+ public HashSet<ProtoId<AccessLevelPrototype>> DenyTags = new();
/// <summary>
/// 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.
/// </summary>
[DataField("access")] [ViewVariables(VVAccess.ReadWrite)]
- public List<HashSet<string>> AccessLists = new();
+ public List<HashSet<ProtoId<AccessLevelPrototype>>> AccessLists = new();
/// <summary>
/// A list of <see cref="StationRecordKey"/>s that grant access. Only a single matching key is required to gain
{
public bool Enabled;
- public HashSet<string> DenyTags;
+ public HashSet<ProtoId<AccessLevelPrototype>> DenyTags;
- public List<HashSet<string>> AccessLists;
+ public List<HashSet<ProtoId<AccessLevelPrototype>>> AccessLists;
public List<(NetEntity, uint)> AccessKeys;
public int AccessLogLimit;
- public AccessReaderComponentState(bool enabled, HashSet<string> denyTags, List<HashSet<string>> accessLists, List<(NetEntity, uint)> accessKeys, Queue<AccessRecord> accessLog, int accessLogLimit)
+ public AccessReaderComponentState(bool enabled, HashSet<ProtoId<AccessLevelPrototype>> denyTags, List<HashSet<ProtoId<AccessLevelPrototype>>> accessLists, List<(NetEntity, uint)> accessKeys, Queue<AccessRecord> accessLog, int accessLogLimit)
{
Enabled = enabled;
DenyTags = denyTags;
AccessLogLimit = accessLogLimit;
}
}
+
+public sealed class AccessReaderConfigurationChangedEvent : EntityEventArgs
+{
+ public AccessReaderConfigurationChangedEvent()
+ {
+ }
+}
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;
{
public readonly string FullName;
public readonly string JobTitle;
- public readonly List<string> AccessList;
- public readonly string JobPrototype;
+ public readonly List<ProtoId<AccessLevelPrototype>> AccessList;
+ public readonly ProtoId<AccessLevelPrototype> JobPrototype;
- public WriteToTargetIdMessage(string fullName, string jobTitle, List<string> accessList, string jobPrototype)
+ public WriteToTargetIdMessage(string fullName, string jobTitle, List<ProtoId<AccessLevelPrototype>> accessList, ProtoId<AccessLevelPrototype> jobPrototype)
{
FullName = fullName;
JobTitle = jobTitle;
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<ProtoId<AccessLevelPrototype>>? TargetIdAccessList;
+ public readonly List<ProtoId<AccessLevelPrototype>>? AllowedModifyAccessList;
+ public readonly ProtoId<AccessLevelPrototype> TargetIdJobPrototype;
public IdCardConsoleBoundUserInterfaceState(bool isPrivilegedIdPresent,
bool isPrivilegedIdAuthorized,
bool isTargetIdPresent,
string? targetIdFullName,
string? targetIdJobTitle,
- string[]? targetIdAccessList,
- string[]? allowedModifyAccessList,
- string targetIdJobPrototype,
+ List<ProtoId<AccessLevelPrototype>>? targetIdAccessList,
+ List<ProtoId<AccessLevelPrototype>>? allowedModifyAccessList,
+ ProtoId<AccessLevelPrototype> targetIdJobPrototype,
string privilegedIdName,
string targetIdName)
{
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;
+ }
+
/// <summary>
/// Check whether the given access permissions satisfy an access reader's requirements.
/// </summary>
public bool IsAllowed(
- ICollection<string> access,
+ ICollection<ProtoId<AccessLevelPrototype>> access,
ICollection<StationRecordKey> stationKeys,
EntityUid target,
AccessReaderComponent reader)
return false;
}
- private bool IsAllowedInternal(ICollection<string> access, ICollection<StationRecordKey> stationKeys, AccessReaderComponent reader)
+ private bool IsAllowedInternal(ICollection<ProtoId<AccessLevelPrototype>> access, ICollection<StationRecordKey> stationKeys, AccessReaderComponent reader)
{
return !reader.Enabled
|| AreAccessTagsAllowed(access, reader)
/// </summary>
/// <param name="accessTags">A list of access tags</param>
/// <param name="reader">An access reader to check against</param>
- public bool AreAccessTagsAllowed(ICollection<string> accessTags, AccessReaderComponent reader)
+ public bool AreAccessTagsAllowed(ICollection<ProtoId<AccessLevelPrototype>> accessTags, AccessReaderComponent reader)
{
if (reader.DenyTags.Overlaps(accessTags))
{
/// </summary>
/// <param name="uid">The entity that is being searched.</param>
/// <param name="items">All of the items to search for access. If none are passed in, <see cref="FindPotentialAccessItems"/> will be used.</param>
- public ICollection<string> FindAccessTags(EntityUid uid, HashSet<EntityUid>? items = null)
+ public ICollection<ProtoId<AccessLevelPrototype>> FindAccessTags(EntityUid uid, HashSet<EntityUid>? items = null)
{
- HashSet<string>? tags = null;
+ HashSet<ProtoId<AccessLevelPrototype>>? tags = null;
var owned = false;
items ??= FindPotentialAccessItems(uid);
FindAccessTagsItem(ent, ref tags, ref owned);
}
- return (ICollection<string>?) tags ?? Array.Empty<string>();
+ return (ICollection<ProtoId<AccessLevelPrototype>>?) tags ?? Array.Empty<ProtoId<AccessLevelPrototype>>();
}
/// <summary>
/// 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).
/// </summary>
- private void FindAccessTagsItem(EntityUid uid, ref HashSet<string>? tags, ref bool owned)
+ private void FindAccessTagsItem(EntityUid uid, ref HashSet<ProtoId<AccessLevelPrototype>>? tags, ref bool owned)
{
if (!FindAccessTagsItem(uid, out var targetTags))
{
}
}
+ public void SetAccesses(EntityUid uid, AccessReaderComponent component, List<ProtoId<AccessLevelPrototype>> accesses)
+ {
+ component.AccessLists.Clear();
+ foreach (var access in accesses)
+ {
+ component.AccessLists.Add(new HashSet<ProtoId<AccessLevelPrototype>>(){access});
+ }
+ RaiseLocalEvent(uid, new AccessReaderConfigurationChangedEvent());
+ }
+
public bool FindAccessItemsInventory(EntityUid uid, out HashSet<EntityUid> items)
{
items = new();
/// Try to find <see cref="AccessComponent"/> on this item
/// or inside this item (if it's pda)
/// </summary>
- private bool FindAccessTagsItem(EntityUid uid, out HashSet<string> tags)
+ private bool FindAccessTagsItem(EntityUid uid, out HashSet<ProtoId<AccessLevelPrototype>> tags)
{
tags = new();
var ev = new GetAccessTagsEvent(tags, _prototype);
/// Replaces the set of access tags we have with the provided set.
/// </summary>
/// <param name="access">The new access tags</param>
- public bool TrySetTags(EntityUid uid, IEnumerable<string> newTags, AccessComponent? access = null)
+ public bool TrySetTags(EntityUid uid, IEnumerable<ProtoId<AccessLevelPrototype>> newTags, AccessComponent? access = null)
{
if (!Resolve(uid, ref access))
return false;
/// Gets the set of access tags.
/// </summary>
/// <param name="access">The new access tags</param>
- public IEnumerable<string>? TryGetTags(EntityUid uid, AccessComponent? access = null)
+ public IEnumerable<ProtoId<AccessLevelPrototype>>? TryGetTags(EntityUid uid, AccessComponent? access = null)
{
return !Resolve(uid, ref access) ? null : access.Tags;
}
- public bool TryAddGroups(EntityUid uid, IEnumerable<string> newGroups, AccessComponent? access = null)
+ public bool TryAddGroups(EntityUid uid, IEnumerable<ProtoId<AccessGroupPrototype>> newGroups, AccessComponent? access = null)
{
if (!Resolve(uid, ref access))
return false;
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
{
_itemSlotsSystem.RemoveItemSlot(uid, component.PrivilegedIdSlot);
_itemSlotsSystem.RemoveItemSlot(uid, component.TargetIdSlot);
}
+
+ [Serializable, NetSerializable]
+ private sealed class IdCardConsoleComponentState : ComponentState
+ {
+ public List<string> AccessLevels;
+
+ public IdCardConsoleComponentState(List<string> accessLevels)
+ {
+ AccessLevels = accessLevels;
+ }
+ }
}
}
--- /dev/null
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
+using Robust.Shared.Prototypes;
+using Content.Shared.Access;
+
+namespace Content.Shared.Doors.Electronics;
+
+/// <summary>
+/// Allows an entity's AccessReader to be configured via UI.
+/// </summary>
+[RegisterComponent, NetworkedComponent]
+public sealed partial class DoorElectronicsComponent : Component
+{
+}
+
+[Serializable, NetSerializable]
+public sealed class DoorElectronicsUpdateConfigurationMessage : BoundUserInterfaceMessage
+{
+ public List<ProtoId<AccessLevelPrototype>> AccessList;
+
+ public DoorElectronicsUpdateConfigurationMessage(List<ProtoId<AccessLevelPrototype>> accessList)
+ {
+ AccessList = accessList;
+ }
+}
+
+[Serializable, NetSerializable]
+public sealed class DoorElectronicsConfigurationState : BoundUserInterfaceState
+{
+ public List<ProtoId<AccessLevelPrototype>> AccessList;
+
+ public DoorElectronicsConfigurationState(List<ProtoId<AccessLevelPrototype>> accessList)
+ {
+ AccessList = accessList;
+ }
+}
+
+[Serializable, NetSerializable]
+public enum DoorElectronicsConfigurationUiKey : byte
+{
+ Key
+}
[DataField("count")]
public int Count = 1;
- [DataField("access", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<AccessLevelPrototype>))]
- public List<string> Access = new();
+ [DataField("access", required: true)]
+ public List<ProtoId<AccessLevelPrototype>> Access = new();
[DataField("range")]
public float Range = 10f;
[DataField("special", serverOnly: true)]
public JobSpecial[] Special { get; private set; } = Array.Empty<JobSpecial>();
- [DataField("access", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessLevelPrototype>))]
- public IReadOnlyCollection<string> Access { get; private set; } = Array.Empty<string>();
+ [DataField("access")]
+ public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> Access { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
- [DataField("accessGroups", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessGroupPrototype>))]
- public IReadOnlyCollection<string> AccessGroups { get; private set; } = Array.Empty<string>();
+ [DataField("accessGroups")]
+ public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> AccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
- [DataField("extendedAccess", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessLevelPrototype>))]
- public IReadOnlyCollection<string> ExtendedAccess { get; private set; } = Array.Empty<string>();
+ [DataField("extendedAccess")]
+ public IReadOnlyCollection<ProtoId<AccessLevelPrototype>> ExtendedAccess { get; private set; } = Array.Empty<ProtoId<AccessLevelPrototype>>();
- [DataField("extendedAccessGroups", customTypeSerializer: typeof(PrototypeIdListSerializer<AccessGroupPrototype>))]
- public IReadOnlyCollection<string> ExtendedAccessGroups { get; private set; } = Array.Empty<string>();
+ [DataField("extendedAccessGroups")]
+ public IReadOnlyCollection<ProtoId<AccessGroupPrototype>> ExtendedAccessGroups { get; private set; } = Array.Empty<ProtoId<AccessGroupPrototype>>();
}
/// <summary>
- 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
--- /dev/null
+
+- 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"]]
id: AirlockServiceLocked
suffix: Service, Locked
components:
- - type: AccessReader
- access: [["Service"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsService ]
- type: entity
parent: Airlock
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
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
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
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
id: AirlockCommandLocked
suffix: Command, Locked
components:
- - type: AccessReader
- access: [["Command"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsCommand ]
- type: Wires
layoutId: AirlockCommand
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
id: AirlockDetectiveLocked
suffix: Detective, Locked
components:
- - type: AccessReader
- access: [["Detective"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsDetective ]
- type: Wires
layoutId: AirlockSecurity
id: AirlockBrigLocked
suffix: Brig, Locked
components:
- - type: AccessReader
- access: [["Brig"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsBrig ]
- type: Wires
layoutId: AirlockSecurity
id: AirlockArmoryLocked
suffix: Armory, Locked
components:
- - type: AccessReader
- access: [["Armory"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsArmory ]
- type: Wires
layoutId: AirlockArmory
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
id: AirlockServiceGlassLocked
suffix: Service, Locked
components:
- - type: AccessReader
- access: [["Service"]]
- - type: Wires
- layoutId: AirlockService
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsService ]
- type: entity
parent: AirlockGlass
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
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
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
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
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
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
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
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
id: AirlockExternalShuttleLocked
suffix: External, Docking, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockShuttleSyndicate
id: AirlockExternalGlassShuttleLocked
suffix: External, Glass, Docking, Locked
components:
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockGlassShuttleSyndicate
components:
- type: PriorityDock
tag: DockEmergency
- - type: AccessReader
- access: [["External"]]
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsExternal ]
- type: entity
parent: AirlockGlassShuttle
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
id: AirlockHatchSyndicate
suffix: Syndicate, Locked
components:
- - type: AccessReader
- access: [["SyndicateAgent"]]
-
+ - type: ContainerFill
+ containers:
+ board: [ DoorElectronicsSyndicateAgent ]
- type: ContainerFill
containers:
board: [ DoorElectronics ]
+ - type: AccessReader
+ containerAccessProvider: board
- type: Door
crushDamage:
types:
- type: PaintableAirlock
group: Standard
department: Civilian
- - type: AccessReader
- type: StaticPrice
price: 150
- type: LightningTarget
- type: NavMapDoor
- type: DoorBolt
- type: AccessReader
+ containerAccessProvider: board
- type: Appearance
- type: WiresVisuals
- type: ApcPowerReceiver
conditions:
- !type:EntityAnchored {}
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon:
- !type:EntityAnchored
anchored: true
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
name: Door Electronics
icon:
sprite: "Objects/Misc/module.rsi"
conditions:
- !type:EntityAnchored {}
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon:
conditions:
- !type:EntityAnchored {}
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon:
conditions:
- !type:EntityAnchored { }
steps:
- - tag: DoorElectronics
+ - component: DoorElectronics
store: board
name: "door electronics circuit board"
icon: