diff --git a/Content.Client/Gravity/GravityGeneratorVisualizer.cs b/Content.Client/Gravity/GravityGeneratorVisualizer.cs deleted file mode 100644 index f3f90fe1de..0000000000 --- a/Content.Client/Gravity/GravityGeneratorVisualizer.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Linq; -using Content.Shared.Gravity; -using JetBrains.Annotations; -using Robust.Client.GameObjects; - -namespace Content.Client.Gravity -{ - [UsedImplicitly] - public sealed class GravityGeneratorVisualizer : AppearanceVisualizer - { - [DataField("spritemap")] - private Dictionary _rawSpriteMap - { - get => _spriteMap.ToDictionary(x => x.Key.ToString().ToLower(), x => x.Value); - set - { - _spriteMap.Clear(); - // Get Sprites for each status - foreach (var status in (GravityGeneratorStatus[]) Enum.GetValues(typeof(GravityGeneratorStatus))) - { - if (value.TryGetValue(status.ToString().ToLower(), out var sprite)) - { - _spriteMap[status] = sprite; - } - } - } - } - - private Dictionary _spriteMap = new(); - - [Obsolete("Subscribe to your component being initialised instead.")] - public override void InitializeEntity(EntityUid entity) - { - base.InitializeEntity(entity); - - if (!IoCManager.Resolve().TryGetComponent(entity, out SpriteComponent? sprite)) - return; - - sprite.LayerMapReserveBlank(GravityGeneratorVisualLayers.Base); - sprite.LayerMapReserveBlank(GravityGeneratorVisualLayers.Core); - } - - [Obsolete("Subscribe to AppearanceChangeEvent instead.")] - public override void OnChangeData(AppearanceComponent component) - { - base.OnChangeData(component); - - var sprite = IoCManager.Resolve().GetComponent(component.Owner); - - if (component.TryGetData(GravityGeneratorVisuals.State, out GravityGeneratorStatus state)) - { - if (_spriteMap.TryGetValue(state, out var spriteState)) - { - var layer = sprite.LayerMapGet(GravityGeneratorVisualLayers.Base); - sprite.LayerSetState(layer, spriteState); - } - } - - if (component.TryGetData(GravityGeneratorVisuals.Charge, out float charge)) - { - var layer = sprite.LayerMapGet(GravityGeneratorVisualLayers.Core); - switch (charge) - { - case < 0.2f: - sprite.LayerSetVisible(layer, false); - break; - case >= 0.2f and < 0.4f: - sprite.LayerSetVisible(layer, true); - sprite.LayerSetState(layer, "startup"); - break; - case >= 0.4f and < 0.6f: - sprite.LayerSetVisible(layer, true); - sprite.LayerSetState(layer, "idle"); - break; - case >= 0.6f and < 0.8f: - sprite.LayerSetVisible(layer, true); - sprite.LayerSetState(layer, "activating"); - break; - default: - sprite.LayerSetVisible(layer, true); - sprite.LayerSetState(layer, "activated"); - break; - } - } - } - - public enum GravityGeneratorVisualLayers : byte - { - Base, - Core - } - } -} diff --git a/Content.Client/Gravity/GravitySystem.cs b/Content.Client/Gravity/GravitySystem.cs index 346c7d79eb..3e87f76ba2 100644 --- a/Content.Client/Gravity/GravitySystem.cs +++ b/Content.Client/Gravity/GravitySystem.cs @@ -1,12 +1,66 @@ using Content.Shared.Gravity; +using Robust.Client.GameObjects; namespace Content.Client.Gravity; public sealed partial class GravitySystem : SharedGravitySystem { + [Dependency] private readonly AppearanceSystem _appearanceSystem = default!; public override void Initialize() { base.Initialize(); + SubscribeLocalEvent(OnAppearanceChange); InitializeShake(); } + + /// + /// Ensures that the visible state of gravity generators are synced with their sprites. + /// + private void OnAppearanceChange(EntityUid uid, SharedGravityGeneratorComponent comp, ref AppearanceChangeEvent args) + { + if (args.Sprite == null) + return; + + if (_appearanceSystem.TryGetData(uid, GravityGeneratorVisuals.State, out var state, args.Component)) + { + if (comp.SpriteMap.TryGetValue(state, out var spriteState)) + { + var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Base); + args.Sprite.LayerSetState(layer, spriteState); + } + } + + if (_appearanceSystem.TryGetData(uid, GravityGeneratorVisuals.Charge, out var charge, args.Component)) + { + var layer = args.Sprite.LayerMapGet(GravityGeneratorVisualLayers.Core); + switch (charge) + { + case < 0.2f: + args.Sprite.LayerSetVisible(layer, false); + break; + case >= 0.2f and < 0.4f: + args.Sprite.LayerSetVisible(layer, true); + args.Sprite.LayerSetState(layer, comp.CoreStartupState); + break; + case >= 0.4f and < 0.6f: + args.Sprite.LayerSetVisible(layer, true); + args.Sprite.LayerSetState(layer, comp.CoreIdleState); + break; + case >= 0.6f and < 0.8f: + args.Sprite.LayerSetVisible(layer, true); + args.Sprite.LayerSetState(layer, comp.CoreActivatingState); + break; + default: + args.Sprite.LayerSetVisible(layer, true); + args.Sprite.LayerSetState(layer, comp.CoreActivatedState); + break; + } + } + } +} + +public enum GravityGeneratorVisualLayers : byte +{ + Base, + Core } diff --git a/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs b/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs index 78bec68e94..4b96a42da8 100644 --- a/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs +++ b/Content.Shared/Gravity/SharedGravityGeneratorComponent.cs @@ -7,6 +7,41 @@ namespace Content.Shared.Gravity [Virtual] public class SharedGravityGeneratorComponent : Component { + /// + /// A map of the sprites used by the gravity generator given its status. + /// + [DataField("spriteMap")] + [Access(typeof(SharedGravitySystem))] + public Dictionary SpriteMap = new(); + + /// + /// The sprite used by the core of the gravity generator when the gravity generator is starting up. + /// + [DataField("coreStartupState")] + [ViewVariables(VVAccess.ReadWrite)] + public string CoreStartupState = "startup"; + + /// + /// The sprite used by the core of the gravity generator when the gravity generator is idle. + /// + [DataField("coreIdleState")] + [ViewVariables(VVAccess.ReadWrite)] + public string CoreIdleState = "idle"; + + /// + /// The sprite used by the core of the gravity generator when the gravity generator is activating. + /// + [DataField("coreActivatingState")] + [ViewVariables(VVAccess.ReadWrite)] + public string CoreActivatingState = "activating"; + + /// + /// The sprite used by the core of the gravity generator when the gravity generator is active. + /// + [DataField("coreActivatedState")] + [ViewVariables(VVAccess.ReadWrite)] + public string CoreActivatedState = "activated"; + /// /// Sent to the server to set whether the generator should be on or off /// diff --git a/Content.Shared/Gravity/SharedGravitySystem.cs b/Content.Shared/Gravity/SharedGravitySystem.cs index 901461d157..a65c386ae5 100644 --- a/Content.Shared/Gravity/SharedGravitySystem.cs +++ b/Content.Shared/Gravity/SharedGravitySystem.cs @@ -88,17 +88,18 @@ namespace Content.Shared.Gravity private void OnGravityChange(ref GravityChangedEvent ev) { - foreach (var (comp, xform) in EntityQuery(true)) + var alerts = AllEntityQuery(); + while(alerts.MoveNext(out var uid, out var comp, out var xform)) { if (xform.GridUid != ev.ChangedGridIndex) continue; if (!ev.HasGravity) { - _alerts.ShowAlert(comp.Owner, AlertType.Weightless); + _alerts.ShowAlert(uid, AlertType.Weightless); } else { - _alerts.ClearAlert(comp.Owner, AlertType.Weightless); + _alerts.ClearAlert(uid, AlertType.Weightless); } } } @@ -117,7 +118,7 @@ namespace Content.Shared.Gravity private void OnAlertsParentChange(EntityUid uid, AlertsComponent component, ref EntParentChangedMessage args) { - if (IsWeightless(component.Owner)) + if (IsWeightless(uid)) { _alerts.ShowAlert(uid, AlertType.Weightless); } diff --git a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml index 5e8dd326f6..5c8db0638f 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/gravity_generator.yml @@ -56,18 +56,16 @@ activePower: 2500 lightRadiusMin: 0.75 lightRadiusMax: 2.5 + spritemap: + broken: "broken" + unpowered: "off" + off: "off" + on: "on" - type: UserInterface interfaces: - key: enum.GravityGeneratorUiKey.Key type: GravityGeneratorBoundUserInterface - type: Appearance - visuals: - - type: GravityGeneratorVisualizer - spritemap: - broken: "broken" - unpowered: "off" - off: "off" - on: "on" - type: PointLight radius: 2.5 energy: 0.5