using Robust.Client.Animations; using Robust.Shared.Animations; using Robust.Shared.GameStates; using Robust.Client.GameObjects; using Content.Shared.Emoting; using System.Numerics; using Robust.Shared.Prototypes; using Content.Shared.Chat.Prototypes; using Content.Shared.Rotation; namespace Content.Client.Emoting; public sealed partial class AnimatedEmotesSystem : SharedAnimatedEmotesSystem { [Dependency] private readonly AnimationPlayerSystem _anim = default!; [Dependency] private readonly AppearanceSystem _appearance = default!; [Dependency] private readonly IPrototypeManager _prot = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnHandleState); SubscribeLocalEvent(OnFlip); SubscribeLocalEvent(OnSpin); SubscribeLocalEvent(OnJump); } public void PlayEmote(EntityUid uid, Animation anim, string animationKey = "emoteAnimKeyId") { if (_anim.HasRunningAnimation(uid, animationKey)) return; _anim.Play(uid, anim, animationKey); } private void OnHandleState(EntityUid uid, AnimatedEmotesComponent component, ref ComponentHandleState args) { if (args.Current is not AnimatedEmotesComponentState state || !_prot.TryIndex(state.Emote, out var emote)) return; if (emote.Event != null) RaiseLocalEvent(uid, emote.Event); } private void OnFlip(Entity ent, ref AnimationFlipEmoteEvent args) { var angle = Angle.Zero; if (TryComp(ent, out var rotation)) { _appearance.TryGetData(ent, RotationVisuals.RotationState, out var state); angle = state switch { RotationState.Vertical => rotation.VerticalRotation, RotationState.Horizontal => rotation.HorizontalRotation, _ => Angle.Zero }; } var a = new Animation { Length = TimeSpan.FromMilliseconds(500), AnimationTracks = { new AnimationTrackComponentProperty { ComponentType = typeof(SpriteComponent), Property = nameof(SpriteComponent.Rotation), InterpolationMode = AnimationInterpolationMode.Linear, KeyFrames = { new AnimationTrackProperty.KeyFrame(angle, 0f), new AnimationTrackProperty.KeyFrame(angle + Angle.FromDegrees(180), 0.25f), new AnimationTrackProperty.KeyFrame(angle + Angle.FromDegrees(360), 0.25f), } } } }; PlayEmote(ent, a); } private void OnSpin(Entity ent, ref AnimationSpinEmoteEvent args) { var a = new Animation { Length = TimeSpan.FromMilliseconds(600), AnimationTracks = { new AnimationTrackComponentProperty { ComponentType = typeof(TransformComponent), Property = nameof(TransformComponent.LocalRotation), InterpolationMode = AnimationInterpolationMode.Linear, KeyFrames = { new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(0), 0f), new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(90), 0.075f), new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.075f), new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(270), 0.075f), new AnimationTrackProperty.KeyFrame(Angle.Zero, 0.075f), new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(90), 0.075f), new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.075f), new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(270), 0.075f), new AnimationTrackProperty.KeyFrame(Angle.Zero, 0.075f), } } } }; PlayEmote(ent, a, "emoteAnimSpin"); } private void OnJump(Entity ent, ref AnimationJumpEmoteEvent args) { var a = new Animation { Length = TimeSpan.FromMilliseconds(250), AnimationTracks = { new AnimationTrackComponentProperty { ComponentType = typeof(SpriteComponent), Property = nameof(SpriteComponent.Offset), InterpolationMode = AnimationInterpolationMode.Cubic, KeyFrames = { new AnimationTrackProperty.KeyFrame(Vector2.Zero, 0f), new AnimationTrackProperty.KeyFrame(new Vector2(0, .35f), 0.125f), new AnimationTrackProperty.KeyFrame(Vector2.Zero, 0.125f), } } } }; PlayEmote(ent, a); } }