P1 (BLOCKER -> RESOLVED, no adaptation needed): retail's CPhysics::SetObjectMovement (0x00509690) drops any movement event whose wire AUTONOMOUS byte is set when the addressed object IsThePlayer - BEFORE unpack_movement's unconditional head-interrupt ever runs. ACE's mt-0 MoveToState echo is IsAutonomous=1 HARDCODED (MovementData.cs:162) and only exists when the client itself sends a MoveToState (the 2026-05-14 'echo kills auto-walk' trace was the pre-#75 build whose overlay leaked outbound packets - post-#75 there is no echo at moveto start). acdream parses isAutonomous (UpdateMotion.cs:129) and consumes it NOWHERE; MotionSequenceGate cites 0x00509690 in its own doc but omitted this final branch. V-commits port the missing gate tail and the verbatim head-cancel lands cleanly; the informal GameWindow no-cancel-on-non-MoveTo note retires. P3 (Ghidra-confirmed live, textual verdict independently identical): heading_diff 0x00528fb0 HAS the TurnLeft mirror - 360-diff whenever the turn command != TurnRight; the extraction's 'arg unused' was a BN x87-setcc artifact (the W6b class). P2 Ghidra-confirmed: get_desired_heading = fwd-towards 0 / fwd-away 180 / back-towards 180 / back-away 0. ghidra-confirmations.md holds both raw decompiles. P4-P7 pinned per V0-pins.md. RemoteMoveToDriver's stale chase/flee class-doc claim corrected (retail and ACE AGREE on the predicates). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
58 lines
1.9 KiB
Markdown
58 lines
1.9 KiB
Markdown
# R4-V0 — Ghidra ground-truth decompiles (patchmem.gpr, fetched live 2026-07-03)
|
||
|
||
Authoritative resolutions for the two pins the BN pseudo-C garbled. Fetched
|
||
via the Ghidra MCP while the V0 pin workflow ran; these OVERRIDE any textual
|
||
adjudication that disagrees.
|
||
|
||
## P3 — `heading_diff` 0x00528fb0: the TurnLeft mirror EXISTS
|
||
|
||
```c
|
||
float __cdecl heading_diff(float param_1, float param_2, ulong param_3)
|
||
{
|
||
float fVar1;
|
||
|
||
fVar1 = param_1 - param_2;
|
||
if (ABS(param_1 - param_2) < F_EPSILON) {
|
||
fVar1 = 0.0f;
|
||
}
|
||
if (fVar1 < -F_EPSILON) {
|
||
fVar1 = fVar1 + 360.0f; // ___real_43b40000
|
||
}
|
||
if ((F_EPSILON < fVar1) && (param_3 != 0x6500000d)) {
|
||
fVar1 = 360.0f - fVar1; // the mirror — NOT-TurnRight only
|
||
}
|
||
return fVar1;
|
||
}
|
||
```
|
||
|
||
Adjudication of the research contradiction:
|
||
- `r4-moveto-decomp.md` §5g ("turn-command arg UNUSED") is **WRONG** — the
|
||
arg gates the mirror.
|
||
- `r4-ace-moveto.md`'s suspicion (an x87-garbled `360−diff` TurnLeft branch)
|
||
is **CONFIRMED**: the mirror applies whenever the turn command is not
|
||
TurnRight (0x6500000d), i.e. the TurnLeft direction measures the
|
||
complementary angle. Port verbatim with the epsilon literal
|
||
0.000199999995f (F_EPSILON).
|
||
|
||
## P2 — `MovementParameters::get_desired_heading` 0x0052aad0: ACE-shaped constants CONFIRMED
|
||
|
||
```c
|
||
float __thiscall MovementParameters::get_desired_heading(
|
||
MovementParameters* this, ulong command, int movingAway)
|
||
{
|
||
if ((command == 0x44000007) || (command == 0x45000005)) { // Run/WalkForward
|
||
if (movingAway == 0)
|
||
return 0.0f;
|
||
}
|
||
else {
|
||
if (command != 0x45000006) // not WalkBackward
|
||
return 0.0f;
|
||
if (movingAway != 0)
|
||
return 0.0f;
|
||
}
|
||
return 180.0f; // ___real_43340000
|
||
}
|
||
```
|
||
|
||
Truth table: forward+towards → 0°; forward+away → 180°;
|
||
backward+towards → 180°; backward+away → 0°; any other command → 0°.
|