fix(B.6+B.7): shrink arrival safety margin; file #66 rotation, #67 door

Margin trim:
  Previous: min(0.5, threshold * 0.4) — for 3 m NPC arrived at 2.5 m
  New:      min(0.2, threshold * 0.2) — for 3 m NPC arrives at 2.8 m
  User feedback: 'compared to retail, it fires too close. In retail
  it fires from a longer range.' Smaller margin matches that — still
  safely inside ACE's strict WithinUseRadius but closer to the boundary.
  Tight pickup radii (0.6 m item) now arrive at 0.48 m (was 0.36 m).

Filed issues:
  #67  Door Use action doesn't complete after auto-walk arrival.
       NPC dialogue fires correctly post-flush-AP+re-send, but
       doors still go silent — need to investigate door-specific
       state requirements in ACE's Door.ActOnUse or our wire
       payload differences.
  #66  Rotation: local player flips back after auto-walk arrival
       (observed from retail observer); NPCs don't turn to face
       the player when used. Both rooted in missing MovementType=8
       TurnToObject handling. Supersedes #65 (which was local-only)
       with a unified rotation-handling phase scope.
This commit is contained in:
Erik 2026-05-15 11:28:06 +02:00
parent 39ff3a5505
commit 64c9793248
2 changed files with 91 additions and 6 deletions

View file

@ -448,15 +448,18 @@ public sealed class PlayerMovementController
// Arrival predicate. CRITICAL: ACE's server-side WithinUseRadius
// is strict (dist <= radius), so arriving exactly at the radius
// boundary fails — ACE rejects the action and replies with
// another MoveToObject. To ensure the re-sent action lands
// INSIDE ACE's radius, we apply a safety margin that walks
// 0.30.5 m past the boundary (capped to 40 % of the threshold
// so tight pickup radii like 0.6 m stay reachable without
// collapsing to zero).
// another MoveToObject. We walk slightly INSIDE the boundary so
// the re-sent action lands safely in-range.
//
// The margin is small — user feedback says retail fires Use
// from longer range, so we minimise the over-walk: 0.2 m at
// typical NPC radii (3 m → arrive at 2.8 m), tapered for tight
// pickup radii (0.6 m → arrive at 0.48 m) so the body stays
// reachable but always inside ACE's strict check.
float arrivalThreshold = _autoWalkMoveTowards
? _autoWalkDistanceToObject
: _autoWalkMinDistance;
float safetyMargin = MathF.Min(0.5f, arrivalThreshold * 0.4f);
float safetyMargin = MathF.Min(0.2f, arrivalThreshold * 0.2f);
float effectiveArrival = MathF.Max(arrivalThreshold - safetyMargin, 0.1f);
bool arrived =
(_autoWalkMoveTowards