Try fix some mover jank (#13503)

This commit is contained in:
Leon Friedrich
2023-01-16 21:20:22 +13:00
committed by GitHub
parent 450dfd5074
commit 4b65fb1579
6 changed files with 79 additions and 68 deletions

View File

@@ -96,13 +96,38 @@ namespace Content.Shared.Movement.Systems
/// Movement while considering actionblockers, weightlessness, etc.
/// </summary>
protected void HandleMobMovement(
EntityUid uid,
InputMoverComponent mover,
PhysicsComponent physicsComponent,
TransformComponent xform,
float frameTime,
EntityQuery<TransformComponent> xformQuery)
EntityQuery<TransformComponent> xformQuery,
EntityQuery<InputMoverComponent> moverQuery,
EntityQuery<MovementRelayTargetComponent> relayTargetQuery)
{
DebugTools.Assert(!UsedMobMovement.ContainsKey(mover.Owner));
DebugTools.Assert(!UsedMobMovement.ContainsKey(uid));
bool canMove = mover.CanMove;
if (relayTargetQuery.TryGetComponent(uid, out var relayTarget) && relayTarget.Entities.Count > 0)
{
DebugTools.Assert(relayTarget.Entities.Count <= 1, "Multiple relayed movers are not supported at the moment");
bool found = false;
foreach (var ent in relayTarget.Entities)
{
if (_mobState.IsIncapacitated(ent) || !moverQuery.TryGetComponent(ent, out var relayedMover))
continue;
found = true;
mover.RelativeEntity = relayedMover.RelativeEntity;
mover.RelativeRotation = relayedMover.RelativeRotation;
mover.TargetRelativeRotation = relayedMover.TargetRelativeRotation;
break;
}
// lets just hope that this is the same entity that set the movement keys/direction.
canMove &= found;
}
// Update relative movement
if (mover.LerpAccumulator > 0f)
@@ -191,15 +216,17 @@ namespace Content.Shared.Movement.Systems
Dirty(mover);
}
if (!UseMobMovement(mover, physicsComponent))
if (!canMove
|| physicsComponent.BodyStatus != BodyStatus.OnGround
|| TryComp(uid, out SharedPullableComponent? pullable) && pullable.BeingPulled)
{
UsedMobMovement[mover.Owner] = false;
UsedMobMovement[uid] = false;
return;
}
UsedMobMovement[mover.Owner] = true;
UsedMobMovement[uid] = true;
// Specifically don't use mover.Owner because that may be different to the actual physics body being moved.
var weightless = _gravity.IsWeightless(physicsComponent.Owner, physicsComponent, xform);
var weightless = _gravity.IsWeightless(uid, physicsComponent, xform);
var (walkDir, sprintDir) = GetVelocityInput(mover);
var touching = false;
@@ -212,11 +239,11 @@ namespace Content.Shared.Movement.Systems
if (!touching)
{
var ev = new CanWeightlessMoveEvent();
RaiseLocalEvent(xform.Owner, ref ev);
RaiseLocalEvent(uid, ref ev);
// No gravity: is our entity touching anything?
touching = ev.CanMove;
if (!touching && TryComp<MobMoverComponent>(xform.Owner, out var mobMover))
if (!touching && TryComp<MobMoverComponent>(uid, out var mobMover))
touching |= IsAroundCollider(PhysicsSystem, xform, mobMover, physicsComponent);
}
}
@@ -224,7 +251,7 @@ namespace Content.Shared.Movement.Systems
// Regular movement.
// Target velocity.
// This is relative to the map / grid we're on.
var moveSpeedComponent = CompOrNull<MovementSpeedModifierComponent>(mover.Owner);
var moveSpeedComponent = CompOrNull<MovementSpeedModifierComponent>(uid);
var walkSpeed = moveSpeedComponent?.CurrentWalkSpeed ?? MovementSpeedModifierComponent.DefaultBaseWalkSpeed;
var sprintSpeed = moveSpeedComponent?.CurrentSprintSpeed ?? MovementSpeedModifierComponent.DefaultBaseSprintSpeed;
@@ -286,16 +313,16 @@ namespace Content.Shared.Movement.Systems
.WithVariation(sound.Params.Variation ?? FootstepVariation);
// If we're a relay target then predict the sound for all relays.
if (TryComp<MovementRelayTargetComponent>(mover.Owner, out var targetComp))
if (relayTarget != null)
{
foreach (var ent in targetComp.Entities)
foreach (var ent in relayTarget.Entities)
{
_audio.PlayPredicted(sound, mover.Owner, ent, audioParams);
_audio.PlayPredicted(sound, uid, ent, audioParams);
}
}
else
{
_audio.PlayPredicted(sound, mover.Owner, mover.Owner, audioParams);
_audio.PlayPredicted(sound, uid, uid, audioParams);
}
}
}
@@ -305,10 +332,10 @@ namespace Content.Shared.Movement.Systems
if (!weightless || touching)
Accelerate(ref velocity, in worldTotal, accel, frameTime);
PhysicsSystem.SetLinearVelocity(physicsComponent.Owner, velocity, body: physicsComponent);
PhysicsSystem.SetLinearVelocity(uid, velocity, body: physicsComponent);
// Ensures that players do not spiiiiiiin
PhysicsSystem.SetAngularVelocity(physicsComponent.Owner, 0, body: physicsComponent);
PhysicsSystem.SetAngularVelocity(uid, 0, body: physicsComponent);
}
private void Friction(float minimumFrictionSpeed, float frameTime, float friction, ref Vector2 velocity)
@@ -351,15 +378,6 @@ namespace Content.Shared.Movement.Systems
return UsedMobMovement.TryGetValue(uid, out var used) && used;
}
protected bool UseMobMovement(InputMoverComponent mover, PhysicsComponent body)
{
return mover.CanMove &&
body.BodyStatus == BodyStatus.OnGround &&
HasComp<InputMoverComponent>(body.Owner) &&
// If we're being pulled then don't mess with our velocity.
(!TryComp(body.Owner, out SharedPullableComponent? pullable) || !pullable.BeingPulled);
}
/// <summary>
/// Used for weightlessness to determine if we are near a wall.
/// </summary>