fix(B.6): tighter 5° alignment + defer Use until rotation completes; file #69 turn anim
User report: 'You should be face to face with the NPC before sending
use. So first is rotation, when you are facing, then using.' and
'it does not face it completely.'
Two changes:
1. Split alignment thresholds in ApplyAutoWalkOverlay:
walkAligned (30°) — gate for synthesised Forward+Run motion
during far-range approach; body walks
while finishing residual turn within 30°.
aligned (5°) — gate for arrival-fire. Final facing
before the auto-walk ends and the action
re-sends. Matches retail's tight pre-Use
rotation tolerance.
Within-arrival check still requires alignment; without alignment
the body holds in turn-only mode regardless of distance.
2. Defer wire Use/PickUp packet for CLOSE-range targets. SendUse
and SendPickUp now check IsCloseRangeTarget(guid): if the player
is already within the target's use-radius, we install the
speculative overlay, set _pendingPostArrivalAction, and RETURN
without sending the wire packet. AutoWalkArrived fires after the
local rotation completes (alignment within 5°); the existing
re-send handler then fires SendUse with isRetryAfterArrival=true,
sending the wire packet at that moment. Effect: rotate first,
THEN Use — the NPC/door/item only sees the action after the
character has turned to face it.
Far-range path unchanged: send immediately, ACE auto-walks,
arrival re-sends.
Filed #69: turn animation (leg/arm cycle while pivoting). The body
now rotates but doesn't play the TurnLeft/TurnRight cycle the user
wants to see. Separate scope — needs motion-interpreter integration.
This commit is contained in:
parent
5b908bcca2
commit
cffb10ff18
3 changed files with 124 additions and 15 deletions
|
|
@ -482,7 +482,8 @@ public sealed class PlayerMovementController
|
|||
// walk-while-turning threshold off, suppress Forward this frame
|
||||
// so the body turns IN PLACE first. Once we're within the
|
||||
// threshold, the synthesised Forward+Run kicks in below.
|
||||
bool aligned = true;
|
||||
bool aligned = true;
|
||||
bool walkAligned = true;
|
||||
if (dist > 1e-4f)
|
||||
{
|
||||
float desiredYaw = MathF.Atan2(dy, dx);
|
||||
|
|
@ -501,13 +502,21 @@ public sealed class PlayerMovementController
|
|||
while (Yaw > MathF.PI) Yaw -= 2f * MathF.PI;
|
||||
while (Yaw < -MathF.PI) Yaw += 2f * MathF.PI;
|
||||
|
||||
// 30° "walk-while-turning" threshold: outside this, body
|
||||
// turns in place. Inside, body walks forward while finishing
|
||||
// any remaining alignment. Matches retail-feel observation;
|
||||
// exact retail value is in MoveToManager but ~30° is a
|
||||
// sensible heuristic for now.
|
||||
// Two alignment thresholds:
|
||||
// walkWhileTurning (30°): outside this, body turns in place.
|
||||
// Inside, body walks forward while
|
||||
// finishing residual alignment.
|
||||
// fullyAligned (5°): the arrival-fire alignment. ACE
|
||||
// rotates server-side via Rotate(target)
|
||||
// BEFORE invoking the Use callback —
|
||||
// user reported 'it does not face it
|
||||
// completely', so the final-alignment
|
||||
// check must be tighter than the
|
||||
// walking gate.
|
||||
const float WalkWhileTurningRad = 30f * MathF.PI / 180f;
|
||||
aligned = MathF.Abs(delta) <= WalkWhileTurningRad;
|
||||
const float FullyAlignedRad = 5f * MathF.PI / 180f;
|
||||
walkAligned = MathF.Abs(delta) <= WalkWhileTurningRad;
|
||||
aligned = MathF.Abs(delta) <= FullyAlignedRad;
|
||||
}
|
||||
|
||||
// End the auto-walk once the body is BOTH within use radius
|
||||
|
|
@ -528,11 +537,12 @@ public sealed class PlayerMovementController
|
|||
// all the way to the object and then stop").
|
||||
bool shouldRun = _autoWalkInitiallyRunning;
|
||||
|
||||
// Turn-first gate: if not yet aligned with the target, suppress
|
||||
// forward motion so the body turns in place rather than
|
||||
// walking an arc. Also suppress when already within arrival —
|
||||
// we just turned to face it; no need to step forward into it.
|
||||
bool moveForward = aligned && !withinArrival;
|
||||
// Turn-first gate: if not yet within the 30° walking band,
|
||||
// suppress forward motion so the body turns in place rather
|
||||
// than walking an arc. Also suppress when already within
|
||||
// arrival — we just turned to face it; no need to step forward
|
||||
// into it.
|
||||
bool moveForward = walkAligned && !withinArrival;
|
||||
|
||||
// Synthesize "moving forward" input. The rest of Update reads
|
||||
// Yaw + input.Forward + input.Run to drive _motion + body
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue