feat(B.6): honor wire WalkRunThreshold — walk vs run per retail semantics
User-observed behaviour: 'When at a distance X it should start running
towards the double clicked target and then stop close to it. When at a
shorter distance it should walk to it.' That's retail's MoveToManager
behaviour driven by the wire's WalkRunThreshold field, which Slice 2
ignored (it always synthesised Run=true regardless of distance).
ACE's defaults (MoveToParameters.SetDefaults): WalkRunThreshold=15.0 m
for Use/PickUp paths — so close-range auto-walks are walks, not runs.
ACE's combat-charge override: 1.0 m — chase runs until the last metre.
Both retail and ACE compute Run vs Walk per-frame from remaining
distance vs threshold.
Wire WalkRunThreshold:
- Already parsed into CreateObject.MoveToPathData.WalkRunThreshold.
- Now plumbed through to PlayerMovementController.BeginServerAutoWalk
as a new parameter, stored in _autoWalkWalkRunThreshold.
- ApplyAutoWalkOverlay sets Run = (dist > _autoWalkWalkRunThreshold)
per frame. The synthesised input flips Run as the body approaches.
The motion-interpreter pipeline downstream picks RunForward vs
WalkForward from input.Run, so the animation cycle naturally switches
as the body crosses into the walk band. Run rate falls back to the
local PlayerWeenie.InqRunRate as before (ACE sends mtRun=0.00 for
Use/PickUp, so we never read mtRun; this is unchanged from Slice 2).
[autowalk-begin] diagnostic now includes walkRunThresh={x:F2} so the
threshold is visible alongside dest/minDist/objDist in the trace.
This commit is contained in:
parent
f18de7ccde
commit
5612ce718a
2 changed files with 27 additions and 7 deletions
|
|
@ -234,6 +234,12 @@ public sealed class PlayerMovementController
|
|||
private float _autoWalkMinDistance;
|
||||
private float _autoWalkDistanceToObject;
|
||||
private bool _autoWalkMoveTowards;
|
||||
// Wire's WalkRunThreshold — retail semantic: locomotion runs while
|
||||
// remaining distance > threshold, walks once inside threshold. ACE's
|
||||
// Use/PickUp path uses MoveToParameters.SetDefaults() = 15.0f, so
|
||||
// most pickup targets walk the entire way. ACE's charge path sets
|
||||
// it to 1.0f so combat chase runs almost the whole way.
|
||||
private float _autoWalkWalkRunThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// True while a server-initiated auto-walk (MoveToObject inbound) is
|
||||
|
|
@ -343,13 +349,15 @@ public sealed class PlayerMovementController
|
|||
Vector3 destinationWorld,
|
||||
float minDistance,
|
||||
float distanceToObject,
|
||||
bool moveTowards)
|
||||
bool moveTowards,
|
||||
float walkRunThreshold)
|
||||
{
|
||||
_autoWalkActive = true;
|
||||
_autoWalkDestination = destinationWorld;
|
||||
_autoWalkMinDistance = minDistance;
|
||||
_autoWalkDistanceToObject = distanceToObject;
|
||||
_autoWalkMoveTowards = moveTowards;
|
||||
_autoWalkWalkRunThreshold = walkRunThreshold;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -444,14 +452,25 @@ public sealed class PlayerMovementController
|
|||
while (Yaw < -MathF.PI) Yaw += 2f * MathF.PI;
|
||||
}
|
||||
|
||||
// Synthesize "running forward" input. The rest of Update reads
|
||||
// Walk vs run per the wire's WalkRunThreshold. Retail semantics:
|
||||
// dist > threshold → RUN, dist ≤ threshold → WALK. ACE's default
|
||||
// for Use/PickUp is 15.0 m (so close targets walk the whole way);
|
||||
// ACE's combat charge path sets it to 1.0 m (so chase runs to the
|
||||
// last metre then walks the final approach). Matches the user's
|
||||
// observed retail behaviour: "When at a distance X it should
|
||||
// start running towards the double clicked target… When at a
|
||||
// shorter distance it should walk to it."
|
||||
bool shouldRun = dist > _autoWalkWalkRunThreshold;
|
||||
|
||||
// Synthesize "moving forward" input. The rest of Update reads
|
||||
// Yaw + input.Forward + input.Run to drive _motion + body
|
||||
// velocity exactly as it does for user-driven W+Shift. We zero
|
||||
// any mouse delta so a stale frame doesn't fight the steering.
|
||||
// velocity exactly as it does for user-driven W (+ optional Shift).
|
||||
// We zero any mouse delta so a stale frame doesn't fight the
|
||||
// steering.
|
||||
return input with
|
||||
{
|
||||
Forward = true,
|
||||
Run = true,
|
||||
Run = shouldRun,
|
||||
Backward = false,
|
||||
StrafeLeft = false,
|
||||
StrafeRight = false,
|
||||
|
|
|
|||
|
|
@ -3338,11 +3338,12 @@ public sealed class GameWindow : IDisposable
|
|||
destWorld,
|
||||
pathData.MinDistance,
|
||||
pathData.DistanceToObject,
|
||||
update.MotionState.MoveTowards);
|
||||
update.MotionState.MoveTowards,
|
||||
pathData.WalkRunThreshold);
|
||||
if (AcDream.Core.Physics.PhysicsDiagnostics.ProbeAutoWalkEnabled)
|
||||
{
|
||||
Console.WriteLine(System.FormattableString.Invariant(
|
||||
$"[autowalk-begin] dest=({destWorld.X:F2},{destWorld.Y:F2},{destWorld.Z:F2}) minDist={pathData.MinDistance:F2} objDist={pathData.DistanceToObject:F2} towards={update.MotionState.MoveTowards}"));
|
||||
$"[autowalk-begin] dest=({destWorld.X:F2},{destWorld.Y:F2},{destWorld.Z:F2}) minDist={pathData.MinDistance:F2} objDist={pathData.DistanceToObject:F2} walkRunThresh={pathData.WalkRunThreshold:F2} towards={update.MotionState.MoveTowards}"));
|
||||
}
|
||||
}
|
||||
// Note: do NOT cancel auto-walk on a non-MoveTo motion
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue