Wires! (#315)
* Wires! * Use state instead of messages * cleanup * Update submodule * actually fix conflict * Maybe fix conflicts? * Localized strings, removed hardcoded sprite path * cleanup * More localization and sounds
This commit is contained in:
committed by
Pieter-Jan Briers
parent
70e3cffa90
commit
264a63b7f6
@@ -8,6 +8,7 @@ using Content.Client.Interfaces.Chat;
|
||||
using Content.Client.Interfaces.Parallax;
|
||||
using Content.Client.Parallax;
|
||||
using Content.Client.UserInterface;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using Content.Shared.GameObjects.Components.Chemistry;
|
||||
using Content.Shared.GameObjects.Components.Markers;
|
||||
using Content.Shared.GameObjects.Components.Research;
|
||||
@@ -110,6 +111,7 @@ namespace Content.Client
|
||||
factory.Register<SolutionComponent>();
|
||||
|
||||
factory.Register<SharedVendingMachineComponent>();
|
||||
factory.Register<SharedWiresComponent>();
|
||||
|
||||
prototypes.RegisterIgnore("material");
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using Robust.Client.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Wires
|
||||
{
|
||||
public class WiresBoundUserInterface : BoundUserInterface
|
||||
{
|
||||
public WiresBoundUserInterface(ClientUserInterfaceComponent owner, object uiKey) : base(owner, uiKey)
|
||||
{
|
||||
}
|
||||
|
||||
private WiresMenu _menu;
|
||||
|
||||
protected override void Open()
|
||||
{
|
||||
base.Open();
|
||||
_menu = new WiresMenu() {Owner = this};
|
||||
|
||||
_menu.OnClose += Close;
|
||||
_menu.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void UpdateState(BoundUserInterfaceState state)
|
||||
{
|
||||
base.UpdateState(state);
|
||||
var castState = (WiresBoundUserInterfaceState) state;
|
||||
_menu.Populate(castState.WiresList);
|
||||
}
|
||||
|
||||
public void PerformAction(Guid guid, WiresAction action)
|
||||
{
|
||||
SendMessage(new WiresActionMessage(guid, action));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Content.Client/GameObjects/Components/Wires/WiresMenu.cs
Normal file
60
Content.Client/GameObjects/Components/Wires/WiresMenu.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Collections.Generic;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Wires
|
||||
{
|
||||
public class WiresMenu : SS14Window
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
#pragma warning restore 649
|
||||
protected override Vector2? CustomSize => (300, 450);
|
||||
public WiresBoundUserInterface Owner { get; set; }
|
||||
|
||||
private readonly VBoxContainer _rows;
|
||||
|
||||
public WiresMenu()
|
||||
{
|
||||
IoCManager.InjectDependencies(this); // TODO: Remove this and use DynamicTypeFactory?
|
||||
Title = _localizationManager.GetString("Wires");
|
||||
_rows = new VBoxContainer();
|
||||
Contents.AddChild(_rows);
|
||||
}
|
||||
|
||||
public void Populate(List<ClientWire> wiresList)
|
||||
{
|
||||
_rows.RemoveAllChildren();
|
||||
foreach (var entry in wiresList)
|
||||
{
|
||||
var container = new HBoxContainer();
|
||||
var newLabel = new Label()
|
||||
{
|
||||
Text = $"{_localizationManager.GetString(entry.Color.Name())}: ",
|
||||
FontColorOverride = entry.Color,
|
||||
};
|
||||
container.AddChild(newLabel);
|
||||
|
||||
var newButton = new Button()
|
||||
{
|
||||
Text = _localizationManager.GetString("Pulse"),
|
||||
};
|
||||
newButton.OnPressed += _ => Owner.PerformAction(entry.Guid, WiresAction.Pulse);
|
||||
container.AddChild(newButton);
|
||||
|
||||
newButton = new Button()
|
||||
{
|
||||
Text = entry.IsCut ? _localizationManager.GetString("Mend") : _localizationManager.GetString("Cut"),
|
||||
};
|
||||
newButton.OnPressed += _ => Owner.PerformAction(entry.Guid, entry.IsCut ? WiresAction.Mend : WiresAction.Cut);
|
||||
container.AddChild(newButton);
|
||||
_rows.AddChild(container);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Wires
|
||||
{
|
||||
public class WiresVisualizer2D : AppearanceVisualizer
|
||||
{
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
if (component.TryGetData<bool>(WiresVisuals.MaintenancePanelState, out var state))
|
||||
{
|
||||
sprite.LayerSetVisible(WiresVisualLayers.MaintenancePanel, state);
|
||||
}
|
||||
}
|
||||
|
||||
public enum WiresVisualLayers
|
||||
{
|
||||
MaintenancePanel,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,23 +5,28 @@ using Content.Shared.VendingMachines;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.Interfaces.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timers;
|
||||
using Robust.Shared.Utility;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Content.Server.GameObjects.Components.Power;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.Random;
|
||||
using static Content.Shared.GameObjects.Components.SharedWiresComponent;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.VendingMachines
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(IActivate))]
|
||||
public class VendingMachineComponent : SharedVendingMachineComponent, IActivate, IExamine, IBreakAct
|
||||
public class VendingMachineComponent : SharedVendingMachineComponent, IActivate, IExamine, IBreakAct, IWires
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IRobustRandom _random;
|
||||
#pragma warning restore 649
|
||||
private AppearanceComponent _appearance;
|
||||
private BoundUserInterface _userInterface;
|
||||
private PowerDeviceComponent _powerDevice;
|
||||
@@ -42,7 +47,14 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
||||
return;
|
||||
}
|
||||
|
||||
_userInterface.Open(actor.playerSession);
|
||||
var wires = Owner.GetComponent<WiresComponent>();
|
||||
if (wires.IsOpen)
|
||||
{
|
||||
wires.OpenInterface(actor.playerSession);
|
||||
} else
|
||||
{
|
||||
_userInterface.Open(actor.playerSession);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ExposeData(ObjectSerializer serializer)
|
||||
@@ -190,6 +202,60 @@ namespace Content.Server.GameObjects.Components.VendingMachines
|
||||
_broken = true;
|
||||
TrySetVisualState(VendingMachineVisualState.Broken);
|
||||
}
|
||||
|
||||
public enum Wires
|
||||
{
|
||||
/// <summary>
|
||||
/// Shoots a random item when pulsed.
|
||||
/// </summary>
|
||||
Shoot
|
||||
}
|
||||
|
||||
void IWires.RegisterWires(WiresComponent.WiresBuilder builder)
|
||||
{
|
||||
builder.CreateWire(Wires.Shoot);
|
||||
}
|
||||
|
||||
void IWires.WiresUpdate(WiresUpdateEventArgs args)
|
||||
{
|
||||
var identifier = (Wires) args.Identifier;
|
||||
if (identifier == Wires.Shoot && args.Action == WiresAction.Pulse)
|
||||
{
|
||||
EjectRandom();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ejects a random item if present.
|
||||
/// </summary>
|
||||
private void EjectRandom()
|
||||
{
|
||||
var availableItems = Inventory.Where(x => x.Amount > 0).ToList();
|
||||
if (availableItems.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
TryEject(_random.Pick(availableItems).ID);
|
||||
}
|
||||
}
|
||||
|
||||
public class WiresUpdateEventArgs : EventArgs
|
||||
{
|
||||
public readonly object Identifier;
|
||||
public readonly WiresAction Action;
|
||||
|
||||
public WiresUpdateEventArgs(object identifier, WiresAction action)
|
||||
{
|
||||
Identifier = identifier;
|
||||
Action = action;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IWires
|
||||
{
|
||||
void RegisterWires(WiresComponent.WiresBuilder builder);
|
||||
void WiresUpdate(WiresUpdateEventArgs args);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
251
Content.Server/GameObjects/Components/WiresComponent.cs
Normal file
251
Content.Server/GameObjects/Components/WiresComponent.cs
Normal file
@@ -0,0 +1,251 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Content.Server.GameObjects.Components.Interactable.Tools;
|
||||
using Content.Server.GameObjects.Components.VendingMachines;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Server.Interfaces.GameObjects;
|
||||
using Content.Shared.GameObjects.Components;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Server.GameObjects.Components.UserInterface;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Server.Interfaces.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Server.GameObjects.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class WiresComponent : SharedWiresComponent, IAttackBy, IExamine
|
||||
{
|
||||
#pragma warning disable 649
|
||||
[Dependency] private readonly IRobustRandom _random;
|
||||
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
||||
[Dependency] private readonly ILocalizationManager _localizationManager;
|
||||
#pragma warning restore 649
|
||||
private AudioSystem _audioSystem;
|
||||
private AppearanceComponent _appearance;
|
||||
private BoundUserInterface _userInterface;
|
||||
private bool _isOpen;
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get => _isOpen;
|
||||
private set
|
||||
{
|
||||
_isOpen = value;
|
||||
_appearance.SetData(WiresVisuals.MaintenancePanelState, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains all registered wires.
|
||||
/// </summary>
|
||||
public readonly List<Wire> WiresList = new List<Wire>();
|
||||
|
||||
/// <summary>
|
||||
/// As seen on /vg/station.
|
||||
/// <see cref="AssignColor"/> and <see cref="WiresBuilder.CreateWire"/>.
|
||||
/// </summary>
|
||||
private readonly List<Color> _availableColors = new List<Color>()
|
||||
{
|
||||
Color.Red,
|
||||
Color.Blue,
|
||||
Color.Green,
|
||||
Color.Orange,
|
||||
Color.Brown,
|
||||
Color.Gold,
|
||||
Color.Gray,
|
||||
Color.Cyan,
|
||||
Color.Navy,
|
||||
Color.Purple,
|
||||
Color.Pink,
|
||||
Color.Fuchsia,
|
||||
Color.Aqua,
|
||||
};
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
_audioSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AudioSystem>();
|
||||
_appearance = Owner.GetComponent<AppearanceComponent>();
|
||||
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsOpen);
|
||||
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
||||
.GetBoundUserInterface(WiresUiKey.Key);
|
||||
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
||||
|
||||
foreach (var wiresProvider in Owner.GetAllComponents<IWires>())
|
||||
{
|
||||
var builder = new WiresBuilder(this, wiresProvider);
|
||||
wiresProvider.RegisterWires(builder);
|
||||
}
|
||||
|
||||
UpdateUserInterface();
|
||||
}
|
||||
|
||||
public class Wire
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in client-server communication to identify a wire without telling the client what the wire does.
|
||||
/// </summary>
|
||||
public readonly Guid Guid;
|
||||
/// <summary>
|
||||
/// Registered by components implementing IWires, used to identify which wire the client interacted with.
|
||||
/// </summary>
|
||||
public readonly object Identifier;
|
||||
/// <summary>
|
||||
/// The color of the wire. It needs to have a corresponding entry in <see cref="Robust.Shared.Maths.Color.DefaultColors"/>.
|
||||
/// </summary>
|
||||
public readonly Color Color;
|
||||
/// <summary>
|
||||
/// The component that registered the wire.
|
||||
/// </summary>
|
||||
public readonly IWires Owner;
|
||||
/// <summary>
|
||||
/// Whether the wire is cut.
|
||||
/// </summary>
|
||||
public bool IsCut;
|
||||
public Wire(Guid guid, object identifier, Color color, IWires owner, bool isCut)
|
||||
{
|
||||
Guid = guid;
|
||||
Identifier = identifier;
|
||||
Color = color;
|
||||
Owner = owner;
|
||||
IsCut = isCut;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by <see cref="IWires.RegisterWires"/>.
|
||||
/// </summary>
|
||||
public class WiresBuilder
|
||||
{
|
||||
[NotNull] private readonly WiresComponent _wires;
|
||||
[NotNull] private readonly IWires _owner;
|
||||
|
||||
public WiresBuilder(WiresComponent wires, IWires owner)
|
||||
{
|
||||
_wires = wires;
|
||||
_owner = owner;
|
||||
}
|
||||
|
||||
public void CreateWire(object identifier, Color? color = null, bool isCut = false)
|
||||
{
|
||||
if (!color.HasValue)
|
||||
{
|
||||
color = _wires.AssignColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
_wires._availableColors.Remove(color.Value);
|
||||
}
|
||||
_wires.WiresList.Add(new Wire(Guid.NewGuid(), identifier, color.Value, _owner, isCut));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Picks a color from <see cref="_availableColors"/> and removes it from the list.
|
||||
/// </summary>
|
||||
/// <returns>The picked color.</returns>
|
||||
private Color AssignColor()
|
||||
{
|
||||
if(_availableColors.Count == 0)
|
||||
{
|
||||
return Color.Black;
|
||||
}
|
||||
return _random.PickAndTake(_availableColors);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Call this from other components to open the wires UI.
|
||||
/// </summary>
|
||||
public void OpenInterface(IPlayerSession session)
|
||||
{
|
||||
_userInterface.Open(session);
|
||||
}
|
||||
|
||||
private void UserInterfaceOnReceiveMessage(ServerBoundUserInterfaceMessage serverMsg)
|
||||
{
|
||||
var message = serverMsg.Message;
|
||||
switch (message)
|
||||
{
|
||||
case WiresActionMessage msg:
|
||||
var wire = WiresList.Find(x => x.Guid == msg.Guid);
|
||||
var player = serverMsg.Session.AttachedEntity;
|
||||
if (!player.TryGetComponent(out IHandsComponent handsComponent))
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You have no hands."));
|
||||
return;
|
||||
}
|
||||
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
||||
switch (msg.Action)
|
||||
{
|
||||
case WiresAction.Cut:
|
||||
if (activeHandEntity?.HasComponent<WirecutterComponent>() != true)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You need to hold a wirecutter in your hand!"));
|
||||
return;
|
||||
}
|
||||
_audioSystem.Play("/Audio/items/wirecutter.ogg", Owner);
|
||||
wire.IsCut = true;
|
||||
UpdateUserInterface();
|
||||
break;
|
||||
case WiresAction.Mend:
|
||||
if (activeHandEntity?.HasComponent<WirecutterComponent>() != true)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You need to hold a wirecutter in your hand!"));
|
||||
return;
|
||||
}
|
||||
_audioSystem.Play("/Audio/items/wirecutter.ogg", Owner);
|
||||
wire.IsCut = false;
|
||||
UpdateUserInterface();
|
||||
break;
|
||||
case WiresAction.Pulse:
|
||||
if (activeHandEntity?.HasComponent<MultitoolComponent>() != true)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You need to hold a multitool in your hand!"));
|
||||
return;
|
||||
}
|
||||
if (wire.IsCut)
|
||||
{
|
||||
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player, _localizationManager.GetString("You can't pulse a wire that's been cut!"));
|
||||
return;
|
||||
}
|
||||
_audioSystem.Play("/Audio/effects/multitool_pulse.ogg", Owner);
|
||||
break;
|
||||
}
|
||||
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, msg.Action));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateUserInterface()
|
||||
{
|
||||
var clientList = new List<ClientWire>();
|
||||
foreach (var entry in WiresList)
|
||||
{
|
||||
clientList.Add(new ClientWire(entry.Guid, entry.Color, entry.IsCut));
|
||||
}
|
||||
_userInterface.SetState(new WiresBoundUserInterfaceState(clientList));
|
||||
}
|
||||
|
||||
bool IAttackBy.AttackBy(AttackByEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.AttackWith.HasComponent<ScrewdriverComponent>()) return false;
|
||||
IsOpen = !IsOpen;
|
||||
return true;
|
||||
}
|
||||
|
||||
void IExamine.Examine(FormattedMessage message)
|
||||
{
|
||||
message.AddText($"The maintenance panel is {(IsOpen ? "open" : "closed")}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components.UserInterface;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components
|
||||
{
|
||||
public class SharedWiresComponent : Component
|
||||
{
|
||||
public override string Name => "Wires";
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum WiresVisuals
|
||||
{
|
||||
MaintenancePanelState
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum WiresUiKey
|
||||
{
|
||||
Key,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum WiresAction
|
||||
{
|
||||
Mend,
|
||||
Cut,
|
||||
Pulse,
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class WiresBoundUserInterfaceState : BoundUserInterfaceState
|
||||
{
|
||||
public readonly List<ClientWire> WiresList;
|
||||
|
||||
public WiresBoundUserInterfaceState(List<ClientWire> wiresList)
|
||||
{
|
||||
WiresList = wiresList;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class ClientWire
|
||||
{
|
||||
public Guid Guid;
|
||||
public Color Color;
|
||||
public bool IsCut;
|
||||
|
||||
public ClientWire(Guid guid, Color color, bool isCut)
|
||||
{
|
||||
Guid = guid;
|
||||
Color = color;
|
||||
IsCut = isCut;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public class WiresActionMessage : BoundUserInterfaceMessage
|
||||
{
|
||||
public readonly Guid Guid;
|
||||
public readonly WiresAction Action;
|
||||
public WiresActionMessage(Guid guid, WiresAction action)
|
||||
{
|
||||
Guid = guid;
|
||||
Action = action;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,5 +24,6 @@
|
||||
public const uint MATERIAL_STORAGE = 1018;
|
||||
public const uint HAND_TELEPORTER = 1019;
|
||||
public const uint VENDING_MACHINE = 1020;
|
||||
public const uint WIRES = 1021;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
Resources/Audio/effects/multitool_pulse.ogg
Normal file
BIN
Resources/Audio/effects/multitool_pulse.ogg
Normal file
Binary file not shown.
@@ -8,6 +8,8 @@
|
||||
layers:
|
||||
- state: normal
|
||||
map: ["enum.VendingMachineVisualLayers.Base"]
|
||||
- texture: Buildings/maintenance_panel.png
|
||||
map: ["enum.WiresVisualLayers.MaintenancePanel"]
|
||||
- type: Icon
|
||||
sprite: Buildings/VendingMachines/empty.rsi
|
||||
state: normal
|
||||
@@ -20,12 +22,16 @@
|
||||
- type: Appearance
|
||||
visuals:
|
||||
- type: VendingMachineVisualizer2D
|
||||
- type: WiresVisualizer2D
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
- key: enum.VendingMachineUiKey.Key
|
||||
type: VendingMachineBoundUserInterface
|
||||
- key: enum.WiresUiKey.Key
|
||||
type: WiresBoundUserInterface
|
||||
- type: PowerDevice
|
||||
priority: Low
|
||||
- type: Wires
|
||||
|
||||
- type: entity
|
||||
parent: VendingMachine
|
||||
|
||||
BIN
Resources/Textures/Buildings/maintenance_panel.png
Normal file
BIN
Resources/Textures/Buildings/maintenance_panel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 147 B |
Reference in New Issue
Block a user