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:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user