Visualizer systems update (#8203)

* optimize appearance updating for subfloor entities

* sprite event args

* a

* stop double appearance update.
This commit is contained in:
Leon Friedrich
2022-05-16 14:41:23 +10:00
committed by GitHub
parent 920b4e5689
commit 25b9e048e5
22 changed files with 135 additions and 112 deletions

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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<PotencyVisualsCompon
{
protected override void OnAppearanceChange(EntityUid uid, PotencyVisualsComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if (!TryComp<SpriteComponent>(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);
}
}
}

View File

@@ -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<ItemCabinetVisualsCompo
{
protected override void OnAppearanceChange(EntityUid uid, ItemCabinetVisualsComponent component, ref AppearanceChangeEvent args)
{
if (TryComp(uid, out SpriteComponent? sprite)
&& args.Component.TryGetData(ItemCabinetVisuals.IsOpen, out bool isOpen)
if (args.Sprite == null)
return;
if (args.Component.TryGetData(ItemCabinetVisuals.IsOpen, out bool isOpen)
&& args.Component.TryGetData(ItemCabinetVisuals.ContainsItem, out bool contains))
{
var state = isOpen ? component.OpenState : component.ClosedState;
sprite.LayerSetState(ItemCabinetVisualLayers.Door, state);
sprite.LayerSetVisible(ItemCabinetVisualLayers.ContainsItem, contains);
args.Sprite.LayerSetState(ItemCabinetVisualLayers.Door, state);
args.Sprite.LayerSetVisible(ItemCabinetVisualLayers.ContainsItem, contains);
}
}
}

View File

@@ -50,7 +50,7 @@ public sealed partial class CargoSystem
private void OnCargoAppChange(EntityUid uid, CargoTelepadComponent component, ref AppearanceChangeEvent args)
{
OnChangeData(args.Component);
OnChangeData(args.Component, args.Sprite);
}
private void OnCargoAnimComplete(EntityUid uid, CargoTelepadComponent component, AnimationCompletedEvent args)
@@ -60,9 +60,10 @@ public sealed partial class CargoSystem
OnChangeData(appearance);
}
private void OnChangeData(AppearanceComponent component)
private void OnChangeData(AppearanceComponent component, SpriteComponent? sprite = null)
{
if (!TryComp<SpriteComponent>(component.Owner, out var sprite)) return;
if (!Resolve(component.Owner, ref sprite))
return;
component.TryGetData(CargoTelepadVisuals.State, out CargoTelepadState? state);
AnimationPlayerComponent? player = null;

View File

@@ -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);
}
}
}

View File

@@ -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<SpriteComponent>(component.Owner, out var spriteComponent)) return;
if (!Resolve(uid, ref spriteComponent))
return;
TryComp<AnimationPlayerComponent>(component.Owner, out var player);
appearance.TryGetData(ProximityTriggerVisualState.State, out ProximityTriggerVisuals state);

View File

@@ -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);
}
}
}

View File

@@ -8,16 +8,16 @@ public sealed class PaperSystem : VisualizerSystem<PaperVisualsComponent>
{
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);
}
}
}

View File

@@ -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<IEntityManager>();
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}");
}
}
}

View File

@@ -0,0 +1,8 @@
namespace Content.Client.Power.Visualizers;
[RegisterComponent]
public sealed class CableVisualizerComponent : Component
{
[DataField("statePrefix")]
public string? StatePrefix;
}

View File

@@ -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<CableVisualizerComponent, AppearanceChangeEvent>(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}");
}
}

View File

@@ -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<StickyVisualizerCo
protected override void OnAppearanceChange(EntityUid uid, StickyVisualizerComponent 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(StickyVisuals.IsStuck, out bool isStuck))
return;
var drawDepth = isStuck ? component.StuckDrawDepth : component.DefaultDrawDepth;
sprite.DrawDepth = drawDepth;
args.Sprite.DrawDepth = drawDepth;
}
}

View File

@@ -1,4 +1,4 @@
using Content.Shared.Storage;
using Content.Shared.Storage;
using Content.Shared.Storage.Components;
using Robust.Client.GameObjects;
@@ -8,7 +8,8 @@ public sealed class StorageFillVisualizerSystem : VisualizerSystem<StorageFillVi
{
protected override void OnAppearanceChange(EntityUid uid, StorageFillVisualizerComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if (args.Sprite == null)
return;
if (!TryComp(uid, out SpriteComponent? sprite))
return;
@@ -17,6 +18,6 @@ public sealed class StorageFillVisualizerSystem : VisualizerSystem<StorageFillVi
return;
var state = $"{component.FillBaseName}-{level}";
sprite.LayerSetState(StorageFillLayers.Fill, state);
args.Sprite.LayerSetState(StorageFillLayers.Fill, state);
}
}

View File

@@ -31,7 +31,7 @@ public sealed class SubFloorHideSystem : SharedSubFloorHideSystem
private void OnAppearanceChanged(EntityUid uid, SubFloorHideComponent component, ref AppearanceChangeEvent args)
{
if (!TryComp(uid, out SpriteComponent? sprite))
if (args.Sprite == null)
return;
args.Component.TryGetData(SubFloorVisuals.Covered, out bool covered);
@@ -43,7 +43,7 @@ public sealed class SubFloorHideSystem : SharedSubFloorHideSystem
var transparency = scannerRevealed ? component.ScannerTransparency : 1f;
// set visibility & color of each layer
foreach (var layer in sprite.AllLayers)
foreach (var layer in args.Sprite.AllLayers)
{
// pipe connection visuals are updated AFTER this, and may re-hide some layers
layer.Visible = revealed;
@@ -53,16 +53,16 @@ public sealed class SubFloorHideSystem : SharedSubFloorHideSystem
}
// Is there some layer that is always visible?
if (sprite.LayerMapTryGet(SubfloorLayers.FirstLayer, out var firstLayer))
if (args.Sprite.LayerMapTryGet(SubfloorLayers.FirstLayer, out var firstLayer))
{
var layer = sprite[firstLayer];
var layer = args.Sprite[firstLayer];
layer.Visible = true;
layer.Color = layer.Color.WithAlpha(1f);
sprite.Visible = true;
args.Sprite.Visible = true;
return;
}
sprite.Visible = revealed;
args.Sprite.Visible = revealed;
}
private void UpdateAll()

View File

@@ -29,11 +29,11 @@ public sealed class ToggleableLightVisualsSystem : VisualizerSystem<ToggleableLi
var modulate = args.Component.TryGetData(ToggleableLightVisuals.Color, out Color color);
// Update the item's sprite
if (TryComp(uid, out SpriteComponent? sprite) && sprite.LayerMapTryGet(component.SpriteLayer, out var layer))
if (args.Sprite != null && args.Sprite.LayerMapTryGet(component.SpriteLayer, out var layer))
{
sprite.LayerSetVisible(layer, enabled);
args.Sprite.LayerSetVisible(layer, enabled);
if (modulate)
sprite.LayerSetColor(layer, color);
args.Sprite.LayerSetColor(layer, color);
}
// Update any point-lights

View File

@@ -8,15 +8,13 @@ public sealed class WeldableVisualizerSystem : VisualizerSystem<WeldableComponen
{
protected override void OnAppearanceChange(EntityUid uid, WeldableComponent component, ref AppearanceChangeEvent args)
{
base.OnAppearanceChange(uid, component, ref args);
if (!TryComp(uid, out SpriteComponent? sprite))
if (args.Sprite == null)
return;
args.Component.TryGetData(WeldableVisuals.IsWelded, out bool isWelded);
if (sprite.LayerMapTryGet(WeldableLayers.BaseWelded, out var layer))
if (args.Sprite.LayerMapTryGet(WeldableLayers.BaseWelded, out var layer))
{
sprite.LayerSetVisible(layer, isWelded);
args.Sprite.LayerSetVisible(layer, isWelded);
}
}
}

View File

@@ -1,4 +1,4 @@
using Content.Client.Tools.Components;
using Content.Client.Tools.Components;
using Content.Shared.Tools.Components;
using Robust.Client.GameObjects;
@@ -8,14 +8,12 @@ public sealed class WelderVisualizerSystem : VisualizerSystem<WelderComponent>
{
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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -22,6 +22,7 @@ namespace Content.Server.Entry
"DiseaseMachineVisuals",
"HandheldGPS",
"ToggleableLightVisuals",
"CableVisualizer",
"PotencyVisuals",
"PaperVisuals"
};

View File

@@ -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)
{

View File

@@ -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