Add sprite movement states (#22940)

* Add sprite movement states

Did it for borgs for reference for future implementations.

* Fix

* Fix prediction issue

* review
This commit is contained in:
metalgearsloth
2023-12-25 18:34:21 +11:00
committed by GitHub
parent 721a445bbd
commit 9a40cf81f5
13 changed files with 227 additions and 25 deletions

View File

@@ -4,6 +4,7 @@ using Content.Shared.Follower.Components;
using Content.Shared.Input;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Events;
using Robust.Shared.GameStates;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Player;
@@ -48,7 +49,8 @@ namespace Content.Shared.Movement.Systems
.Register<SharedMoverController>();
SubscribeLocalEvent<InputMoverComponent, ComponentInit>(OnInputInit);
SubscribeLocalEvent<InputMoverComponent, AfterAutoHandleStateEvent>(OnInputHandleState);
SubscribeLocalEvent<InputMoverComponent, ComponentGetState>(OnMoverGetState);
SubscribeLocalEvent<InputMoverComponent, ComponentHandleState>(OnMoverHandleState);
SubscribeLocalEvent<InputMoverComponent, EntParentChangedMessage>(OnInputParentChange);
SubscribeLocalEvent<AutoOrientComponent, EntParentChangedMessage>(OnAutoParentChange);
@@ -64,19 +66,76 @@ namespace Content.Shared.Movement.Systems
CameraRotationLocked = obj;
}
/// <summary>
/// Gets the buttons held with opposites cancelled out.
/// </summary>
public static MoveButtons GetNormalizedMovement(MoveButtons buttons)
{
var oldMovement = buttons;
if ((oldMovement & (MoveButtons.Left | MoveButtons.Right)) == (MoveButtons.Left | MoveButtons.Right))
{
oldMovement &= ~MoveButtons.Left;
oldMovement &= ~MoveButtons.Right;
}
if ((oldMovement & (MoveButtons.Up | MoveButtons.Down)) == (MoveButtons.Up | MoveButtons.Down))
{
oldMovement &= ~MoveButtons.Up;
oldMovement &= ~MoveButtons.Down;
}
return oldMovement;
}
protected void SetMoveInput(InputMoverComponent component, MoveButtons buttons)
{
if (component.HeldMoveButtons == buttons)
return;
// Relay the fact we had any movement event.
// TODO: Ideally we'd do these in a tick instead of out of sim.
var moveEvent = new MoveInputEvent(component.Owner, component, component.HeldMoveButtons);
component.HeldMoveButtons = buttons;
Dirty(component);
RaiseLocalEvent(component.Owner, ref moveEvent);
Dirty(component.Owner, component);
}
private void OnInputHandleState(EntityUid uid, InputMoverComponent component, ref AfterAutoHandleStateEvent args)
private void OnMoverHandleState(EntityUid uid, InputMoverComponent component, ComponentHandleState args)
{
if (args.Current is not InputMoverComponentState state)
return;
// Handle state
component.LerpTarget = state.LerpTarget;
component.RelativeRotation = state.RelativeRotation;
component.TargetRelativeRotation = state.TargetRelativeRotation;
component.CanMove = state.CanMove;
component.RelativeEntity = EnsureEntity<InputMoverComponent>(state.RelativeEntity, uid);
// Reset
component.LastInputTick = GameTick.Zero;
component.LastInputSubTick = 0;
if (component.HeldMoveButtons != state.HeldMoveButtons)
{
var moveEvent = new MoveInputEvent(uid, component, component.HeldMoveButtons);
component.HeldMoveButtons = state.HeldMoveButtons;
RaiseLocalEvent(uid, ref moveEvent);
}
}
private void OnMoverGetState(EntityUid uid, InputMoverComponent component, ref ComponentGetState args)
{
args.State = new InputMoverComponentState()
{
CanMove = component.CanMove,
RelativeEntity = GetNetEntity(component.RelativeEntity),
LerpTarget = component.LerpTarget,
HeldMoveButtons = component.HeldMoveButtons,
RelativeRotation = component.RelativeRotation,
TargetRelativeRotation = component.TargetRelativeRotation,
};
}
private void ShutdownInput()
@@ -260,11 +319,6 @@ namespace Content.Shared.Movement.Systems
if (!MoverQuery.TryGetComponent(entity, out var moverComp))
return;
// Relay the fact we had any movement event.
// TODO: Ideally we'd do these in a tick instead of out of sim.
var moveEvent = new MoveInputEvent(entity);
RaiseLocalEvent(entity, ref moveEvent);
// For stuff like "Moving out of locker" or the likes
// We'll relay a movement input to the parent.
if (_container.IsEntityInContainer(entity) &&
@@ -276,7 +330,7 @@ namespace Content.Shared.Movement.Systems
RaiseLocalEvent(xform.ParentUid, ref relayMoveEvent);
}
SetVelocityDirection(moverComp, dir, subTick, state);
SetVelocityDirection(entity, moverComp, dir, subTick, state);
}
private void OnInputInit(EntityUid uid, InputMoverComponent component, ComponentInit args)
@@ -308,7 +362,7 @@ namespace Content.Shared.Movement.Systems
if (moverComp == null) return;
SetSprinting(moverComp, subTick, walking);
SetSprinting(uid, moverComp, subTick, walking);
}
public (Vector2 Walking, Vector2 Sprinting) GetVelocityInput(InputMoverComponent mover)
@@ -359,7 +413,7 @@ namespace Content.Shared.Movement.Systems
/// composed into a single direction vector, <see cref="VelocityDir"/>. Enabling
/// opposite directions will cancel each other out, resulting in no direction.
/// </summary>
public void SetVelocityDirection(InputMoverComponent component, Direction direction, ushort subTick, bool enabled)
public void SetVelocityDirection(EntityUid entity, InputMoverComponent component, Direction direction, ushort subTick, bool enabled)
{
// Logger.Info($"[{_gameTiming.CurTick}/{subTick}] {direction}: {enabled}");
@@ -372,10 +426,10 @@ namespace Content.Shared.Movement.Systems
_ => throw new ArgumentException(nameof(direction))
};
SetMoveInput(component, subTick, enabled, bit);
SetMoveInput(entity, component, subTick, enabled, bit);
}
private void SetMoveInput(InputMoverComponent component, ushort subTick, bool enabled, MoveButtons bit)
private void SetMoveInput(EntityUid entity, InputMoverComponent component, ushort subTick, bool enabled, MoveButtons bit)
{
// Modifies held state of a movement button at a certain sub tick and updates current tick movement vectors.
ResetSubtick(component);
@@ -415,11 +469,11 @@ namespace Content.Shared.Movement.Systems
component.LastInputSubTick = 0;
}
public void SetSprinting(InputMoverComponent component, ushort subTick, bool walking)
public void SetSprinting(EntityUid entity, InputMoverComponent component, ushort subTick, bool walking)
{
// Logger.Info($"[{_gameTiming.CurTick}/{subTick}] Sprint: {enabled}");
SetMoveInput(component, subTick, walking, MoveButtons.Walk);
SetMoveInput(entity, component, subTick, walking, MoveButtons.Walk);
}
/// <summary>