Wires refactor (#7699)

Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Co-authored-by: Kara <lunarautomaton6@gmail.com>
This commit is contained in:
Flipp Syder
2022-05-05 19:35:06 -07:00
committed by GitHub
parent 39a35641ab
commit 2c6158e115
51 changed files with 2656 additions and 1660 deletions

View File

@@ -2,23 +2,17 @@ using System;
using System.Threading;
using System.Collections.Generic;
using Content.Server.Atmos.Monitor.Systems;
using Content.Server.DeviceNetwork.Components;
using Content.Server.Power.Components;
using Content.Server.VendingMachines; // TODO: Move this out of vending machines???
using Content.Server.WireHacking;
using Content.Shared.Atmos.Monitor.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.ViewVariables;
using static Content.Shared.Wires.SharedWiresComponent;
using static Content.Shared.Wires.SharedWiresComponent.WiresAction;
namespace Content.Server.Atmos.Monitor.Components
{
[RegisterComponent]
public sealed class AirAlarmComponent : Component, IWires
public sealed class AirAlarmComponent : Component
{
[Dependency] private readonly IEntityManager _entMan = default!;
@@ -33,188 +27,6 @@ namespace Content.Server.Atmos.Monitor.Components
public HashSet<NetUserId> ActivePlayers = new();
public bool FullAccess = false;
public bool CanSync = true;
// <-- Wires -->
private CancellationTokenSource _powerPulsedCancel = new();
private int PowerPulsedTimeout = 30;
private enum Wires
{
// Cutting this kills power.
// Pulsing it disrupts power.
Power,
// Cutting this allows full access.
// Pulsing this does nothing.
Access,
// Cutting/Remending this resets ONLY from panic mode.
// Pulsing this sets panic mode.
Panic,
// Cutting this clears sync'd devices, and makes
// the alarm unable to resync.
// Pulsing this resyncs all devices (ofc current
// implementation just auto-does this anyways)
DeviceSync,
// This does nothing. (placeholder for AI wire,
// if that ever gets implemented)
Dummy
}
public void RegisterWires(WiresComponent.WiresBuilder builder)
{
foreach (var wire in Enum.GetValues<Wires>())
builder.CreateWire(wire);
UpdateWires();
}
public void UpdateWires()
{
if (_airAlarmSystem == null)
_airAlarmSystem = EntitySystem.Get<AirAlarmSystem>();
if (!_entMan.TryGetComponent<WiresComponent>(Owner, out var wires)) return;
var pwrLightState = (PowerPulsed, PowerCut) switch {
(true, false) => StatusLightState.BlinkingFast,
(_, true) => StatusLightState.Off,
(_, _) => StatusLightState.On
};
var powerLight = new StatusLightData(Color.Yellow, pwrLightState, "POWR");
var accessLight = new StatusLightData(
Color.Green,
wires.IsWireCut(Wires.Access) ? StatusLightState.Off : StatusLightState.On,
"ACC"
);
var panicLight = new StatusLightData(
Color.Red,
CurrentMode == AirAlarmMode.Panic ? StatusLightState.On : StatusLightState.Off,
"PAN"
);
var syncLightState = StatusLightState.BlinkingSlow;
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent) && !atmosMonitorComponent.NetEnabled)
syncLightState = StatusLightState.Off;
else if (DeviceData.Count != 0)
syncLightState = StatusLightState.On;
var syncLight = new StatusLightData(Color.Orange, syncLightState, "NET");
wires.SetStatus(AirAlarmWireStatus.Power, powerLight);
wires.SetStatus(AirAlarmWireStatus.Access, accessLight);
wires.SetStatus(AirAlarmWireStatus.Panic, panicLight);
wires.SetStatus(AirAlarmWireStatus.DeviceSync, syncLight);
}
private bool _powerCut;
private bool PowerCut
{
get => _powerCut;
set
{
_powerCut = value;
SetPower();
}
}
private bool _powerPulsed;
private bool PowerPulsed
{
get => _powerPulsed && !_powerCut;
set
{
_powerPulsed = value;
SetPower();
}
}
private void SetPower()
{
if (_entMan.TryGetComponent<ApcPowerReceiverComponent>(Owner, out var receiverComponent)
&& _entMan.HasComponent<WiresComponent>(Owner))
receiverComponent.PowerDisabled = PowerPulsed || PowerCut;
}
public void WiresUpdate(WiresUpdateEventArgs args)
{
if (!_entMan.TryGetComponent<DeviceNetworkComponent>(Owner, out var deviceNetworkComponent)) return;
if (_airAlarmSystem == null)
_airAlarmSystem = EntitySystem.Get<AirAlarmSystem>();
switch (args.Action)
{
case Pulse:
switch (args.Identifier)
{
case Wires.Power:
PowerPulsed = true;
_powerPulsedCancel.Cancel();
_powerPulsedCancel = new CancellationTokenSource();
Owner.SpawnTimer(TimeSpan.FromSeconds(PowerPulsedTimeout),
() => PowerPulsed = false,
_powerPulsedCancel.Token);
break;
case Wires.Panic:
if (CurrentMode != AirAlarmMode.Panic)
_airAlarmSystem.SetMode(Owner, deviceNetworkComponent.Address, AirAlarmMode.Panic, true, false);
break;
case Wires.DeviceSync:
_airAlarmSystem.SyncAllDevices(Owner);
break;
}
break;
case Mend:
switch (args.Identifier)
{
case Wires.Power:
_powerPulsedCancel.Cancel();
PowerPulsed = false;
PowerCut = false;
break;
case Wires.Panic:
if (CurrentMode == AirAlarmMode.Panic)
_airAlarmSystem.SetMode(Owner, deviceNetworkComponent.Address, AirAlarmMode.Filtering, true, false);
break;
case Wires.Access:
FullAccess = false;
break;
case Wires.DeviceSync:
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent))
atmosMonitorComponent.NetEnabled = true;
break;
}
break;
case Cut:
switch (args.Identifier)
{
case Wires.DeviceSync:
DeviceData.Clear();
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent))
{
atmosMonitorComponent.NetworkAlarmStates.Clear();
atmosMonitorComponent.NetEnabled = false;
}
break;
case Wires.Power:
PowerCut = true;
break;
case Wires.Access:
FullAccess = true;
break;
}
break;
}
UpdateWires();
}
}
}

View File

@@ -1,165 +1,7 @@
using System;
using System.Threading;
using Content.Server.Atmos.Monitor.Systems;
using Content.Server.Power.Components;
using Content.Server.VendingMachines; // TODO: Move this out of vending machines???
using Content.Server.WireHacking;
using Content.Shared.Interaction;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Robust.Server.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using static Content.Shared.Wires.SharedWiresComponent;
using static Content.Shared.Wires.SharedWiresComponent.WiresAction;
namespace Content.Server.Atmos.Monitor.Components
{
[RegisterComponent]
public sealed class FireAlarmComponent : Component, IWires
public sealed class FireAlarmComponent : Component
{
[Dependency] private readonly IEntityManager _entMan = default!;
private AtmosMonitorSystem? _atmosMonitorSystem;
private CancellationTokenSource _powerPulsedCancel = new();
private int PowerPulsedTimeout = 30;
// Much more simpler than the air alarm wire set.
private enum Wires
{
// Cutting this kills power,
// pulsing it disrupts.
Power,
// Cutting this disables network
// connectivity,
// pulsing it sets off an alarm.
Alarm,
Dummy1,
Dummy2,
}
private bool _powerCut;
private bool PowerCut
{
get => _powerCut;
set
{
_powerCut = value;
SetPower();
}
}
private bool _powerPulsed;
private bool PowerPulsed
{
get => _powerPulsed && !_powerCut;
set
{
_powerPulsed = value;
SetPower();
}
}
private void SetPower()
{
if (_entMan.TryGetComponent<ApcPowerReceiverComponent>(Owner, out var receiverComponent) && _entMan.HasComponent<WiresComponent>(Owner))
receiverComponent.PowerDisabled = PowerPulsed || PowerCut;
}
public void RegisterWires(WiresComponent.WiresBuilder builder)
{
builder.CreateWire(Wires.Power);
builder.CreateWire(Wires.Alarm);
builder.CreateWire(Wires.Dummy1);
builder.CreateWire(Wires.Dummy2);
UpdateWires();
}
public void UpdateWires()
{
if (!_entMan.TryGetComponent<WiresComponent>(Owner, out var wiresComponent)) return;
var powerLight = new StatusLightData(Color.Yellow, StatusLightState.On, "POWR");
if (PowerPulsed)
powerLight = new StatusLightData(Color.Yellow, StatusLightState.BlinkingFast, "POWR");
else if (PowerCut)
powerLight = new StatusLightData(Color.Yellow, StatusLightState.Off, "POWR");
var syncLight = new StatusLightData(Color.Orange, StatusLightState.On, "NET");
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent))
if (!atmosMonitorComponent.NetEnabled)
syncLight = new StatusLightData(Color.Orange, StatusLightState.Off, "NET");
else if (atmosMonitorComponent.HighestAlarmInNetwork == AtmosMonitorAlarmType.Danger)
syncLight = new StatusLightData(Color.Orange, StatusLightState.BlinkingFast, "NET");
wiresComponent.SetStatus(FireAlarmWireStatus.Power, powerLight);
wiresComponent.SetStatus(FireAlarmWireStatus.Alarm, syncLight);
}
public void WiresUpdate(WiresUpdateEventArgs args)
{
if (_atmosMonitorSystem == null)
_atmosMonitorSystem = EntitySystem.Get<AtmosMonitorSystem>();
switch (args.Action)
{
case Pulse:
switch (args.Identifier)
{
case Wires.Power:
PowerPulsed = true;
_powerPulsedCancel.Cancel();
_powerPulsedCancel = new CancellationTokenSource();
Owner.SpawnTimer(TimeSpan.FromSeconds(PowerPulsedTimeout),
() => PowerPulsed = false,
_powerPulsedCancel.Token);
break;
case Wires.Alarm:
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent))
_atmosMonitorSystem.Alert(Owner, AtmosMonitorAlarmType.Danger, monitor: atmosMonitorComponent);
break;
}
break;
case Mend:
switch (args.Identifier)
{
case Wires.Power:
_powerPulsedCancel.Cancel();
PowerPulsed = false;
PowerCut = false;
break;
case Wires.Alarm:
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent))
atmosMonitorComponent.NetEnabled = true;
break;
}
break;
case Cut:
switch (args.Identifier)
{
case Wires.Power:
PowerCut = true;
break;
case Wires.Alarm:
if (_entMan.TryGetComponent<AtmosMonitorComponent>(Owner, out var atmosMonitorComponent))
atmosMonitorComponent.NetEnabled = false;
break;
}
break;
}
UpdateWires();
}
}
}

View File

@@ -7,7 +7,7 @@ using Content.Server.DeviceNetwork.Components;
using Content.Server.DeviceNetwork.Systems;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.WireHacking;
using Content.Server.Wires;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Atmos;
@@ -263,7 +263,7 @@ namespace Content.Server.Atmos.Monitor.Systems
if (!EntityManager.TryGetComponent(uid, out AccessReaderComponent reader) || user == null)
return false;
if (!_accessSystem.IsAllowed(reader, user.Value) && !component.FullAccess)
if (!_accessSystem.IsAllowed(reader, user.Value))
{
_popup.PopupEntity(Loc.GetString("air-alarm-ui-access-denied"), user.Value, Filter.Entities(user.Value));
return false;
@@ -401,7 +401,7 @@ namespace Content.Server.Atmos.Monitor.Systems
// _airAlarmDataSystem.UpdateDeviceData(uid, args.SenderAddress, data);
//
_uiSystem.TrySendUiMessage(uid, SharedAirAlarmInterfaceKey.Key, new AirAlarmUpdateDeviceDataMessage(args.SenderAddress, data));
if (HasComp<WiresComponent>(uid)) controller.UpdateWires();
// if (HasComp<WiresComponent>(uid)) controller.UpdateWires();
if (!controller.DeviceData.TryAdd(args.SenderAddress, data))
controller.DeviceData[args.SenderAddress] = data;

View File

@@ -0,0 +1,75 @@
using Content.Server.Atmos.Monitor.Components;
using Content.Server.Atmos.Monitor.Systems;
using Content.Server.DeviceNetwork.Components;
using Content.Server.Wires;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Wires;
namespace Content.Server.Atmos.Monitor;
[DataDefinition]
public sealed class AirAlarmPanicWire : BaseWireAction
{
private string _text = "PANC";
private Color _color = Color.Red;
private AirAlarmSystem _airAlarmSystem = default!;
public override object StatusKey { get; } = AirAlarmWireStatus.Panic;
public override StatusLightData? GetStatusLightData(Wire wire)
{
var lightState = StatusLightState.Off;
if (IsPowered(wire.Owner) && EntityManager.TryGetComponent<AirAlarmComponent>(wire.Owner, out var alarm))
{
lightState = alarm.CurrentMode == AirAlarmMode.Panic
? StatusLightState.On
: StatusLightState.Off;
}
return new StatusLightData(
_color,
lightState,
_text);
}
public override void Initialize()
{
base.Initialize();
_airAlarmSystem = EntitySystem.Get<AirAlarmSystem>();
}
public override bool Cut(EntityUid user, Wire wire)
{
if (EntityManager.TryGetComponent<DeviceNetworkComponent>(wire.Owner, out var devNet))
{
_airAlarmSystem.SetMode(wire.Owner, devNet.Address, AirAlarmMode.Panic, true, false);
}
return true;
}
public override bool Mend(EntityUid user, Wire wire)
{
if (EntityManager.TryGetComponent<DeviceNetworkComponent>(wire.Owner, out var devNet)
&& EntityManager.TryGetComponent<AirAlarmComponent>(wire.Owner, out var alarm)
&& alarm.CurrentMode == AirAlarmMode.Panic)
{
_airAlarmSystem.SetMode(wire.Owner, devNet.Address, AirAlarmMode.Filtering, true, false, alarm);
}
return true;
}
public override bool Pulse(EntityUid user, Wire wire)
{
if (EntityManager.TryGetComponent<DeviceNetworkComponent>(wire.Owner, out var devNet))
{
_airAlarmSystem.SetMode(wire.Owner, devNet.Address, AirAlarmMode.Panic, true, false);
}
return true;
}
}

View File

@@ -0,0 +1,77 @@
using Content.Server.Atmos.Monitor.Components;
using Content.Server.Atmos.Monitor.Systems;
using Content.Server.Wires;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Wires;
namespace Content.Server.Atmos.Monitor;
[DataDefinition]
public sealed class AtmosMonitorDeviceNetWire : BaseWireAction
{
// whether or not this wire will send out an alarm upon
// being pulsed
[DataField("alarmOnPulse")]
private bool _alarmOnPulse = false;
private string _text = "NETW";
private Color _color = Color.Orange;
private AtmosMonitorSystem _atmosMonitorSystem = default!;
public override object StatusKey { get; } = AtmosMonitorAlarmWireActionKeys.Network;
public override StatusLightData? GetStatusLightData(Wire wire)
{
var lightState = StatusLightState.Off;
if (IsPowered(wire.Owner) && EntityManager.TryGetComponent<AtmosMonitorComponent>(wire.Owner, out var monitor))
{
lightState = monitor.HighestAlarmInNetwork == AtmosMonitorAlarmType.Danger
? StatusLightState.BlinkingFast
: StatusLightState.On;
}
return new StatusLightData(
_color,
lightState,
_text);
}
public override void Initialize()
{
base.Initialize();
_atmosMonitorSystem = EntitySystem.Get<AtmosMonitorSystem>();
}
public override bool Cut(EntityUid user, Wire wire)
{
if (EntityManager.TryGetComponent<AtmosMonitorComponent>(wire.Owner, out var monitor))
{
monitor.NetEnabled = false;
}
return true;
}
public override bool Mend(EntityUid user, Wire wire)
{
if (EntityManager.TryGetComponent<AtmosMonitorComponent>(wire.Owner, out var monitor))
{
monitor.NetEnabled = true;
}
return true;
}
public override bool Pulse(EntityUid user, Wire wire)
{
if (_alarmOnPulse)
{
_atmosMonitorSystem.Alert(wire.Owner, AtmosMonitorAlarmType.Danger);
}
return true;
}
}