Nerf hacking a smidge (#5940)

This commit is contained in:
metalgearsloth
2022-01-26 15:26:53 +11:00
committed by GitHub
parent e63ad2eb0f
commit 73e7b53edf
6 changed files with 331 additions and 157 deletions

View File

@@ -1,7 +1,16 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Content.Server.Tools;
using Content.Server.VendingMachines;
using Content.Shared.ActionBlocker;
using Content.Shared.Examine;
using Content.Shared.GameTicking;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Player;
using Robust.Shared.Random;
using Robust.Shared.ViewVariables;
using static Content.Shared.Wires.SharedWiresComponent;
@@ -9,6 +18,10 @@ namespace Content.Server.WireHacking
{
public class WireHackingSystem : EntitySystem
{
[Dependency] private readonly IRobustRandom _random = default!;
[Dependency] private readonly ActionBlockerSystem _blocker = default!;
[Dependency] private readonly ToolSystem _tools = default!;
[ViewVariables] private readonly Dictionary<string, WireLayout> _layouts =
new();
@@ -18,23 +31,184 @@ namespace Content.Server.WireHacking
{
base.Initialize();
SubscribeLocalEvent<WiresComponent, ComponentStartup>(OnWiresStartup);
SubscribeLocalEvent<WiresComponent, MapInitEvent>(OnWiresMapInit);
SubscribeLocalEvent<WiresComponent, ExaminedEvent>(OnWiresExamine);
// Hacking DoAfters
SubscribeLocalEvent<WiresComponent, WiresComponent.WiresCutEvent>(OnWiresCut);
SubscribeLocalEvent<WiresComponent, WiresComponent.WiresMendedEvent>(OnWiresMended);
SubscribeLocalEvent<WiresComponent, WiresComponent.WiresPulsedEvent>(OnWiresPulsed);
SubscribeLocalEvent<WiresComponent, WiresComponent.WiresCancelledEvent>(OnWiresCancelled);
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
}
public bool TryGetLayout(string id, [NotNullWhen(true)] out WireLayout? layout)
private void OnWiresCancelled(EntityUid uid, WiresComponent component, WiresComponent.WiresCancelledEvent args)
{
return _layouts.TryGetValue(id, out layout);
component.PendingDoAfters.Remove(args.Wire.Id);
}
public void AddLayout(string id, WireLayout layout)
private void HackingInteract(WiresComponent component, WiresComponent.Wire wire)
{
_layouts.Add(id, layout);
component.PendingDoAfters.Remove(wire.Id);
}
public void Reset(RoundRestartCleanupEvent ev)
private void OnWiresCut(EntityUid uid, WiresComponent component, WiresComponent.WiresCutEvent args)
{
HackingInteract(component, args.Wire);
// Re-validate
// Deletion for user + wires should already be handled by do-after and tool is checked once at end in active-hand anyway.
if (!component.CanWiresInteract(args.User, out var tool)) return;
if (!tool.Qualities.Contains(component.CuttingQuality)) return;
var wire = args.Wire;
_tools.PlayToolSound(args.Tool.Owner, args.Tool);
wire.IsCut = true;
component.UpdateUserInterface();
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, WiresAction.Cut));
}
private void OnWiresMended(EntityUid uid, WiresComponent component, WiresComponent.WiresMendedEvent args)
{
HackingInteract(component, args.Wire);
if (!component.CanWiresInteract(args.User, out var tool)) return;
if (!tool.Qualities.Contains(component.CuttingQuality)) return;
var wire = args.Wire;
_tools.PlayToolSound(args.Tool.Owner, args.Tool);
wire.IsCut = false;
component.UpdateUserInterface();
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, WiresAction.Mend));
}
private void OnWiresPulsed(EntityUid uid, WiresComponent component, WiresComponent.WiresPulsedEvent args)
{
HackingInteract(component, args.Wire);
if (args.Wire.IsCut || !component.CanWiresInteract(args.User, out var tool)) return;
if (!tool.Qualities.Contains(component.PulsingQuality)) return;
var wire = args.Wire;
SoundSystem.Play(Filter.Pvs(uid), component.PulseSound.GetSound(), uid);
wire.Owner.WiresUpdate(new WiresUpdateEventArgs(wire.Identifier, WiresAction.Pulse));
}
private void OnWiresExamine(EntityUid uid, WiresComponent component, ExaminedEvent args)
{
args.PushMarkup(Loc.GetString(component.IsPanelOpen
? "wires-component-on-examine-panel-open"
: "wires-component-on-examine-panel-closed"));
}
private void OnWiresStartup(EntityUid uid, WiresComponent component, ComponentStartup args)
{
WireLayout? layout = null;
if (component.LayoutId != null)
{
_layouts.TryGetValue(component.LayoutId, out layout);
}
foreach (var wiresProvider in EntityManager.GetComponents<IWires>(uid))
{
var builder = new WiresComponent.WiresBuilder(component, wiresProvider, layout);
wiresProvider.RegisterWires(builder);
}
if (layout != null)
{
component.WiresList.Sort((a, b) =>
{
var pA = layout.Specifications[a.Identifier].Position;
var pB = layout.Specifications[b.Identifier].Position;
return pA.CompareTo(pB);
});
}
else
{
_random.Shuffle(component.WiresList);
if (component.LayoutId != null)
{
var dict = new Dictionary<object, WireLayout.WireData>();
for (var i = 0; i < component.WiresList.Count; i++)
{
var d = component.WiresList[i];
dict.Add(d.Identifier, new WireLayout.WireData(d.Letter, d.Color, i));
}
_layouts.Add(component.LayoutId, new WireLayout(dict));
}
}
var id = 0;
foreach (var wire in component.WiresList)
{
wire.Id = ++id;
}
component.UpdateUserInterface();
}
private void Reset(RoundRestartCleanupEvent ev)
{
_layouts.Clear();
}
private void OnWiresMapInit(EntityUid uid, WiresComponent component, MapInitEvent args)
{
if (component.SerialNumber == null)
{
GenerateSerialNumber(component);
}
if (component.WireSeed == 0)
{
component.WireSeed = _random.Next(1, int.MaxValue);
component.UpdateUserInterface();
}
}
private void GenerateSerialNumber(WiresComponent component)
{
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);
}
component.SerialNumber = new string(data);
}
}
public sealed class WireLayout