diff --git a/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs b/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs index 44323d2af7..bbfbe8b464 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs @@ -2,6 +2,7 @@ using Content.Client.SubFloor; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; using Content.Shared.Atmos.Piping; +using Content.Shared.SubFloor; using JetBrains.Annotations; using Robust.Client.GameObjects; using Robust.Client.ResourceManagement; @@ -48,6 +49,16 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem if (!TryComp(uid, out SpriteComponent? sprite)) return; + if (args.Component.TryGetData(SubFloorVisuals.Covered, out bool isUnderCover) + && isUnderCover + && args.Component.TryGetData(SubFloorVisuals.ScannerRevealed, out bool revealed) + && !revealed) + { + // This entity is below a floor and is not even visible to the user -> don't bother updating sprite data. + // Note that if the subfloor visuals change, then another AppearanceChangeEvent will get triggered. + return; + } + if (!args.Component.TryGetData(PipeColorVisuals.Color, out Color color)) color = Color.White; diff --git a/Content.Client/Bed/StasisBedSystem.cs b/Content.Client/Bed/StasisBedSystem.cs index cde80c1686..94e20699d2 100644 --- a/Content.Client/Bed/StasisBedSystem.cs +++ b/Content.Client/Bed/StasisBedSystem.cs @@ -7,10 +7,10 @@ namespace Content.Client.Bed { protected override void OnAppearanceChange(EntityUid uid, StasisBedVisualsComponent component, ref AppearanceChangeEvent args) { - if (TryComp(uid, out SpriteComponent? sprite) + if (args.Sprite != null && args.Component.TryGetData(StasisBedVisuals.IsOn, out bool isOn)) { - sprite.LayerSetVisible(StasisBedVisualLayers.IsOn, isOn); + args.Sprite.LayerSetVisible(StasisBedVisualLayers.IsOn, isOn); } } } diff --git a/Content.Client/Botany/PotencyVisualsSystem.cs b/Content.Client/Botany/PotencyVisualsSystem.cs index 187a2d3005..f107a4b690 100644 --- a/Content.Client/Botany/PotencyVisualsSystem.cs +++ b/Content.Client/Botany/PotencyVisualsSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Botany; +using Content.Shared.Botany; using Robust.Client.GameObjects; namespace Content.Client.Botany; @@ -7,15 +7,13 @@ public sealed class PotencyVisualsSystem : VisualizerSystem(uid, out var sprite)) + if (args.Sprite == null) return; if (args.Component.TryGetData(ProduceVisuals.Potency, out float potency)) { var scale = MathHelper.Lerp(component.MinimumScale, component.MaximumScale, potency / 100); - sprite.Scale = new Vector2(scale, scale); + args.Sprite.Scale = new Vector2(scale, scale); } } } diff --git a/Content.Client/Cabinet/ItemCabinetSystem.cs b/Content.Client/Cabinet/ItemCabinetSystem.cs index bc9b29ae35..f81d368182 100644 --- a/Content.Client/Cabinet/ItemCabinetSystem.cs +++ b/Content.Client/Cabinet/ItemCabinetSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Cabinet; +using Content.Shared.Cabinet; using Robust.Client.GameObjects; namespace Content.Client.Cabinet; @@ -7,13 +7,15 @@ public sealed class ItemCabinetSystem : VisualizerSystem(component.Owner, out var sprite)) return; + if (!Resolve(component.Owner, ref sprite)) + return; component.TryGetData(CargoTelepadVisuals.State, out CargoTelepadState? state); AnimationPlayerComponent? player = null; diff --git a/Content.Client/Disease/DiseaseMachineSystem.cs b/Content.Client/Disease/DiseaseMachineSystem.cs index b910a07874..e81aadfe73 100644 --- a/Content.Client/Disease/DiseaseMachineSystem.cs +++ b/Content.Client/Disease/DiseaseMachineSystem.cs @@ -11,13 +11,15 @@ namespace Content.Client.Disease { protected override void OnAppearanceChange(EntityUid uid, DiseaseMachineVisualsComponent component, ref AppearanceChangeEvent args) { - if (TryComp(uid, out SpriteComponent? sprite) - && args.Component.TryGetData(DiseaseMachineVisuals.IsOn, out bool isOn) + if (args.Sprite == null) + return; + + if (args.Component.TryGetData(DiseaseMachineVisuals.IsOn, out bool isOn) && args.Component.TryGetData(DiseaseMachineVisuals.IsRunning, out bool isRunning)) { var state = isRunning ? component.RunningState : component.IdleState; - sprite.LayerSetVisible(DiseaseMachineVisualLayers.IsOn, isOn); - sprite.LayerSetState(DiseaseMachineVisualLayers.IsRunning, state); + args.Sprite.LayerSetVisible(DiseaseMachineVisualLayers.IsOn, isOn); + args.Sprite.LayerSetState(DiseaseMachineVisualLayers.IsRunning, state); } } } diff --git a/Content.Client/Explosion/TriggerSystem.Proximity.cs b/Content.Client/Explosion/TriggerSystem.Proximity.cs index 0373368b9e..6e76e14631 100644 --- a/Content.Client/Explosion/TriggerSystem.Proximity.cs +++ b/Content.Client/Explosion/TriggerSystem.Proximity.cs @@ -64,12 +64,13 @@ public sealed partial class TriggerSystem private void OnProxAppChange(EntityUid uid, TriggerOnProximityComponent component, ref AppearanceChangeEvent args) { - OnChangeData(uid, component, args.Component); + OnChangeData(uid, component, args.Component, args.Sprite); } - private void OnChangeData(EntityUid uid, TriggerOnProximityComponent component, AppearanceComponent appearance) + private void OnChangeData(EntityUid uid, TriggerOnProximityComponent component, AppearanceComponent appearance, SpriteComponent? spriteComponent = null) { - if (!TryComp(component.Owner, out var spriteComponent)) return; + if (!Resolve(uid, ref spriteComponent)) + return; TryComp(component.Owner, out var player); appearance.TryGetData(ProximityTriggerVisualState.State, out ProximityTriggerVisuals state); diff --git a/Content.Client/Lathe/LatheSystem.cs b/Content.Client/Lathe/LatheSystem.cs index 391a908bd8..4f7f9ad485 100644 --- a/Content.Client/Lathe/LatheSystem.cs +++ b/Content.Client/Lathe/LatheSystem.cs @@ -11,39 +11,40 @@ namespace Content.Client.Lathe { protected override void OnAppearanceChange(EntityUid uid, LatheVisualsComponent component, ref AppearanceChangeEvent args) { - if (!TryComp(uid, out SpriteComponent? sprite)) return; + if (args.Sprite == null) + return; if (args.Component.TryGetData(PowerDeviceVisuals.Powered, out bool powered) && - sprite.LayerMapTryGet(PowerDeviceVisualLayers.Powered, out _)) + args.Sprite.LayerMapTryGet(PowerDeviceVisualLayers.Powered, out _)) { - sprite.LayerSetVisible(PowerDeviceVisualLayers.Powered, powered); + args.Sprite.LayerSetVisible(PowerDeviceVisualLayers.Powered, powered); } if (args.Component.TryGetData(WiresVisuals.MaintenancePanelState, out bool panel) - && sprite.LayerMapTryGet(WiresVisualizer.WiresVisualLayers.MaintenancePanel, out _)) + && args.Sprite.LayerMapTryGet(WiresVisualizer.WiresVisualLayers.MaintenancePanel, out _)) { - sprite.LayerSetVisible(WiresVisualizer.WiresVisualLayers.MaintenancePanel, panel); + args.Sprite.LayerSetVisible(WiresVisualizer.WiresVisualLayers.MaintenancePanel, panel); } // Lathe specific stuff if (args.Component.TryGetData(LatheVisuals.IsRunning, out bool isRunning)) { var state = isRunning ? component.RunningState : component.IdleState; - sprite.LayerSetAnimationTime(LatheVisualLayers.IsRunning, 0f); - sprite.LayerSetState(LatheVisualLayers.IsRunning, state); + args.Sprite.LayerSetAnimationTime(LatheVisualLayers.IsRunning, 0f); + args.Sprite.LayerSetState(LatheVisualLayers.IsRunning, state); } if (args.Component.TryGetData(LatheVisuals.IsInserting, out bool isInserting) - && sprite.LayerMapTryGet(LatheVisualLayers.IsInserting, out var isInsertingLayer)) + && args.Sprite.LayerMapTryGet(LatheVisualLayers.IsInserting, out var isInsertingLayer)) { if (args.Component.TryGetData(LatheVisuals.InsertingColor, out Color color) && !component.IgnoreColor) { - sprite.LayerSetColor(isInsertingLayer, color); + args.Sprite.LayerSetColor(isInsertingLayer, color); } - sprite.LayerSetAnimationTime(isInsertingLayer, 0f); - sprite.LayerSetVisible(isInsertingLayer, isInserting); + args.Sprite.LayerSetAnimationTime(isInsertingLayer, 0f); + args.Sprite.LayerSetVisible(isInsertingLayer, isInserting); } } } diff --git a/Content.Client/Paper/UI/PaperSystem.cs b/Content.Client/Paper/UI/PaperSystem.cs index e98656252c..72606c2811 100644 --- a/Content.Client/Paper/UI/PaperSystem.cs +++ b/Content.Client/Paper/UI/PaperSystem.cs @@ -8,16 +8,16 @@ public sealed class PaperSystem : VisualizerSystem { protected override void OnAppearanceChange(EntityUid uid, PaperVisualsComponent component, ref AppearanceChangeEvent args) { - if (!TryComp(uid, out SpriteComponent? sprite)) + if (args.Sprite == null) return; if (args.Component.TryGetData(PaperVisuals.Status , out PaperStatus writingStatus)) - sprite.LayerSetVisible(PaperVisualLayers.Writing, writingStatus == PaperStatus.Written); + args.Sprite.LayerSetVisible(PaperVisualLayers.Writing, writingStatus == PaperStatus.Written); if (args.Component.TryGetData(PaperVisuals.Stamp, out string stampState)) { - sprite.LayerSetState(PaperVisualLayers.Stamp, stampState); - sprite.LayerSetVisible(PaperVisualLayers.Stamp, true); + args.Sprite.LayerSetState(PaperVisualLayers.Stamp, stampState); + args.Sprite.LayerSetVisible(PaperVisualLayers.Stamp, true); } } } diff --git a/Content.Client/Power/Visualizers/CableVisualizer.cs b/Content.Client/Power/Visualizers/CableVisualizer.cs deleted file mode 100644 index ad614428fc..0000000000 --- a/Content.Client/Power/Visualizers/CableVisualizer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Content.Shared.Wires; -using Robust.Client.GameObjects; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Serialization.Manager.Attributes; - -namespace Content.Client.Power -{ - [DataDefinition] - public sealed class CableVisualizer : AppearanceVisualizer - { - [DataField("base")] - public string? StateBase; - - public override void OnChangeData(AppearanceComponent component) - { - base.OnChangeData(component); - - var entities = IoCManager.Resolve(); - if (!entities.TryGetComponent(component.Owner, out SpriteComponent? sprite)) - return; - - if (!component.TryGetData(WireVisVisuals.ConnectedMask, out WireVisDirFlags mask)) - mask = WireVisDirFlags.None; - - sprite.LayerSetState(0, $"{StateBase}{(int) mask}"); - } - } -} diff --git a/Content.Client/Power/Visualizers/CableVisualizerComponent.cs b/Content.Client/Power/Visualizers/CableVisualizerComponent.cs new file mode 100644 index 0000000000..a03f49e97d --- /dev/null +++ b/Content.Client/Power/Visualizers/CableVisualizerComponent.cs @@ -0,0 +1,8 @@ +namespace Content.Client.Power.Visualizers; + +[RegisterComponent] +public sealed class CableVisualizerComponent : Component +{ + [DataField("statePrefix")] + public string? StatePrefix; +} diff --git a/Content.Client/Power/Visualizers/CableVisualizerSystem.cs b/Content.Client/Power/Visualizers/CableVisualizerSystem.cs new file mode 100644 index 0000000000..0a22fcad8d --- /dev/null +++ b/Content.Client/Power/Visualizers/CableVisualizerSystem.cs @@ -0,0 +1,38 @@ +using Content.Client.SubFloor; +using Content.Shared.SubFloor; +using Content.Shared.Wires; +using Robust.Client.GameObjects; + +namespace Content.Client.Power.Visualizers; + +public sealed partial class CableVisualizerSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAppearanceChanged, after: new[] { typeof(SubFloorHideSystem) }); + } + + private void OnAppearanceChanged(EntityUid uid, CableVisualizerComponent component, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + + if (args.Component.TryGetData(SubFloorVisuals.Covered, out bool isUnderCover) + && isUnderCover + && args.Component.TryGetData(SubFloorVisuals.ScannerRevealed, out bool revealed) + && !revealed) + { + // This entity is below a floor and is not even visible to the user -> don't bother updating sprite data. + // Note that if the subfloor visuals change, then another AppearanceChangeEvent will get triggered. + return; + } + + if (!args.Component.TryGetData(WireVisVisuals.ConnectedMask, out WireVisDirFlags mask)) + mask = WireVisDirFlags.None; + + args.Sprite.LayerSetState(0, $"{component.StatePrefix}{(int) mask}"); + } + +} diff --git a/Content.Client/Sticky/Visualizers/StickyVisualizerSystem.cs b/Content.Client/Sticky/Visualizers/StickyVisualizerSystem.cs index fdf80ff41a..3dff5c86d4 100644 --- a/Content.Client/Sticky/Visualizers/StickyVisualizerSystem.cs +++ b/Content.Client/Sticky/Visualizers/StickyVisualizerSystem.cs @@ -1,4 +1,4 @@ -using Content.Shared.Sticky.Components; +using Content.Shared.Sticky.Components; using Robust.Client.GameObjects; namespace Content.Client.Sticky.Visualizers; @@ -21,16 +21,14 @@ public sealed class StickyVisualizerSystem : VisualizerSystem { protected override void OnAppearanceChange(EntityUid uid, WelderComponent component, ref AppearanceChangeEvent args) { - base.OnAppearanceChange(uid, component, ref args); - - if (!TryComp(uid, out SpriteComponent? sprite)) + if (args.Sprite == null) return; if (args.Component.TryGetData(WelderVisuals.Lit, out bool isLit)) { - sprite.LayerSetVisible(WelderLayers.Flame, isLit); + args.Sprite.LayerSetVisible(WelderLayers.Flame, isLit); } } } diff --git a/Content.Client/Vehicle/VehicleVisualsSystem.cs b/Content.Client/Vehicle/VehicleVisualsSystem.cs index f47afc04cc..412c382d19 100644 --- a/Content.Client/Vehicle/VehicleVisualsSystem.cs +++ b/Content.Client/Vehicle/VehicleVisualsSystem.cs @@ -11,16 +11,18 @@ namespace Content.Client.Vehicle { protected override void OnAppearanceChange(EntityUid uid, VehicleVisualsComponent component, ref AppearanceChangeEvent args) { + if (args.Sprite == null) + return; + /// First check is for the sprite itself - if (TryComp(uid, out SpriteComponent? sprite) - && args.Component.TryGetData(VehicleVisuals.DrawDepth, out int drawDepth) && sprite != null) + if (args.Component.TryGetData(VehicleVisuals.DrawDepth, out int drawDepth)) { - sprite.DrawDepth = drawDepth; + args.Sprite.DrawDepth = drawDepth; } /// Set vehicle layer to animated or not (i.e. are the wheels turning or not) if (args.Component.TryGetData(VehicleVisuals.AutoAnimate, out bool autoAnimate)) { - sprite?.LayerSetAutoAnimated(VehicleVisualLayers.AutoAnimate, autoAnimate); + args.Sprite.LayerSetAutoAnimated(VehicleVisualLayers.AutoAnimate, autoAnimate); } } } diff --git a/Content.Server/Entry/IgnoredComponents.cs b/Content.Server/Entry/IgnoredComponents.cs index 47354f87e2..668556d8a3 100644 --- a/Content.Server/Entry/IgnoredComponents.cs +++ b/Content.Server/Entry/IgnoredComponents.cs @@ -22,6 +22,7 @@ namespace Content.Server.Entry "DiseaseMachineVisuals", "HandheldGPS", "ToggleableLightVisuals", + "CableVisualizer", "PotencyVisuals", "PaperVisuals" }; diff --git a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs index 8533aec1c9..4640d47bf7 100644 --- a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs +++ b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs @@ -63,9 +63,6 @@ namespace Content.Shared.SubFloor var xform = Transform(uid); _trayScannerSystem.OnSubfloorAnchored(uid, component, xform); UpdateFloorCover(uid, component, xform); - - if (component.IsUnderCover) - UpdateAppearance(uid, component); } else if (component.IsUnderCover) { diff --git a/Resources/Prototypes/Entities/Structures/Power/cables.yml b/Resources/Prototypes/Entities/Structures/Power/cables.yml index fd64ea97a3..2e11a3827a 100644 --- a/Resources/Prototypes/Entities/Structures/Power/cables.yml +++ b/Resources/Prototypes/Entities/Structures/Power/cables.yml @@ -23,6 +23,7 @@ - !type:DoActsBehavior acts: ["Destruction"] - type: SubFloorHide + - type: Appearance - type: Electrified onHandInteract: false onInteractUsing: false # wire-cutting handled separately. @@ -74,10 +75,8 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Appearance - visuals: - - type: CableVisualizer - base: hvcable_ + - type: CableVisualizer + statePrefix: hvcable_ - type: AmbientSound enabled: true volume: -15 @@ -126,10 +125,8 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Appearance - visuals: - - type: CableVisualizer - base: mvcable_ + - type: CableVisualizer + statePrefix: mvcable_ - type: AmbientSound enabled: true volume: -16 @@ -181,10 +178,8 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Appearance - visuals: - - type: CableVisualizer - base: lvcable_ + - type: CableVisualizer + statePrefix: lvcable_ - type: AmbientSound enabled: true volume: -17