From e3f5ec25e3b9e10fde5f39ee318a19b4aba37c8f Mon Sep 17 00:00:00 2001 From: Cinka Date: Sat, 24 Feb 2024 16:37:40 +0300 Subject: [PATCH] - add: shared animation --- .../Animation/SharebleAnimationSystem.cs | 99 +++++++++++++++++++ .../_Amour/Vibrator/VibratorSystem.cs | 4 +- .../Animation/SharebleAnimationSystem.cs | 38 +++++++ .../_Amour/InteractionPanel/Interactions.cs | 44 ++++++++- .../_Amour/Animation/AnimationData.cs | 28 ++++++ .../_Amour/Animation/AnimationMessages.cs | 32 ++++++ .../_Amour/Animation/AnimationPrototype.cs | 10 ++ .../_Amour/Animation/SharedAnimationSystem.cs | 27 +++++ .../Prototypes/Entities/Mobs/Species/base.yml | 2 +- .../_Amour/AnimationTracks/meow.yml | 28 ++++++ .../_Amour/Interactions/interaction.yml | 4 +- 11 files changed, 306 insertions(+), 10 deletions(-) create mode 100644 Content.Client/_Amour/Animation/SharebleAnimationSystem.cs create mode 100644 Content.Server/_Amour/Animation/SharebleAnimationSystem.cs create mode 100644 Content.Shared/_Amour/Animation/AnimationData.cs create mode 100644 Content.Shared/_Amour/Animation/AnimationMessages.cs create mode 100644 Content.Shared/_Amour/Animation/AnimationPrototype.cs create mode 100644 Content.Shared/_Amour/Animation/SharedAnimationSystem.cs create mode 100644 Resources/Prototypes/_Amour/AnimationTracks/meow.yml diff --git a/Content.Client/_Amour/Animation/SharebleAnimationSystem.cs b/Content.Client/_Amour/Animation/SharebleAnimationSystem.cs new file mode 100644 index 0000000000..8c896bbed0 --- /dev/null +++ b/Content.Client/_Amour/Animation/SharebleAnimationSystem.cs @@ -0,0 +1,99 @@ +using System.Linq; +using Content.Client.Light.Components; +using Content.Shared._Amour.Animation; +using Content.Shared._Amour.Hole; +using Content.Shared.Verbs; +using Robust.Client.Animations; +using Robust.Client.GameObjects; +using Robust.Shared.Animations; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization.Markdown.Value; +using Robust.Shared.Utility; + +namespace Content.Client._Amour.Animation; + +public sealed class SharebleAnimationSystem : SharedAnimationSystem +{ + [Dependency] private readonly AnimationPlayerSystem _animation = default!; + [Dependency] private readonly IComponentFactory _componentFactory = default!; + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + [Dependency] private readonly ISerializationManager _serializationManager = default!; + + public override void Initialize() + { + SubscribeNetworkEvent(OnStart); + SubscribeNetworkEvent(OnProtoStart); + } + + private void OnProtoStart(AnimationProtoStartMessage ev) + { + Play(GetEntity(ev.Owner),ev.ProtoId); + } + + private void OnStart(AnimationStartMessage ev) + { + Play(GetEntity(ev.Owner),ev.Data,ev.Id); + } + + public override void Play(EntityUid uid,ProtoId protoId) + { + if(!_prototypeManager.TryIndex(protoId, out var prototype)) + return; + + Play(uid, prototype, protoId); + } + + public override void Play(EntityUid uid,AnimationData data, string animationId = "funny") + { + if(_animation.HasRunningAnimation(uid,animationId)) + return; + + var animation = ParseAnimation(data); + _animation.Play(uid,animation,animationId); + } + + public Robust.Client.Animations.Animation ParseAnimation(AnimationData data) + { + var animation = new Robust.Client.Animations.Animation + { + Length = data.Length + }; + + foreach (var track in data.AnimationTracks) + { + var component = _componentFactory.GetComponent(track.ComponentType); + var componentType = component.GetType(); + var propertyType = AnimationHelper.GetAnimatableProperty(component, track.Property)?.GetType(); + + if (propertyType is null) + { + Logger.Error($"OH FUCK SEMPAI~~ PROPERTY FOR ANIMATION NOT FOUND: {track.Property} in component: {track.ComponentType}"); + continue; + } + + var property = new AnimationTrackComponentProperty() + { + ComponentType = componentType, + InterpolationMode = track.InterpolationMode, + Property = track.Property + }; + + + foreach (var key in track.KeyFrames) + { + var value = _serializationManager.Read(propertyType, new ValueDataNode(key.Value)); + if (value is null) + { + Logger.Error($"FUCK HARDER, SEMPAI~~ value not found: {key.Value}"); + continue; + } + + property.KeyFrames.Add(new AnimationTrackProperty.KeyFrame(value, key.KeyTime)); + } + animation.AnimationTracks.Add(property); + } + + return animation; + } +} diff --git a/Content.Client/_Amour/Vibrator/VibratorSystem.cs b/Content.Client/_Amour/Vibrator/VibratorSystem.cs index 55a284e9e7..a8f11c0be7 100644 --- a/Content.Client/_Amour/Vibrator/VibratorSystem.cs +++ b/Content.Client/_Amour/Vibrator/VibratorSystem.cs @@ -33,9 +33,9 @@ public sealed class VibratorSystem : SharedVibratorSystem } - private Animation GetAnimation() + private Robust.Client.Animations.Animation GetAnimation() { - return new Animation + return new Robust.Client.Animations.Animation { Length = TimeSpan.FromMilliseconds(100), AnimationTracks = diff --git a/Content.Server/_Amour/Animation/SharebleAnimationSystem.cs b/Content.Server/_Amour/Animation/SharebleAnimationSystem.cs new file mode 100644 index 0000000000..164b24d95a --- /dev/null +++ b/Content.Server/_Amour/Animation/SharebleAnimationSystem.cs @@ -0,0 +1,38 @@ +using Content.Shared._Amour.Animation; +using Content.Shared._Amour.Hole; +using Content.Shared.Verbs; +using Robust.Shared.Prototypes; + +namespace Content.Server._Amour.Animation; + +public sealed class SharebleAnimationSystem : SharedAnimationSystem +{ + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; + + public override void Initialize() + { + SubscribeLocalEvent>(OnVerb); + } + + private void OnVerb(EntityUid uid, HoleContainerComponent component, GetVerbsEvent args) + { + if(!_prototypeManager.TryIndex("meow",out var prototype)) + return; + + args.Verbs.Add(new Verb() + { + Text = "MEOW ABOUT IT", + Act = () => Play(uid, prototype) + }); + } + + public override void Play(EntityUid uid, ProtoId protoId) + { + RaiseNetworkEvent(new AnimationProtoStartMessage(GetNetEntity(uid),protoId)); + } + + public override void Play(EntityUid uid, AnimationData data, string animationId = "funny") + { + RaiseNetworkEvent(new AnimationStartMessage(GetNetEntity(uid),data,animationId)); + } +} diff --git a/Content.Server/_Amour/InteractionPanel/Interactions.cs b/Content.Server/_Amour/InteractionPanel/Interactions.cs index 890cf4d6f0..544ef22310 100644 --- a/Content.Server/_Amour/InteractionPanel/Interactions.cs +++ b/Content.Server/_Amour/InteractionPanel/Interactions.cs @@ -1,9 +1,15 @@ +using System.Numerics; +using Content.Server._Amour.Animation; +using Content.Shared._Amour.Animation; using Content.Shared._Amour.InteractionPanel; +using Content.Shared.Movement.Components; +using Robust.Shared.Animations; namespace Content.Server._Amour.InteractionPanel; public sealed class Interactions : EntitySystem { + [Dependency] private readonly SharebleAnimationSystem _animationSystem = default!; public override void Initialize() { SubscribeLocalEvent(OnBegin); @@ -15,8 +21,6 @@ public sealed class Interactions : EntitySystem if(args.Handled) return; - Logger.Debug(args.Id + " END"); - switch (args.Id) { @@ -28,11 +32,41 @@ public sealed class Interactions : EntitySystem if(args.Handled) return; - Logger.Debug(args.Id + " START"); - switch (args.Id) { - + case "SlapButt": + OnSlapButt(uid,component,args); + break; } } + + private void OnSlapButt(EntityUid uid, InteractionPanelComponent component, InteractionBeginningEvent args) + { + if(!TryComp(uid,out var moverComponent)) + return; + + var viewerRot = moverComponent.TargetRelativeRotation; + var rotation = (Transform(args.Performer).LocalRotation - viewerRot).ToWorldVec()*0.25f; + + + _animationSystem.Play(uid,new AnimationData() + { + Length = TimeSpan.FromSeconds(0.5), + AnimationTracks = + { + new AnimationTrackData() + { + ComponentType = "SpriteComponent", + Property = "Offset", + InterpolationMode = AnimationInterpolationMode.Cubic, + KeyFrames = + { + _animationSystem.KeyFrame(Vector2.Zero,0), + _animationSystem.KeyFrame(rotation,0.150f), + _animationSystem.KeyFrame(Vector2.Zero,0.250f) + } + } + } + }); + } } diff --git a/Content.Shared/_Amour/Animation/AnimationData.cs b/Content.Shared/_Amour/Animation/AnimationData.cs new file mode 100644 index 0000000000..899e090f17 --- /dev/null +++ b/Content.Shared/_Amour/Animation/AnimationData.cs @@ -0,0 +1,28 @@ +using Robust.Shared.Animations; +using Robust.Shared.Serialization; + +namespace Content.Shared._Amour.Animation; + +[DataDefinition,Serializable,NetSerializable,Virtual] +public partial class AnimationData +{ + [DataField] public TimeSpan Length; + [DataField] public List AnimationTracks; +} + +[DataDefinition, Serializable, NetSerializable] +public sealed partial class AnimationTrackData +{ + [DataField] public string ComponentType; + [DataField] public string Property; + [DataField] public AnimationInterpolationMode InterpolationMode; + [DataField] public List KeyFrames; +} + +[DataDefinition, Serializable, NetSerializable] +public sealed partial class AnimationKeyData +{ + [DataField] public string Value; + [DataField] public float KeyTime; +} + diff --git a/Content.Shared/_Amour/Animation/AnimationMessages.cs b/Content.Shared/_Amour/Animation/AnimationMessages.cs new file mode 100644 index 0000000000..78e273888d --- /dev/null +++ b/Content.Shared/_Amour/Animation/AnimationMessages.cs @@ -0,0 +1,32 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared._Amour.Animation; + +[Serializable,NetSerializable] +public sealed class AnimationProtoStartMessage : EntityEventArgs +{ + public NetEntity Owner; + public string ProtoId; + + public AnimationProtoStartMessage(NetEntity owner, string protoId) + { + Owner = owner; + ProtoId = protoId; + } +} + +[Serializable,NetSerializable] +public sealed class AnimationStartMessage : EntityEventArgs +{ + public NetEntity Owner; + public AnimationData Data; + public string Id; + + public AnimationStartMessage(NetEntity owner, AnimationData data, string id) + { + Owner = owner; + Data = data; + Id = id; + } +} diff --git a/Content.Shared/_Amour/Animation/AnimationPrototype.cs b/Content.Shared/_Amour/Animation/AnimationPrototype.cs new file mode 100644 index 0000000000..f6df720f50 --- /dev/null +++ b/Content.Shared/_Amour/Animation/AnimationPrototype.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared._Amour.Animation; + +[Prototype("animation"),Serializable,NetSerializable] +public sealed partial class AnimationPrototype : AnimationData, IPrototype +{ + [IdDataField] public string ID { get; private set; } = default!; +} diff --git a/Content.Shared/_Amour/Animation/SharedAnimationSystem.cs b/Content.Shared/_Amour/Animation/SharedAnimationSystem.cs new file mode 100644 index 0000000000..e4654e4615 --- /dev/null +++ b/Content.Shared/_Amour/Animation/SharedAnimationSystem.cs @@ -0,0 +1,27 @@ +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization.Manager; +using Robust.Shared.Serialization.Markdown.Value; + +namespace Content.Shared._Amour.Animation; + +public abstract class SharedAnimationSystem : EntitySystem +{ + [Dependency] private readonly ISerializationManager _serializationManager = default!; + + public virtual void Play(EntityUid uid,ProtoId protoId) + { + } + + public virtual void Play(EntityUid uid,AnimationData data, string animationId = "funny") + { + } + + public AnimationKeyData KeyFrame(object value, float keyTime) + { + return new AnimationKeyData() + { + KeyTime = keyTime, + Value = _serializationManager.WriteValueAs(value).Value + }; + } +} diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml index a09be229ff..21c6f369a2 100644 --- a/Resources/Prototypes/Entities/Mobs/Species/base.yml +++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml @@ -267,7 +267,7 @@ - type: Arousal - type: InteractionPanel actionPrototypes: - - basic + - SlapButt - type: entity save: false diff --git a/Resources/Prototypes/_Amour/AnimationTracks/meow.yml b/Resources/Prototypes/_Amour/AnimationTracks/meow.yml new file mode 100644 index 0000000000..48ce5cb7dc --- /dev/null +++ b/Resources/Prototypes/_Amour/AnimationTracks/meow.yml @@ -0,0 +1,28 @@ +- type: animation + id: meow + length: 1 + animationTracks: + - componentType: Sprite + property: Scale + interpolationMode: Linear + keyFrames: + - keyTime: 0 + value: 1,1 + - keyTime: 0.2 + value: 1.5,1.5 + - keyTime: 0.3 + value: 0.25,0.25 + - keyTime: 0.3 + value: 1,1 + - componentType: Sprite + property: Rotation + interpolationMode: Linear + keyFrames: + - keyTime: 0 + value: 15 + - keyTime: 0.2 + value: 45 + - keyTime: 0.3 + value: 90 + - keyTime: 0.3 + value: 0 diff --git a/Resources/Prototypes/_Amour/Interactions/interaction.yml b/Resources/Prototypes/_Amour/Interactions/interaction.yml index 7c9c134f65..58eaed9767 100644 --- a/Resources/Prototypes/_Amour/Interactions/interaction.yml +++ b/Resources/Prototypes/_Amour/Interactions/interaction.yml @@ -1,6 +1,6 @@ - type: interaction - id: basic + id: SlapButt checks: - !type:HasSmallDistance beginningMessages: - - шлёпает по попе + - interaction-butt-slap