diff --git a/Content.Client/Pinpointer/PinpointerSystem.cs b/Content.Client/Pinpointer/PinpointerSystem.cs index 1266cbe452..486241b56b 100644 --- a/Content.Client/Pinpointer/PinpointerSystem.cs +++ b/Content.Client/Pinpointer/PinpointerSystem.cs @@ -1,78 +1,41 @@ using Content.Shared.Pinpointer; using Robust.Client.GameObjects; using Robust.Client.Graphics; -using Robust.Shared.GameStates; -namespace Content.Client.Pinpointer +namespace Content.Client.Pinpointer; + +public sealed class PinpointerSystem : SharedPinpointerSystem { - public sealed class PinpointerSystem : SharedPinpointerSystem + [Dependency] private readonly IEyeManager _eyeManager = default!; + + public override void Update(float frameTime) { - [Dependency] private readonly IEyeManager _eyeManager = default!; - [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + base.Update(frameTime); - public override void Initialize() + // we want to show pinpointers arrow direction relative + // to players eye rotation (like it was in SS13) + + // because eye can change it rotation anytime + // we need to update this arrow in a update loop + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var _, out var pinpointer, out var sprite)) { - base.Initialize(); - SubscribeLocalEvent(HandleCompState); - } - - public override void FrameUpdate(float frameTime) - { - base.FrameUpdate(frameTime); - - // we want to show pinpointers arrow direction relative - // to players eye rotation (like it was in SS13) - - // because eye can change it rotation anytime - // we need to update this arrow in a update loop - foreach (var pinpointer in EntityQuery()) - { - UpdateAppearance(pinpointer.Owner, pinpointer); - UpdateEyeDir(pinpointer.Owner, pinpointer); - } - } - - private void HandleCompState(EntityUid uid, PinpointerComponent pinpointer, ref ComponentHandleState args) - { - if (args.Current is not PinpointerComponentState state) - return; - - pinpointer.IsActive = state.IsActive; - pinpointer.ArrowAngle = state.ArrowAngle; - pinpointer.DistanceToTarget = state.DistanceToTarget; - } - - private void UpdateAppearance(EntityUid uid, PinpointerComponent? pinpointer = null, - AppearanceComponent? appearance = null) - { - if (!Resolve(uid, ref pinpointer, ref appearance)) - return; - - _appearance.SetData(uid, PinpointerVisuals.IsActive, pinpointer.IsActive, appearance); - _appearance.SetData(uid, PinpointerVisuals.TargetDistance, pinpointer.DistanceToTarget, appearance); - } - - private void UpdateArrowAngle(EntityUid uid, Angle angle, PinpointerComponent? pinpointer = null, - AppearanceComponent? appearance = null) - { - if (!Resolve(uid, ref pinpointer, ref appearance)) - return; - - _appearance.SetData(uid, PinpointerVisuals.ArrowAngle, angle, appearance); - } - - /// - /// Transform pinpointer arrow from world space to eye space - /// And send it to the appearance component - /// - private void UpdateEyeDir(EntityUid uid, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer) || !pinpointer.HasTarget) - return; - + if (!pinpointer.HasTarget) + continue; var eye = _eyeManager.CurrentEye; var angle = pinpointer.ArrowAngle + eye.Rotation; - UpdateArrowAngle(uid, angle, pinpointer); + + switch (pinpointer.DistanceToTarget) + { + case Distance.Close: + case Distance.Medium: + case Distance.Far: + sprite.LayerSetRotation(PinpointerLayers.Screen, angle); + break; + default: + sprite.LayerSetRotation(PinpointerLayers.Screen, Angle.Zero); + break; + } } } } diff --git a/Content.Client/Pinpointer/PinpointerVisualizerSystem.cs b/Content.Client/Pinpointer/PinpointerVisualizerSystem.cs deleted file mode 100644 index b59a2ab37c..0000000000 --- a/Content.Client/Pinpointer/PinpointerVisualizerSystem.cs +++ /dev/null @@ -1,60 +0,0 @@ -using Content.Shared.Pinpointer; -using JetBrains.Annotations; -using Robust.Client.GameObjects; - -namespace Content.Client.Pinpointer -{ - [UsedImplicitly] - public sealed class PinpointerVisualizerSystem : VisualizerSystem - { - protected override void OnAppearanceChange(EntityUid uid, PinpointerComponent component, ref AppearanceChangeEvent args) - { - base.OnAppearanceChange(uid, component, ref args); - - if (!TryComp(component.Owner, out SpriteComponent? sprite)) - return; - - // check if pinpointer screen is active - if (!AppearanceSystem.TryGetData(uid, PinpointerVisuals.IsActive, out var isActive, args.Component) || !isActive) - { - sprite.LayerSetVisible(PinpointerLayers.Screen, false); - return; - } - - sprite.LayerSetVisible(PinpointerLayers.Screen, true); - - // check distance and direction to target - if (!AppearanceSystem.TryGetData(uid, PinpointerVisuals.TargetDistance, out var dis, args.Component) || - !AppearanceSystem.TryGetData(uid, PinpointerVisuals.ArrowAngle, out var angle, args.Component)) - { - sprite.LayerSetState(PinpointerLayers.Screen, "pinonnull"); - sprite.LayerSetRotation(PinpointerLayers.Screen, Angle.Zero); - return; - } - - switch (dis) - { - case Distance.Reached: - sprite.LayerSetState(PinpointerLayers.Screen, "pinondirect"); - sprite.LayerSetRotation(PinpointerLayers.Screen, Angle.Zero); - break; - case Distance.Close: - sprite.LayerSetState(PinpointerLayers.Screen, "pinonclose"); - sprite.LayerSetRotation(PinpointerLayers.Screen, angle); - break; - case Distance.Medium: - sprite.LayerSetState(PinpointerLayers.Screen, "pinonmedium"); - sprite.LayerSetRotation(PinpointerLayers.Screen, angle); - break; - case Distance.Far: - sprite.LayerSetState(PinpointerLayers.Screen, "pinonfar"); - sprite.LayerSetRotation(PinpointerLayers.Screen, angle); - break; - case Distance.Unknown: - sprite.LayerSetState(PinpointerLayers.Screen, "pinonnull"); - sprite.LayerSetRotation(PinpointerLayers.Screen, Angle.Zero); - break; - } - } - } -} diff --git a/Content.Server/Pinpointer/PinpointerSystem.cs b/Content.Server/Pinpointer/PinpointerSystem.cs index 21b96a98e3..e0b5af3192 100644 --- a/Content.Server/Pinpointer/PinpointerSystem.cs +++ b/Content.Server/Pinpointer/PinpointerSystem.cs @@ -4,183 +4,201 @@ using System.Linq; using Robust.Shared.Utility; using Content.Server.Shuttles.Events; -namespace Content.Server.Pinpointer +namespace Content.Server.Pinpointer; + +public sealed class PinpointerSystem : SharedPinpointerSystem { - public sealed class PinpointerSystem : SharedPinpointerSystem + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + + public override void Initialize() { - [Dependency] private readonly SharedTransformSystem _transform = default!; + base.Initialize(); + SubscribeLocalEvent(OnActivate); + SubscribeLocalEvent(OnLocateTarget); + } - public override void Initialize() + private void OnActivate(EntityUid uid, PinpointerComponent component, ActivateInWorldEvent args) + { + TogglePinpointer(uid, component); + LocateTarget(uid, component); + } + + public bool TogglePinpointer(EntityUid uid, PinpointerComponent? pinpointer = null) + { + if (!Resolve(uid, ref pinpointer)) + return false; + + var isActive = !pinpointer.IsActive; + SetActive(uid, isActive, pinpointer); + UpdateAppearance(uid, pinpointer); + return isActive; + } + + private void UpdateAppearance(EntityUid uid, PinpointerComponent pinpointer, AppearanceComponent? appearance = null) + { + if (!Resolve(uid, ref appearance)) + return; + _appearance.SetData(uid, PinpointerVisuals.IsActive, pinpointer.IsActive, appearance); + _appearance.SetData(uid, PinpointerVisuals.TargetDistance, pinpointer.DistanceToTarget, appearance); + } + + private void OnLocateTarget(ref FTLCompletedEvent ev) + { + // This feels kind of expensive, but it only happens once per hyperspace jump + + // todo: ideally, you would need to raise this event only on jumped entities + // this code update ALL pinpointers in game + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var pinpointer)) { - base.Initialize(); - SubscribeLocalEvent(OnActivate); - SubscribeLocalEvent(OnLocateTarget); - } - - private void OnActivate(EntityUid uid, PinpointerComponent component, ActivateInWorldEvent args) - { - TogglePinpointer(uid, component); - LocateTarget(uid, component); - } - - private void OnLocateTarget(ref FTLCompletedEvent ev) - { - // This feels kind of expensive, but it only happens once per hyperspace jump - - // todo: ideally, you would need to raise this event only on jumped entities - // this code update ALL pinpointers in game - foreach (var pinpointer in EntityQuery()) - { - LocateTarget(pinpointer.Owner, pinpointer); - } - } - - private void LocateTarget(EntityUid uid, PinpointerComponent component) - { - // try to find target from whitelist - if (component.IsActive && component.Component != null) - { - if (!EntityManager.ComponentFactory.TryGetRegistration(component.Component, out var reg)) - { - Logger.Error($"Unable to find component registration for {component.Component} for pinpointer!"); - DebugTools.Assert(false); - return; - } - - var target = FindTargetFromComponent(uid, reg.Type); - SetTarget(uid, target, component); - } - } - - public override void Update(float frameTime) - { - base.Update(frameTime); - - // because target or pinpointer can move - // we need to update pinpointers arrow each frame - foreach (var pinpointer in EntityQuery()) - { - UpdateDirectionToTarget(pinpointer.Owner, pinpointer); - } - } - - /// - /// Try to find the closest entity from whitelist on a current map - /// Will return null if can't find anything - /// - private EntityUid? FindTargetFromComponent(EntityUid uid, Type whitelist, TransformComponent? transform = null) - { - var xformQuery = GetEntityQuery(); - - if (transform == null) - xformQuery.TryGetComponent(uid, out transform); - - if (transform == null) - return null; - - // sort all entities in distance increasing order - var mapId = transform.MapID; - var l = new SortedList(); - var worldPos = _transform.GetWorldPosition(transform, xformQuery); - - foreach (var comp in EntityManager.GetAllComponents(whitelist)) - { - if (!xformQuery.TryGetComponent(comp.Owner, out var compXform) || compXform.MapID != mapId) - continue; - - var dist = (_transform.GetWorldPosition(compXform, xformQuery) - worldPos).LengthSquared; - l.TryAdd(dist, comp.Owner); - } - - // return uid with a smallest distance - return l.Count > 0 ? l.First().Value : null; - } - - /// - /// Set pinpointers target to track - /// - public void SetTarget(EntityUid uid, EntityUid? target, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return; - - if (pinpointer.Target == target) - return; - - pinpointer.Target = target; - if (pinpointer.IsActive) - UpdateDirectionToTarget(uid, pinpointer); - } - - /// - /// Update direction from pinpointer to selected target (if it was set) - /// - private void UpdateDirectionToTarget(EntityUid uid, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return; - - if (!pinpointer.IsActive) - return; - - var target = pinpointer.Target; - if (target == null || !EntityManager.EntityExists(target.Value)) - { - SetDistance(uid, Distance.Unknown, pinpointer); - return; - } - - var dirVec = CalculateDirection(uid, target.Value); - if (dirVec != null) - { - var angle = dirVec.Value.ToWorldAngle(); - TrySetArrowAngle(uid, angle, pinpointer); - var dist = CalculateDistance(uid, dirVec.Value, pinpointer); - SetDistance(uid, dist, pinpointer); - } - else - { - SetDistance(uid, Distance.Unknown, pinpointer); - } - } - - /// - /// Calculate direction from pinUid to trgUid - /// - /// Null if failed to calculate distance between two entities - private Vector2? CalculateDirection(EntityUid pinUid, EntityUid trgUid) - { - var xformQuery = GetEntityQuery(); - - // check if entities have transform component - if (!xformQuery.TryGetComponent(pinUid, out var pin)) - return null; - if (!xformQuery.TryGetComponent(trgUid, out var trg)) - return null; - - // check if they are on same map - if (pin.MapID != trg.MapID) - return null; - - // get world direction vector - var dir = (_transform.GetWorldPosition(trg, xformQuery) - _transform.GetWorldPosition(pin, xformQuery)); - return dir; - } - - private Distance CalculateDistance(EntityUid uid, Vector2 vec, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return Distance.Unknown; - - var dist = vec.Length; - if (dist <= pinpointer.ReachedDistance) - return Distance.Reached; - else if (dist <= pinpointer.CloseDistance) - return Distance.Close; - else if (dist <= pinpointer.MediumDistance) - return Distance.Medium; - else - return Distance.Far; + LocateTarget(uid, pinpointer); } } + + private void LocateTarget(EntityUid uid, PinpointerComponent component) + { + // try to find target from whitelist + if (component.IsActive && component.Component != null) + { + if (!EntityManager.ComponentFactory.TryGetRegistration(component.Component, out var reg)) + { + Logger.Error($"Unable to find component registration for {component.Component} for pinpointer!"); + DebugTools.Assert(false); + return; + } + + var target = FindTargetFromComponent(uid, reg.Type); + SetTarget(uid, target, component); + } + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + // because target or pinpointer can move + // we need to update pinpointers arrow each frame + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var pinpointer)) + { + UpdateDirectionToTarget(uid, pinpointer); + } + } + + /// + /// Try to find the closest entity from whitelist on a current map + /// Will return null if can't find anything + /// + private EntityUid? FindTargetFromComponent(EntityUid uid, Type whitelist, TransformComponent? transform = null) + { + var xformQuery = GetEntityQuery(); + + if (transform == null) + xformQuery.TryGetComponent(uid, out transform); + + if (transform == null) + return null; + + // sort all entities in distance increasing order + var mapId = transform.MapID; + var l = new SortedList(); + var worldPos = _transform.GetWorldPosition(transform, xformQuery); + + foreach (var comp in EntityManager.GetAllComponents(whitelist)) + { + if (!xformQuery.TryGetComponent(comp.Owner, out var compXform) || compXform.MapID != mapId) + continue; + + var dist = (_transform.GetWorldPosition(compXform, xformQuery) - worldPos).LengthSquared; + l.TryAdd(dist, comp.Owner); + } + + // return uid with a smallest distance + return l.Count > 0 ? l.First().Value : null; + } + + /// + /// Set pinpointers target to track + /// + public void SetTarget(EntityUid uid, EntityUid? target, PinpointerComponent? pinpointer = null) + { + if (!Resolve(uid, ref pinpointer)) + return; + + if (pinpointer.Target == target) + return; + + pinpointer.Target = target; + if (pinpointer.IsActive) + UpdateDirectionToTarget(uid, pinpointer); + } + + /// + /// Update direction from pinpointer to selected target (if it was set) + /// + private void UpdateDirectionToTarget(EntityUid uid, PinpointerComponent pinpointer) + { + if (!pinpointer.IsActive) + return; + + var target = pinpointer.Target; + if (target == null || !EntityManager.EntityExists(target.Value)) + { + SetDistance(uid, Distance.Unknown, pinpointer); + return; + } + + var dirVec = CalculateDirection(uid, target.Value); + var oldDist = pinpointer.DistanceToTarget; + if (dirVec != null) + { + var angle = dirVec.Value.ToWorldAngle(); + TrySetArrowAngle(uid, angle, pinpointer); + var dist = CalculateDistance(dirVec.Value, pinpointer); + SetDistance(uid, dist, pinpointer); + } + else + { + SetDistance(uid, Distance.Unknown, pinpointer); + } + if (oldDist != pinpointer.DistanceToTarget) + UpdateAppearance(uid, pinpointer); + } + + /// + /// Calculate direction from pinUid to trgUid + /// + /// Null if failed to calculate distance between two entities + private Vector2? CalculateDirection(EntityUid pinUid, EntityUid trgUid) + { + var xformQuery = GetEntityQuery(); + + // check if entities have transform component + if (!xformQuery.TryGetComponent(pinUid, out var pin)) + return null; + if (!xformQuery.TryGetComponent(trgUid, out var trg)) + return null; + + // check if they are on same map + if (pin.MapID != trg.MapID) + return null; + + // get world direction vector + var dir = _transform.GetWorldPosition(trg, xformQuery) - _transform.GetWorldPosition(pin, xformQuery); + return dir; + } + + private static Distance CalculateDistance(Vector2 vec, PinpointerComponent pinpointer) + { + var dist = vec.Length; + if (dist <= pinpointer.ReachedDistance) + return Distance.Reached; + else if (dist <= pinpointer.CloseDistance) + return Distance.Close; + else if (dist <= pinpointer.MediumDistance) + return Distance.Medium; + else + return Distance.Far; + } } diff --git a/Content.Shared/Pinpointer/PinpointerComponent.cs b/Content.Shared/Pinpointer/PinpointerComponent.cs index 7e467f14b0..0b49ad5e99 100644 --- a/Content.Shared/Pinpointer/PinpointerComponent.cs +++ b/Content.Shared/Pinpointer/PinpointerComponent.cs @@ -1,57 +1,60 @@ using Robust.Shared.GameStates; using Robust.Shared.Serialization; -namespace Content.Shared.Pinpointer +namespace Content.Shared.Pinpointer; + +/// +/// Displays a sprite on the item that points towards the target component. +/// +[RegisterComponent, NetworkedComponent] +[AutoGenerateComponentState] +[Access(typeof(SharedPinpointerSystem))] +public sealed partial class PinpointerComponent : Component { + // TODO: Type serializer oh god + [DataField("component")] + public string? Component; + + [DataField("mediumDistance"), ViewVariables(VVAccess.ReadWrite)] + public float MediumDistance = 16f; + + [DataField("closeDistance"), ViewVariables(VVAccess.ReadWrite)] + public float CloseDistance = 8f; + + [DataField("reachedDistance"), ViewVariables(VVAccess.ReadWrite)] + public float ReachedDistance = 1f; + /// - /// Displays a sprite on the item that points towards the target component. + /// Pinpointer arrow precision in radians. /// - [RegisterComponent] - [NetworkedComponent] - [Access(typeof(SharedPinpointerSystem))] - public sealed class PinpointerComponent : Component - { - // TODO: Type serializer oh god - [DataField("component")] - public string? Component; + [DataField("precision"), ViewVariables(VVAccess.ReadWrite)] + public double Precision = 0.09; - [DataField("mediumDistance")] - public float MediumDistance = 16f; + [ViewVariables] + public EntityUid? Target = null; - [DataField("closeDistance")] - public float CloseDistance = 8f; + [ViewVariables] + [AutoNetworkedField] + public bool IsActive = false; - [DataField("reachedDistance")] - public float ReachedDistance = 1f; + [ViewVariables] + [AutoNetworkedField] + public Angle ArrowAngle; - /// - /// Pinpointer arrow precision in radians. - /// - [DataField("precision")] - public double Precision = 0.09; + [ViewVariables] + [AutoNetworkedField] + public Distance DistanceToTarget = Distance.Unknown; - public EntityUid? Target = null; - public bool IsActive = false; - public Angle ArrowAngle; - public Distance DistanceToTarget = Distance.Unknown; - public bool HasTarget => DistanceToTarget != Distance.Unknown; - } - - [Serializable, NetSerializable] - public sealed class PinpointerComponentState : ComponentState - { - public bool IsActive; - public Angle ArrowAngle; - public Distance DistanceToTarget; - } - - [Serializable, NetSerializable] - public enum Distance : byte - { - Unknown, - Reached, - Close, - Medium, - Far - } + [ViewVariables] + public bool HasTarget => DistanceToTarget != Distance.Unknown; +} + +[Serializable, NetSerializable] +public enum Distance : byte +{ + Unknown, + Reached, + Close, + Medium, + Far } diff --git a/Content.Shared/Pinpointer/SharedPinpointerSystem.cs b/Content.Shared/Pinpointer/SharedPinpointerSystem.cs index 17e5de8cfd..5491e53dd2 100644 --- a/Content.Shared/Pinpointer/SharedPinpointerSystem.cs +++ b/Content.Shared/Pinpointer/SharedPinpointerSystem.cs @@ -1,86 +1,52 @@ -using Robust.Shared.GameStates; +namespace Content.Shared.Pinpointer; -namespace Content.Shared.Pinpointer +public abstract class SharedPinpointerSystem : EntitySystem { - public abstract class SharedPinpointerSystem : EntitySystem + /// + /// Manually set distance from pinpointer to target + /// + public void SetDistance(EntityUid uid, Distance distance, PinpointerComponent? pinpointer = null) { - public override void Initialize() - { - base.Initialize(); - SubscribeLocalEvent(GetCompState); - } + if (!Resolve(uid, ref pinpointer)) + return; - private void GetCompState(EntityUid uid, PinpointerComponent pinpointer, ref ComponentGetState args) - { - args.State = new PinpointerComponentState - { - IsActive = pinpointer.IsActive, - ArrowAngle = pinpointer.ArrowAngle, - DistanceToTarget = pinpointer.DistanceToTarget - }; - } + if (distance == pinpointer.DistanceToTarget) + return; - /// - /// Manually set distance from pinpointer to target - /// - public void SetDistance(EntityUid uid, Distance distance, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return; + pinpointer.DistanceToTarget = distance; + Dirty(pinpointer); + } - if (distance == pinpointer.DistanceToTarget) - return; + /// + /// Try to manually set pinpointer arrow direction. + /// If difference between current angle and new angle is smaller than + /// pinpointer precision, new value will be ignored and it will return false. + /// + public bool TrySetArrowAngle(EntityUid uid, Angle arrowAngle, PinpointerComponent? pinpointer = null) + { + if (!Resolve(uid, ref pinpointer)) + return false; - pinpointer.DistanceToTarget = distance; - Dirty(pinpointer); - } + if (pinpointer.ArrowAngle.EqualsApprox(arrowAngle, pinpointer.Precision)) + return false; - /// - /// Try to manually set pinpointer arrow direction. - /// If difference between current angle and new angle is smaller than - /// pinpointer precision, new value will be ignored and it will return false. - /// - public bool TrySetArrowAngle(EntityUid uid, Angle arrowAngle, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return false; + pinpointer.ArrowAngle = arrowAngle; + Dirty(pinpointer); - if (pinpointer.ArrowAngle.EqualsApprox(arrowAngle, pinpointer.Precision)) - return false; + return true; + } - pinpointer.ArrowAngle = arrowAngle; - Dirty(pinpointer); + /// + /// Activate/deactivate pinpointer screen. If it has target it will start tracking it. + /// + public void SetActive(EntityUid uid, bool isActive, PinpointerComponent? pinpointer = null) + { + if (!Resolve(uid, ref pinpointer)) + return; + if (isActive == pinpointer.IsActive) + return; - return true; - } - - /// - /// Activate/deactivate pinpointer screen. If it has target it will start tracking it. - /// - public void SetActive(EntityUid uid, bool isActive, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return; - if (isActive == pinpointer.IsActive) - return; - - pinpointer.IsActive = isActive; - Dirty(pinpointer); - } - - - /// - /// Toggle Pinpointer screen. If it has target it will start tracking it. - /// - /// True if pinpointer was activated, false otherwise - public bool TogglePinpointer(EntityUid uid, PinpointerComponent? pinpointer = null) - { - if (!Resolve(uid, ref pinpointer)) - return false; - - var isActive = !pinpointer.IsActive; - SetActive(uid, isActive, pinpointer); - return isActive; - } + pinpointer.IsActive = isActive; + Dirty(pinpointer); } } diff --git a/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml b/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml index 48682b4547..054bb26ea6 100644 --- a/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml +++ b/Resources/Prototypes/Entities/Objects/Devices/pinpointer.yml @@ -8,7 +8,6 @@ - type: Transform noRot: True - type: Sprite - netsync: false noRot: True sprite: Objects/Devices/pinpointer.rsi layers: @@ -16,10 +15,26 @@ map: ["enum.PinpointerLayers.Base"] - state: pinonnull map: ["enum.PinpointerLayers.Screen"] + shader: unshaded + visible: false - type: Item sprite: Objects/Devices/pinpointer.rsi - type: Pinpointer - type: Appearance + - type: GenericVisualizer + visuals: + enum.PinpointerVisuals.IsActive: + enum.PinpointerLayers.Screen: + True: { visible: True } + False: { visible: False } + enum.PinpointerVisuals.TargetDistance: + enum.PinpointerLayers.Screen: + Unknown: { state: pinonnull } + Reached: { state: pinondirect } + Close: { state: pinonclose } + Medium: { state: pinonmedium } + Far: { state: pinonfar } + - type: AnimationPlayer - type: entity name: pinpointer