| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- using System.Numerics;
- using Content.Client.Animations;
- using Content.Client.Weapons.Melee.Components;
- using Content.Shared.Weapons.Melee;
- using Robust.Client.Animations;
- using Robust.Client.GameObjects;
- using Robust.Shared.Animations;
- using Robust.Shared.Map;
- namespace Content.Client.Weapons.Melee;
- public sealed partial class MeleeWeaponSystem
- {
- private const string FadeAnimationKey = "melee-fade";
- private const string SlashAnimationKey = "melee-slash";
- private const string ThrustAnimationKey = "melee-thrust";
- /// <summary>
- /// Does all of the melee effects for a player that are predicted, i.e. character lunge and weapon animation.
- /// </summary>
- public override void DoLunge(EntityUid user, EntityUid weapon, Angle angle, Vector2 localPos, string? animation, bool predicted = true)
- {
- if (!Timing.IsFirstTimePredicted)
- return;
- var lunge = GetLungeAnimation(localPos);
- // Stop any existing lunges on the user.
- _animation.Stop(user, MeleeLungeKey);
- _animation.Play(user, lunge, MeleeLungeKey);
- if (localPos == Vector2.Zero || animation == null)
- return;
- if (!_xformQuery.TryGetComponent(user, out var userXform) || userXform.MapID == MapId.Nullspace)
- return;
- var animationUid = Spawn(animation, userXform.Coordinates);
- if (!TryComp<SpriteComponent>(animationUid, out var sprite)
- || !TryComp<WeaponArcVisualsComponent>(animationUid, out var arcComponent))
- {
- return;
- }
- var spriteRotation = Angle.Zero;
- if (arcComponent.Animation != WeaponArcAnimation.None
- && TryComp(weapon, out MeleeWeaponComponent? meleeWeaponComponent))
- {
- if (user != weapon
- && TryComp(weapon, out SpriteComponent? weaponSpriteComponent))
- sprite.CopyFrom(weaponSpriteComponent);
- spriteRotation = meleeWeaponComponent.WideAnimationRotation;
- if (meleeWeaponComponent.SwingLeft)
- angle *= -1;
- }
- sprite.Rotation = localPos.ToWorldAngle();
- var distance = Math.Clamp(localPos.Length() / 2f, 0.2f, 1f);
- var xform = _xformQuery.GetComponent(animationUid);
- TrackUserComponent track;
- switch (arcComponent.Animation)
- {
- case WeaponArcAnimation.Slash:
- track = EnsureComp<TrackUserComponent>(animationUid);
- track.User = user;
- _animation.Play(animationUid, GetSlashAnimation(sprite, angle, spriteRotation), SlashAnimationKey);
- if (arcComponent.Fadeout)
- _animation.Play(animationUid, GetFadeAnimation(sprite, 0.065f, 0.065f + 0.05f), FadeAnimationKey);
- break;
- case WeaponArcAnimation.Thrust:
- track = EnsureComp<TrackUserComponent>(animationUid);
- track.User = user;
- _animation.Play(animationUid, GetThrustAnimation(sprite, distance, spriteRotation), ThrustAnimationKey);
- if (arcComponent.Fadeout)
- _animation.Play(animationUid, GetFadeAnimation(sprite, 0.05f, 0.15f), FadeAnimationKey);
- break;
- case WeaponArcAnimation.None:
- var (mapPos, mapRot) = TransformSystem.GetWorldPositionRotation(userXform);
- var worldPos = mapPos + (mapRot - userXform.LocalRotation).RotateVec(localPos);
- var newLocalPos = Vector2.Transform(worldPos, TransformSystem.GetInvWorldMatrix(xform.ParentUid));
- TransformSystem.SetLocalPositionNoLerp(animationUid, newLocalPos, xform);
- if (arcComponent.Fadeout)
- _animation.Play(animationUid, GetFadeAnimation(sprite, 0f, 0.15f), FadeAnimationKey);
- break;
- }
- }
- private Animation GetSlashAnimation(SpriteComponent sprite, Angle arc, Angle spriteRotation)
- {
- const float slashStart = 0.03f;
- const float slashEnd = 0.065f;
- const float length = slashEnd + 0.05f;
- var startRotation = sprite.Rotation + arc / 2;
- var endRotation = sprite.Rotation - arc / 2;
- var startRotationOffset = startRotation.RotateVec(new Vector2(0f, -1f));
- var endRotationOffset = endRotation.RotateVec(new Vector2(0f, -1f));
- startRotation += spriteRotation;
- endRotation += spriteRotation;
- return new Animation()
- {
- Length = TimeSpan.FromSeconds(length),
- AnimationTracks =
- {
- new AnimationTrackComponentProperty()
- {
- ComponentType = typeof(SpriteComponent),
- Property = nameof(SpriteComponent.Rotation),
- KeyFrames =
- {
- new AnimationTrackProperty.KeyFrame(startRotation, 0f),
- new AnimationTrackProperty.KeyFrame(startRotation, slashStart),
- new AnimationTrackProperty.KeyFrame(endRotation, slashEnd)
- }
- },
- new AnimationTrackComponentProperty()
- {
- ComponentType = typeof(SpriteComponent),
- Property = nameof(SpriteComponent.Offset),
- KeyFrames =
- {
- new AnimationTrackProperty.KeyFrame(startRotationOffset, 0f),
- new AnimationTrackProperty.KeyFrame(startRotationOffset, slashStart),
- new AnimationTrackProperty.KeyFrame(endRotationOffset, slashEnd)
- }
- },
- }
- };
- }
- private Animation GetThrustAnimation(SpriteComponent sprite, float distance, Angle spriteRotation)
- {
- const float thrustEnd = 0.05f;
- const float length = 0.15f;
- var startOffset = sprite.Rotation.RotateVec(new Vector2(0f, -distance / 5f));
- var endOffset = sprite.Rotation.RotateVec(new Vector2(0f, -distance));
- sprite.Rotation += spriteRotation;
- return new Animation()
- {
- Length = TimeSpan.FromSeconds(length),
- AnimationTracks =
- {
- new AnimationTrackComponentProperty()
- {
- ComponentType = typeof(SpriteComponent),
- Property = nameof(SpriteComponent.Offset),
- KeyFrames =
- {
- new AnimationTrackProperty.KeyFrame(startOffset, 0f),
- new AnimationTrackProperty.KeyFrame(endOffset, thrustEnd),
- new AnimationTrackProperty.KeyFrame(endOffset, length),
- }
- },
- }
- };
- }
- private Animation GetFadeAnimation(SpriteComponent sprite, float start, float end)
- {
- return new Animation
- {
- Length = TimeSpan.FromSeconds(end),
- AnimationTracks =
- {
- new AnimationTrackComponentProperty()
- {
- ComponentType = typeof(SpriteComponent),
- Property = nameof(SpriteComponent.Color),
- KeyFrames =
- {
- new AnimationTrackProperty.KeyFrame(sprite.Color, start),
- new AnimationTrackProperty.KeyFrame(sprite.Color.WithAlpha(0f), end)
- }
- }
- }
- };
- }
- /// <summary>
- /// Get the sprite offset animation to use for mob lunges.
- /// </summary>
- private Animation GetLungeAnimation(Vector2 direction)
- {
- const float length = 0.1f;
- return new Animation
- {
- Length = TimeSpan.FromSeconds(length),
- AnimationTracks =
- {
- new AnimationTrackComponentProperty()
- {
- ComponentType = typeof(SpriteComponent),
- Property = nameof(SpriteComponent.Offset),
- InterpolationMode = AnimationInterpolationMode.Linear,
- KeyFrames =
- {
- new AnimationTrackProperty.KeyFrame(direction.Normalized() * 0.15f, 0f),
- new AnimationTrackProperty.KeyFrame(Vector2.Zero, length)
- }
- }
- }
- };
- }
- /// <summary>
- /// Updates the effect positions to follow the user
- /// </summary>
- private void UpdateEffects()
- {
- var query = EntityQueryEnumerator<TrackUserComponent, TransformComponent>();
- while (query.MoveNext(out var uid, out var arcComponent, out var xform))
- {
- if (arcComponent.User == null)
- continue;
- Vector2 targetPos = TransformSystem.GetWorldPosition(arcComponent.User.Value);
- if (arcComponent.Offset != Vector2.Zero)
- {
- var entRotation = TransformSystem.GetWorldRotation(xform);
- targetPos += entRotation.RotateVec(arcComponent.Offset);
- }
- TransformSystem.SetWorldPosition(uid, targetPos);
- }
- }
- }
|