Fix rotation visuals desync & appearance state spam (#23016)

* Fix rotation visuals desync

* :bucklemeup:

* A
This commit is contained in:
Leon Friedrich
2023-12-26 18:32:25 -05:00
committed by GitHub
parent 476ea14e8a
commit cf98300ba2
13 changed files with 106 additions and 69 deletions

View File

@@ -1,6 +1,7 @@
using Content.Client.Rotation; using Content.Client.Rotation;
using Content.Shared.Buckle; using Content.Shared.Buckle;
using Content.Shared.Buckle.Components; using Content.Shared.Buckle.Components;
using Content.Shared.Rotation;
using Content.Shared.Vehicle.Components; using Content.Shared.Vehicle.Components;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;
@@ -56,17 +57,15 @@ internal sealed class BuckleSystem : SharedBuckleSystem
if (!TryComp<RotationVisualsComponent>(uid, out var rotVisuals)) if (!TryComp<RotationVisualsComponent>(uid, out var rotVisuals))
return; return;
if (!Appearance.TryGetData<int>(uid, StrapVisuals.RotationAngle, out var angle, args.Component) || if (!Appearance.TryGetData<bool>(uid, BuckleVisuals.Buckled, out var buckled, args.Component) ||
!Appearance.TryGetData<bool>(uid, BuckleVisuals.Buckled, out var buckled, args.Component) ||
!buckled || !buckled ||
args.Sprite == null) args.Sprite == null)
{ {
_rotationVisualizerSystem.SetHorizontalAngle(uid, rotVisuals.DefaultRotation, rotVisuals); _rotationVisualizerSystem.SetHorizontalAngle((uid, rotVisuals), rotVisuals.DefaultRotation);
return; return;
} }
// Animate strapping yourself to something at a given angle // Animate strapping yourself to something at a given angle
_rotationVisualizerSystem.SetHorizontalAngle(uid, Angle.FromDegrees(angle), rotVisuals);
// TODO: Dump this when buckle is better // TODO: Dump this when buckle is better
_rotationVisualizerSystem.AnimateSpriteRotation(uid, args.Sprite, rotVisuals.HorizontalRotation, 0.125f); _rotationVisualizerSystem.AnimateSpriteRotation(uid, args.Sprite, rotVisuals.HorizontalRotation, 0.125f);
} }

View File

@@ -1,4 +1,5 @@
using Content.Shared.Chemistry; using Content.Shared.Chemistry;
using Content.Shared.Chemistry.Components;
using Content.Shared.Chemistry.Reagent; using Content.Shared.Chemistry.Reagent;
using Content.Shared.Rounding; using Content.Shared.Rounding;
using Robust.Client.GameObjects; using Robust.Client.GameObjects;

View File

@@ -5,29 +5,26 @@ using Robust.Shared.Animations;
namespace Content.Client.Rotation; namespace Content.Client.Rotation;
public sealed class RotationVisualizerSystem : VisualizerSystem<RotationVisualsComponent> public sealed class RotationVisualizerSystem : SharedRotationVisualsSystem
{ {
public void SetHorizontalAngle(EntityUid uid, Angle angle, RotationVisualsComponent? component = null)
[Dependency] private readonly AppearanceSystem _appearance = default!;
[Dependency] private readonly AnimationPlayerSystem _animation = default!;
public override void Initialize()
{ {
if (!Resolve(uid, ref component)) base.Initialize();
return;
if (component.HorizontalRotation.Equals(angle)) SubscribeLocalEvent<RotationVisualsComponent, AppearanceChangeEvent>(OnAppearanceChange);
return;
component.HorizontalRotation = angle;
Dirty(component);
} }
protected override void OnAppearanceChange(EntityUid uid, RotationVisualsComponent component, ref AppearanceChangeEvent args) private void OnAppearanceChange(EntityUid uid, RotationVisualsComponent component, ref AppearanceChangeEvent args)
{ {
base.OnAppearanceChange(uid, component, ref args);
if (args.Sprite == null) if (args.Sprite == null)
return; return;
// If not defined, defaults to standing. // If not defined, defaults to standing.
AppearanceSystem.TryGetData<RotationState>(uid, RotationVisuals.RotationState, out var state, args.Component); _appearance.TryGetData<RotationState>(uid, RotationVisuals.RotationState, out var state, args.Component);
switch (state) switch (state)
{ {
@@ -53,9 +50,9 @@ public sealed class RotationVisualizerSystem : VisualizerSystem<RotationVisualsC
var animationComp = EnsureComp<AnimationPlayerComponent>(uid); var animationComp = EnsureComp<AnimationPlayerComponent>(uid);
const string animationKey = "rotate"; const string animationKey = "rotate";
// Stop the current rotate animation and then start a new one // Stop the current rotate animation and then start a new one
if (AnimationSystem.HasRunningAnimation(animationComp, animationKey)) if (_animation.HasRunningAnimation(animationComp, animationKey))
{ {
AnimationSystem.Stop(animationComp, animationKey); _animation.Stop(animationComp, animationKey);
} }
var animation = new Animation var animation = new Animation
@@ -77,6 +74,6 @@ public sealed class RotationVisualizerSystem : VisualizerSystem<RotationVisualsC
} }
}; };
AnimationSystem.Play((uid, animationComp), animation, animationKey); _animation.Play((uid, animationComp), animation, animationKey);
} }
} }

View File

@@ -1,19 +0,0 @@
namespace Content.Client.Rotation;
[RegisterComponent]
public sealed partial class RotationVisualsComponent : Component
{
[DataField("defaultRotation")]
[ViewVariables(VVAccess.ReadOnly)]
public Angle DefaultRotation = Angle.FromDegrees(90);
[ViewVariables(VVAccess.ReadWrite)]
public Angle VerticalRotation = 0;
[DataField("horizontalRotation")]
[ViewVariables(VVAccess.ReadWrite)]
public Angle HorizontalRotation = Angle.FromDegrees(90);
[ViewVariables(VVAccess.ReadWrite)]
public float AnimationTime = 0.125f;
}

View File

@@ -0,0 +1,7 @@
using Content.Shared.Rotation;
namespace Content.Server.Rotation;
public sealed class RotationVisualsSystem : SharedRotationVisualsSystem
{
}

View File

@@ -357,6 +357,8 @@ public abstract partial class SharedBuckleSystem
if (TryComp<AppearanceComponent>(buckleUid, out var appearance)) if (TryComp<AppearanceComponent>(buckleUid, out var appearance))
Appearance.SetData(buckleUid, BuckleVisuals.Buckled, true, appearance); Appearance.SetData(buckleUid, BuckleVisuals.Buckled, true, appearance);
_rotationVisuals.SetHorizontalAngle(buckleUid, strapComp.Rotation);
ReAttach(buckleUid, strapUid, buckleComp, strapComp); ReAttach(buckleUid, strapUid, buckleComp, strapComp);
SetBuckledTo(buckleUid, strapUid, strapComp, buckleComp); SetBuckledTo(buckleUid, strapUid, strapComp, buckleComp);
// TODO user is currently set to null because if it isn't the sound fails to play in some situations, fix that // TODO user is currently set to null because if it isn't the sound fails to play in some situations, fix that
@@ -471,6 +473,7 @@ public abstract partial class SharedBuckleSystem
if (TryComp(buckleUid, out AppearanceComponent? appearance)) if (TryComp(buckleUid, out AppearanceComponent? appearance))
Appearance.SetData(buckleUid, BuckleVisuals.Buckled, false, appearance); Appearance.SetData(buckleUid, BuckleVisuals.Buckled, false, appearance);
_rotationVisuals.ResetHorizontalAngle(buckleUid);
if (TryComp<MobStateComponent>(buckleUid, out var mobState) if (TryComp<MobStateComponent>(buckleUid, out var mobState)
&& _mobState.IsIncapacitated(buckleUid, mobState) && _mobState.IsIncapacitated(buckleUid, mobState)

View File

@@ -5,6 +5,7 @@ using Content.Shared.Destructible;
using Content.Shared.DragDrop; using Content.Shared.DragDrop;
using Content.Shared.Foldable; using Content.Shared.Foldable;
using Content.Shared.Interaction; using Content.Shared.Interaction;
using Content.Shared.Rotation;
using Content.Shared.Storage; using Content.Shared.Storage;
using Content.Shared.Verbs; using Content.Shared.Verbs;
using Robust.Shared.Containers; using Robust.Shared.Containers;
@@ -13,6 +14,8 @@ namespace Content.Shared.Buckle;
public abstract partial class SharedBuckleSystem public abstract partial class SharedBuckleSystem
{ {
[Dependency] private readonly SharedRotationVisualsSystem _rotationVisuals = default!;
private void InitializeStrap() private void InitializeStrap()
{ {
SubscribeLocalEvent<StrapComponent, ComponentStartup>(OnStrapStartup); SubscribeLocalEvent<StrapComponent, ComponentStartup>(OnStrapStartup);
@@ -292,8 +295,6 @@ public abstract partial class SharedBuckleSystem
strapComp.OccupiedSize += buckleComp.Size; strapComp.OccupiedSize += buckleComp.Size;
Appearance.SetData(buckleUid, StrapVisuals.RotationAngle, strapComp.Rotation);
Appearance.SetData(strapUid, StrapVisuals.State, true); Appearance.SetData(strapUid, StrapVisuals.State, true);
Dirty(strapUid, strapComp); Dirty(strapUid, strapComp);

View File

@@ -1,7 +1,6 @@
using Content.Shared.Chemistry;
using Robust.Shared.Utility; using Robust.Shared.Utility;
namespace Content.Client.Chemistry.Visualizers namespace Content.Shared.Chemistry.Components
{ {
[RegisterComponent] [RegisterComponent]
public sealed partial class SolutionContainerVisualsComponent : Component public sealed partial class SolutionContainerVisualsComponent : Component

View File

@@ -228,8 +228,7 @@ public sealed partial class SolutionContainerSystem : EntitySystem
public void UpdateAppearance(EntityUid uid, Solution solution, public void UpdateAppearance(EntityUid uid, Solution solution,
AppearanceComponent? appearanceComponent = null) AppearanceComponent? appearanceComponent = null)
{ {
if (!EntityManager.EntityExists(uid) if (!HasComp<SolutionContainerVisualsComponent>(uid) || !Resolve(uid, ref appearanceComponent, false))
|| !Resolve(uid, ref appearanceComponent, false))
return; return;
_appearance.SetData(uid, SolutionContainerVisuals.FillFraction, solution.FillFraction, appearanceComponent); _appearance.SetData(uid, SolutionContainerVisuals.FillFraction, solution.FillFraction, appearanceComponent);

View File

@@ -0,0 +1,43 @@
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
namespace Content.Shared.Rotation;
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
public sealed partial class RotationVisualsComponent : Component
{
/// <summary>
/// Default value of <see cref="HorizontalRotation"/>
/// </summary>
[DataField]
public Angle DefaultRotation = Angle.FromDegrees(90);
[DataField]
public Angle VerticalRotation = 0;
[DataField, AutoNetworkedField]
public Angle HorizontalRotation = Angle.FromDegrees(90);
[DataField]
public float AnimationTime = 0.125f;
}
[Serializable, NetSerializable]
public enum RotationVisuals
{
RotationState
}
[Serializable, NetSerializable]
public enum RotationState
{
/// <summary>
/// Standing up. This is the default value.
/// </summary>
Vertical = 0,
/// <summary>
/// Laying down
/// </summary>
Horizontal,
}

View File

@@ -1,24 +0,0 @@
using Robust.Shared.Serialization;
namespace Content.Shared.Rotation
{
[Serializable, NetSerializable]
public enum RotationVisuals
{
RotationState
}
[Serializable, NetSerializable]
public enum RotationState
{
/// <summary>
/// Standing up. This is the default value.
/// </summary>
Vertical = 0,
/// <summary>
/// Laying down
/// </summary>
Horizontal,
}
}

View File

@@ -0,0 +1,29 @@
namespace Content.Shared.Rotation;
public abstract class SharedRotationVisualsSystem : EntitySystem
{
/// <summary>
/// Sets the rotation an entity will have when it is "horizontal"
/// </summary>
public void SetHorizontalAngle(Entity<RotationVisualsComponent?> ent, Angle angle)
{
if (!Resolve(ent, ref ent.Comp, false))
return;
if (ent.Comp.HorizontalRotation.Equals(angle))
return;
ent.Comp.HorizontalRotation = angle;
Dirty(ent);
}
/// <summary>
/// Resets the rotation an entity will have when it is "horizontal" back to it's default value.
/// </summary>
public void ResetHorizontalAngle(Entity<RotationVisualsComponent?> ent)
{
if (Resolve(ent, ref ent.Comp, false))
SetHorizontalAngle(ent, ent.Comp.DefaultRotation);
}
}

View File

@@ -74,6 +74,8 @@ public abstract partial class SharedVehicleSystem : EntitySystem
if (!vehicle.AutoAnimate) if (!vehicle.AutoAnimate)
continue; continue;
// Why is this updating appearance data every tick, instead of when it needs to be updated???
if (_mover.GetVelocityInput(mover).Sprinting == Vector2.Zero) if (_mover.GetVelocityInput(mover).Sprinting == Vector2.Zero)
{ {
UpdateAutoAnimate(uid, false); UpdateAutoAnimate(uid, false);