Mob movement rewrite (#35931)
* Conveyor optimisations - Optimise movement for moving stuff. Better flags + less resolves + slapped parallelrobustjob on it. - Sleeping for entities getting conveyed into walls. * Blocker version * Finish * Final * Fix conveyor power mispredict * Bagel save * Revert "Bagel save" This reverts commit 1b93fda81fb852d89b89b0beae0b80f8a61165f2. * Conveyor resave * Fix prediction * Mob movement rewrite * Bandaid * Working version * Tentatively working * Friction to fix cornering * More fixes * Revert bagel * Revert this * a * Reviewed * Funky re-save * Fix velocity * Table fix * Review * a
This commit is contained in:
@@ -155,7 +155,6 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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(physicsUid, physicsComponent, xform);
|
||||
@@ -203,20 +202,21 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
var total = walkDir * walkSpeed + sprintDir * sprintSpeed;
|
||||
|
||||
var parentRotation = GetParentGridAngle(mover);
|
||||
var worldTotal = _relativeMovement ? parentRotation.RotateVec(total) : total;
|
||||
var wishDir = _relativeMovement ? parentRotation.RotateVec(total) : total;
|
||||
|
||||
DebugTools.Assert(MathHelper.CloseToPercent(total.Length(), worldTotal.Length()));
|
||||
DebugTools.Assert(MathHelper.CloseToPercent(total.Length(), wishDir.Length()));
|
||||
|
||||
var velocity = physicsComponent.LinearVelocity;
|
||||
float friction;
|
||||
float weightlessModifier;
|
||||
float accel;
|
||||
var velocity = physicsComponent.LinearVelocity;
|
||||
|
||||
// Whether we use weightless friction or not.
|
||||
if (weightless)
|
||||
{
|
||||
if (gridComp == null && !MapGridQuery.HasComp(xform.GridUid))
|
||||
friction = moveSpeedComponent?.OffGridFriction ?? MovementSpeedModifierComponent.DefaultOffGridFriction;
|
||||
else if (worldTotal != Vector2.Zero && touching)
|
||||
else if (wishDir != Vector2.Zero && touching)
|
||||
friction = moveSpeedComponent?.WeightlessFriction ?? MovementSpeedModifierComponent.DefaultWeightlessFriction;
|
||||
else
|
||||
friction = moveSpeedComponent?.WeightlessFrictionNoInput ?? MovementSpeedModifierComponent.DefaultWeightlessFrictionNoInput;
|
||||
@@ -226,7 +226,7 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
}
|
||||
else
|
||||
{
|
||||
if (worldTotal != Vector2.Zero || moveSpeedComponent?.FrictionNoInput == null)
|
||||
if (wishDir != Vector2.Zero || moveSpeedComponent?.FrictionNoInput == null)
|
||||
{
|
||||
friction = tileDef?.MobFriction ?? moveSpeedComponent?.Friction ?? MovementSpeedModifierComponent.DefaultFriction;
|
||||
}
|
||||
@@ -242,14 +242,27 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
var minimumFrictionSpeed = moveSpeedComponent?.MinimumFrictionSpeed ?? MovementSpeedModifierComponent.DefaultMinimumFrictionSpeed;
|
||||
Friction(minimumFrictionSpeed, frameTime, friction, ref velocity);
|
||||
|
||||
if (worldTotal != Vector2.Zero)
|
||||
wishDir *= weightlessModifier;
|
||||
|
||||
if (!weightless || touching)
|
||||
Accelerate(ref velocity, in wishDir, accel, frameTime);
|
||||
|
||||
SetWishDir((uid, mover), wishDir);
|
||||
|
||||
PhysicsSystem.SetLinearVelocity(physicsUid, velocity, body: physicsComponent);
|
||||
|
||||
// Ensures that players do not spiiiiiiin
|
||||
PhysicsSystem.SetAngularVelocity(physicsUid, 0, body: physicsComponent);
|
||||
|
||||
// Handle footsteps at the end
|
||||
if (total != Vector2.Zero)
|
||||
{
|
||||
if (!NoRotateQuery.HasComponent(uid))
|
||||
{
|
||||
// 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?
|
||||
var worldRot = _transform.GetWorldRotation(xform);
|
||||
_transform.SetLocalRotation(xform, xform.LocalRotation + worldTotal.ToWorldAngle() - worldRot);
|
||||
_transform.SetLocalRotation(xform, xform.LocalRotation + wishDir.ToWorldAngle() - worldRot);
|
||||
}
|
||||
|
||||
if (!weightless && MobMoverQuery.TryGetComponent(uid, out var mobMover) &&
|
||||
@@ -272,16 +285,23 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
worldTotal *= weightlessModifier;
|
||||
public Vector2 GetWishDir(Entity<InputMoverComponent?> mover)
|
||||
{
|
||||
if (!MoverQuery.Resolve(mover.Owner, ref mover.Comp, false))
|
||||
return Vector2.Zero;
|
||||
|
||||
if (!weightless || touching)
|
||||
Accelerate(ref velocity, in worldTotal, accel, frameTime);
|
||||
return mover.Comp.WishDir;
|
||||
}
|
||||
|
||||
PhysicsSystem.SetLinearVelocity(physicsUid, velocity, body: physicsComponent);
|
||||
public void SetWishDir(Entity<InputMoverComponent> mover, Vector2 wishDir)
|
||||
{
|
||||
if (mover.Comp.WishDir.Equals(wishDir))
|
||||
return;
|
||||
|
||||
// Ensures that players do not spiiiiiiin
|
||||
PhysicsSystem.SetAngularVelocity(physicsUid, 0, body: physicsComponent);
|
||||
mover.Comp.WishDir = wishDir;
|
||||
Dirty(mover);
|
||||
}
|
||||
|
||||
public void LerpRotation(EntityUid uid, InputMoverComponent mover, float frameTime)
|
||||
@@ -317,7 +337,7 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
}
|
||||
}
|
||||
|
||||
private void Friction(float minimumFrictionSpeed, float frameTime, float friction, ref Vector2 velocity)
|
||||
public void Friction(float minimumFrictionSpeed, float frameTime, float friction, ref Vector2 velocity)
|
||||
{
|
||||
var speed = velocity.Length();
|
||||
|
||||
@@ -338,7 +358,10 @@ public abstract partial class SharedMoverController : VirtualController
|
||||
velocity *= newSpeed;
|
||||
}
|
||||
|
||||
private void Accelerate(ref Vector2 currentVelocity, in Vector2 velocity, float accel, float frameTime)
|
||||
/// <summary>
|
||||
/// Adjusts the current velocity to the target velocity based on the specified acceleration.
|
||||
/// </summary>
|
||||
public static void Accelerate(ref Vector2 currentVelocity, in Vector2 velocity, float accel, float frameTime)
|
||||
{
|
||||
var wishDir = velocity != Vector2.Zero ? velocity.Normalized() : Vector2.Zero;
|
||||
var wishSpeed = velocity.Length();
|
||||
|
||||
Reference in New Issue
Block a user