diff --git a/Content.Client/Power/APC/ApcVisualizer.cs b/Content.Client/Power/APC/ApcVisualizer.cs index a7fee79461..55bfdc5f5f 100644 --- a/Content.Client/Power/APC/ApcVisualizer.cs +++ b/Content.Client/Power/APC/ApcVisualizer.cs @@ -1,10 +1,5 @@ using Content.Shared.APC; -using JetBrains.Annotations; using Robust.Client.GameObjects; -using Robust.Client.State; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Maths; namespace Content.Client.Power.APC { @@ -15,32 +10,6 @@ namespace Content.Client.Power.APC public static readonly Color FullColor = Color.FromHex("#3db83b"); public static readonly Color EmagColor = Color.FromHex("#1f48d6"); - [UsedImplicitly] - [Obsolete("Subscribe to your component being initialised instead.")] - public override void InitializeEntity(EntityUid entity) - { - base.InitializeEntity(entity); - - var sprite = IoCManager.Resolve().GetComponent(entity); - - sprite.LayerMapSet(Layers.Panel, sprite.AddLayerState("apc0")); - - sprite.LayerMapSet(Layers.ChargeState, sprite.AddLayerState("apco3-0")); - sprite.LayerSetShader(Layers.ChargeState, "unshaded"); - - sprite.LayerMapSet(Layers.Lock, sprite.AddLayerState("apcox-0")); - sprite.LayerSetShader(Layers.Lock, "unshaded"); - - sprite.LayerMapSet(Layers.Equipment, sprite.AddLayerState("apco0-3")); - sprite.LayerSetShader(Layers.Equipment, "unshaded"); - - sprite.LayerMapSet(Layers.Lighting, sprite.AddLayerState("apco1-3")); - sprite.LayerSetShader(Layers.Lighting, "unshaded"); - - sprite.LayerMapSet(Layers.Environment, sprite.AddLayerState("apco2-3")); - sprite.LayerSetShader(Layers.Environment, "unshaded"); - } - [Obsolete("Subscribe to AppearanceChangeEvent instead.")] public override void OnChangeData(AppearanceComponent component) { @@ -48,36 +17,8 @@ namespace Content.Client.Power.APC var ent = IoCManager.Resolve(); var sprite = ent.GetComponent(component.Owner); - if (component.TryGetData(ApcVisuals.PanelState, out var panelState)) - { - switch (panelState) - { - case ApcPanelState.Closed: - sprite.LayerSetState(Layers.Panel, "apc0"); - break; - case ApcPanelState.Open: - sprite.LayerSetState(Layers.Panel, "apcframe"); - break; - } - } if (component.TryGetData(ApcVisuals.ChargeState, out var chargeState)) { - switch (chargeState) - { - case ApcChargeState.Lack: - sprite.LayerSetState(Layers.ChargeState, "apco3-0"); - break; - case ApcChargeState.Charging: - sprite.LayerSetState(Layers.ChargeState, "apco3-1"); - break; - case ApcChargeState.Full: - sprite.LayerSetState(Layers.ChargeState, "apco3-2"); - break; - case ApcChargeState.Emag: - sprite.LayerSetState(Layers.ChargeState, "emag-unlit"); - break; - } - if (ent.TryGetComponent(component.Owner, out SharedPointLightComponent? light)) { light.Color = chargeState switch @@ -90,20 +31,15 @@ namespace Content.Client.Power.APC }; } } - else - { - sprite.LayerSetState(Layers.ChargeState, "apco3-0"); - } } - enum Layers : byte + enum ApcVisualLayers : byte { ChargeState, Lock, Equipment, Lighting, Environment, - Panel, } } } diff --git a/Content.IntegrationTests/Tests/Construction/Interaction/PanelScrewing.cs b/Content.IntegrationTests/Tests/Construction/Interaction/PanelScrewing.cs index a0b6611072..f6ca9ec72e 100644 --- a/Content.IntegrationTests/Tests/Construction/Interaction/PanelScrewing.cs +++ b/Content.IntegrationTests/Tests/Construction/Interaction/PanelScrewing.cs @@ -1,41 +1,12 @@ using System.Threading.Tasks; using Content.IntegrationTests.Tests.Interaction; -using Content.Server.Power.Components; using Content.Shared.Wires; using NUnit.Framework; -using Robust.Shared.GameObjects; namespace Content.IntegrationTests.Tests.Construction.Interaction; public sealed class PanelScrewing : InteractionTest { - [Test] - public async Task ApcPanel() - { - await SpawnTarget("APCBasic"); - var comp = Comp(); - - // Open & close panel - Assert.That(comp.IsApcOpen, Is.False); - - await Interact(Screw); - Assert.That(comp.IsApcOpen, Is.True); - await Interact(Screw); - Assert.That(comp.IsApcOpen, Is.False); - - // Interrupted DoAfters - await Interact(Screw, awaitDoAfters: false); - await CancelDoAfters(); - Assert.That(comp.IsApcOpen, Is.False); - await Interact(Screw); - Assert.That(comp.IsApcOpen, Is.True); - await Interact(Screw, awaitDoAfters: false); - await CancelDoAfters(); - Assert.That(comp.IsApcOpen, Is.True); - await Interact(Screw); - Assert.That(comp.IsApcOpen, Is.False); - } - // Test wires panel on both airlocks & tcomms servers. These both use the same component, but comms may have // conflicting interactions due to encryption key removal interactions. [Test] diff --git a/Content.Server/Construction/Conditions/ApcPanel.cs b/Content.Server/Construction/Conditions/ApcPanel.cs deleted file mode 100644 index 35d73aaba8..0000000000 --- a/Content.Server/Construction/Conditions/ApcPanel.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Content.Server.Power.Components; -using Content.Shared.Construction; -using Content.Shared.Examine; -using JetBrains.Annotations; - -namespace Content.Server.Construction.Conditions -{ - [UsedImplicitly] - [DataDefinition] - public sealed class ApcPanel : IGraphCondition - { - [DataField("open")] public bool Open { get; private set; } = true; - - public bool Condition(EntityUid uid, IEntityManager entityManager) - { - if (!entityManager.TryGetComponent(uid, out ApcComponent? apc)) - return true; - - return apc.IsApcOpen == Open; - } - - public bool DoExamine(ExaminedEvent args) - { - var entity = args.Examined; - - if (!IoCManager.Resolve().TryGetComponent(entity, out ApcComponent? apc)) return false; - - switch (Open) - { - case true when !apc.IsApcOpen: - args.PushMarkup(Loc.GetString("construction-examine-condition-apc-open")); - return true; - case false when apc.IsApcOpen: - args.PushMarkup(Loc.GetString("construction-examine-condition-apc-close")); - return true; - } - - return false; - } - - public IEnumerable GenerateGuideEntry() - { - yield return new ConstructionGuideEntry() - { - Localization = Open - ? "construction-step-condition-apc-open" - : "construction-step-condition-apc-close" - }; - } - } -} diff --git a/Content.Server/Power/Components/ApcComponent.cs b/Content.Server/Power/Components/ApcComponent.cs index 1109f5a22e..e6e6dc5845 100644 --- a/Content.Server/Power/Components/ApcComponent.cs +++ b/Content.Server/Power/Components/ApcComponent.cs @@ -14,12 +14,6 @@ public sealed class ApcComponent : BaseApcNetComponent public ApcChargeState LastChargeState; public TimeSpan LastChargeStateTime; - /// - /// Is the panel open for this entity's APC? - /// - [DataField("open")] - public bool IsApcOpen { get; set; } - [ViewVariables] public ApcExternalPowerState LastExternalState; public TimeSpan LastUiUpdate; @@ -41,11 +35,4 @@ public sealed class ApcComponent : BaseApcNetComponent { apcNet.RemoveApc(this); } - - [DataField("screwdriverOpenSound")] - public SoundSpecifier ScrewdriverOpenSound = new SoundPathSpecifier("/Audio/Machines/screwdriveropen.ogg"); - - [DataField("screwdriverCloseSound")] - public SoundSpecifier ScrewdriverCloseSound = new SoundPathSpecifier("/Audio/Machines/screwdriverclose.ogg"); - } diff --git a/Content.Server/Power/EntitySystems/ApcSystem.cs b/Content.Server/Power/EntitySystems/ApcSystem.cs index 97ee17db6a..c1d864e845 100644 --- a/Content.Server/Power/EntitySystems/ApcSystem.cs +++ b/Content.Server/Power/EntitySystems/ApcSystem.cs @@ -5,19 +5,12 @@ using Content.Server.Power.Pow3r; using Content.Shared.Access.Components; using Content.Shared.Access.Systems; using Content.Shared.APC; -using Content.Shared.DoAfter; using Content.Shared.Emag.Components; using Content.Shared.Emag.Systems; -using Content.Shared.Examine; -using Content.Shared.Interaction; using Content.Shared.Popups; -using Content.Shared.Power; -using Content.Shared.Tools; -using Content.Shared.Tools.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Audio; -using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Server.Power.EntitySystems @@ -26,15 +19,12 @@ namespace Content.Server.Power.EntitySystems internal sealed class ApcSystem : EntitySystem { [Dependency] private readonly AccessReaderSystem _accessReader = default!; - [Dependency] private readonly UserInterfaceSystem _userInterfaceSystem = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly SharedToolSystem _toolSystem = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedAudioSystem _audio = default!; - private const float ScrewTime = 2f; - public override void Initialize() { base.Initialize(); @@ -47,10 +37,6 @@ namespace Content.Server.Power.EntitySystems SubscribeLocalEvent(OnToggleMainBreaker); SubscribeLocalEvent(OnEmagged); - SubscribeLocalEvent(OnToolFinished); - SubscribeLocalEvent(OnInteractUsing); - SubscribeLocalEvent(OnExamine); - SubscribeLocalEvent(OnEmpPulse); } @@ -93,7 +79,7 @@ namespace Content.Server.Power.EntitySystems } else { - _popupSystem.PopupCursor(Loc.GetString("apc-component-insufficient-access"), + _popup.PopupCursor(Loc.GetString("apc-component-insufficient-access"), args.Session, PopupType.Medium); } } @@ -107,7 +93,7 @@ namespace Content.Server.Power.EntitySystems battery.CanDischarge = apc.MainBreakerEnabled; UpdateUIState(uid, apc); - SoundSystem.Play(apc.OnReceiveMessageSound.GetSound(), Filter.Pvs(uid), uid, AudioParams.Default.WithVolume(-2f)); + _audio.PlayPvs(apc.OnReceiveMessageSound, uid, AudioParams.Default.WithVolume(-2f)); } private void OnEmagged(EntityUid uid, ApcComponent comp, ref GotEmaggedEvent args) @@ -123,18 +109,13 @@ namespace Content.Server.Power.EntitySystems if (!Resolve(uid, ref apc, ref battery)) return; - if (TryComp(uid, out AppearanceComponent? appearance)) - { - UpdatePanelAppearance(uid, appearance, apc); - } - var newState = CalcChargeState(uid, battery.NetworkBattery); if (newState != apc.LastChargeState && apc.LastChargeStateTime + ApcComponent.VisualsChangeDelay < _gameTiming.CurTime) { apc.LastChargeState = newState; apc.LastChargeStateTime = _gameTiming.CurTime; - if (appearance != null) + if (TryComp(uid, out AppearanceComponent? appearance)) { _appearance.SetData(uid, ApcVisuals.ChargeState, newState, appearance); } @@ -164,7 +145,7 @@ namespace Content.Server.Power.EntitySystems (int) MathF.Ceiling(battery.CurrentSupply), apc.LastExternalState, battery.AvailableSupply / battery.Capacity); - _userInterfaceSystem.TrySetUiState(uid, ApcUiKey.Key, state, ui: ui); + _ui.TrySetUiState(uid, ApcUiKey.Key, state, ui: ui); } private ApcChargeState CalcChargeState(EntityUid uid, PowerState.Battery battery) @@ -197,51 +178,6 @@ namespace Content.Server.Power.EntitySystems return ApcExternalPowerState.Good; } - public static ApcPanelState GetPanelState(ApcComponent apc) - { - if (apc.IsApcOpen) - return ApcPanelState.Open; - else - return ApcPanelState.Closed; - } - - private void OnInteractUsing(EntityUid uid, ApcComponent component, InteractUsingEvent args) - { - if (!EntityManager.TryGetComponent(args.Used, out ToolComponent? tool)) - return; - - if (_toolSystem.UseTool(args.Used, args.User, uid, ScrewTime, "Screwing", new ApcToolFinishedEvent(), toolComponent:tool)) - args.Handled = true; - } - - private void OnToolFinished(EntityUid uid, ApcComponent component, ApcToolFinishedEvent args) - { - if (args.Cancelled) - return; - - component.IsApcOpen = !component.IsApcOpen; - UpdatePanelAppearance(uid, apc: component); - - // this will play on top of the normal screw driver tool sound. - var sound = component.IsApcOpen ? component.ScrewdriverOpenSound : component.ScrewdriverCloseSound; - _audio.PlayPvs(sound, uid); - } - - private void UpdatePanelAppearance(EntityUid uid, AppearanceComponent? appearance = null, ApcComponent? apc = null) - { - if (!Resolve(uid, ref appearance, ref apc, false)) - return; - - _appearance.SetData(uid, ApcVisuals.PanelState, GetPanelState(apc), appearance); - } - - private void OnExamine(EntityUid uid, ApcComponent component, ExaminedEvent args) - { - args.PushMarkup(Loc.GetString(component.IsApcOpen - ? "apc-component-on-examine-panel-open" - : "apc-component-on-examine-panel-closed")); - } - private void OnEmpPulse(EntityUid uid, ApcComponent component, ref EmpPulseEvent args) { if (component.MainBreakerEnabled) diff --git a/Content.Shared/APC/SharedApc.cs b/Content.Shared/APC/SharedApc.cs index cb634a107d..01f07f4eaa 100644 --- a/Content.Shared/APC/SharedApc.cs +++ b/Content.Shared/APC/SharedApc.cs @@ -9,24 +9,6 @@ namespace Content.Shared.APC /// APC lights/HUD. /// ChargeState, - - /// - /// APC frame. - /// - PanelState - } - - [Serializable, NetSerializable] - public enum ApcPanelState - { - /// - /// APC is closed. - /// - Closed, - /// - /// APC opened. - /// - Open } [Serializable, NetSerializable] diff --git a/Content.Shared/Wires/WiresPanelComponent.cs b/Content.Shared/Wires/WiresPanelComponent.cs index 878ef13044..668e7f0100 100644 --- a/Content.Shared/Wires/WiresPanelComponent.cs +++ b/Content.Shared/Wires/WiresPanelComponent.cs @@ -11,7 +11,7 @@ public sealed class WiresPanelComponent : Component /// /// Is the panel open for this entity's wires? /// - [ViewVariables] + [DataField("open")] public bool Open; /// diff --git a/Resources/Prototypes/Catalog/Research/technologies.yml b/Resources/Prototypes/Catalog/Research/technologies.yml index b10d8d2b1e..e492a847c5 100644 --- a/Resources/Prototypes/Catalog/Research/technologies.yml +++ b/Resources/Prototypes/Catalog/Research/technologies.yml @@ -359,7 +359,7 @@ description: technologies-electromagnetic-theory-description icon: sprite: Structures/Power/apc.rsi - state: apc0 + state: base requiredPoints: 10000 requiredTechnologies: - BasicResearch diff --git a/Resources/Prototypes/Entities/Structures/Power/apc.yml b/Resources/Prototypes/Entities/Structures/Power/apc.yml index 57c04860d0..719b4f6aa0 100644 --- a/Resources/Prototypes/Entities/Structures/Power/apc.yml +++ b/Resources/Prototypes/Entities/Structures/Power/apc.yml @@ -28,7 +28,25 @@ drawdepth: WallMountedItems netsync: false sprite: Structures/Power/apc.rsi - state: apc0 + layers: + - state: base + - state: powered-1 + shader: unshaded + map: ["enum.ApcVisualLayers.ChargeState"] + - state: apcox-0 + shader: unshaded + map: ["enum.ApcVisualLayers.Lock"] + - state: apco0-3 + shader: unshaded + map: ["enum.ApcVisualLayers.Equipment"] + - state: apco1-3 + shader: unshaded + map: ["enum.ApcVisualLayers.Lighting"] + - state: apco2-3 + shader: unshaded + map: ["enum.ApcVisualLayers.Environment"] + - state: panel + map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: Appearance visuals: - type: ApcVisualizer @@ -69,6 +87,18 @@ supplyRampTolerance: 1000 supplyRampRate: 500 - type: WallMount + - type: Wires + BoardName: "APC" + LayoutId: APC + - type: WiresVisuals + - type: GenericVisualizer + visuals: + enum.ApcVisuals.ChargeState: + enum.ApcVisualLayers.ChargeState: + Lack: { state: powered-1 } + Charging: { state: powered-2 } + Full: { state: powered-3 } + Emag: { state: emag-unlit } - type: Damageable damageContainer: Inorganic damageModifierSet: StrongMetallic @@ -146,8 +176,7 @@ id: APCConstructed suffix: Open components: - - type: Apc - voltage: Apc + - type: WiresPanel open: true # APCs in use diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/utilities/APC.yml b/Resources/Prototypes/Recipes/Construction/Graphs/utilities/APC.yml index 6808f62d7a..2941ba8235 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/utilities/APC.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/utilities/APC.yml @@ -36,7 +36,7 @@ prototype: APCElectronics amount: 1 conditions: - - !type:ApcPanel + - !type:WirePanel open: true steps: - tool: Prying diff --git a/Resources/Prototypes/Recipes/Construction/utilities.yml b/Resources/Prototypes/Recipes/Construction/utilities.yml index 835ad8b6bf..fccaada6d6 100644 --- a/Resources/Prototypes/Recipes/Construction/utilities.yml +++ b/Resources/Prototypes/Recipes/Construction/utilities.yml @@ -39,7 +39,7 @@ description: "Area Power Controller (APC). Controls power. In an area." icon: sprite: Structures/Power/apc.rsi - state: apc0 + state: base objectType: Structure placementMode: SnapgridCenter canBuildInImpassable: true diff --git a/Resources/Textures/Structures/Power/apc.rsi/apc0.png b/Resources/Textures/Structures/Power/apc.rsi/base.png similarity index 100% rename from Resources/Textures/Structures/Power/apc.rsi/apc0.png rename to Resources/Textures/Structures/Power/apc.rsi/base.png diff --git a/Resources/Textures/Structures/Power/apc.rsi/meta.json b/Resources/Textures/Structures/Power/apc.rsi/meta.json index 865a256e11..0cb9c31ae5 100644 --- a/Resources/Textures/Structures/Power/apc.rsi/meta.json +++ b/Resources/Textures/Structures/Power/apc.rsi/meta.json @@ -27,7 +27,7 @@ ] }, { - "name": "apc0" + "name": "base" }, { "name": "emag-unlit", @@ -78,7 +78,7 @@ "name": "apco2-3" }, { - "name": "apco3-0", + "name": "powered-1", "delays": [ [ 1, @@ -87,7 +87,7 @@ ] }, { - "name": "apco3-1", + "name": "powered-2", "delays": [ [ 0.1, @@ -100,7 +100,7 @@ ] }, { - "name": "apco3-2", + "name": "powered-3", "delays": [ [ 1, diff --git a/Resources/Textures/Structures/Power/apc.rsi/apco3-0.png b/Resources/Textures/Structures/Power/apc.rsi/powered-1.png similarity index 100% rename from Resources/Textures/Structures/Power/apc.rsi/apco3-0.png rename to Resources/Textures/Structures/Power/apc.rsi/powered-1.png diff --git a/Resources/Textures/Structures/Power/apc.rsi/apco3-1.png b/Resources/Textures/Structures/Power/apc.rsi/powered-2.png similarity index 100% rename from Resources/Textures/Structures/Power/apc.rsi/apco3-1.png rename to Resources/Textures/Structures/Power/apc.rsi/powered-2.png diff --git a/Resources/Textures/Structures/Power/apc.rsi/apco3-2.png b/Resources/Textures/Structures/Power/apc.rsi/powered-3.png similarity index 100% rename from Resources/Textures/Structures/Power/apc.rsi/apco3-2.png rename to Resources/Textures/Structures/Power/apc.rsi/powered-3.png