feat(R3-W6): LOCAL PLAYER UNIFICATION — edge-driven retail input; UpdatePlayerAnimation + the synthesis layer DELETED (closes J15)
The local player now drives the SAME pipeline remotes use. The controller's per-frame RawMotionState rebuild (level-triggered D6.2) is replaced by retail's CommandInterpreter altitude: key EDGES fire DoMotion/StopMotion (0x00528d20/0x00528530) and the Shift edge fires set_hold_run (0x00528b70, caller-0x006b33ca shape) — the interpreter's own RawState mutates via ApplyMotion/RemoveMotion and every dispatch routes the funnel + DefaultSink into the sequencer. GameWindow's UpdatePlayerAnimation (169 lines) is DELETED with both LocalAnimationCommand/LocalAnimationSpeed MovementResult fields and all three synthesis sites (K-fix5 pacing, Walk→Run cycle selection, the auto-walk overrides): run pacing now comes from apply_run_to_command's my_run_rate promotion — the same source remotes use; airborne-Falling falls out of contact_allows_move (the funnel's second dispatch). Auto-walk's #69 turn-phase legs re-expressed as DoMotion(Turn*) edges; teleport idle = StopCompletely (retail's full stop) + an edge-tracker reset so held keys walk straight out of a portal. Map discovery R1 fixed: ChargeJump() now fires at charge START (the 0x0056afac input-boundary site) — StandingLongJump had NEVER armed in production despite the W3 port. TWO root-cause fixes the cutover surfaced (each would have been invisible under the old synthesis layer): - CurrentHoldKey was a shadow FIELD synced only on the raw dispatch branch; set_hold_run writes RawState.CurrentHoldKey, so an edge-driven Shift toggle followed by DoMotion read a stale None and lost the run promotion. Now an alias of RawState.CurrentHoldKey (retail's adjust_motion reads raw_state.current_holdkey directly). - The controller's grounded velocity + jump-launch writes used set_local_velocity's default autonomous:false, silently clearing LastMoveWasAutonomous and flipping the A3 dual dispatch to the interpreted branch for the local player. Both marked autonomous. EXPECTED-DIFFS (map §6, for the R3 visual pass): #45's 1.248x sidestep factor + ACDREAM_ANIM_SPEED_SCALE died with UpdatePlayerAnimation — local sidestep pacing now matches how remotes have always played; auto-walk-at-run plays walk-pace legs until R4; ApplyServerRunRate's apply_current_movement goes live (Branch-2 fast re-speed absorbs the echo — retail's own mid-run speed-change mechanism). Wire: outbound values stay input-derived (the L.2b-verified byte stream untouched; RawState-sourcing needs the map §2b cdb TODO and R7 owns outbound). MotionStateChanged = the old comparison minus the dead localAnimCmd leg, OR any edge fired. Full suite green: 3,731 passed. Live smoke: in-world, user-driven input through the new path (walk/turn/strafe), 12k entities, zero exceptions. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
fc5a2cda28
commit
fb7beb706b
4 changed files with 177 additions and 287 deletions
|
|
@ -587,12 +587,15 @@ public sealed class MotionInterpreter : IMotionDoneSink
|
|||
/// <summary>
|
||||
/// The physics object's currently-held movement key (retail
|
||||
/// <c>this->raw_state.current_holdkey</c>). <see cref="adjust_motion"/>
|
||||
/// falls back to this field when the per-channel holdKey argument passed
|
||||
/// in is <see cref="HoldKey.Invalid"/>. D6.2 (the raw-state orchestrator)
|
||||
/// is responsible for keeping this in sync with the raw motion state;
|
||||
/// default <see cref="HoldKey.None"/> is a safe no-op until then.
|
||||
/// falls back to this property when the per-channel holdKey argument
|
||||
/// passed in is <see cref="HoldKey.Invalid"/>. R3-W6: an ALIAS of
|
||||
/// <see cref="RawMotionState.CurrentHoldKey"/> — retail's adjust_motion
|
||||
/// reads <c>raw_state.current_holdkey</c> directly; the former shadow
|
||||
/// field only synced on the raw dispatch branch, so an edge-driven
|
||||
/// set_hold_run followed by DoMotion read a stale None and lost the
|
||||
/// run promotion (the W6 cutover surfaced this).
|
||||
/// </summary>
|
||||
public HoldKey CurrentHoldKey = HoldKey.None;
|
||||
public HoldKey CurrentHoldKey => RawState.CurrentHoldKey;
|
||||
|
||||
/// <summary>True when crouching-in-place for a standing long jump (offset +0x70).</summary>
|
||||
public bool StandingLongJump;
|
||||
|
|
@ -1345,7 +1348,10 @@ public sealed class MotionInterpreter : IMotionDoneSink
|
|||
/// </summary>
|
||||
public void apply_raw_movement(RawMotionState raw)
|
||||
{
|
||||
CurrentHoldKey = raw.CurrentHoldKey;
|
||||
// R3-W6: CurrentHoldKey is now an alias of RawState.CurrentHoldKey;
|
||||
// keep the interpreter's raw state authoritative when a snapshot
|
||||
// arrives through this legacy overload.
|
||||
RawState.CurrentHoldKey = raw.CurrentHoldKey;
|
||||
|
||||
// Copy raw -> interpreted. Retail copies 7 fields; our
|
||||
// InterpretedMotionState omits current_style (velocity doesn't use it).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue