Telecom server panel check (#14523)

This commit is contained in:
Slava0135
2023-03-24 03:09:45 +03:00
committed by GitHub
parent 8c7e917038
commit d03ca61da1
17 changed files with 226 additions and 138 deletions

View File

@@ -0,0 +1,7 @@
using Content.Shared.Wires;
namespace Content.Client.Wires;
public sealed class WiresSystem : SharedWiresSystem
{
}

View File

@@ -9,11 +9,12 @@ using Robust.Shared.Prototypes;
using Content.Server.Storage.Components;
using Content.Server.VendingMachines;
using Content.Server.VendingMachines.Restock;
using Content.Server.Wires;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.VendingMachines;
using Content.Shared.Wires;
using Content.Server.Wires;
namespace Content.IntegrationTests.Tests
{
@@ -188,7 +189,7 @@ namespace Content.IntegrationTests.Tests
VendingMachineComponent machineComponent;
VendingMachineRestockComponent restockRightComponent;
VendingMachineRestockComponent restockWrongComponent;
WiresComponent machineWires;
WiresPanelComponent machineWiresPanel;
var testMap = await PoolManager.CreateTestMap(pairTracker);
@@ -206,7 +207,7 @@ namespace Content.IntegrationTests.Tests
Assert.True(entityManager.TryGetComponent(machine, out machineComponent!), $"Machine has no {nameof(VendingMachineComponent)}");
Assert.True(entityManager.TryGetComponent(packageRight, out restockRightComponent!), $"Correct package has no {nameof(VendingMachineRestockComponent)}");
Assert.True(entityManager.TryGetComponent(packageWrong, out restockWrongComponent!), $"Wrong package has no {nameof(VendingMachineRestockComponent)}");
Assert.True(entityManager.TryGetComponent(machine, out machineWires!), $"Machine has no {nameof(WiresComponent)}");
Assert.True(entityManager.TryGetComponent(machine, out machineWiresPanel!), $"Machine has no {nameof(WiresPanelComponent)}");
var systemRestock = entitySystemManager.GetEntitySystem<VendingMachineRestockSystem>();
var systemMachine = entitySystemManager.GetEntitySystem<VendingMachineSystem>();
@@ -215,8 +216,9 @@ namespace Content.IntegrationTests.Tests
Assert.That(systemRestock.TryAccessMachine(packageRight, restockRightComponent, machineComponent, user, machine), Is.False, "Right package is able to restock without opened access panel");
Assert.That(systemRestock.TryAccessMachine(packageWrong, restockWrongComponent, machineComponent, user, machine), Is.False, "Wrong package is able to restock without opened access panel");
var systemWires = entitySystemManager.GetEntitySystem<WiresSystem>();
// Open the panel.
machineWires.IsPanelOpen = true;
systemWires.TogglePanel(machine, machineWiresPanel, true);
// Test that the right package works for the right machine.
Assert.That(systemRestock.TryAccessMachine(packageRight, restockRightComponent, machineComponent, user, machine), Is.True, "Correct package is unable to restock with access panel opened");

View File

@@ -7,7 +7,6 @@ using Content.Server.DeviceNetwork.Systems;
using Content.Server.Popups;
using Content.Server.Power.Components;
using Content.Server.Power.EntitySystems;
using Content.Server.Wires;
using Content.Shared.Access.Components;
using Content.Shared.Access.Systems;
using Content.Shared.Atmos;
@@ -16,8 +15,8 @@ using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Content.Shared.DeviceNetwork;
using Content.Shared.Interaction;
using Content.Shared.Wires;
using Robust.Server.GameObjects;
using Robust.Shared.Player;
namespace Content.Server.Atmos.Monitor.Systems;
@@ -227,10 +226,10 @@ public sealed class AirAlarmSystem : EntitySystem
if (!_interactionSystem.InRangeUnobstructed(args.User, args.Target))
return;
if (!EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
if (!TryComp<ActorComponent>(args.User, out var actor))
return;
if (EntityManager.TryGetComponent(uid, out WiresComponent? wire) && wire.IsPanelOpen)
if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open)
{
args.Handled = false;
return;
@@ -239,7 +238,9 @@ public sealed class AirAlarmSystem : EntitySystem
if (!this.IsPowered(uid, EntityManager))
return;
_uiSystem.GetUiOrNull(component.Owner, SharedAirAlarmInterfaceKey.Key)?.Open(actor.PlayerSession);
var ui = _uiSystem.GetUiOrNull(uid, SharedAirAlarmInterfaceKey.Key);
if (ui != null)
_uiSystem.OpenUi(ui, actor.PlayerSession);
component.ActivePlayers.Add(actor.PlayerSession.UserId);
AddActiveInterface(uid);
SyncAllDevices(uid);

View File

@@ -1,6 +1,6 @@
using Content.Server.Wires;
using Content.Shared.Construction;
using Content.Shared.Examine;
using Content.Shared.Wires;
using JetBrains.Annotations;
namespace Content.Server.Construction.Conditions
@@ -14,24 +14,23 @@ namespace Content.Server.Construction.Conditions
public bool Condition(EntityUid uid, IEntityManager entityManager)
{
//if it doesn't have a wire panel, then just let it work.
if (!entityManager.TryGetComponent(uid, out WiresComponent? wires))
if (!entityManager.TryGetComponent<WiresPanelComponent>(uid, out var wires))
return true;
return wires.IsPanelOpen == Open;
return wires.Open == Open;
}
public bool DoExamine(ExaminedEvent args)
{
var entity = args.Examined;
if (!IoCManager.Resolve<IEntityManager>().TryGetComponent(entity, out WiresComponent? wires)) return false;
if (!IoCManager.Resolve<IEntityManager>().TryGetComponent<WiresPanelComponent>(entity, out var panel)) return false;
switch (Open)
{
case true when !wires.IsPanelOpen:
case true when !panel.Open:
args.PushMarkup(Loc.GetString("construction-examine-condition-wire-panel-open"));
return true;
case false when wires.IsPanelOpen:
case false when panel.Open:
args.PushMarkup(Loc.GetString("construction-examine-condition-wire-panel-close"));
return true;
}

View File

@@ -3,13 +3,13 @@ using Content.Server.Construction.Components;
using Content.Server.DoAfter;
using Content.Server.Storage.Components;
using Content.Server.Storage.EntitySystems;
using Content.Server.Wires;
using Content.Shared.DoAfter;
using Content.Shared.Construction.Components;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Robust.Shared.Containers;
using Robust.Shared.Utility;
using Content.Shared.Wires;
namespace Content.Server.Construction;
@@ -103,7 +103,7 @@ public sealed class PartExchangerSystem : EntitySystem
if (!HasComp<MachineComponent>(args.Target))
return;
if (TryComp<WiresComponent>(args.Target, out var wires) && !wires.IsPanelOpen)
if (TryComp<WiresPanelComponent>(args.Target, out var panel) && !panel.Open)
{
_popup.PopupEntity(Loc.GetString("construction-step-condition-wire-panel-open"),
args.Target.Value);

View File

@@ -7,6 +7,7 @@ using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Interaction;
using Robust.Server.GameObjects;
using Content.Shared.Wires;
namespace Content.Server.Doors.Systems
{
@@ -71,11 +72,9 @@ namespace Content.Server.Doors.Systems
// means that sometimes the panels & bolt lights may be visible despite a door being completely open.
// Only show the maintenance panel if the airlock is closed
if (TryComp<WiresComponent>(uid, out var wiresComponent))
if (TryComp<WiresPanelComponent>(uid, out var wiresPanel))
{
wiresComponent.IsPanelVisible =
component.OpenPanelVisible
|| args.State != DoorState.Open;
_wiresSystem.ChangePanelVisibility(uid, wiresPanel, component.OpenPanelVisible || args.State != DoorState.Open);
}
// If the door is closed, we should look if the bolt was locked while closing
UpdateBoltLightStatus(uid, component);
@@ -144,8 +143,8 @@ namespace Content.Server.Doors.Systems
private void OnActivate(EntityUid uid, AirlockComponent component, ActivateInWorldEvent args)
{
if (TryComp<WiresComponent>(uid, out var wiresComponent) && wiresComponent.IsPanelOpen &&
EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open &&
TryComp<ActorComponent>(args.User, out var actor))
{
_wiresSystem.OpenUserInterface(uid, actor.PlayerSession);
args.Handled = true;

View File

@@ -3,7 +3,6 @@ using Content.Server.Atmos.EntitySystems;
using Content.Server.DoAfter;
using Content.Server.Mech.Components;
using Content.Server.Power.Components;
using Content.Server.Wires;
using Content.Shared.ActionBlocker;
using Content.Shared.Damage;
using Content.Shared.DoAfter;
@@ -15,6 +14,7 @@ using Content.Shared.Mech.EntitySystems;
using Content.Shared.Movement.Events;
using Content.Shared.Tools.Components;
using Content.Shared.Verbs;
using Content.Shared.Wires;
using Robust.Server.Containers;
using Robust.Server.GameObjects;
using Robust.Shared.Map;
@@ -72,7 +72,7 @@ public sealed class MechSystem : SharedMechSystem
}
private void OnInteractUsing(EntityUid uid, MechComponent component, InteractUsingEvent args)
{
if (TryComp<WiresComponent>(uid, out var wires) && !wires.IsPanelOpen)
if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
return;
if (component.BatterySlot.ContainedEntity == null && TryComp<BatteryComponent>(args.Used, out var battery))

View File

@@ -1,37 +1,38 @@
using Content.Shared.Popups;
using Content.Server.Power.Components;
using Content.Server.UserInterface;
using Content.Server.Wires;
using JetBrains.Annotations;
using Content.Shared.Wires;
namespace Content.Server.Power.EntitySystems
namespace Content.Server.Power.EntitySystems;
[UsedImplicitly]
internal sealed class ActivatableUIRequiresPowerSystem : EntitySystem
{
[UsedImplicitly]
internal sealed class ActivatableUIRequiresPowerSystem : EntitySystem
[Dependency] private readonly ActivatableUISystem _activatableUI = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
public override void Initialize()
{
[Dependency] private readonly ActivatableUISystem _activatableUISystem = default!;
public override void Initialize()
{
base.Initialize();
base.Initialize();
SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, ActivatableUIOpenAttemptEvent>(OnActivate);
SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, PowerChangedEvent>(OnPowerChanged);
}
SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, ActivatableUIOpenAttemptEvent>(OnActivate);
SubscribeLocalEvent<ActivatableUIRequiresPowerComponent, PowerChangedEvent>(OnPowerChanged);
}
private void OnActivate(EntityUid uid, ActivatableUIRequiresPowerComponent component, ActivatableUIOpenAttemptEvent args)
{
if (args.Cancelled) return;
if (this.IsPowered(uid, EntityManager)) return;
if (TryComp<WiresComponent>(uid, out var wires) && wires.IsPanelOpen)
return;
args.User.PopupMessageCursor(Loc.GetString("base-computer-ui-component-not-powered", ("machine", uid)));
args.Cancel();
}
private void OnActivate(EntityUid uid, ActivatableUIRequiresPowerComponent component, ActivatableUIOpenAttemptEvent args)
{
if (args.Cancelled) return;
if (this.IsPowered(uid, EntityManager)) return;
if (TryComp<WiresPanelComponent>(uid, out var panel) && panel.Open)
return;
_popup.PopupCursor(Loc.GetString("base-computer-ui-component-not-powered", ("machine", uid)), args.User);
args.Cancel();
}
private void OnPowerChanged(EntityUid uid, ActivatableUIRequiresPowerComponent component, ref PowerChangedEvent args)
{
if (!args.Powered)
_activatableUISystem.CloseAll(uid);
}
private void OnPowerChanged(EntityUid uid, ActivatableUIRequiresPowerComponent component, ref PowerChangedEvent args)
{
if (!args.Powered)
_activatableUI.CloseAll(uid);
}
}

View File

@@ -1,11 +1,11 @@
using System.Linq;
using Content.Server.Cargo.Systems;
using Content.Server.DoAfter;
using Content.Server.Wires;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Content.Shared.VendingMachines;
using Content.Shared.Wires;
using Robust.Server.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.Prototypes;
@@ -35,7 +35,7 @@ namespace Content.Server.VendingMachines.Restock
EntityUid user,
EntityUid target)
{
if (!TryComp<WiresComponent>(target, out var wires) || !wires.IsPanelOpen)
if (!TryComp<WiresPanelComponent>(target, out var panel) || !panel.Open)
{
_popupSystem.PopupCursor(Loc.GetString("vending-machine-restock-needs-panel-open",
("this", uid),

View File

@@ -5,18 +5,6 @@ namespace Content.Server.Wires;
[RegisterComponent]
public sealed class WiresComponent : Component
{
/// <summary>
/// Is the panel open for this entity's wires?
/// </summary>
[ViewVariables]
public bool IsPanelOpen { get; set; }
/// <summary>
/// Should this entity's wires panel be visible at all?
/// </summary>
[ViewVariables]
public bool IsPanelVisible { get; set; } = true;
/// <summary>
/// The name of this entity's internal board.
/// </summary>
@@ -62,13 +50,6 @@ public sealed class WiresComponent : Component
[DataField("alwaysRandomize")]
public bool AlwaysRandomize { get; }
/// <summary>
/// Marks if maintenance panel being open/closed by someone with a screwdriver.
/// Prevents do after spam.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public bool IsScrewing;
/// <summary>
/// Per wire status, keyed by an object.
/// </summary>
@@ -85,10 +66,4 @@ public sealed class WiresComponent : Component
[DataField("pulseSound")]
public SoundSpecifier PulseSound = new SoundPathSpecifier("/Audio/Effects/multitool_pulse.ogg");
[DataField("screwdriverOpenSound")]
public SoundSpecifier ScrewdriverOpenSound = new SoundPathSpecifier("/Audio/Machines/screwdriveropen.ogg");
[DataField("screwdriverCloseSound")]
public SoundSpecifier ScrewdriverCloseSound = new SoundPathSpecifier("/Audio/Machines/screwdriverclose.ogg");
}

View File

@@ -7,7 +7,6 @@ using Content.Server.Hands.Components;
using Content.Server.Power.Components;
using Content.Shared.DoAfter;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.GameTicking;
using Content.Shared.Interaction;
using Content.Shared.Popups;
@@ -21,17 +20,17 @@ using Robust.Shared.Random;
namespace Content.Server.Wires;
public sealed class WiresSystem : EntitySystem
public sealed class WiresSystem : SharedWiresSystem
{
[Dependency] private readonly IPrototypeManager _protoMan = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly DoAfterSystem _doAfter = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
private IRobustRandom _random = new RobustRandom();
@@ -44,6 +43,8 @@ public sealed class WiresSystem : EntitySystem
#region Initialization
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<RoundRestartCleanupEvent>(Reset);
// this is a broadcast event
@@ -52,7 +53,6 @@ public sealed class WiresSystem : EntitySystem
SubscribeLocalEvent<WiresComponent, ComponentStartup>(OnWiresStartup);
SubscribeLocalEvent<WiresComponent, WiresActionMessage>(OnWiresActionMessage);
SubscribeLocalEvent<WiresComponent, InteractUsingEvent>(OnInteractUsing);
SubscribeLocalEvent<WiresComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<WiresComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<WiresComponent, TimedWireEvent>(OnTimedWire);
SubscribeLocalEvent<WiresComponent, PowerChangedEvent>(OnWiresPowered);
@@ -244,7 +244,6 @@ public sealed class WiresSystem : EntitySystem
SetOrCreateWireLayout(uid, component);
UpdateUserInterface(uid);
UpdateAppearance(uid);
}
#endregion
@@ -456,75 +455,71 @@ public sealed class WiresSystem : EntitySystem
private void OnInteractUsing(EntityUid uid, WiresComponent component, InteractUsingEvent args)
{
if (!EntityManager.TryGetComponent(args.Used, out ToolComponent? tool))
if (!TryComp<ToolComponent>(args.Used, out var tool) || !TryComp<WiresPanelComponent>(uid, out var panel))
return;
if (component.IsPanelOpen &&
if (panel.Open &&
(_toolSystem.HasQuality(args.Used, "Cutting", tool) ||
_toolSystem.HasQuality(args.Used, "Pulsing", tool)))
{
if (EntityManager.TryGetComponent(args.User, out ActorComponent? actor))
{
_uiSystem.GetUiOrNull(uid, WiresUiKey.Key)?.Open(actor.PlayerSession);
var ui = _uiSystem.GetUiOrNull(uid, WiresUiKey.Key);
if (ui != null)
_uiSystem.OpenUi(ui, actor.PlayerSession);
args.Handled = true;
}
}
else if (!component.IsScrewing && _toolSystem.HasQuality(args.Used, "Screwing", tool))
else if (!panel.IsScrewing && _toolSystem.HasQuality(args.Used, "Screwing", tool))
{
var toolEvData = new ToolEventData(new WireToolFinishedEvent(uid, args.User), cancelledEv: new WireToolCanceledEvent(uid));
component.IsScrewing = _toolSystem.UseTool(args.Used, args.User, uid, ScrewTime, new[] { "Screwing" }, toolEvData, toolComponent: tool);
args.Handled = component.IsScrewing;
panel.IsScrewing = _toolSystem.UseTool(args.Used, args.User, uid, ScrewTime, new[] { "Screwing" }, toolEvData, toolComponent: tool);
args.Handled = panel.IsScrewing;
// Log attempt
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} is screwing {ToPrettyString(uid):target}'s {(component.IsPanelOpen ? "open" : "closed")} maintenance panel at {Transform(uid).Coordinates:targetlocation}");
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} is screwing {ToPrettyString(uid):target}'s {(panel.Open ? "open" : "closed")} maintenance panel at {Transform(uid).Coordinates:targetlocation}");
}
}
private void OnToolFinished(WireToolFinishedEvent args)
{
if (!EntityManager.TryGetComponent(args.Target, out WiresComponent? component))
if (!TryComp<WiresPanelComponent>((args.Target), out var panel))
return;
component.IsScrewing = false;
component.IsPanelOpen = !component.IsPanelOpen;
UpdateAppearance(args.Target);
panel.IsScrewing = false;
TogglePanel(args.Target, panel, !panel.Open);
// Log success
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} screwed {ToPrettyString(args.Target):target}'s maintenance panel {(component.IsPanelOpen ? "open" : "closed")}");
_adminLogger.Add(LogType.Action, LogImpact.Low, $"{ToPrettyString(args.User):user} screwed {ToPrettyString(args.Target):target}'s maintenance panel {(panel.Open ? "open" : "closed")}");
if (component.IsPanelOpen)
if (panel.Open)
{
_audio.PlayPvs(component.ScrewdriverOpenSound, args.Target);
_audio.PlayPvs(panel.ScrewdriverOpenSound, args.Target);
}
else
{
_audio.PlayPvs(component.ScrewdriverCloseSound, args.Target);
_audio.PlayPvs(panel.ScrewdriverCloseSound, args.Target);
var ui = _uiSystem.GetUiOrNull(args.Target, WiresUiKey.Key);
if (ui != null)
{
_uiSystem.CloseAll(ui);
}
}
Dirty(panel);
}
private void OnToolCanceled(WireToolCanceledEvent ev)
{
if (!TryComp(ev.Target, out WiresComponent? component))
if (!TryComp<WiresPanelComponent>(ev.Target, out var component))
return;
component.IsScrewing = false;
}
private void OnExamine(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 OnMapInit(EntityUid uid, WiresComponent component, MapInitEvent args)
{
EnsureComp<WiresPanelComponent>(uid);
if (component.SerialNumber == null)
{
GenerateSerialNumber(uid, component);
@@ -574,14 +569,6 @@ public sealed class WiresSystem : EntitySystem
UpdateUserInterface(uid);
}
private void UpdateAppearance(EntityUid uid, AppearanceComponent? appearance = null, WiresComponent? wires = null)
{
if (!Resolve(uid, ref appearance, ref wires, false))
return;
_appearance.SetData(uid, WiresVisuals.MaintenancePanelState, wires.IsPanelOpen && wires.IsPanelVisible, appearance);
}
private void UpdateUserInterface(EntityUid uid, WiresComponent? wires = null, ServerUserInterfaceComponent? ui = null)
{
if (!Resolve(uid, ref wires, ref ui, false)) // logging this means that we get a bunch of errors
@@ -655,6 +642,26 @@ public sealed class WiresSystem : EntitySystem
}
}
public void ChangePanelVisibility(EntityUid uid, WiresPanelComponent component, bool visible)
{
component.Visible = visible;
UpdateAppearance(uid, component);
Dirty(component);
}
public void TogglePanel(EntityUid uid, WiresPanelComponent component, bool open)
{
component.Open = open;
UpdateAppearance(uid, component);
Dirty(component);
}
private void UpdateAppearance(EntityUid uid, WiresPanelComponent panel)
{
if (TryComp<AppearanceComponent>(uid, out var appearance))
_appearance.SetData(uid, WiresVisuals.MaintenancePanelState, panel.Open && panel.Visible, appearance);
}
private void TryDoWireAction(EntityUid used, EntityUid user, EntityUid toolEntity, int id, WiresAction action, WiresComponent? wires = null, ToolComponent? tool = null)
{
if (!Resolve(used, ref wires)
@@ -720,7 +727,7 @@ public sealed class WiresSystem : EntitySystem
if (_toolTime > 0f)
{
var data = new WireExtraData(action, id);
var args = new DoAfterEventArgs(user, _toolTime, target:used, used:toolEntity)
var args = new DoAfterEventArgs(user, _toolTime, target: used, used: toolEntity)
{
NeedHand = true,
BreakOnStun = true,

View File

@@ -7,7 +7,9 @@ using Content.Shared.Popups;
using Content.Shared.Radio.Components;
using Content.Shared.Tools;
using Content.Shared.Tools.Components;
using Content.Shared.Wires;
using Robust.Shared.Containers;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
@@ -20,8 +22,9 @@ public sealed class EncryptionKeySystem : EntitySystem
{
[Dependency] private readonly IPrototypeManager _protoManager = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedToolSystem _tool = default!;
[Dependency] private readonly SharedPopupSystem _popup = default!;
[Dependency] private readonly SharedContainerSystem _container = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
@@ -55,7 +58,7 @@ public sealed class EncryptionKeySystem : EntitySystem
}
// if tool use ever gets predicted this needs changing.
_popupSystem.PopupEntity(Loc.GetString("encryption-keys-all-extracted"), uid, args.User);
_popup.PopupEntity(Loc.GetString("encryption-keys-all-extracted"), uid, args.User);
_audio.PlayPvs(component.KeyExtractionSound, uid);
component.Removing = false;
}
@@ -92,8 +95,8 @@ public sealed class EncryptionKeySystem : EntitySystem
return;
if (!component.KeysUnlocked)
{
if (_timing.IsFirstTimePredicted)
_popupSystem.PopupEntity(Loc.GetString("encryption-keys-are-locked"), uid, args.User);
if (_net.IsClient && _timing.IsFirstTimePredicted)
_popup.PopupEntity(Loc.GetString("encryption-keys-are-locked"), uid, args.User);
return;
}
if (TryComp<EncryptionKeyComponent>(args.Used, out var key))
@@ -108,20 +111,26 @@ public sealed class EncryptionKeySystem : EntitySystem
private void TryInsertKey(EntityUid uid, EncryptionKeyHolderComponent component, InteractUsingEvent args)
{
args.Handled = true;
if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
{
if (_net.IsClient && _timing.IsFirstTimePredicted)
_popup.PopupEntity(Loc.GetString("encryption-keys-panel-locked"), uid, args.User);
return;
}
if (component.KeySlots <= component.KeyContainer.ContainedEntities.Count)
{
if (_timing.IsFirstTimePredicted)
_popupSystem.PopupEntity(Loc.GetString("encryption-key-slots-already-full"), uid, args.User);
if (_net.IsClient && _timing.IsFirstTimePredicted)
_popup.PopupEntity(Loc.GetString("encryption-key-slots-already-full"), uid, args.User);
return;
}
if (component.KeyContainer.Insert(args.Used))
{
if (_timing.IsFirstTimePredicted)
_popupSystem.PopupEntity(Loc.GetString("encryption-key-successfully-installed"), uid, args.User);
if (_net.IsClient&& _timing.IsFirstTimePredicted)
_popup.PopupEntity(Loc.GetString("encryption-key-successfully-installed"), uid, args.User);
_audio.PlayPredicted(component.KeyInsertionSound, args.Target, args.User);
args.Handled = true;
return;
}
}
@@ -131,21 +140,28 @@ public sealed class EncryptionKeySystem : EntitySystem
if (!TryComp<ToolComponent>(args.Used, out var tool) || !tool.Qualities.Contains(component.KeysExtractionMethod))
return;
args.Handled = true;
if (component.KeyContainer.ContainedEntities.Count == 0)
if (TryComp<WiresPanelComponent>(uid, out var panel) && !panel.Open)
{
if (_timing.IsFirstTimePredicted)
_popupSystem.PopupEntity(Loc.GetString("encryption-keys-no-keys"), uid, args.User);
if (_net.IsClient && _timing.IsFirstTimePredicted)
_popup.PopupEntity(Loc.GetString("encryption-keys-panel-locked"), uid, args.User);
return;
}
//This is honestly the poor mans fix because the InteractUsingEvent fires off 12 times
component.Removing = true;
if (component.KeyContainer.ContainedEntities.Count == 0)
{
if (_net.IsClient && _timing.IsFirstTimePredicted)
_popup.PopupEntity(Loc.GetString("encryption-keys-no-keys"), uid, args.User);
return;
}
var toolEvData = new ToolEventData(new EncryptionRemovalFinishedEvent(args.User), cancelledEv: new EncryptionRemovalCancelledEvent(), targetEntity: uid);
_toolSystem.UseTool(args.Used, args.User, uid, 1f, new[] { component.KeysExtractionMethod }, toolEvData, toolComponent: tool);
if (_net.IsServer)
{
//This is honestly the poor mans fix because the InteractUsingEvent fires off 12 times
component.Removing = true;
var toolEvData = new ToolEventData(new EncryptionRemovalFinishedEvent(args.User), cancelledEv: new EncryptionRemovalCancelledEvent(), targetEntity: uid);
if (_tool.UseTool(args.Used, args.User, uid, 1f, new[] { component.KeysExtractionMethod }, toolEvData, toolComponent: tool))
args.Handled = true;
}
}
private void OnStartup(EntityUid uid, EncryptionKeyHolderComponent component, ComponentStartup args)

View File

@@ -0,0 +1,39 @@
using Content.Shared.Examine;
using Robust.Shared.GameStates;
namespace Content.Shared.Wires;
public abstract class SharedWiresSystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<WiresPanelComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<WiresPanelComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<WiresPanelComponent, ComponentHandleState>(OnHandleState);
}
private void OnExamine(EntityUid uid, WiresPanelComponent component, ExaminedEvent args)
{
args.PushMarkup(Loc.GetString(component.Open
? "wires-panel-component-on-examine-open"
: "wires-panel-component-on-examine-closed"));
}
private void OnGetState(EntityUid uid, WiresPanelComponent component, ref ComponentGetState args)
{
args.State = new WiresPanelComponentState
{
Open = component.Open,
Visible = component.Visible
};
}
private void OnHandleState(EntityUid uid, WiresPanelComponent component, ref ComponentHandleState args)
{
if (args.Current is not WiresPanelComponentState state)
return;
component.Open = state.Open;
component.Visible = state.Visible;
}
}

View File

@@ -0,0 +1,41 @@
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Wires;
[NetworkedComponent, RegisterComponent]
[Access(typeof(SharedWiresSystem))]
public sealed class WiresPanelComponent : Component
{
/// <summary>
/// Is the panel open for this entity's wires?
/// </summary>
[ViewVariables]
public bool Open;
/// <summary>
/// Should this entity's wires panel be visible at all?
/// </summary>
[ViewVariables]
public bool Visible = true;
/// <summary>
/// Marks if maintenance panel being open/closed by someone with a screwdriver.
/// Prevents do after spam.
/// </summary>
public bool IsScrewing;
[DataField("screwdriverOpenSound")]
public SoundSpecifier ScrewdriverOpenSound = new SoundPathSpecifier("/Audio/Machines/screwdriveropen.ogg");
[DataField("screwdriverCloseSound")]
public SoundSpecifier ScrewdriverCloseSound = new SoundPathSpecifier("/Audio/Machines/screwdriverclose.ogg");
}
[Serializable, NetSerializable]
public sealed class WiresPanelComponentState : ComponentState
{
public bool Open;
public bool Visible;
}

View File

@@ -3,6 +3,7 @@ encryption-key-slots-already-full = There is no place for another encryption key
encryption-keys-all-extracted = You pop out the encryption keys!
encryption-keys-no-keys = This device has no encryption keys!
encryption-keys-are-locked = Encryption key slots are locked!
encryption-keys-panel-locked = Open maintenance panel first!
examine-encryption-channels-prefix = Available frequencies:
examine-encryption-channel = [color={$color}]{$key} for {$id} ({$freq})[/color]

View File

@@ -5,8 +5,6 @@ wires-component-ui-on-receive-message-need-multitool = You need to hold a multit
wires-component-ui-on-receive-message-cannot-pulse-cut-wire = You can't pulse a wire that's been cut!
wires-component-ui-on-receive-message-cannot-cut-cut-wire = You can't cut a wire that's been cut!
wires-component-ui-on-receive-message-cannot-mend-uncut-wire = You can't mend a wire that's been mended!
wires-component-on-examine-panel-open = The [color=lightgray]maintenance panel[/color] is [color=red]open[/color].
wires-component-on-examine-panel-closed = The [color=lightgray]maintenance panel[/color] is [color=darkgreen]closed[/color].
## UI

View File

@@ -0,0 +1,2 @@
wires-panel-component-on-examine-open = The [color=lightgray]maintenance panel[/color] is [color=red]open[/color].
wires-panel-component-on-examine-closed = The [color=lightgray]maintenance panel[/color] is [color=darkgreen]closed[/color].