2020-05-31 19:29:06 +01:00
|
|
|
|
using System;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
using System.Collections.Generic;
|
2019-09-06 10:05:02 +02:00
|
|
|
|
using System.Linq;
|
2020-04-29 13:43:07 +02:00
|
|
|
|
using Content.Server.GameObjects.Components.Interactable;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
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;
|
2020-04-29 13:43:07 +02:00
|
|
|
|
using Content.Shared.GameObjects.Components.Interactable;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
using JetBrains.Annotations;
|
|
|
|
|
|
using Robust.Server.GameObjects;
|
|
|
|
|
|
using Robust.Server.GameObjects.Components.UserInterface;
|
|
|
|
|
|
using Robust.Server.GameObjects.EntitySystems;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
using Robust.Server.Interfaces.GameObjects;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
using Robust.Server.Interfaces.Player;
|
|
|
|
|
|
using Robust.Shared.GameObjects;
|
2020-05-23 02:27:31 -07:00
|
|
|
|
using Robust.Shared.GameObjects.Systems;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
using Robust.Shared.Interfaces.Random;
|
|
|
|
|
|
using Robust.Shared.IoC;
|
|
|
|
|
|
using Robust.Shared.Localization;
|
|
|
|
|
|
using Robust.Shared.Random;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
using Robust.Shared.Serialization;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
using Robust.Shared.Utility;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
using Robust.Shared.ViewVariables;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
|
|
|
|
|
|
namespace Content.Server.GameObjects.Components
|
|
|
|
|
|
{
|
|
|
|
|
|
[RegisterComponent]
|
2020-05-27 15:09:22 +02:00
|
|
|
|
public class WiresComponent : SharedWiresComponent, IInteractUsing, IExamine, IMapInit
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
|
|
|
|
|
#pragma warning disable 649
|
|
|
|
|
|
[Dependency] private readonly IRobustRandom _random;
|
|
|
|
|
|
[Dependency] private readonly IServerNotifyManager _notifyManager;
|
|
|
|
|
|
#pragma warning restore 649
|
|
|
|
|
|
private AudioSystem _audioSystem;
|
|
|
|
|
|
private AppearanceComponent _appearance;
|
|
|
|
|
|
private BoundUserInterface _userInterface;
|
|
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
private bool _isPanelOpen;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Opening the maintenance panel (typically with a screwdriver) changes this.
|
|
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[ViewVariables]
|
2019-09-18 22:12:36 +02:00
|
|
|
|
public bool IsPanelOpen
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2019-09-18 22:12:36 +02:00
|
|
|
|
get => _isPanelOpen;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
private set
|
|
|
|
|
|
{
|
2019-09-18 22:12:36 +02:00
|
|
|
|
if (_isPanelOpen == value)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
_isPanelOpen = value;
|
|
|
|
|
|
UpdateAppearance();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private bool _isPanelVisible = true;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Components can set this to prevent the maintenance panel overlay from showing even if it's open
|
|
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[ViewVariables]
|
2019-09-18 22:12:36 +02:00
|
|
|
|
public bool IsPanelVisible
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _isPanelVisible;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_isPanelVisible == value)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
_isPanelVisible = value;
|
|
|
|
|
|
UpdateAppearance();
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[ViewVariables(VVAccess.ReadWrite)]
|
|
|
|
|
|
public string BoardName
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _boardName;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
_boardName = value;
|
|
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[ViewVariables(VVAccess.ReadWrite)]
|
|
|
|
|
|
public string SerialNumber
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _serialNumber;
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
_serialNumber = value;
|
|
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
private void UpdateAppearance()
|
|
|
|
|
|
{
|
|
|
|
|
|
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen && IsPanelVisible);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Contains all registered wires.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public readonly List<Wire> WiresList = new List<Wire>();
|
|
|
|
|
|
|
2019-09-06 10:05:02 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Status messages are displayed at the bottom of the UI.
|
|
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
private readonly Dictionary<object, object> _statuses = new Dictionary<object, object>();
|
2019-09-06 10:05:02 +02:00
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// <summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
/// <see cref="AssignAppearance"/> and <see cref="WiresBuilder.CreateWire"/>.
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
private readonly List<WireColor> _availableColors =
|
|
|
|
|
|
new List<WireColor>((WireColor[]) Enum.GetValues(typeof(WireColor)));
|
|
|
|
|
|
|
|
|
|
|
|
private readonly List<WireLetter> _availableLetters =
|
|
|
|
|
|
new List<WireLetter>((WireLetter[]) Enum.GetValues(typeof(WireLetter)));
|
|
|
|
|
|
|
|
|
|
|
|
private string _boardName;
|
|
|
|
|
|
|
|
|
|
|
|
private string _serialNumber;
|
|
|
|
|
|
|
|
|
|
|
|
// Used to generate wire appearance randomization client side.
|
|
|
|
|
|
// We honestly don't care what it is or such but do care that it doesn't change between UI re-opens.
|
|
|
|
|
|
[ViewVariables]
|
|
|
|
|
|
private int _wireSeed;
|
|
|
|
|
|
[ViewVariables]
|
|
|
|
|
|
private string _layoutId;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
|
|
|
|
|
|
public override void Initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.Initialize();
|
2020-05-23 02:27:31 -07:00
|
|
|
|
_audioSystem = EntitySystem.Get<AudioSystem>();
|
2019-09-01 22:15:34 +02:00
|
|
|
|
_appearance = Owner.GetComponent<AppearanceComponent>();
|
2019-09-18 22:12:36 +02:00
|
|
|
|
_appearance.SetData(WiresVisuals.MaintenancePanelState, IsPanelOpen);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
_userInterface = Owner.GetComponent<ServerUserInterfaceComponent>()
|
|
|
|
|
|
.GetBoundUserInterface(WiresUiKey.Key);
|
|
|
|
|
|
_userInterface.OnReceiveMessage += UserInterfaceOnReceiveMessage;
|
2020-02-27 00:16:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
private void GenerateSerialNumber()
|
|
|
|
|
|
{
|
|
|
|
|
|
var random = IoCManager.Resolve<IRobustRandom>();
|
|
|
|
|
|
Span<char> data = stackalloc char[9];
|
|
|
|
|
|
data[4] = '-';
|
|
|
|
|
|
|
|
|
|
|
|
if (random.Prob(0.01f))
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < 4; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Cyrillic Letters
|
|
|
|
|
|
data[i] = (char) random.Next(0x0410, 0x0430);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < 4; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Letters
|
|
|
|
|
|
data[i] = (char) random.Next(0x41, 0x5B);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (var i = 5; i < 9; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Digits
|
|
|
|
|
|
data[i] = (char) random.Next(0x30, 0x3A);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SerialNumber = new string(data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-27 00:16:39 +01:00
|
|
|
|
protected override void Startup()
|
|
|
|
|
|
{
|
|
|
|
|
|
base.Startup();
|
2019-09-01 22:15:34 +02:00
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
|
|
|
|
|
WireLayout layout = null;
|
|
|
|
|
|
var hackingSystem = EntitySystem.Get<WireHackingSystem>();
|
|
|
|
|
|
if (_layoutId != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
hackingSystem.TryGetLayout(_layoutId, out layout);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
foreach (var wiresProvider in Owner.GetAllComponents<IWires>())
|
|
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
var builder = new WiresBuilder(this, wiresProvider, layout);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
wiresProvider.RegisterWires(builder);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
if (layout != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
WiresList.Sort((a, b) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var pA = layout.Specifications[a.Identifier].Position;
|
|
|
|
|
|
var pB = layout.Specifications[b.Identifier].Position;
|
|
|
|
|
|
|
|
|
|
|
|
return pA.CompareTo(pB);
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
IoCManager.Resolve<IRobustRandom>().Shuffle(WiresList);
|
|
|
|
|
|
|
|
|
|
|
|
if (_layoutId != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dict = new Dictionary<object, WireLayout.WireData>();
|
|
|
|
|
|
for (var i = 0; i < WiresList.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var d = WiresList[i];
|
|
|
|
|
|
dict.Add(d.Identifier, new WireLayout.WireData(d.Letter, d.Color, i));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
hackingSystem.AddLayout(_layoutId, new WireLayout(dict));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var id = 0;
|
|
|
|
|
|
foreach (var wire in WiresList)
|
|
|
|
|
|
{
|
|
|
|
|
|
wire.Id = ++id;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-06 10:05:02 +02:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Returns whether the wire associated with <see cref="identifier"/> is cut.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <exception cref="ArgumentException"></exception>
|
|
|
|
|
|
public bool IsWireCut(object identifier)
|
|
|
|
|
|
{
|
|
|
|
|
|
var wire = WiresList.Find(x => x.Identifier.Equals(identifier));
|
2020-05-27 15:09:22 +02:00
|
|
|
|
if (wire == null) throw new ArgumentException();
|
2019-09-06 10:05:02 +02:00
|
|
|
|
return wire.IsCut;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
public class Wire
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
/// The component that registered the wire.
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
public IWires Owner { get; }
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// <summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
/// Whether the wire is cut.
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
public bool IsCut { get; set; }
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// <summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
/// Used in client-server communication to identify a wire without telling the client what the wire does.
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[ViewVariables]
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// <summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
/// The color of the wire.
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[ViewVariables]
|
|
|
|
|
|
public WireColor Color { get; }
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// <summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
/// The greek letter shown below the wire.
|
2019-09-01 22:15:34 +02:00
|
|
|
|
/// </summary>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[ViewVariables]
|
|
|
|
|
|
public WireLetter Letter { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Registered by components implementing IWires, used to identify which wire the client interacted with.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[ViewVariables]
|
|
|
|
|
|
public object Identifier { get; }
|
|
|
|
|
|
|
|
|
|
|
|
public Wire(IWires owner, bool isCut, WireColor color, WireLetter letter, object identifier)
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
|
|
|
|
|
Owner = owner;
|
|
|
|
|
|
IsCut = isCut;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
Color = color;
|
|
|
|
|
|
Letter = letter;
|
|
|
|
|
|
Identifier = identifier;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Used by <see cref="IWires.RegisterWires"/>.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class WiresBuilder
|
|
|
|
|
|
{
|
|
|
|
|
|
[NotNull] private readonly WiresComponent _wires;
|
|
|
|
|
|
[NotNull] private readonly IWires _owner;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
[CanBeNull] private readonly WireLayout _layout;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
public WiresBuilder(WiresComponent wires, IWires owner, WireLayout layout)
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
|
|
|
|
|
_wires = wires;
|
|
|
|
|
|
_owner = owner;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_layout = layout;
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
public void CreateWire(object identifier, (WireColor, WireLetter)? appearance = null, bool isCut = false)
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
WireLetter letter;
|
|
|
|
|
|
WireColor color;
|
|
|
|
|
|
if (!appearance.HasValue)
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
if (_layout != null && _layout.Specifications.TryGetValue(identifier, out var specification))
|
|
|
|
|
|
{
|
|
|
|
|
|
color = specification.Color;
|
|
|
|
|
|
letter = specification.Letter;
|
|
|
|
|
|
_wires._availableColors.Remove(color);
|
|
|
|
|
|
_wires._availableLetters.Remove(letter);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
(color, letter) = _wires.AssignAppearance();
|
|
|
|
|
|
}
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
(color, letter) = appearance.Value;
|
|
|
|
|
|
_wires._availableColors.Remove(color);
|
|
|
|
|
|
_wires._availableLetters.Remove(letter);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
|
|
|
|
|
// TODO: ENSURE NO RANDOM OVERLAP.
|
|
|
|
|
|
_wires.WiresList.Add(new Wire(_owner, isCut, color, letter, identifier));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Picks a color from <see cref="_availableColors"/> and removes it from the list.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>The picked color.</returns>
|
2020-05-27 15:09:22 +02:00
|
|
|
|
private (WireColor, WireLetter) AssignAppearance()
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
var color = _availableColors.Count == 0 ? WireColor.Red : _random.PickAndTake(_availableColors);
|
|
|
|
|
|
var letter = _availableLetters.Count == 0 ? WireLetter.α : _random.PickAndTake(_availableLetters);
|
|
|
|
|
|
|
|
|
|
|
|
return (color, letter);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <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:
|
2020-05-27 15:09:22 +02:00
|
|
|
|
var wire = WiresList.Find(x => x.Id == msg.Id);
|
|
|
|
|
|
if (wire == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
var player = serverMsg.Session.AttachedEntity;
|
|
|
|
|
|
if (!player.TryGetComponent(out IHandsComponent handsComponent))
|
|
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player,
|
|
|
|
|
|
Loc.GetString("You have no hands."));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-08 14:01:33 +02:00
|
|
|
|
|
2020-05-26 14:23:25 +02:00
|
|
|
|
if (!EntitySystem.Get<SharedInteractionSystem>().InRangeUnobstructed(player.Transform.MapPosition, Owner.Transform.MapPosition, ignoredEnt: Owner))
|
2020-05-08 14:01:33 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_notifyManager.PopupMessage(Owner.Transform.GridPosition, player,
|
|
|
|
|
|
Loc.GetString("You can't reach there!"));
|
2020-05-08 14:01:33 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
var activeHandEntity = handsComponent.GetActiveHand?.Owner;
|
2020-05-27 15:09:22 +02:00
|
|
|
|
ToolComponent tool = null;
|
|
|
|
|
|
activeHandEntity?.TryGetComponent(out tool);
|
|
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
switch (msg.Action)
|
|
|
|
|
|
{
|
|
|
|
|
|
case WiresAction.Cut:
|
2020-05-19 13:55:52 +02:00
|
|
|
|
if (tool == null || !tool.HasQuality(ToolQuality.Cutting))
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_notifyManager.PopupMessageCursor(player,
|
|
|
|
|
|
Loc.GetString("You need to hold a wirecutter in your hand!"));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2020-04-29 13:43:07 +02:00
|
|
|
|
tool.PlayUseSound();
|
2019-09-01 22:15:34 +02:00
|
|
|
|
wire.IsCut = true;
|
|
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WiresAction.Mend:
|
2020-05-19 13:55:52 +02:00
|
|
|
|
if (tool == null || !tool.HasQuality(ToolQuality.Cutting))
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_notifyManager.PopupMessageCursor(player,
|
|
|
|
|
|
Loc.GetString("You need to hold a wirecutter in your hand!"));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2020-04-29 13:43:07 +02:00
|
|
|
|
tool.PlayUseSound();
|
2019-09-01 22:15:34 +02:00
|
|
|
|
wire.IsCut = false;
|
|
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WiresAction.Pulse:
|
2020-05-19 13:55:52 +02:00
|
|
|
|
if (tool == null || !tool.HasQuality(ToolQuality.Multitool))
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_notifyManager.PopupMessageCursor(player,
|
|
|
|
|
|
Loc.GetString("You need to hold a multitool in your hand!"));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
if (wire.IsCut)
|
|
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
_notifyManager.PopupMessageCursor(player,
|
|
|
|
|
|
Loc.GetString("You can't pulse a wire that's been cut!"));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2020-06-07 08:55:15 -05:00
|
|
|
|
_audioSystem.PlayFromEntity("/Audio/effects/multitool_pulse.ogg", Owner);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
2019-09-01 22:15:34 +02:00
|
|
|
|
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, msg.Action));
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void UpdateUserInterface()
|
|
|
|
|
|
{
|
|
|
|
|
|
var clientList = new List<ClientWire>();
|
|
|
|
|
|
foreach (var entry in WiresList)
|
|
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
clientList.Add(new ClientWire(entry.Id, entry.IsCut, entry.Color,
|
|
|
|
|
|
entry.Letter));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
|
|
|
|
|
_userInterface.SetState(
|
|
|
|
|
|
new WiresBoundUserInterfaceState(
|
|
|
|
|
|
clientList.ToArray(),
|
|
|
|
|
|
_statuses.Select(p => new StatusEntry(p.Key, p.Value)).ToArray(),
|
|
|
|
|
|
BoardName,
|
|
|
|
|
|
SerialNumber,
|
|
|
|
|
|
_wireSeed));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override void ExposeData(ObjectSerializer serializer)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.ExposeData(serializer);
|
|
|
|
|
|
|
|
|
|
|
|
serializer.DataField(ref _boardName, "BoardName", "Wires");
|
|
|
|
|
|
serializer.DataField(ref _serialNumber, "SerialNumber", null);
|
|
|
|
|
|
serializer.DataField(ref _wireSeed, "WireSeed", 0);
|
|
|
|
|
|
serializer.DataField(ref _layoutId, "LayoutId", null);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-23 17:23:25 +02:00
|
|
|
|
bool IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs)
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2020-05-23 18:00:28 +02:00
|
|
|
|
if (!eventArgs.Using.TryGetComponent<ToolComponent>(out var tool))
|
2020-04-29 13:43:07 +02:00
|
|
|
|
return false;
|
2020-05-19 13:55:52 +02:00
|
|
|
|
if (!tool.UseTool(eventArgs.User, Owner, ToolQuality.Screwing))
|
2019-10-13 19:45:25 +02:00
|
|
|
|
return false;
|
|
|
|
|
|
|
2019-09-18 22:12:36 +02:00
|
|
|
|
IsPanelOpen = !IsPanelOpen;
|
2020-05-23 02:27:31 -07:00
|
|
|
|
EntitySystem.Get<AudioSystem>()
|
2020-06-07 08:55:15 -05:00
|
|
|
|
.PlayFromEntity(IsPanelOpen ? "/Audio/machines/screwdriveropen.ogg" : "/Audio/machines/screwdriverclose.ogg",
|
2020-05-27 15:09:22 +02:00
|
|
|
|
Owner);
|
2019-09-01 22:15:34 +02:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-05-31 19:29:06 +01:00
|
|
|
|
void IExamine.Examine(FormattedMessage message, bool inDetailsRange)
|
2019-09-01 22:15:34 +02:00
|
|
|
|
{
|
2019-10-13 19:45:25 +02:00
|
|
|
|
var loc = IoCManager.Resolve<ILocalizationManager>();
|
2019-10-13 22:49:07 +02:00
|
|
|
|
|
|
|
|
|
|
message.AddMarkup(loc.GetString(IsPanelOpen
|
|
|
|
|
|
? "The [color=lightgray]maintenance panel[/color] is [color=darkgreen]open[/color]."
|
|
|
|
|
|
: "The [color=lightgray]maintenance panel[/color] is [color=darkred]closed[/color]."));
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
2019-09-06 10:05:02 +02:00
|
|
|
|
|
2020-05-27 15:09:22 +02:00
|
|
|
|
public void SetStatus(object statusIdentifier, object status)
|
2019-09-06 10:05:02 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (_statuses.TryGetValue(statusIdentifier, out var storedMessage))
|
|
|
|
|
|
{
|
2020-05-27 15:09:22 +02:00
|
|
|
|
if (storedMessage == status)
|
2019-09-06 10:05:02 +02:00
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
|
|
|
|
|
_statuses[statusIdentifier] = status;
|
2019-09-06 10:05:02 +02:00
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
}
|
2020-05-27 15:09:22 +02:00
|
|
|
|
|
|
|
|
|
|
void IMapInit.MapInit()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (SerialNumber == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GenerateSerialNumber();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (_wireSeed == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
_wireSeed = IoCManager.Resolve<IRobustRandom>().Next(1, int.MaxValue);
|
|
|
|
|
|
UpdateUserInterface();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-09-01 22:15:34 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|