From c157d8168a295530d014e5af913d0f8d541dd069 Mon Sep 17 00:00:00 2001 From: Vonsant Date: Sun, 5 Jan 2025 15:31:21 +0300 Subject: [PATCH 1/2] flipflap --- .../Emoting/AnimatedEmotesSystem.cs | 124 ++++++++++++++++++ .../Chat/Systems/ChatSystem.Emote.cs | 2 +- .../Emoting/AnimatedEmotesSystem.cs | 29 ++++ .../Chat/Prototypes/EmotePrototype.cs | 5 + .../Emoting/AnimatedEmotesComponent.cs | 28 ++++ .../Emoting/SharedAnimatedEmotesSystem.cs | 18 +++ Resources/Locale/ru-RU/_corvaxnext/emotes.ftl | 7 + Resources/Prototypes/Entities/Mobs/base.yml | 1 + .../Prototypes/_CorvaxNext/Actions/emotes.yml | 66 ++++++++++ 9 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 Content.Client/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs create mode 100644 Content.Server/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs create mode 100644 Content.Shared/_CorvaxNext/Emoting/AnimatedEmotesComponent.cs create mode 100644 Content.Shared/_CorvaxNext/Emoting/SharedAnimatedEmotesSystem.cs create mode 100644 Resources/Locale/ru-RU/_corvaxnext/emotes.ftl create mode 100644 Resources/Prototypes/_CorvaxNext/Actions/emotes.yml diff --git a/Content.Client/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs b/Content.Client/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs new file mode 100644 index 00000000000..ff7487df76f --- /dev/null +++ b/Content.Client/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs @@ -0,0 +1,124 @@ +using Robust.Client.Animations; +using Robust.Shared.Animations; +using Robust.Shared.GameStates; +using Robust.Client.GameObjects; +using Content.Shared.Emoting; +using Content.Shared._CorvaxNext.Emoting; +using System.Numerics; +using Robust.Shared.Prototypes; +using Content.Shared.Chat.Prototypes; + +namespace Content.Client._CorvaxNext.Emoting; + +public sealed partial class AnimatedEmotesSystem : SharedAnimatedEmotesSystem +{ + [Dependency] private readonly AnimationPlayerSystem _anim = 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 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.Zero, 0f), + new AnimationTrackProperty.KeyFrame(Angle.FromDegrees(180), 0.25f), + new AnimationTrackProperty.KeyFrame(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); + } +} diff --git a/Content.Server/Chat/Systems/ChatSystem.Emote.cs b/Content.Server/Chat/Systems/ChatSystem.Emote.cs index fddf453ff06..c100e5ea630 100644 --- a/Content.Server/Chat/Systems/ChatSystem.Emote.cs +++ b/Content.Server/Chat/Systems/ChatSystem.Emote.cs @@ -210,7 +210,7 @@ private bool AllowedToUseEmote(EntityUid source, EmotePrototype emote) private void InvokeEmoteEvent(EntityUid uid, EmotePrototype proto) { var ev = new EmoteEvent(proto); - RaiseLocalEvent(uid, ref ev); + RaiseLocalEvent(uid, ref ev, true); // Corvax-Next-AnimateEmote } } diff --git a/Content.Server/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs b/Content.Server/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs new file mode 100644 index 00000000000..a16a5e6e413 --- /dev/null +++ b/Content.Server/_CorvaxNext/Emoting/AnimatedEmotesSystem.cs @@ -0,0 +1,29 @@ +using Robust.Shared.GameStates; +using Content.Server.Chat.Systems; +using Content.Shared.Chat.Prototypes; +using Content.Shared.Emoting; +using Content.Shared._CorvaxNext.Emoting; +using Robust.Shared.Prototypes; + +namespace Content.Server._CorvaxNext.Emoting; + +public sealed partial class AnimatedEmotesSystem : SharedAnimatedEmotesSystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnEmote); + } + + private void OnEmote(EntityUid uid, AnimatedEmotesComponent component, ref EmoteEvent args) + { + PlayEmoteAnimation(uid, component, args.Emote.ID); + } + + public void PlayEmoteAnimation(EntityUid uid, AnimatedEmotesComponent component, ProtoId prot) + { + component.Emote = prot; + Dirty(uid, component); + } +} diff --git a/Content.Shared/Chat/Prototypes/EmotePrototype.cs b/Content.Shared/Chat/Prototypes/EmotePrototype.cs index 7ee958ee6a7..114e6afe75d 100644 --- a/Content.Shared/Chat/Prototypes/EmotePrototype.cs +++ b/Content.Shared/Chat/Prototypes/EmotePrototype.cs @@ -68,6 +68,11 @@ public sealed partial class EmotePrototype : IPrototype /// [DataField] public HashSet ChatTriggers = new(); + + // Corvax-Next-AnimateEmote-Start + [DataField] + public object? Event = null; + // Corvax-Next-AnimateEmote-End } /// diff --git a/Content.Shared/_CorvaxNext/Emoting/AnimatedEmotesComponent.cs b/Content.Shared/_CorvaxNext/Emoting/AnimatedEmotesComponent.cs new file mode 100644 index 00000000000..753cee31fea --- /dev/null +++ b/Content.Shared/_CorvaxNext/Emoting/AnimatedEmotesComponent.cs @@ -0,0 +1,28 @@ +using Content.Shared.Chat.Prototypes; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared._CorvaxNext.Emoting; + +// use as a template +//[Serializable, NetSerializable, DataDefinition] public sealed partial class AnimationNameEmoteEvent : EntityEventArgs { } + +[Serializable, NetSerializable, DataDefinition] public sealed partial class AnimationFlipEmoteEvent : EntityEventArgs { } +[Serializable, NetSerializable, DataDefinition] public sealed partial class AnimationSpinEmoteEvent : EntityEventArgs { } +[Serializable, NetSerializable, DataDefinition] public sealed partial class AnimationJumpEmoteEvent : EntityEventArgs { } + +[RegisterComponent, NetworkedComponent] public sealed partial class AnimatedEmotesComponent : Component +{ + [DataField] public ProtoId? Emote; +} + +[Serializable, NetSerializable] public sealed partial class AnimatedEmotesComponentState : ComponentState +{ + public ProtoId? Emote; + + public AnimatedEmotesComponentState(ProtoId? emote) + { + Emote = emote; + } +} diff --git a/Content.Shared/_CorvaxNext/Emoting/SharedAnimatedEmotesSystem.cs b/Content.Shared/_CorvaxNext/Emoting/SharedAnimatedEmotesSystem.cs new file mode 100644 index 00000000000..f83892ed3fe --- /dev/null +++ b/Content.Shared/_CorvaxNext/Emoting/SharedAnimatedEmotesSystem.cs @@ -0,0 +1,18 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared._CorvaxNext.Emoting; + +public abstract class SharedAnimatedEmotesSystem : EntitySystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnGetState); + } + + private void OnGetState(Entity ent, ref ComponentGetState args) + { + args.State = new AnimatedEmotesComponentState(ent.Comp.Emote); + } +} diff --git a/Resources/Locale/ru-RU/_corvaxnext/emotes.ftl b/Resources/Locale/ru-RU/_corvaxnext/emotes.ftl new file mode 100644 index 00000000000..4494c552c2b --- /dev/null +++ b/Resources/Locale/ru-RU/_corvaxnext/emotes.ftl @@ -0,0 +1,7 @@ +chat-emote-name-flip = Сделать сальто +chat-emote-name-spin = Покрутиться +chat-emote-name-jump = Прыгнуть + +chat-emote-msg-flip = делает сальто! +chat-emote-msg-spin = вращается! +chat-emote-msg-jump = прыгает! diff --git a/Resources/Prototypes/Entities/Mobs/base.yml b/Resources/Prototypes/Entities/Mobs/base.yml index d1c6f878bdc..48c54318ac6 100644 --- a/Resources/Prototypes/Entities/Mobs/base.yml +++ b/Resources/Prototypes/Entities/Mobs/base.yml @@ -44,6 +44,7 @@ - type: TTS # Corvax-TTS - type: RequireProjectileTarget active: False + - type: AnimatedEmotes # Corvax-Next-AutoAnimate - type: entity save: false diff --git a/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml b/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml new file mode 100644 index 00000000000..6edfe10eeae --- /dev/null +++ b/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml @@ -0,0 +1,66 @@ +- type: emote + id: Flip + name: chat-emote-name-flip + chatMessages: ["chat-emote-msg-flip"] + chatTriggers: + - flip + - flips + - flipping + - does a flip + - do a flip + - backflip + - frontflip + - somersault + - cartwheel + - прыжок с переворотом + - кувырок + - сальто + - делает сальто + - сделал сальто + - делает сальтуху + - прыгает с переворотом + event: !type:AnimationFlipEmoteEvent + +- type: emote + id: Spin + name: chat-emote-name-spin + chatMessages: ["chat-emote-msg-spin"] + chatTriggers: + - spin + - spins + - spinning + - twirl + - twirls + - twirling + - rotates + - rotating + - вращается + - вращается на месте + - кружится + - кружится на месте + - вертится + - закручивается + event: !type:AnimationSpinEmoteEvent + +- type: emote + id: Jump + name: chat-emote-name-jump + chatMessages: ["chat-emote-msg-jump"] + chatTriggers: + - jump + - jumps + - jumping + - hops + - hopping + - leaps + - leaping + - bounce + - bounces + - bouncing + - прыгает + - прыгнул + - подпрыгнул + - прыгает вверх + - подскакивает + - скачет + event: !type:AnimationJumpEmoteEvent From 7efa5e5837bd53865badc6ed9b70db339862f3a4 Mon Sep 17 00:00:00 2001 From: Vonsant Date: Sun, 5 Jan 2025 15:36:54 +0300 Subject: [PATCH 2/2] jump --- Resources/Prototypes/_CorvaxNext/Actions/emotes.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml b/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml index 6edfe10eeae..5f69c48e7bc 100644 --- a/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml +++ b/Resources/Prototypes/_CorvaxNext/Actions/emotes.yml @@ -40,6 +40,7 @@ - кружится на месте - вертится - закручивается + - разворот event: !type:AnimationSpinEmoteEvent - type: emote @@ -63,4 +64,5 @@ - прыгает вверх - подскакивает - скачет + - прыжок event: !type:AnimationJumpEmoteEvent