Code lock console (#3060)
Co-authored-by: KaiserMaus <kaiser.ratte@gmail.com>
This commit is contained in:
parent
0edc918beb
commit
78a63ae4b5
10 changed files with 565 additions and 0 deletions
|
|
@ -0,0 +1,62 @@
|
|||
using Content.Shared._Sunrise.CodeConsole;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.UserInterface;
|
||||
|
||||
namespace Content.Client._Sunrise.CodeConsole;
|
||||
|
||||
[UsedImplicitly]
|
||||
public sealed class CodeConsoleBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
[ViewVariables]
|
||||
private CodeConsoleMenu? _menu;
|
||||
|
||||
public CodeConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
_menu = this.CreateWindow<CodeConsoleMenu>();
|
||||
|
||||
_menu.OnKeypadButtonPressed += i =>
|
||||
{
|
||||
SendMessage(new CodeConsoleKeypadMessage(i));
|
||||
};
|
||||
_menu.OnEnterButtonPressed += () =>
|
||||
{
|
||||
SendMessage(new CodeConsoleKeypadEnterMessage());
|
||||
};
|
||||
_menu.OnClearButtonPressed += () =>
|
||||
{
|
||||
SendMessage(new CodeConsoleKeypadClearMessage());
|
||||
};
|
||||
|
||||
_menu.ActivateButton.OnPressed += _ =>
|
||||
{
|
||||
SendMessage(new CodeConsoleActivateButtonMessage());
|
||||
};
|
||||
_menu.LockButton.OnPressed += _ =>
|
||||
{
|
||||
SendMessage(new CodeConsoleLockButtonMessage());
|
||||
};
|
||||
|
||||
_menu.OnClose += Close;
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
|
||||
if (_menu == null)
|
||||
return;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case CodeConsoleUiState msg:
|
||||
_menu.UpdateState(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Content.Client/_Sunrise/CodeConsole/CodeConsoleMenu.xaml
Normal file
42
Content.Client/_Sunrise/CodeConsole/CodeConsoleMenu.xaml
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<DefaultWindow xmlns="https://spacestation14.io"
|
||||
xmlns:gfx="clr-namespace:Robust.Client.Graphics;assembly=Robust.Client"
|
||||
Title="{Loc 'code-console-user-interface-title'}"
|
||||
MinSize="280 256"
|
||||
SetSize="280 256">
|
||||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
VerticalExpand="True">
|
||||
<!-- Status label -->
|
||||
<PanelContainer Margin="0 0 0 5">
|
||||
<PanelContainer.PanelOverride>
|
||||
<gfx:StyleBoxFlat BackgroundColor="#001c00" />
|
||||
</PanelContainer.PanelOverride>
|
||||
<Label Name="StatusLabel"/>
|
||||
</PanelContainer>
|
||||
<!-- Code label -->
|
||||
<PanelContainer Margin="0 0 0 5">
|
||||
<PanelContainer.PanelOverride>
|
||||
<gfx:StyleBoxFlat BackgroundColor="#001c00" />
|
||||
</PanelContainer.PanelOverride>
|
||||
<Label Name="CodeEnteringLabel"/>
|
||||
</PanelContainer>
|
||||
<BoxContainer Orientation="Horizontal" >
|
||||
<GridContainer Columns="3"
|
||||
Name="KeypadGrid">
|
||||
<!-- Keypad is filled by code -->
|
||||
</GridContainer>
|
||||
<BoxContainer Orientation="Vertical"
|
||||
HorizontalExpand="True"
|
||||
Margin="5 0">
|
||||
<Button Name="ActivateButton"
|
||||
Text="{Loc 'code-console-user-interface-activate-button'}"
|
||||
Margin="0 0 0 5"
|
||||
Access="Public"/>
|
||||
<Button Name="LockButton"
|
||||
Text="{Loc 'code-console-user-interface-lock-button'}"
|
||||
Access="Public"
|
||||
StyleClasses="Caution"/>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</BoxContainer>
|
||||
</DefaultWindow>
|
||||
83
Content.Client/_Sunrise/CodeConsole/CodeConsoleMenu.xaml.cs
Normal file
83
Content.Client/_Sunrise/CodeConsole/CodeConsoleMenu.xaml.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
using Content.Shared._Sunrise.CodeConsole;
|
||||
using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
|
||||
namespace Content.Client._Sunrise.CodeConsole;
|
||||
|
||||
[GenerateTypedNameReferences]
|
||||
public sealed partial class CodeConsoleMenu : DefaultWindow
|
||||
{
|
||||
public event Action<int>? OnKeypadButtonPressed;
|
||||
public event Action? OnClearButtonPressed;
|
||||
public event Action? OnEnterButtonPressed;
|
||||
|
||||
public CodeConsoleMenu()
|
||||
{
|
||||
RobustXamlLoader.Load(this);
|
||||
FillKeypadGrid();
|
||||
}
|
||||
|
||||
private void FillKeypadGrid()
|
||||
{
|
||||
// add 3 rows of keypad buttons (1-9)
|
||||
for (var i = 1; i <= 9; i++)
|
||||
{
|
||||
AddKeypadButton(i);
|
||||
}
|
||||
|
||||
// clear button
|
||||
var clearBtn = new Button()
|
||||
{
|
||||
Text = "C"
|
||||
};
|
||||
clearBtn.OnPressed += _ => OnClearButtonPressed?.Invoke();
|
||||
KeypadGrid.AddChild(clearBtn);
|
||||
|
||||
// zero button
|
||||
AddKeypadButton(0);
|
||||
|
||||
// enter button
|
||||
var enterBtn = new Button()
|
||||
{
|
||||
Text = "E"
|
||||
};
|
||||
enterBtn.OnPressed += _ => OnEnterButtonPressed?.Invoke();
|
||||
KeypadGrid.AddChild(enterBtn);
|
||||
}
|
||||
|
||||
private void AddKeypadButton(int i)
|
||||
{
|
||||
var btn = new Button()
|
||||
{
|
||||
Text = i.ToString()
|
||||
};
|
||||
|
||||
btn.OnPressed += _ => OnKeypadButtonPressed?.Invoke(i);
|
||||
KeypadGrid.AddChild(btn);
|
||||
}
|
||||
|
||||
public void UpdateState(CodeConsoleUiState state)
|
||||
{
|
||||
if (state.IsLocked)
|
||||
StatusLabel.Text = Loc.GetString("code-console-interface-code-waiting");
|
||||
else
|
||||
StatusLabel.Text = Loc.GetString("code-console-interface-opened");
|
||||
|
||||
CodeEnteringLabel.Text = Loc.GetString("nuke-user-interface-second-status-current-code",
|
||||
("code", VisualizeCode(state.EnteredCodeLength, state.MaxCodeLength)));
|
||||
|
||||
|
||||
ActivateButton.Disabled = state.IsLocked;
|
||||
LockButton.Disabled = state.IsLocked;
|
||||
}
|
||||
|
||||
private static string VisualizeCode(int codeLength, int maxLength)
|
||||
{
|
||||
var code = new string('*', codeLength);
|
||||
var blanksCount = maxLength - codeLength;
|
||||
var blanks = new string('_', blanksCount);
|
||||
return code + blanks;
|
||||
}
|
||||
}
|
||||
220
Content.Server/_Sunrise/CodeConsole/CodeConsoleSystem.cs
Normal file
220
Content.Server/_Sunrise/CodeConsole/CodeConsoleSystem.cs
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
using Content.Server.DeviceLinking.Systems;
|
||||
using Content.Shared._Sunrise.CodeConsole;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.DeviceNetwork.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server._Sunrise.CodeConsole;
|
||||
|
||||
public sealed class CodeConsoleSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _random = default!;
|
||||
[Dependency] private readonly SharedAudioSystem _audio = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _ui = default!;
|
||||
[Dependency] private readonly DeviceLinkSystem _deviceLink = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<CodeConsoleComponent, MapInitEvent>(OnMapInit);
|
||||
|
||||
SubscribeLocalEvent<CodeConsoleComponent, CodeConsoleActivateButtonMessage>(OnActivateButtonPressed);
|
||||
SubscribeLocalEvent<CodeConsoleComponent, CodeConsoleLockButtonMessage>(OnLockButtonPressed);
|
||||
|
||||
SubscribeLocalEvent<CodeConsoleComponent, CodeConsoleKeypadMessage>(OnKeypadButtonPressed);
|
||||
SubscribeLocalEvent<CodeConsoleComponent, CodeConsoleKeypadClearMessage>(OnClearButtonPressed);
|
||||
SubscribeLocalEvent<CodeConsoleComponent, CodeConsoleKeypadEnterMessage>(OnEnterButtonPressed);
|
||||
|
||||
SubscribeLocalEvent<CodeConsoleComponent, InteractUsingEvent>(OnInteractUsing);
|
||||
SubscribeLocalEvent<CodeConsoleComponent, GetVerbsEvent<AlternativeVerb>>(OnGetVerbs);
|
||||
}
|
||||
|
||||
private void OnMapInit(Entity<CodeConsoleComponent> ent, ref MapInitEvent args)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(ent.Comp.Code))
|
||||
{
|
||||
if (ent.Comp.CodeLength <= 0 || ent.Comp.CodeLength > 16)
|
||||
ent.Comp.CodeLength = 16;
|
||||
|
||||
ent.Comp.Code = GetRandomCode(ent.Comp.CodeLength);
|
||||
}
|
||||
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
private void OnActivateButtonPressed(Entity<CodeConsoleComponent> ent, ref CodeConsoleActivateButtonMessage args)
|
||||
{
|
||||
_audio.PlayPvs(ent.Comp.KeypadPressSound, ent.Owner);
|
||||
|
||||
if (ent.Comp.IsLocked)
|
||||
return;
|
||||
|
||||
_deviceLink.InvokePort(ent.Owner, ent.Comp.ActivatePort);
|
||||
}
|
||||
|
||||
private void OnLockButtonPressed(Entity<CodeConsoleComponent> ent, ref CodeConsoleLockButtonMessage args)
|
||||
{
|
||||
if (ent.Comp.IsLocked)
|
||||
return;
|
||||
|
||||
UpdateStatus(ent);
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
private void OnKeypadButtonPressed(Entity<CodeConsoleComponent> ent, ref CodeConsoleKeypadMessage args)
|
||||
{
|
||||
if (args.Value < 0 || args.Value > 9)
|
||||
return;
|
||||
|
||||
PlayKeypadSound(ent, args.Value);
|
||||
|
||||
if (!ent.Comp.IsLocked)
|
||||
return;
|
||||
|
||||
if (ent.Comp.EnteredCode.Length >= ent.Comp.CodeLength)
|
||||
return;
|
||||
|
||||
ent.Comp.EnteredCode += args.Value.ToString();
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
private void OnClearButtonPressed(Entity<CodeConsoleComponent> ent, ref CodeConsoleKeypadClearMessage args)
|
||||
{
|
||||
_audio.PlayPvs(ent.Comp.KeypadPressSound, ent.Owner);
|
||||
|
||||
if (!ent.Comp.IsLocked)
|
||||
return;
|
||||
|
||||
ent.Comp.EnteredCode = "";
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
private void OnEnterButtonPressed(Entity<CodeConsoleComponent> ent, ref CodeConsoleKeypadEnterMessage args)
|
||||
{
|
||||
if (!ent.Comp.IsLocked)
|
||||
{
|
||||
_audio.PlayPvs(ent.Comp.KeypadPressSound, ent.Owner);
|
||||
return;
|
||||
}
|
||||
|
||||
UpdateStatus(ent);
|
||||
UpdateUserInterface(ent);
|
||||
}
|
||||
|
||||
private void OnInteractUsing(Entity<CodeConsoleComponent> ent, ref InteractUsingEvent args)
|
||||
{
|
||||
if (TryComp<NetworkConfiguratorComponent>(args.Used, out _) && ent.Comp.IsSealed)
|
||||
{
|
||||
args.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGetVerbs(Entity<CodeConsoleComponent> ent, ref GetVerbsEvent<AlternativeVerb> args)
|
||||
{
|
||||
if (ent.Comp.IsSealed)
|
||||
return;
|
||||
|
||||
if (!args.CanInteract || !args.CanAccess)
|
||||
return;
|
||||
|
||||
var verb = new AlternativeVerb()
|
||||
{
|
||||
Text = Loc.GetString("code-console-verb-seal-name"),
|
||||
Message = Loc.GetString("code-console-verb-seal-desc"),
|
||||
Icon = new SpriteSpecifier.Texture(
|
||||
new("/Textures/Interface/VerbIcons/lock.svg.192dpi.png")),
|
||||
Act = () => { ent.Comp.IsSealed = true; }
|
||||
};
|
||||
args.Verbs.Add(verb);
|
||||
}
|
||||
|
||||
private void UpdateStatus(Entity<CodeConsoleComponent> ent)
|
||||
{
|
||||
|
||||
if (ent.Comp.IsLocked)
|
||||
{
|
||||
if (ent.Comp.EnteredCode == ent.Comp.Code)
|
||||
{
|
||||
ent.Comp.IsLocked = false;
|
||||
_audio.PlayPvs(ent.Comp.AccessGrantedSound, ent.Owner);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ent.Comp.EnteredCode.Length == ent.Comp.CodeLength)
|
||||
_deviceLink.InvokePort(ent.Owner, ent.Comp.WrongCodePort);
|
||||
|
||||
ent.Comp.EnteredCode = "";
|
||||
_audio.PlayPvs(ent.Comp.AccessDeniedSound, ent.Owner);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ent.Comp.IsLocked = true;
|
||||
ent.Comp.EnteredCode = "";
|
||||
_audio.PlayPvs(ent.Comp.KeypadPressSound, ent.Owner);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayKeypadSound(Entity<CodeConsoleComponent> ent, int number)
|
||||
{
|
||||
// This is a C mixolydian blues scale.
|
||||
// 1 2 3 C D Eb
|
||||
// 4 5 6 E F F#
|
||||
// 7 8 9 G A Bb
|
||||
var semitoneShift = number switch
|
||||
{
|
||||
1 => 0,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
6 => 6,
|
||||
7 => 7,
|
||||
8 => 9,
|
||||
9 => 10,
|
||||
0 => 8,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
var opts = ent.Comp.KeypadPressSound.Params;
|
||||
opts = AudioHelpers.ShiftSemitone(opts, semitoneShift).AddVolume(-5f);
|
||||
_audio.PlayPvs(ent.Comp.KeypadPressSound, ent.Owner, opts);
|
||||
}
|
||||
|
||||
private void UpdateUserInterface(Entity<CodeConsoleComponent> ent)
|
||||
{
|
||||
if (!_ui.HasUi(ent.Owner, CodeConsoleUiKey.Key))
|
||||
return;
|
||||
|
||||
var state = new CodeConsoleUiState
|
||||
{
|
||||
IsLocked = ent.Comp.IsLocked,
|
||||
EnteredCodeLength = ent.Comp.EnteredCode.Length,
|
||||
MaxCodeLength = ent.Comp.CodeLength
|
||||
};
|
||||
|
||||
_ui.SetUiState(ent.Owner, CodeConsoleUiKey.Key, state);
|
||||
}
|
||||
|
||||
private string GetRandomCode(int codeLength)
|
||||
{
|
||||
if (codeLength < 0)
|
||||
codeLength = 6;
|
||||
|
||||
var symbols = "1234567890".ToCharArray();
|
||||
var code = new char[codeLength];
|
||||
|
||||
for (int i = 0; i < codeLength; i++)
|
||||
{
|
||||
code[i] = _random.Pick(symbols);
|
||||
}
|
||||
|
||||
return new string(code);
|
||||
}
|
||||
}
|
||||
55
Content.Shared/_Sunrise/CodeConsole/CodeConsoleComponent.cs
Normal file
55
Content.Shared/_Sunrise/CodeConsole/CodeConsoleComponent.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using System.Linq;
|
||||
|
||||
namespace Content.Shared._Sunrise.CodeConsole;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
|
||||
public sealed partial class CodeConsoleComponent : Component
|
||||
{
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool IsLocked = true;
|
||||
|
||||
[DataField, AutoNetworkedField, ViewVariables(VVAccess.ReadOnly)]
|
||||
public int CodeLength = 6;
|
||||
|
||||
[DataField(serverOnly: true)]
|
||||
public string Code
|
||||
{
|
||||
get => _code;
|
||||
set
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value) || !value.All(char.IsDigit))
|
||||
return;
|
||||
|
||||
CodeLength = value.Length;
|
||||
_code = value;
|
||||
}
|
||||
}
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool IsSealed = false;
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public string ActivatePort = "Pressed";
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public string WrongCodePort = "WrongCode";
|
||||
|
||||
private string _code = string.Empty;
|
||||
|
||||
[DataField(serverOnly: true)]
|
||||
public string EnteredCode = string.Empty;
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier KeypadPressSound = new SoundPathSpecifier("/Audio/Machines/Nuke/general_beep.ogg");
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier AccessGrantedSound = new SoundPathSpecifier("/Audio/Machines/Nuke/confirm_beep.ogg");
|
||||
|
||||
[DataField]
|
||||
public SoundSpecifier AccessDeniedSound = new SoundPathSpecifier("/Audio/Machines/Nuke/angry_beep.ogg");
|
||||
}
|
||||
|
||||
|
||||
|
||||
40
Content.Shared/_Sunrise/CodeConsole/CodeConsoleMessages.cs
Normal file
40
Content.Shared/_Sunrise/CodeConsole/CodeConsoleMessages.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared._Sunrise.CodeConsole;
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CodeConsoleKeypadMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public int Value;
|
||||
|
||||
public CodeConsoleKeypadMessage(int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CodeConsoleKeypadEnterMessage : BoundUserInterfaceMessage { }
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CodeConsoleKeypadClearMessage : BoundUserInterfaceMessage { }
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CodeConsoleActivateButtonMessage : BoundUserInterfaceMessage { }
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CodeConsoleLockButtonMessage : BoundUserInterfaceMessage { }
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class CodeConsoleUiState : BoundUserInterfaceState
|
||||
{
|
||||
public bool IsLocked;
|
||||
public int EnteredCodeLength;
|
||||
public int MaxCodeLength;
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CodeConsoleUiKey : byte
|
||||
{
|
||||
Key
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
ent-CodeConsole = кодовая консоль
|
||||
.desc = Конcоль, предназначенная для ввода кода. Страшно пищит.
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
code-console-verb-seal-name = запечатать порты
|
||||
code-console-verb-seal-desc = Закрывает доступ к портам, делая невозможным перепривязку устройства.
|
||||
|
||||
code-console-user-interface-title = Кодовая консоль
|
||||
|
||||
code-console-interface-code-waiting = ВВЕДИТЕ КОД
|
||||
code-console-interface-opened = УСТРОЙСТВО АКТИВНО
|
||||
|
||||
code-console-user-interface-activate-button = Активировать
|
||||
code-console-user-interface-lock-button = Заблокировать
|
||||
|
||||
signal-port-name-wrong-code = Неверный ввод
|
||||
signal-port-description-wrong-code = Активируется каждый раз, когда код введён неверно.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
- type: sourcePort
|
||||
id: WrongCode
|
||||
name: signal-port-name-wrong-code
|
||||
description: signal-port-description-wrong-code
|
||||
|
|
@ -71,3 +71,47 @@
|
|||
- type: Tag
|
||||
tags:
|
||||
- CantInteract
|
||||
|
||||
- type: entity
|
||||
parent: BaseComputerAiAccess
|
||||
id: CodeConsole
|
||||
name: code input console
|
||||
description: A computer used to enter the password.
|
||||
components:
|
||||
- type: CodeConsole
|
||||
- type: DeviceNetwork
|
||||
deviceNetId: Wireless
|
||||
- type: WirelessNetworkConnection
|
||||
range: 50 # This can be changed if necessary
|
||||
- type: DeviceLinkSource
|
||||
ports:
|
||||
- Pressed
|
||||
- WrongCode
|
||||
- type: Sprite
|
||||
layers:
|
||||
- map: ["computerLayerBody"]
|
||||
state: computer
|
||||
- map: ["computerLayerKeyboard"]
|
||||
state: generic_keyboard
|
||||
- map: ["computerLayerScreen"]
|
||||
state: generic
|
||||
- map: ["computerLayerKeys"]
|
||||
state: generic_keys
|
||||
- map: [ "enum.WiresVisualLayers.MaintenancePanel" ]
|
||||
state: generic_panel_open
|
||||
- type: GenericVisualizer
|
||||
visuals:
|
||||
enum.ComputerVisuals.Powered:
|
||||
computerLayerScreen:
|
||||
True: { visible: true, shader: unshaded }
|
||||
False: { visible: false }
|
||||
computerLayerKeys:
|
||||
True: { visible: true, shader: unshaded }
|
||||
False: { visible: true, shader: shaded }
|
||||
- type: ActivatableUI
|
||||
singleUser: true
|
||||
key: enum.CodeConsoleUiKey.Key
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
enum.CodeConsoleUiKey.Key:
|
||||
type: CodeConsoleBoundUserInterface
|
||||
Loading…
Add table
Reference in a new issue