Travelling pointing arrows, brains can no longer point (#24864)
* Decoupled from gravity, constant animation time, manual networking, cubic interpolation * Reduced overshoot * Implemented PointAttemptEvent, reacts with mobstate & sleeping * Brains can no longer point, PBs must be inside a chassis * Removed chassis check, made callback more obvious
This commit is contained in:
@@ -1,19 +1,12 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Pointing.Components;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Content.Client.Pointing.Components;
|
||||
[RegisterComponent]
|
||||
public sealed partial class PointingArrowComponent : SharedPointingArrowComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// How long it takes to go from the bottom of the animation to the top.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("animationTime")]
|
||||
public float AnimationTime = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// How far it goes in any direction.
|
||||
/// How far the arrow moves up and down during the floating phase.
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("offset")]
|
||||
|
||||
62
Content.Client/Pointing/PointingSystem.Visualizer.cs
Normal file
62
Content.Client/Pointing/PointingSystem.Visualizer.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Content.Client.Pointing.Components;
|
||||
using Content.Shared.Pointing;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Animations;
|
||||
using Robust.Shared.Animations;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Content.Client.Pointing;
|
||||
|
||||
public sealed partial class PointingSystem : SharedPointingSystem
|
||||
{
|
||||
[Dependency] private readonly AnimationPlayerSystem _animationPlayer = default!;
|
||||
|
||||
public void InitializeVisualizer()
|
||||
{
|
||||
SubscribeLocalEvent<PointingArrowComponent, AnimationCompletedEvent>(OnAnimationCompleted);
|
||||
}
|
||||
|
||||
private void OnAnimationCompleted(EntityUid uid, PointingArrowComponent component, AnimationCompletedEvent args)
|
||||
{
|
||||
if (args.Key == component.AnimationKey)
|
||||
_animationPlayer.Stop(uid, component.AnimationKey);
|
||||
}
|
||||
|
||||
private void BeginPointAnimation(EntityUid uid, Vector2 startPosition, Vector2 offset, string animationKey)
|
||||
{
|
||||
if (_animationPlayer.HasRunningAnimation(uid, animationKey))
|
||||
return;
|
||||
|
||||
var animation = new Animation
|
||||
{
|
||||
Length = PointDuration,
|
||||
AnimationTracks =
|
||||
{
|
||||
new AnimationTrackComponentProperty
|
||||
{
|
||||
ComponentType = typeof(SpriteComponent),
|
||||
Property = nameof(SpriteComponent.Offset),
|
||||
InterpolationMode = AnimationInterpolationMode.Cubic,
|
||||
KeyFrames =
|
||||
{
|
||||
// We pad here to prevent improper looping and tighten the overshoot, just a touch
|
||||
new AnimationTrackProperty.KeyFrame(startPosition, 0f),
|
||||
new AnimationTrackProperty.KeyFrame(Vector2.Lerp(startPosition, offset, 0.9f), PointKeyTimeMove),
|
||||
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeMove),
|
||||
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeMove),
|
||||
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(offset, PointKeyTimeHover),
|
||||
new AnimationTrackProperty.KeyFrame(Vector2.Zero, PointKeyTimeHover),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_animationPlayer.Play(uid, animation, animationKey);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,25 @@
|
||||
using Content.Client.Pointing.Components;
|
||||
using Content.Client.Gravity;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Content.Shared.Pointing;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Utility;
|
||||
using DrawDepth = Content.Shared.DrawDepth.DrawDepth;
|
||||
|
||||
namespace Content.Client.Pointing;
|
||||
|
||||
public sealed class PointingSystem : SharedPointingSystem
|
||||
public sealed partial class PointingSystem : SharedPointingSystem
|
||||
{
|
||||
[Dependency] private readonly MobStateSystem _mobState = default!;
|
||||
[Dependency] private readonly FloatingVisualizerSystem _floatingSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<GetVerbsEvent<Verb>>(AddPointingVerb);
|
||||
SubscribeLocalEvent<PointingArrowComponent, ComponentStartup>(OnArrowStartup);
|
||||
SubscribeLocalEvent<PointingArrowComponent, AnimationCompletedEvent>(OnArrowAnimation);
|
||||
SubscribeLocalEvent<RoguePointingArrowComponent, ComponentStartup>(OnRogueArrowStartup);
|
||||
}
|
||||
SubscribeLocalEvent<PointingArrowComponent, ComponentHandleState>(HandleCompState);
|
||||
|
||||
private void OnArrowAnimation(EntityUid uid, PointingArrowComponent component, AnimationCompletedEvent args)
|
||||
{
|
||||
_floatingSystem.FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime);
|
||||
InitializeVisualizer();
|
||||
}
|
||||
|
||||
private void AddPointingVerb(GetVerbsEvent<Verb> args)
|
||||
@@ -38,15 +31,11 @@ public sealed class PointingSystem : SharedPointingSystem
|
||||
// I'm just adding this verb exclusively to clients so that the verb-loading pop-in on the verb menu isn't
|
||||
// as bad. Important for this verb seeing as its usually an option on just about any entity.
|
||||
|
||||
// this is a pointing arrow. no pointing here...
|
||||
if (HasComp<PointingArrowComponent>(args.Target))
|
||||
{
|
||||
// this is a pointing arrow. no pointing here...
|
||||
return;
|
||||
}
|
||||
|
||||
// Can the user point? Checking mob state directly instead of some action blocker, as many action blockers are blocked for
|
||||
// ghosts and there is no obvious choice for pointing (unless ghosts CanEmote?).
|
||||
if (_mobState.IsIncapacitated(args.User))
|
||||
if (!CanPoint(args.User))
|
||||
return;
|
||||
|
||||
// We won't check in range or visibility, as this verb is currently only executable via the context menu,
|
||||
@@ -66,11 +55,9 @@ public sealed class PointingSystem : SharedPointingSystem
|
||||
private void OnArrowStartup(EntityUid uid, PointingArrowComponent component, ComponentStartup args)
|
||||
{
|
||||
if (TryComp<SpriteComponent>(uid, out var sprite))
|
||||
{
|
||||
sprite.DrawDepth = (int) DrawDepth.Overlays;
|
||||
}
|
||||
|
||||
_floatingSystem.FloatAnimation(uid, component.Offset, component.AnimationKey, component.AnimationTime);
|
||||
BeginPointAnimation(uid, component.StartPosition, component.Offset, component.AnimationKey);
|
||||
}
|
||||
|
||||
private void OnRogueArrowStartup(EntityUid uid, RoguePointingArrowComponent arrow, ComponentStartup args)
|
||||
@@ -81,4 +68,13 @@ public sealed class PointingSystem : SharedPointingSystem
|
||||
sprite.NoRotation = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleCompState(Entity<PointingArrowComponent> entity, ref ComponentHandleState args)
|
||||
{
|
||||
if (args.Current is not SharedPointingArrowComponentState state)
|
||||
return;
|
||||
|
||||
entity.Comp.StartPosition = state.StartPosition;
|
||||
entity.Comp.EndTime = state.EndTime;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user