Mobmover tweaks (#15942)
This commit is contained in:
@@ -68,8 +68,12 @@ namespace Content.Client.Physics.Controllers
|
|||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
var moverQuery = GetEntityQuery<InputMoverComponent>();
|
var moverQuery = GetEntityQuery<InputMoverComponent>();
|
||||||
var relayTargetQuery = GetEntityQuery<MovementRelayTargetComponent>();
|
var relayTargetQuery = GetEntityQuery<MovementRelayTargetComponent>();
|
||||||
|
var mobMoverQuery = GetEntityQuery<MobMoverComponent>();
|
||||||
|
var pullableQuery = GetEntityQuery<SharedPullableComponent>();
|
||||||
|
var physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||||
|
var modifierQuery = GetEntityQuery<MovementSpeedModifierComponent>();
|
||||||
|
|
||||||
if (!TryComp(player, out InputMoverComponent? mover) ||
|
if (!moverQuery.TryGetComponent(player, out var mover) ||
|
||||||
!xformQuery.TryGetComponent(player, out var xform))
|
!xformQuery.TryGetComponent(player, out var xform))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -106,24 +110,24 @@ namespace Content.Client.Physics.Controllers
|
|||||||
{
|
{
|
||||||
foreach (var joint in jointComponent.GetJoints.Values)
|
foreach (var joint in jointComponent.GetJoints.Values)
|
||||||
{
|
{
|
||||||
if (TryComp(joint.BodyAUid, out PhysicsComponent? physics))
|
if (physicsQuery.TryGetComponent(joint.BodyAUid, out var physics))
|
||||||
physics.Predict = true;
|
physics.Predict = true;
|
||||||
|
|
||||||
if (TryComp(joint.BodyBUid, out physics))
|
if (physicsQuery.TryGetComponent(joint.BodyBUid, out physics))
|
||||||
physics.Predict = true;
|
physics.Predict = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're being pulled then we won't predict anything and will receive server lerps so it looks way smoother.
|
// If we're being pulled then we won't predict anything and will receive server lerps so it looks way smoother.
|
||||||
if (TryComp(player, out SharedPullableComponent? pullableComp))
|
if (pullableQuery.TryGetComponent(player, out var pullableComp))
|
||||||
{
|
{
|
||||||
if (pullableComp.Puller is {Valid: true} puller && TryComp<PhysicsComponent?>(puller, out var pullerBody))
|
if (pullableComp.Puller is {Valid: true} puller && TryComp<PhysicsComponent>(puller, out var pullerBody))
|
||||||
{
|
{
|
||||||
pullerBody.Predict = false;
|
pullerBody.Predict = false;
|
||||||
body.Predict = false;
|
body.Predict = false;
|
||||||
|
|
||||||
if (TryComp<SharedPullerComponent>(player, out var playerPuller) && playerPuller.Pulling != null &&
|
if (TryComp<SharedPullerComponent>(player, out var playerPuller) && playerPuller.Pulling != null &&
|
||||||
TryComp<PhysicsComponent>(playerPuller.Pulling, out var pulledBody))
|
physicsQuery.TryGetComponent(playerPuller.Pulling, out var pulledBody))
|
||||||
{
|
{
|
||||||
pulledBody.Predict = false;
|
pulledBody.Predict = false;
|
||||||
}
|
}
|
||||||
@@ -131,7 +135,19 @@ namespace Content.Client.Physics.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Server-side should just be handled on its own so we'll just do this shizznit
|
// Server-side should just be handled on its own so we'll just do this shizznit
|
||||||
HandleMobMovement(player, mover, physicsUid, body, xformMover, frameTime, xformQuery, moverQuery, relayTargetQuery);
|
HandleMobMovement(
|
||||||
|
player,
|
||||||
|
mover,
|
||||||
|
physicsUid,
|
||||||
|
body,
|
||||||
|
xformMover,
|
||||||
|
frameTime,
|
||||||
|
xformQuery,
|
||||||
|
moverQuery,
|
||||||
|
mobMoverQuery,
|
||||||
|
relayTargetQuery,
|
||||||
|
pullableQuery,
|
||||||
|
modifierQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool CanSound()
|
protected override bool CanSound()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Content.Server.Shuttles.Components;
|
|||||||
using Content.Server.Shuttles.Systems;
|
using Content.Server.Shuttles.Systems;
|
||||||
using Content.Shared.Movement.Components;
|
using Content.Shared.Movement.Components;
|
||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
|
using Content.Shared.Pulling.Components;
|
||||||
using Content.Shared.Shuttles.Components;
|
using Content.Shared.Shuttles.Components;
|
||||||
using Content.Shared.Shuttles.Systems;
|
using Content.Shared.Shuttles.Systems;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
@@ -65,11 +66,14 @@ namespace Content.Server.Physics.Controllers
|
|||||||
var relayTargetQuery = GetEntityQuery<MovementRelayTargetComponent>();
|
var relayTargetQuery = GetEntityQuery<MovementRelayTargetComponent>();
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
var moverQuery = GetEntityQuery<InputMoverComponent>();
|
var moverQuery = GetEntityQuery<InputMoverComponent>();
|
||||||
|
var mobMoverQuery = GetEntityQuery<MobMoverComponent>();
|
||||||
|
var pullableQuery = GetEntityQuery<SharedPullableComponent>();
|
||||||
|
var inputQueryEnumerator = AllEntityQuery<InputMoverComponent>();
|
||||||
|
var modifierQuery = GetEntityQuery<MovementSpeedModifierComponent>();
|
||||||
|
|
||||||
foreach (var mover in EntityQuery<InputMoverComponent>(true))
|
while (inputQueryEnumerator.MoveNext(out var uid, out var mover))
|
||||||
{
|
{
|
||||||
var uid = mover.Owner;
|
var physicsUid = uid;
|
||||||
EntityUid physicsUid = uid;
|
|
||||||
|
|
||||||
if (relayQuery.HasComponent(uid))
|
if (relayQuery.HasComponent(uid))
|
||||||
continue;
|
continue;
|
||||||
@@ -97,7 +101,18 @@ namespace Content.Server.Physics.Controllers
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleMobMovement(uid, mover, physicsUid, body, xformMover, frameTime, xformQuery, moverQuery, relayTargetQuery);
|
HandleMobMovement(uid,
|
||||||
|
mover,
|
||||||
|
physicsUid,
|
||||||
|
body,
|
||||||
|
xformMover,
|
||||||
|
frameTime,
|
||||||
|
xformQuery,
|
||||||
|
moverQuery,
|
||||||
|
mobMoverQuery,
|
||||||
|
relayTargetQuery,
|
||||||
|
pullableQuery,
|
||||||
|
modifierQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleShuttleMovement(frameTime);
|
HandleShuttleMovement(frameTime);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Content.Shared.Movement.Systems;
|
using Content.Shared.Movement.Systems;
|
||||||
using Robust.Shared.GameStates;
|
using Robust.Shared.GameStates;
|
||||||
|
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
|
|
||||||
namespace Content.Shared.Movement.Components
|
namespace Content.Shared.Movement.Components
|
||||||
@@ -61,8 +62,8 @@ namespace Content.Shared.Movement.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// If we traverse on / off a grid then set a timer to update our relative inputs.
|
/// If we traverse on / off a grid then set a timer to update our relative inputs.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite), DataField("lerpTarget", customTypeSerializer: typeof(TimeOffsetSerializer))]
|
||||||
public float LerpAccumulator;
|
public TimeSpan LerpTarget;
|
||||||
|
|
||||||
public const float LerpTime = 1.0f;
|
public const float LerpTime = 1.0f;
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
component.RelativeRotation = state.RelativeRotation;
|
component.RelativeRotation = state.RelativeRotation;
|
||||||
component.TargetRelativeRotation = state.TargetRelativeRotation;
|
component.TargetRelativeRotation = state.TargetRelativeRotation;
|
||||||
component.RelativeEntity = state.RelativeEntity;
|
component.RelativeEntity = state.RelativeEntity;
|
||||||
component.LerpAccumulator = state.LerpAccumulator;
|
component.LerpTarget = state.LerpAccumulator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInputGetState(EntityUid uid, InputMoverComponent component, ref ComponentGetState args)
|
private void OnInputGetState(EntityUid uid, InputMoverComponent component, ref ComponentGetState args)
|
||||||
@@ -94,7 +94,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
component.RelativeRotation,
|
component.RelativeRotation,
|
||||||
component.TargetRelativeRotation,
|
component.TargetRelativeRotation,
|
||||||
component.RelativeEntity,
|
component.RelativeEntity,
|
||||||
component.LerpAccumulator);
|
component.LerpTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShutdownInput()
|
private void ShutdownInput()
|
||||||
@@ -121,13 +121,73 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
public void ResetCamera(EntityUid uid)
|
public void ResetCamera(EntityUid uid)
|
||||||
{
|
{
|
||||||
if (CameraRotationLocked || !TryComp<InputMoverComponent>(uid, out var mover) || mover.TargetRelativeRotation.Equals(Angle.Zero))
|
if (CameraRotationLocked ||
|
||||||
|
!TryComp<InputMoverComponent>(uid, out var mover))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we updated parent then cancel the accumulator and force it now.
|
||||||
|
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||||
|
|
||||||
|
if (!TryUpdateRelative(mover, xformQuery.GetComponent(uid), xformQuery) && mover.TargetRelativeRotation.Equals(Angle.Zero))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
mover.LerpTarget = TimeSpan.Zero;
|
||||||
mover.TargetRelativeRotation = Angle.Zero;
|
mover.TargetRelativeRotation = Angle.Zero;
|
||||||
Dirty(mover);
|
Dirty(mover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool TryUpdateRelative(InputMoverComponent mover, TransformComponent xform, EntityQuery<TransformComponent> xformQuery)
|
||||||
|
{
|
||||||
|
var relative = xform.GridUid;
|
||||||
|
relative ??= xform.MapUid;
|
||||||
|
|
||||||
|
// So essentially what we want:
|
||||||
|
// 1. If we go from grid to map then preserve our rotation and continue as usual
|
||||||
|
// 2. If we go from grid -> grid then (after lerp time) snap to nearest cardinal (probably imperceptible)
|
||||||
|
// 3. If we go from map -> grid then (after lerp time) snap to nearest cardinal
|
||||||
|
|
||||||
|
if (mover.RelativeEntity.Equals(relative))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Okay need to get our old relative rotation with respect to our new relative rotation
|
||||||
|
// e.g. if we were right side up on our current grid need to get what that is on our new grid.
|
||||||
|
var currentRotation = Angle.Zero;
|
||||||
|
var targetRotation = Angle.Zero;
|
||||||
|
|
||||||
|
// Get our current relative rotation
|
||||||
|
if (xformQuery.TryGetComponent(mover.RelativeEntity, out var oldRelativeXform))
|
||||||
|
{
|
||||||
|
currentRotation = _transform.GetWorldRotation(oldRelativeXform, xformQuery) + mover.RelativeRotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xformQuery.TryGetComponent(relative, out var relativeXform))
|
||||||
|
{
|
||||||
|
// This is our current rotation relative to our new parent.
|
||||||
|
mover.RelativeRotation = (currentRotation - _transform.GetWorldRotation(relativeXform, xformQuery)).FlipPositive();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we went from grid -> map we'll preserve our worldrotation
|
||||||
|
if (relative != null && _mapManager.IsMap(relative.Value))
|
||||||
|
{
|
||||||
|
targetRotation = currentRotation.FlipPositive().Reduced();
|
||||||
|
}
|
||||||
|
// If we went from grid -> grid OR grid -> map then snap the target to cardinal and lerp there.
|
||||||
|
// OR just rotate to zero (depending on cvar)
|
||||||
|
else if (relative != null && _mapManager.IsGrid(relative.Value))
|
||||||
|
{
|
||||||
|
if (CameraRotationLocked)
|
||||||
|
targetRotation = Angle.Zero;
|
||||||
|
else
|
||||||
|
targetRotation = mover.RelativeRotation.GetCardinalDir().ToAngle().Reduced();
|
||||||
|
}
|
||||||
|
|
||||||
|
mover.RelativeEntity = relative;
|
||||||
|
mover.TargetRelativeRotation = targetRotation;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public Angle GetParentGridAngle(InputMoverComponent mover, EntityQuery<TransformComponent> xformQuery)
|
public Angle GetParentGridAngle(InputMoverComponent mover, EntityQuery<TransformComponent> xformQuery)
|
||||||
{
|
{
|
||||||
var rotation = mover.RelativeRotation;
|
var rotation = mover.RelativeRotation;
|
||||||
@@ -140,12 +200,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
public Angle GetParentGridAngle(InputMoverComponent mover)
|
public Angle GetParentGridAngle(InputMoverComponent mover)
|
||||||
{
|
{
|
||||||
var rotation = mover.RelativeRotation;
|
return GetParentGridAngle(mover, GetEntityQuery<TransformComponent>());
|
||||||
|
|
||||||
if (TryComp<TransformComponent>(mover.RelativeEntity, out var relativeXform))
|
|
||||||
return (relativeXform.WorldRotation + rotation);
|
|
||||||
|
|
||||||
return rotation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFollowedParentChange(EntityUid uid, FollowedComponent component, ref EntParentChangedMessage args)
|
private void OnFollowedParentChange(EntityUid uid, FollowedComponent component, ref EntParentChangedMessage args)
|
||||||
@@ -185,7 +240,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
component.RelativeEntity = relative;
|
component.RelativeEntity = relative;
|
||||||
component.TargetRelativeRotation = Angle.Zero;
|
component.TargetRelativeRotation = Angle.Zero;
|
||||||
component.RelativeRotation = Angle.Zero;
|
component.RelativeRotation = Angle.Zero;
|
||||||
component.LerpAccumulator = 0f;
|
component.LerpTarget = TimeSpan.Zero;
|
||||||
Dirty(component);
|
Dirty(component);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -193,16 +248,16 @@ namespace Content.Shared.Movement.Systems
|
|||||||
// If we go on a grid and back off then just reset the accumulator.
|
// If we go on a grid and back off then just reset the accumulator.
|
||||||
if (relative == component.RelativeEntity)
|
if (relative == component.RelativeEntity)
|
||||||
{
|
{
|
||||||
if (component.LerpAccumulator != 0f)
|
if (component.LerpTarget >= Timing.CurTime)
|
||||||
{
|
{
|
||||||
component.LerpAccumulator = 0f;
|
component.LerpTarget = TimeSpan.Zero;
|
||||||
Dirty(component);
|
Dirty(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
component.LerpAccumulator = InputMoverComponent.LerpTime;
|
component.LerpTarget = TimeSpan.FromSeconds(InputMoverComponent.LerpTime) + Timing.CurTime;
|
||||||
Dirty(component);
|
Dirty(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,18 +288,17 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
// Relay the fact we had any movement event.
|
// Relay the fact we had any movement event.
|
||||||
// TODO: Ideally we'd do these in a tick instead of out of sim.
|
// TODO: Ideally we'd do these in a tick instead of out of sim.
|
||||||
var owner = moverComp.Owner;
|
|
||||||
var moveEvent = new MoveInputEvent(entity);
|
var moveEvent = new MoveInputEvent(entity);
|
||||||
RaiseLocalEvent(owner, ref moveEvent);
|
RaiseLocalEvent(entity, ref moveEvent);
|
||||||
|
|
||||||
// For stuff like "Moving out of locker" or the likes
|
// For stuff like "Moving out of locker" or the likes
|
||||||
// We'll relay a movement input to the parent.
|
// We'll relay a movement input to the parent.
|
||||||
if (_container.IsEntityInContainer(owner) &&
|
if (_container.IsEntityInContainer(entity) &&
|
||||||
TryComp<TransformComponent>(owner, out var xform) &&
|
TryComp<TransformComponent>(entity, out var xform) &&
|
||||||
xform.ParentUid.IsValid() &&
|
xform.ParentUid.IsValid() &&
|
||||||
_mobState.IsAlive(owner))
|
_mobState.IsAlive(entity))
|
||||||
{
|
{
|
||||||
var relayMoveEvent = new ContainerRelayMovementEntityEvent(owner);
|
var relayMoveEvent = new ContainerRelayMovementEntityEvent(entity);
|
||||||
RaiseLocalEvent(xform.ParentUid, ref relayMoveEvent);
|
RaiseLocalEvent(xform.ParentUid, ref relayMoveEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -531,16 +585,16 @@ namespace Content.Shared.Movement.Systems
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Angle TargetRelativeRotation;
|
public Angle TargetRelativeRotation;
|
||||||
public EntityUid? RelativeEntity;
|
public EntityUid? RelativeEntity;
|
||||||
public float LerpAccumulator = 0f;
|
public TimeSpan LerpAccumulator;
|
||||||
|
|
||||||
public InputMoverComponentState(MoveButtons buttons, bool canMove, Angle relativeRotation, Angle targetRelativeRotation, EntityUid? relativeEntity, float lerpAccumulator)
|
public InputMoverComponentState(MoveButtons buttons, bool canMove, Angle relativeRotation, Angle targetRelativeRotation, EntityUid? relativeEntity, TimeSpan lerpTarget)
|
||||||
{
|
{
|
||||||
Buttons = buttons;
|
Buttons = buttons;
|
||||||
CanMove = canMove;
|
CanMove = canMove;
|
||||||
RelativeRotation = relativeRotation;
|
RelativeRotation = relativeRotation;
|
||||||
TargetRelativeRotation = targetRelativeRotation;
|
TargetRelativeRotation = targetRelativeRotation;
|
||||||
RelativeEntity = relativeEntity;
|
RelativeEntity = relativeEntity;
|
||||||
LerpAccumulator = lerpAccumulator;
|
LerpAccumulator = lerpTarget;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,10 +108,11 @@ namespace Content.Shared.Movement.Systems
|
|||||||
float frameTime,
|
float frameTime,
|
||||||
EntityQuery<TransformComponent> xformQuery,
|
EntityQuery<TransformComponent> xformQuery,
|
||||||
EntityQuery<InputMoverComponent> moverQuery,
|
EntityQuery<InputMoverComponent> moverQuery,
|
||||||
EntityQuery<MovementRelayTargetComponent> relayTargetQuery)
|
EntityQuery<MobMoverComponent> mobMoverQuery,
|
||||||
|
EntityQuery<MovementRelayTargetComponent> relayTargetQuery,
|
||||||
|
EntityQuery<SharedPullableComponent> pullableQuery,
|
||||||
|
EntityQuery<MovementSpeedModifierComponent> modifierQuery)
|
||||||
{
|
{
|
||||||
DebugTools.Assert(!UsedMobMovement.ContainsKey(uid));
|
|
||||||
|
|
||||||
bool canMove = mover.CanMove;
|
bool canMove = mover.CanMove;
|
||||||
if (relayTargetQuery.TryGetComponent(uid, out var relayTarget) && relayTarget.Entities.Count > 0)
|
if (relayTargetQuery.TryGetComponent(uid, out var relayTarget) && relayTarget.Entities.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -135,59 +136,11 @@ namespace Content.Shared.Movement.Systems
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update relative movement
|
// Update relative movement
|
||||||
if (mover.LerpAccumulator > 0f)
|
if (mover.LerpTarget < Timing.CurTime)
|
||||||
{
|
{
|
||||||
Dirty(mover);
|
if (TryUpdateRelative(mover, xform, xformQuery))
|
||||||
mover.LerpAccumulator -= frameTime;
|
|
||||||
|
|
||||||
if (mover.LerpAccumulator <= 0f)
|
|
||||||
{
|
{
|
||||||
mover.LerpAccumulator = 0f;
|
Dirty(mover);
|
||||||
var relative = xform.GridUid;
|
|
||||||
relative ??= xform.MapUid;
|
|
||||||
|
|
||||||
// So essentially what we want:
|
|
||||||
// 1. If we go from grid to map then preserve our rotation and continue as usual
|
|
||||||
// 2. If we go from grid -> grid then (after lerp time) snap to nearest cardinal (probably imperceptible)
|
|
||||||
// 3. If we go from map -> grid then (after lerp time) snap to nearest cardinal
|
|
||||||
|
|
||||||
if (!mover.RelativeEntity.Equals(relative))
|
|
||||||
{
|
|
||||||
// Okay need to get our old relative rotation with respect to our new relative rotation
|
|
||||||
// e.g. if we were right side up on our current grid need to get what that is on our new grid.
|
|
||||||
var currentRotation = Angle.Zero;
|
|
||||||
var targetRotation = Angle.Zero;
|
|
||||||
|
|
||||||
// Get our current relative rotation
|
|
||||||
if (xformQuery.TryGetComponent(mover.RelativeEntity, out var oldRelativeXform))
|
|
||||||
{
|
|
||||||
currentRotation = oldRelativeXform.WorldRotation + mover.RelativeRotation;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (xformQuery.TryGetComponent(relative, out var relativeXform))
|
|
||||||
{
|
|
||||||
// This is our current rotation relative to our new parent.
|
|
||||||
mover.RelativeRotation = (currentRotation - relativeXform.WorldRotation).FlipPositive();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we went from grid -> map we'll preserve our worldrotation
|
|
||||||
if (relative != null && _mapManager.IsMap(relative.Value))
|
|
||||||
{
|
|
||||||
targetRotation = currentRotation.FlipPositive().Reduced();
|
|
||||||
}
|
|
||||||
// If we went from grid -> grid OR grid -> map then snap the target to cardinal and lerp there.
|
|
||||||
// OR just rotate to zero (depending on cvar)
|
|
||||||
else if (relative != null && _mapManager.IsGrid(relative.Value))
|
|
||||||
{
|
|
||||||
if (CameraRotationLocked)
|
|
||||||
targetRotation = Angle.Zero;
|
|
||||||
else
|
|
||||||
targetRotation = mover.RelativeRotation.GetCardinalDir().ToAngle().Reduced();
|
|
||||||
}
|
|
||||||
|
|
||||||
mover.RelativeEntity = relative;
|
|
||||||
mover.TargetRelativeRotation = targetRotation;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +176,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
if (!canMove
|
if (!canMove
|
||||||
|| physicsComponent.BodyStatus != BodyStatus.OnGround
|
|| physicsComponent.BodyStatus != BodyStatus.OnGround
|
||||||
|| TryComp(uid, out SharedPullableComponent? pullable) && pullable.BeingPulled)
|
|| pullableQuery.TryGetComponent(uid, out var pullable) && pullable.BeingPulled)
|
||||||
{
|
{
|
||||||
UsedMobMovement[uid] = false;
|
UsedMobMovement[uid] = false;
|
||||||
return;
|
return;
|
||||||
@@ -249,14 +202,14 @@ namespace Content.Shared.Movement.Systems
|
|||||||
touching = ev.CanMove;
|
touching = ev.CanMove;
|
||||||
|
|
||||||
if (!touching && TryComp<MobMoverComponent>(uid, out var mobMover))
|
if (!touching && TryComp<MobMoverComponent>(uid, out var mobMover))
|
||||||
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, physicsComponent);
|
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, physicsUid, physicsComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Regular movement.
|
// Regular movement.
|
||||||
// Target velocity.
|
// Target velocity.
|
||||||
// This is relative to the map / grid we're on.
|
// This is relative to the map / grid we're on.
|
||||||
var moveSpeedComponent = CompOrNull<MovementSpeedModifierComponent>(uid);
|
var moveSpeedComponent = modifierQuery.CompOrNull(uid);
|
||||||
|
|
||||||
var walkSpeed = moveSpeedComponent?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
|
var walkSpeed = moveSpeedComponent?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
|
||||||
var sprintSpeed = moveSpeedComponent?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
|
var sprintSpeed = moveSpeedComponent?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
|
||||||
@@ -308,8 +261,8 @@ namespace Content.Shared.Movement.Systems
|
|||||||
// TODO apparently this results in a duplicate move event because "This should have its event run during
|
// TODO apparently this results in a duplicate move event because "This should have its event run during
|
||||||
// island solver"??. So maybe SetRotation needs an argument to avoid raising an event?
|
// island solver"??. So maybe SetRotation needs an argument to avoid raising an event?
|
||||||
|
|
||||||
if (!weightless && TryComp<MobMoverComponent>(mover.Owner, out var mobMover) &&
|
if (!weightless && mobMoverQuery.TryGetComponent(uid, out var mobMover) &&
|
||||||
TryGetSound(weightless, mover, mobMover, xform, out var sound))
|
TryGetSound(weightless, uid, mover, mobMover, xform, out var sound))
|
||||||
{
|
{
|
||||||
var soundModifier = mover.Sprinting ? 1.0f : FootstepWalkingAddedVolumeMultiplier;
|
var soundModifier = mover.Sprinting ? 1.0f : FootstepWalkingAddedVolumeMultiplier;
|
||||||
|
|
||||||
@@ -347,7 +300,8 @@ namespace Content.Shared.Movement.Systems
|
|||||||
{
|
{
|
||||||
var speed = velocity.Length;
|
var speed = velocity.Length;
|
||||||
|
|
||||||
if (speed < minimumFrictionSpeed) return;
|
if (speed < minimumFrictionSpeed)
|
||||||
|
return;
|
||||||
|
|
||||||
var drop = 0f;
|
var drop = 0f;
|
||||||
|
|
||||||
@@ -356,7 +310,8 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
var newSpeed = MathF.Max(0f, speed - drop);
|
var newSpeed = MathF.Max(0f, speed - drop);
|
||||||
|
|
||||||
if (newSpeed.Equals(speed)) return;
|
if (newSpeed.Equals(speed))
|
||||||
|
return;
|
||||||
|
|
||||||
newSpeed /= speed;
|
newSpeed /= speed;
|
||||||
velocity *= newSpeed;
|
velocity *= newSpeed;
|
||||||
@@ -370,7 +325,8 @@ namespace Content.Shared.Movement.Systems
|
|||||||
var currentSpeed = Vector2.Dot(currentVelocity, wishDir);
|
var currentSpeed = Vector2.Dot(currentVelocity, wishDir);
|
||||||
var addSpeed = wishSpeed - currentSpeed;
|
var addSpeed = wishSpeed - currentSpeed;
|
||||||
|
|
||||||
if (addSpeed <= 0f) return;
|
if (addSpeed <= 0f)
|
||||||
|
return;
|
||||||
|
|
||||||
var accelSpeed = accel * frameTime * wishSpeed;
|
var accelSpeed = accel * frameTime * wishSpeed;
|
||||||
accelSpeed = MathF.Min(accelSpeed, addSpeed);
|
accelSpeed = MathF.Min(accelSpeed, addSpeed);
|
||||||
@@ -386,9 +342,9 @@ namespace Content.Shared.Movement.Systems
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Used for weightlessness to determine if we are near a wall.
|
/// Used for weightlessness to determine if we are near a wall.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, MobMoverComponent mover, PhysicsComponent collider)
|
private bool IsAroundCollider(SharedPhysicsSystem broadPhaseSystem, TransformComponent transform, MobMoverComponent mover, EntityUid physicsUid, PhysicsComponent collider)
|
||||||
{
|
{
|
||||||
var enlargedAABB = _lookup.GetWorldAABB(collider.Owner, transform).Enlarged(mover.GrabRangeVV);
|
var enlargedAABB = _lookup.GetWorldAABB(physicsUid, transform).Enlarged(mover.GrabRangeVV);
|
||||||
|
|
||||||
foreach (var otherCollider in broadPhaseSystem.GetCollidingEntities(transform.MapID, enlargedAABB))
|
foreach (var otherCollider in broadPhaseSystem.GetCollidingEntities(transform.MapID, enlargedAABB))
|
||||||
{
|
{
|
||||||
@@ -412,11 +368,12 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
protected abstract bool CanSound();
|
protected abstract bool CanSound();
|
||||||
|
|
||||||
private bool TryGetSound(bool weightless, InputMoverComponent mover, MobMoverComponent mobMover, TransformComponent xform, [NotNullWhen(true)] out SoundSpecifier? sound)
|
private bool TryGetSound(bool weightless, EntityUid uid, InputMoverComponent mover, MobMoverComponent mobMover, TransformComponent xform, [NotNullWhen(true)] out SoundSpecifier? sound)
|
||||||
{
|
{
|
||||||
sound = null;
|
sound = null;
|
||||||
|
|
||||||
if (!CanSound() || !_tags.HasTag(mover.Owner, "FootstepSound")) return false;
|
if (!CanSound() || !_tags.HasTag(uid, "FootstepSound"))
|
||||||
|
return false;
|
||||||
|
|
||||||
var coordinates = xform.Coordinates;
|
var coordinates = xform.Coordinates;
|
||||||
var distanceNeeded = mover.Sprinting ? StepSoundMoveDistanceRunning : StepSoundMoveDistanceWalking;
|
var distanceNeeded = mover.Sprinting ? StepSoundMoveDistanceRunning : StepSoundMoveDistanceWalking;
|
||||||
@@ -443,27 +400,28 @@ namespace Content.Shared.Movement.Systems
|
|||||||
|
|
||||||
mobMover.LastPosition = coordinates;
|
mobMover.LastPosition = coordinates;
|
||||||
|
|
||||||
if (mobMover.StepSoundDistance < distanceNeeded) return false;
|
if (mobMover.StepSoundDistance < distanceNeeded)
|
||||||
|
return false;
|
||||||
|
|
||||||
mobMover.StepSoundDistance -= distanceNeeded;
|
mobMover.StepSoundDistance -= distanceNeeded;
|
||||||
|
|
||||||
if (TryComp<FootstepModifierComponent>(mover.Owner, out var moverModifier))
|
if (TryComp<FootstepModifierComponent>(uid, out var moverModifier))
|
||||||
{
|
{
|
||||||
sound = moverModifier.Sound;
|
sound = moverModifier.Sound;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_inventory.TryGetSlotEntity(mover.Owner, "shoes", out var shoes) &&
|
if (_inventory.TryGetSlotEntity(uid, "shoes", out var shoes) &&
|
||||||
TryComp<FootstepModifierComponent>(shoes, out var modifier))
|
TryComp<FootstepModifierComponent>(shoes, out var modifier))
|
||||||
{
|
{
|
||||||
sound = modifier.Sound;
|
sound = modifier.Sound;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TryGetFootstepSound(xform, shoes != null, out sound);
|
return TryGetFootstepSound(uid, xform, shoes != null, out sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryGetFootstepSound(TransformComponent xform, bool haveShoes, [NotNullWhen(true)] out SoundSpecifier? sound)
|
private bool TryGetFootstepSound(EntityUid uid, TransformComponent xform, bool haveShoes, [NotNullWhen(true)] out SoundSpecifier? sound)
|
||||||
{
|
{
|
||||||
sound = null;
|
sound = null;
|
||||||
|
|
||||||
@@ -480,7 +438,7 @@ namespace Content.Shared.Movement.Systems
|
|||||||
}
|
}
|
||||||
|
|
||||||
var position = grid.LocalToTile(xform.Coordinates);
|
var position = grid.LocalToTile(xform.Coordinates);
|
||||||
var soundEv = new GetFootstepSoundEvent(xform.Owner);
|
var soundEv = new GetFootstepSoundEvent(uid);
|
||||||
|
|
||||||
// If the coordinates have a FootstepModifier component
|
// If the coordinates have a FootstepModifier component
|
||||||
// i.e. component that emit sound on footsteps emit that sound
|
// i.e. component that emit sound on footsteps emit that sound
|
||||||
|
|||||||
Reference in New Issue
Block a user