diff --git a/Content.Client/Pointing/Components/PointingArrowComponent.cs b/Content.Client/Pointing/Components/PointingArrowComponent.cs
index cbc1527482..3c82e62588 100644
--- a/Content.Client/Pointing/Components/PointingArrowComponent.cs
+++ b/Content.Client/Pointing/Components/PointingArrowComponent.cs
@@ -1,12 +1,7 @@
using Content.Shared.Pointing.Components;
-using Robust.Client.GameObjects;
-using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
namespace Content.Client.Pointing.Components
{
[RegisterComponent]
- [ComponentReference(typeof(SharedPointingArrowComponent))]
- public sealed class PointingArrowComponent : SharedPointingArrowComponent
- {
- }
+ public sealed class PointingArrowComponent : SharedPointingArrowComponent {}
}
diff --git a/Content.Client/Pointing/PointingSystem.cs b/Content.Client/Pointing/PointingSystem.cs
index 2cc4a2b5bc..53082c3d27 100644
--- a/Content.Client/Pointing/PointingSystem.cs
+++ b/Content.Client/Pointing/PointingSystem.cs
@@ -2,23 +2,66 @@ using Content.Client.Pointing.Components;
using Content.Shared.MobState.EntitySystems;
using Content.Shared.Pointing;
using Content.Shared.Verbs;
+using Robust.Client.Animations;
using Robust.Client.GameObjects;
+using Robust.Shared.Animations;
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
namespace Content.Client.Pointing;
-public sealed class PointingSystem : EntitySystem
+public sealed class PointingSystem : SharedPointingSystem
{
+ [Dependency] private readonly AnimationPlayerSystem _player = default!;
[Dependency] private readonly SharedMobStateSystem _mobState = default!;
+ private const string AnimationKey = "pointingarrow";
+
+ ///
+ /// How far it goes in any direction.
+ ///
+ private const float Offset = 0.25f;
+
+ ///
+ /// How long it takes to go from the bottom of the animation to the top.
+ ///
+ private const float UpTime = 0.5f;
+
+ ///
+ /// Starts at the bottom then goes up and comes back down. Seems to look nicer than starting in the middle.
+ ///
+ private static readonly Animation PointingAnimation = new Animation()
+ {
+ Length = TimeSpan.FromSeconds(2 * UpTime),
+ AnimationTracks =
+ {
+ new AnimationTrackComponentProperty()
+ {
+ ComponentType = typeof(SpriteComponent),
+ Property = nameof(SpriteComponent.Offset),
+ InterpolationMode = AnimationInterpolationMode.Linear,
+ KeyFrames =
+ {
+ new AnimationTrackProperty.KeyFrame(Vector2.Zero, 0f),
+ new AnimationTrackProperty.KeyFrame(new Vector2(0f, Offset), UpTime),
+ new AnimationTrackProperty.KeyFrame(Vector2.Zero, UpTime),
+ }
+ }
+ }
+ };
+
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent>(AddPointingVerb);
SubscribeLocalEvent(OnArrowStartup);
+ SubscribeLocalEvent(OnArrowAnimation);
SubscribeLocalEvent(OnRogueArrowStartup);
+ }
+ private void OnArrowAnimation(EntityUid uid, PointingArrowComponent component, AnimationCompletedEvent args)
+ {
+ _player.Play(uid, PointingAnimation, AnimationKey);
}
private void AddPointingVerb(GetVerbsEvent args)
@@ -58,6 +101,8 @@ public sealed class PointingSystem : EntitySystem
{
sprite.DrawDepth = (int) DrawDepth.Overlays;
}
+
+ _player.Play(uid, PointingAnimation, AnimationKey);
}
private void OnRogueArrowStartup(EntityUid uid, RoguePointingArrowComponent arrow, ComponentStartup args)
@@ -65,6 +110,7 @@ public sealed class PointingSystem : EntitySystem
if (EntityManager.TryGetComponent(uid, out SpriteComponent? sprite))
{
sprite.DrawDepth = (int) DrawDepth.Overlays;
+ sprite.NoRotation = false;
}
}
}
diff --git a/Content.Client/Pointing/RoguePointingArrowVisualizer.cs b/Content.Client/Pointing/RoguePointingArrowVisualizer.cs
deleted file mode 100644
index fe8e359563..0000000000
--- a/Content.Client/Pointing/RoguePointingArrowVisualizer.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-using System;
-using Content.Shared.Pointing.Components;
-using JetBrains.Annotations;
-using Robust.Client.Animations;
-using Robust.Client.GameObjects;
-using Robust.Shared.Animations;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Maths;
-
-namespace Content.Client.Pointing
-{
- [UsedImplicitly]
- public sealed class RoguePointingArrowVisualizer : AppearanceVisualizer
- {
- [Obsolete("Subscribe to AppearanceChangeEvent instead.")]
- public override void OnChangeData(AppearanceComponent component)
- {
- base.OnChangeData(component);
-
- if (component.TryGetData(RoguePointingArrowVisuals.Rotation, out var degrees))
- {
- SetRotation(component, Angle.FromDegrees(degrees));
- }
- }
-
- private void SetRotation(AppearanceComponent component, Angle rotation)
- {
- var sprite = IoCManager.Resolve().GetComponent(component.Owner);
-
- if (!IoCManager.Resolve().TryGetComponent(sprite.Owner, out AnimationPlayerComponent? animation))
- {
- sprite.Rotation = rotation;
- return;
- }
-
- if (animation.HasRunningAnimation("rotate"))
- {
- animation.Stop("rotate");
- }
-
- animation.Play(new Animation
- {
- Length = TimeSpan.FromSeconds(0.125),
- AnimationTracks =
- {
- new AnimationTrackComponentProperty
- {
- ComponentType = typeof(ISpriteComponent),
- Property = nameof(ISpriteComponent.Rotation),
- InterpolationMode = AnimationInterpolationMode.Linear,
- KeyFrames =
- {
- new AnimationTrackProperty.KeyFrame(sprite.Rotation, 0),
- new AnimationTrackProperty.KeyFrame(rotation, 0.125f)
- }
- }
- }
- }, "rotate");
- }
- }
-}
diff --git a/Content.Server/Pointing/Components/PointingArrowComponent.cs b/Content.Server/Pointing/Components/PointingArrowComponent.cs
index 34e4178447..309440aea1 100644
--- a/Content.Server/Pointing/Components/PointingArrowComponent.cs
+++ b/Content.Server/Pointing/Components/PointingArrowComponent.cs
@@ -1,84 +1,18 @@
+using Content.Server.Pointing.EntitySystems;
using Content.Shared.Pointing.Components;
-using Robust.Server.GameObjects;
-using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
namespace Content.Server.Pointing.Components
{
[RegisterComponent]
- [ComponentReference(typeof(SharedPointingArrowComponent))]
+ [Access(typeof(PointingSystem))]
public sealed class PointingArrowComponent : SharedPointingArrowComponent
{
- [Dependency] private readonly IEntityManager _entMan = default!;
-
- ///
- /// The current amount of seconds left on this arrow.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("duration")]
- private float _duration = 4;
-
- ///
- /// The amount of seconds before the arrow changes movement direction.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("step")]
- private float _step = 0.5f;
-
- ///
- /// The amount of units that this arrow will move by when multiplied
- /// by the frame time.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- [DataField("speed")]
- private float _speed = 1;
-
- ///
- /// The current amount of seconds left before the arrow changes
- /// movement direction.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- private float _currentStep;
-
- ///
- /// Whether or not this arrow is currently going up.
- ///
- [ViewVariables(VVAccess.ReadWrite)]
- private bool _up;
-
///
/// Whether or not this arrow will convert into a
/// when its duration runs out.
///
[ViewVariables(VVAccess.ReadWrite)]
[DataField("rogue")]
- public bool Rogue = false;
-
- public void Update(float frameTime)
- {
- var movement = _speed * frameTime * (_up ? 1 : -1);
- _entMan.GetComponent(Owner).LocalPosition += (0, movement);
-
- _duration -= frameTime;
- _currentStep -= frameTime;
-
- if (_duration <= 0)
- {
- if (Rogue)
- {
- _entMan.RemoveComponent(Owner);
- _entMan.AddComponent(Owner);
- return;
- }
-
- _entMan.DeleteEntity(Owner);
- return;
- }
-
- if (_currentStep <= 0)
- {
- _currentStep = _step;
- _up ^= true;
- }
- }
+ public bool Rogue;
}
}
diff --git a/Content.Server/Pointing/EntitySystems/PointingSystem.cs b/Content.Server/Pointing/EntitySystems/PointingSystem.cs
index c7d09fe9a5..2dcbcd248d 100644
--- a/Content.Server/Pointing/EntitySystems/PointingSystem.cs
+++ b/Content.Server/Pointing/EntitySystems/PointingSystem.cs
@@ -24,7 +24,7 @@ using Robust.Shared.Timing;
namespace Content.Server.Pointing.EntitySystems
{
[UsedImplicitly]
- internal sealed class PointingSystem : EntitySystem
+ internal sealed class PointingSystem : SharedPointingSystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
@@ -128,7 +128,12 @@ namespace Content.Server.Pointing.EntitySystems
_rotateToFaceSystem.TryFaceCoordinates(player, mapCoords.Position);
- var arrow = EntityManager.SpawnEntity("pointingarrow", mapCoords);
+ var arrow = EntityManager.SpawnEntity("PointingArrow", mapCoords);
+
+ if (TryComp(arrow, out var pointing))
+ {
+ pointing.EndTime = _gameTiming.CurTime + TimeSpan.FromSeconds(4);
+ }
if (EntityQuery().FirstOrDefault() != null)
{
@@ -231,10 +236,28 @@ namespace Content.Server.Pointing.EntitySystems
public override void Update(float frameTime)
{
- foreach (var component in EntityManager.EntityQuery(true))
+ var currentTime = _gameTiming.CurTime;
+
+ foreach (var component in EntityQuery(true))
{
- component.Update(frameTime);
+ Update(component, currentTime);
}
}
+
+ private void Update(PointingArrowComponent component, TimeSpan currentTime)
+ {
+ // TODO: That pause PR
+ if (component.EndTime > currentTime)
+ return;
+
+ if (component.Rogue)
+ {
+ RemComp(component.Owner);
+ EnsureComp(component.Owner);
+ return;
+ }
+
+ Del(component.Owner);
+ }
}
}
diff --git a/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs b/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs
index d7439c5157..45ccb0cefb 100644
--- a/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs
+++ b/Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs
@@ -61,7 +61,7 @@ namespace Content.Server.Pointing.EntitySystems
if (component.Chasing is not {Valid: true} chasing || Deleted(chasing))
{
EntityManager.QueueDeleteEntity(uid);
- return;
+ continue;
}
component.TurningDelay -= frameTime;
@@ -73,10 +73,10 @@ namespace Content.Server.Pointing.EntitySystems
var adjusted = angle.Degrees + 90;
var newAngle = Angle.FromDegrees(adjusted);
- transform.LocalRotation = newAngle;
+ transform.WorldRotation = newAngle;
UpdateAppearance(uid, component, transform);
- return;
+ continue;
}
transform.WorldRotation += Angle.FromDegrees(20);
@@ -91,8 +91,10 @@ namespace Content.Server.Pointing.EntitySystems
if (component.ChasingTime > 0)
{
- return;
+ continue;
}
+
+
_explosion.QueueExplosion(uid, ExplosionSystem.DefaultExplosionPrototypeId, 50, 3, 10);
EntityManager.QueueDeleteEntity(uid);
}
diff --git a/Content.Shared/Pointing/Components/SharedPointingArrowComponent.cs b/Content.Shared/Pointing/Components/SharedPointingArrowComponent.cs
index 615f93ee6c..09b5157aa5 100644
--- a/Content.Shared/Pointing/Components/SharedPointingArrowComponent.cs
+++ b/Content.Shared/Pointing/Components/SharedPointingArrowComponent.cs
@@ -1,5 +1,13 @@
+using Robust.Shared.GameStates;
+
namespace Content.Shared.Pointing.Components;
+[NetworkedComponent]
public abstract class SharedPointingArrowComponent : Component
{
+ ///
+ /// When the pointing arrow ends
+ ///
+ [ViewVariables(VVAccess.ReadWrite), DataField("endTime")]
+ public TimeSpan EndTime;
}
diff --git a/Content.Shared/Pointing/Components/SharedRoguePointingArrowComponent.cs b/Content.Shared/Pointing/Components/SharedRoguePointingArrowComponent.cs
index e54892c86b..4d6de3a90d 100644
--- a/Content.Shared/Pointing/Components/SharedRoguePointingArrowComponent.cs
+++ b/Content.Shared/Pointing/Components/SharedRoguePointingArrowComponent.cs
@@ -1,13 +1,15 @@
-using Robust.Shared.Serialization;
+using Robust.Shared.GameStates;
+using Robust.Shared.Serialization;
namespace Content.Shared.Pointing.Components
{
+ [NetworkedComponent]
public abstract class SharedRoguePointingArrowComponent : Component
{
}
[Serializable, NetSerializable]
- public enum RoguePointingArrowVisuals
+ public enum RoguePointingArrowVisuals : byte
{
Rotation
}
diff --git a/Content.Shared/Pointing/SharedPointingSystem.cs b/Content.Shared/Pointing/SharedPointingSystem.cs
new file mode 100644
index 0000000000..05e4b4aa27
--- /dev/null
+++ b/Content.Shared/Pointing/SharedPointingSystem.cs
@@ -0,0 +1,17 @@
+using Robust.Shared.Serialization;
+
+namespace Content.Shared.Pointing;
+
+public abstract class SharedPointingSystem : EntitySystem
+{
+ [Serializable, NetSerializable]
+ protected sealed class PointingArrowComponentState : ComponentState
+ {
+ public TimeSpan EndTime;
+
+ public PointingArrowComponentState(TimeSpan endTime)
+ {
+ EndTime = endTime;
+ }
+ }
+}
diff --git a/Resources/Prototypes/Entities/Markers/pointing.yml b/Resources/Prototypes/Entities/Markers/pointing.yml
index fe94471bbf..de0f7057d3 100644
--- a/Resources/Prototypes/Entities/Markers/pointing.yml
+++ b/Resources/Prototypes/Entities/Markers/pointing.yml
@@ -1,6 +1,6 @@
- type: entity
name: pointing arrow
- id: pointingarrow
+ id: PointingArrow
save: false
components:
- type: Tag
@@ -11,10 +11,9 @@
sprite: Interface/Misc/pointing.rsi
state: pointing
drawDepth: Overlays
+ noRot: true
- type: PointingArrow
duration: 4
step: 0.5
speed: 1
- type: Appearance
- visuals:
- - type: RoguePointingArrowVisualizer