Rewrites src/AcDream.Core/Physics/InterpolationManager.cs from the spec in docs/research/2026-05-04-l3-port/04-interp-manager.md. Public API preserved (Vector3-returning AdjustOffset, Enqueue, Clear, IsActive, Count) so PositionManager + GameWindow callers continue to compile; internals are full retail spec. Bug fixes vs prior port (audit 04-interp-manager.md § 7): #1 progress_quantum accumulates dt (sum of frame deltas), not step magnitude. Retail line 353140; the prior port's `+= step` made the secondary stall ratio meaningless. #3 Far-branch Enqueue (dist > AutonomyBlipDistance = 100m) sets _failCount = StallFailCountThreshold + 1 = 4, so the next AdjustOffset call's post-stall check fires an immediate blip-to- tail snap. Retail line 352944. Prior port silently drifted toward far targets at catch-up speed instead of teleporting. #4 Secondary stall test ports the retail formula verbatim: cumulative / progress_quantum / dt < CREATURE_FAILED_INTERPOLATION_PERCENTAGE. Audit notes the units are 1/sec (likely Turbine bug or x87 FPU misread by Binary Ninja) — mirrored byte-for-byte regardless. #5 Tail-prune is a tail-walking loop, not a single-tail compare. Multiple consecutive stale tail entries within DesiredDistance (0.05 m) of the new target collapse together. Retail line 352977. #6 Cap-eviction at the HEAD when count reaches 20 (already correct in the prior port; verified). New API: Enqueue gains an optional `currentBodyPosition` parameter so the far-branch detection can reference the body when the queue is empty. Backward-compatible (default null = pre-far-branch behavior). UseTime collapsed into AdjustOffset's tail (post-stall blip check) since acdream has no per-tick UseTime call separate from adjust_offset; identical semantic outcome. State fields renamed to retail names with sentinel values: _frameCounter, _progressQuantum, _originalDistance (init = 999999f sentinel per retail line 0x00555D30 ctor), _failCount. Tests: - 17/17 InterpolationManagerTests green. - New test Enqueue_FarBranch_PrearmsImmediateBlipOnNextAdjustOffset pins the bug #3 fix: enqueueing 150 m away triggers a same-tick blip (delta length ≈ 150 m), and the queue clears. Spec tree: 17 research docs (00–14) under docs/research/2026-05-04-l3-port/. 00-master-plan + 00-port-plan describe the 8-phase rollout. 01-per-tick, 03-up-routing, 04-interp-manager, 05-position-manager-and-partarray, 06-acdream-audit, 14-local-player-audit are the L.3 spec used by this commit and the M2 follow-up. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
26 KiB
13 — Retail's cycle decision tree
Question: When InterpretedMotionState has simultaneous
forward_command=RunForward + sidestep_command=SidestepRight +
turn_command=TurnLeft, what cycle plays in retail?
Answer (TL;DR): All three. Retail does not pick "the winning
substate" out of a 3-axis state. Instead, apply_interpreted_movement
issues three separate DoInterpretedMotion calls —
forward-cmd, then sidestep-cmd, then turn-cmd — each landing in
CMotionTable::GetObjectSequence, which dispatches by command class
bits (0x40000000 substate / 0x10000000 action / 0x20000000 modifier)
to either replace the substate or attach a modifier. Forward goes
into the substate slot; sidestep+turn go into the modifier list. The
CSequence is rebuilt with all three layers via add_motion.
This means acdream's "priority winner" picker is wrong — and so is
the RunForward → WalkForward → Ready fallback chain. Retail has no
fallback chain; it just calls GetObjectSequence per axis and ignores
NULL results.
A. Top of the call tree — CMotionInterp::apply_interpreted_movement
Line 305713–305788 (acclient_2013_pseudo_c.txt), address 00528600.
void CMotionInterp::apply_interpreted_movement(this, arg2, arg3) {
if (!physics_obj) return;
MovementParameters var_2c; // 305719
MovementParameters::MovementParameters(&var_2c);
// Sync run-rate from forward_speed if running
if (interpreted_state.forward_command == 0x44000007 /*RunForward*/)
my_run_rate = (float)interpreted_state.forward_speed; // 305722
// 1) Always re-issue current_style (e.g. CombatMode_NonCombat)
DoInterpretedMotion(this, interpreted_state.current_style, &var_2c); // 305724
// 2) Forward axis
if (!contact_allows_move(this, interpreted_state.forward_command)) {
var_18_2 = 0x3f800000; // 1.0f speed
DoInterpretedMotion(this, 0x40000015 /*Stand*/, &var_2c); // 305729
} else if (standing_longjump) {
DoInterpretedMotion(this, 0x41000003 /*Ready*/, &var_2c); // 305738
StopInterpretedMotion(this, 0x6500000f /*Sidestep*/, &var_2c);
} else {
DoInterpretedMotion(this, interpreted_state.forward_command, &var_2c); // 305744
// 3) Sidestep axis
if (interpreted_state.sidestep_command == 0)
StopInterpretedMotion(this, 0x6500000f /*Sidestep*/, &var_2c); // 305748
else
DoInterpretedMotion(this, interpreted_state.sidestep_command, &var_2c); // 305752
}
// 4) Turn axis
if (interpreted_state.turn_command != 0)
DoInterpretedMotion(this, interpreted_state.turn_command, &var_2c); // 305762
else
// No turn — explicitly stop any prior TurnLeft modifier
StopInterpretedMotion(this, 0x6500000d /*TurnLeft*/, &var_2c); // implied 305770
}
Critical observation: this is four DoInterpretedMotion calls
per UM (current_style, forward, sidestep, turn). Each one is a
distinct MotionTableManager::PerformMovement → CMotionTable::DoObjectMotion
→ CMotionTable::GetObjectSequence round-trip. The composite cycle is
the sum of four state-machine transitions, not the result of a
priority pick.
apply_interpreted_movement is invoked by apply_current_movement
(305838–305857). apply_current_movement is called by every UM
arrival on the player or remote object after RawMotionState::ApplyMotion
(or InterpretedMotionState::ApplyMotion) populates the state struct.
B. The state-routing dispatcher — RawMotionState::ApplyMotion
Line 293630–293703, address 0051eb60. This is the retail
analog of acdream's AnimationCommandRouter.Classify.
void RawMotionState::ApplyMotion(this, arg2, arg3) {
// arg2 = motion command (e.g. 0x44000007 RunForward)
// arg3 = MovementParameters (speed, hold_key_to_apply, etc.)
if ((arg2 - 0x6500000d) > 3) { // not Turn/Sidestep range
if ((arg2 & 0x40000000) == 0) { // not substate
if (arg2 >= 0) {
if ((arg2 & 0x10000000) != 0) // ACTION class
AddAction(this, arg2, ...); // 293640 → action queue
} else if (current_style != arg2) { // STYLE change
forward_command = 0x41000003; // Ready
current_style = arg2; // 293645
}
} else if (arg2 != 0x44000007 /*RunForward*/) {
// 0x40000000-class but NOT RunForward (i.e. WalkForward,
// BackForward etc) goes into FORWARD slot
forward_command = arg2; // 293650
forward_holdkey = arg3->hold_key_to_apply;
forward_speed = arg3->speed;
}
return;
}
switch (arg2) { // 293666
case 0x6500000d /*TurnLeft*/:
case 0x6500000e /*TurnRight*/:
turn_command = arg2; // 293671
turn_holdkey = arg3->hold_key_to_apply;
turn_speed = arg3->speed;
return;
case 0x6500000f /*SidestepRight*/:
case 0x65000010 /*SidestepLeft*/:
sidestep_command = arg2; // 293688
sidestep_holdkey = arg3->hold_key_to_apply;
sidestep_speed = arg3->speed;
return;
}
}
Routing classes (matches 0x40000000/0x10000000/0x20000000 mask
checks, also visible in CMotionTable::GetObjectSequence):
| Class bit | Range | Slot | Effect |
|---|---|---|---|
0x40000000 |
substate (e.g. 0x44000007 RunForward, 0x40000015 Stand) |
forward_command (or replaces substate) |
replaces previous substate; modifiers may be cleared |
0x10000000 |
action (e.g. emote) | action_head queue |
overlay; substate cycle keeps running |
0x20000000 |
modifier | modifier_head list |
overlay; substate cycle keeps running |
0x6500000d-10 |
turn/sidestep (special-cased) | turn_command / sidestep_command |
dedicated slots (effectively modifiers) |
< 0 (0x80...) |
style change | current_style |
full reset, forward_command → Ready |
0x44000007 |
RunForward is special-cased OUT of the forward slot here — see below | — | not stored in forward_command directly by RawMotionState; it's the result of adjust_motion running on WalkForward + HoldKey.Run |
(The InterpretedMotionState equivalent at line 293531 is functionally
the same with one extra branch — current_style initialization.)
C. adjust_motion — the WalkForward + Run → RunForward transform
Line 305343–305400, address 00528010. This is what DoMotion
calls before DoInterpretedMotion to translate a raw key event into
a substate.
void CMotionInterp::adjust_motion(this, arg2 /*&cmd*/, arg3 /*&speed*/, arg4 /*hold_key*/) {
if (weenie_obj == 0 || weenie_obj->IsCreature()) {
switch (*arg2) {
case 0x65000010 /*SidestepLeft*/:
*arg2 = 0x6500000f; // collapse Left → Right
*arg3 *= -1; // with negative speed
// fallthrough
case 0x6500000f /*SidestepRight*/:
// Sidestep speed-mod: (3.12/1.25) * 0.5 = 1.248
*arg3 = (3.12f / 1.25f) * 0.5f * (*arg3);
break;
case 0x6500000e /*TurnRight*/:
*arg2 = 0x6500000d; // collapse Right → Left
*arg3 *= -1; // with negative speed
break;
case 0x45000006 /*WalkBackward*/:
*arg2 = 0x45000005; // collapse to BackForward
*arg3 = -0.65f * (*arg3);
break;
case 0x44000007 /*RunForward*/:
// already a run cmd — fall through to apply_run_to_command
break;
}
// Then: if hold_key == HoldKey_Run, escalate to RunForward
HoldKey current = arg4 == HoldKey_Invalid ? raw_state.current_holdkey : arg4;
if (current == HoldKey_Run)
apply_run_to_command(this, arg2, arg3);
}
}
apply_run_to_command (line 305062, addr 00527be0):
void CMotionInterp::apply_run_to_command(this, arg2, arg3) {
float run_rate = weenie_obj ? weenie_obj->InqRunRate() : my_run_rate;
if (*arg2 == 0x45000005 /*WalkForward*/) {
if (*arg3 != 0)
*arg2 = 0x44000007; // → RunForward
*arg3 *= run_rate; // speed *= runRate (e.g. 2.94)
} else if (*arg2 == 0x6500000d /*TurnLeft*/) {
*arg3 *= 1.5f; // turn 1.5x while running
} else if (*arg2 == 0x6500000f /*SidestepRight*/) {
*arg3 *= run_rate;
// clamp to ±3 m/s
if (fabs(*arg3) > 3.0f)
*arg3 = (sign(*arg3)) * 3.0f;
}
}
So the way RunForward gets into forward_command in retail is:
- Wire UM has
cmd=WalkForward (0x45000005)+hold_key=HoldKey_Run DoMotion(0x45000005, params)is called.adjust_motionswapscmd → 0x44000007 RunForward,speed *= runRate.RawMotionState::ApplyMotion(0x44000007, ...)runs. The special-casearg2 != 0x44000007branch at line 293648 means RunForward is NOT stored inforward_commandhere. (This appears intentional —RunForwardis the post-adjust_motionform; the persistentRawMotionStatekeeps the original WalkForward.)- InterpretedMotionState stores the post-adjust value because
apply_raw_movement(305817) copiesraw_state.*then runsadjust_motionover each of the three axes (305829-305831) beforeapply_interpreted_movementconsumes it.
ACE matches this: it auto-upgrades WalkForward + HoldKey.Run →
RunForward on the outbound wire to remote observers, which is
why our inbound parser sees fwd=0x07 for "remote is running."
D. The cycle-decision core — CMotionTable::GetObjectSequence
Line 298636–298950, address 00522860. This is where a single
motion command lands and the CSequence is rebuilt. It is invoked once
per DoInterpretedMotion call.
Signature:
int CMotionTable::GetObjectSequence(
this,
uint32_t motion, // arg2 — the command
MotionState* state, // arg3 — table-internal state
CSequence* sequence, // arg4 — the part-array sequence to mutate
float speed_mod, // arg5
uint32_t* num_anims_out, // arg6
int32_t force_flag); // arg7 — re-modify recursion guard
Three dispatch branches based on the high-bit class of motion:
D.1 — motion < 0 (style change, e.g. 0x80000003D)
Lines 298661–298735. Substate's effect: reset to default substate of the new style, optionally clear modifiers, replace cycles.
D.2 — motion & 0x40000000 (substate)
Lines 298737–298848. The forward-axis path.
if ((motion & 0x40000000) != 0) { // 298737
uint32_t key = (motion & 0xffffff);
MotionData* incoming = LongHash::lookup(&this->cycles, (state->style << 0x10) | key);
if (incoming == 0)
incoming = LongHash::lookup(&this->cycles, (this->default_style << 0x10) | key); // fallback to default style
if (incoming != 0 && is_allowed(this, motion, incoming, state)) {
// Same-cycle re-speed shortcut: we're already on this cycle
// and just changing speed (e.g. forward_speed delta)
if (motion == state->substate &&
same_sign(speed_mod, state->substate_mod) &&
sequence->has_anims()) {
change_cycle_speed(sequence, incoming, state->substate_mod, speed_mod);
subtract_motion(sequence, incoming, state->substate_mod);
combine_motion(sequence, incoming, speed_mod);
state->substate_mod = speed_mod;
return 1;
}
// Full transition: clear-anims + (link from current substate) + (incoming)
if (incoming->bitfield & 1)
state->clear_modifiers(); // some cycles clear modifiers on entry
MotionData* link = get_link(this, state->style, state->substate, state->substate_mod, motion, speed_mod);
// (with two-stage fallback through default_substate if direct link missing)
sequence->clear_physics();
sequence->remove_cyclic_anims();
// If no direct link, route through default substate
add_motion(sequence, link, ...); // transition anim
add_motion(sequence, incoming, speed_mod); // new cycle
// Re-add prior substate as a modifier if it had the 0x20000000 flag
if (state->substate != motion && (state->substate & 0x20000000))
state->add_modifier_no_check(state->substate, state->substate_mod);
state->substate_mod = speed_mod;
state->substate = motion;
re_modify(this, sequence, state); // re-attach all modifiers
return 1;
}
}
Key takeaway: if the cycle-bound lookup LongHash::lookup(&cycles, (style<<16)|key) returns NULL and the default-style fallback also
returns NULL, retail returns 0 (failure) and the call has no effect.
There is no RunForward → WalkForward → Ready fallback chain — that
is purely an acdream artifact.
D.3 — motion & 0x10000000 (action, e.g. emote)
Lines 298850–298907. Overlay path:
if ((motion & 0x10000000) != 0) {
uint32_t key = (state->style << 0x10) | (state->substate & 0xffffff);
MotionData* current_substate_md = LongHash::lookup(&this->cycles, key);
if (current_substate_md != 0) {
MotionData* link = get_link(this, state->style, state->substate, state->substate_mod, motion, speed_mod);
if (link != 0) {
state->add_action(motion, speed_mod); // append to action queue
sequence->clear_physics();
sequence->remove_cyclic_anims(); // remove looping anims
add_motion(sequence, link, speed_mod); // transition anim (one-shot)
add_motion(sequence, current_substate_md, state->substate_mod); // re-add substate cycle!
re_modify(this, sequence, state);
return 1;
}
}
}
Crucial: actions DO NOT replace the substate cycle. They prepend a one-shot link animation, then re-add the current substate cycle so it keeps looping after the action. Acdream's "Action route" is correct in spirit but should preserve the running cycle exactly like this.
D.4 — motion & 0x20000000 (modifier — turn, sidestep, all overlay cycles)
Lines 298909–298945. Modifier list overlay:
if ((motion & 0x20000000) != 0) {
// current substate must be a non-OneShot cycle
MotionData* current_substate_md = LongHash::lookup(&this->cycles, (state->style << 0x10) | (state->substate & 0xffffff));
if (current_substate_md != 0 && (current_substate_md->bitfield & 1) == 0) {
// Look up the modifier cycle
MotionData* mod_md = LongHash::lookup(&this->modifiers, (state->style << 0x10) | (motion & 0xffffff));
if (mod_md == 0)
mod_md = LongHash::lookup(&this->modifiers, (motion & 0xffffff)); // default-style fallback
if (mod_md != 0) {
int rc = state->add_modifier(motion, speed_mod); // adds to modifier_head list
if (rc == 0) {
// already has a modifier with this motion — stop it and re-add
StopSequenceMotion(this, motion, 1.0f, state, sequence, &num_out);
rc = state->add_modifier(motion, speed_mod);
}
if (rc != 0) {
combine_motion(sequence, mod_md, speed_mod); // BLEND velocity/omega into sequence
return 1;
}
}
}
}
combine_motion (line 298472, addr 00522580) — adds the modifier's
velocity AND omega into the existing sequence via
CSequence::combine_physics. So turn modifiers contribute their omega
on top of the substate's velocity. This is how retail composes
"running while turning while strafing": three layers of physics
contributions in the same CSequence, animated by whichever layers
brought animations in.
E. is_allowed — the gating predicate
Line 298526–298548, address 005226c0. Determines whether an
incoming substate is legal in the current state.
int CMotionTable::is_allowed(this, motion, motion_data, state) {
if (motion_data == 0) return 0;
if ((motion_data->bitfield & 2) != 0) { // requires "default substate"
if (motion != state->substate) {
// Look up the default substate for this style; legal only if state is in it
uint32_t default_substate;
LongNIValHash::lookup(&style_defaults, state->style, &default_substate);
return (default_substate == state->substate) ? 1 : 0;
}
}
return 1;
}
So a substate transition that requires the "ready" state (bitfield bit
- will fail if the player is currently in a non-default substate. This is the retail-correct way to block (for example) a Sit cycle mid-Run — not a custom acdream "skip if airborne" hack.
F. re_modify — the "re-attach modifiers after substate change"
Line 298300–298328, address 005222e0. After a substate transition
that may have cleared modifiers, this walks the modifier list and
re-applies each via GetObjectSequence:
void CMotionTable::re_modify(this, sequence, state) {
if (state->modifier_head == 0) return;
MotionState backup; // 298308
MotionState::MotionState(&backup, state);
while (i != 0) {
MotionList* mod = state->modifier_head;
uint32_t motion = mod->motion;
float speed = mod->speed_mod;
state->remove_modifier(mod, NULL);
backup.remove_modifier(i, NULL);
GetObjectSequence(this, motion, state, sequence, speed, &num_out, 0); // recurse
}
backup.~MotionState();
}
This is why turn + sidestep persist across forward-cycle transitions
(WalkForward → RunForward) — they are stored in modifier_head and
get re-blended every time the substate changes.
G. Final critical answers
G.1 — When forward=RunForward + sidestep=SidestepRight + turn=TurnLeft arrive in one UM, what cycle plays?
All three layered. Specifically, after apply_interpreted_movement
processes the UM:
DoInterpretedMotion(current_style)— re-asserts style; usually no-op if unchanged.DoInterpretedMotion(0x44000007 RunForward, speed=runRate*1.0)—GetObjectSequencetakes the substate path (D.2). Replaces prior substate.state->substate = RunForward.DoInterpretedMotion(0x6500000f SidestepRight, speed=1.248)—GetObjectSequencetakes the modifier path (D.4). Adds tomodifier_head, callscombine_motionto blend sidestep velocity into the runningCSequence. Substate cycle is unchanged (still RunForward).DoInterpretedMotion(0x6500000d TurnLeft, speed=1.5)— same as 3 but for turn. Blends turn omega into the sequence.
Visual result: the RunForward animation cycle plays. Sidestep and
turn contribute velocity/omega only (their cycles are typically motion-
data with velocity != 0 and omega != 0 but num_anims == 0 —
they're physics-only modifiers that don't override the running anim).
Some MotionTables may have animation content on sidestep/turn modifiers
for emphasis, in which case the bones get an additive blend.
G.2 — Substate winner pick, sequential SetCycle, or Frame-level composition?
Sequential GetObjectSequence calls per axis (current_style →
forward → sidestep → turn), each mutating the same CSequence via:
- substate:
clear_physics + remove_cyclic_anims + add_motion(link) + add_motion(new)(replace) - modifier:
combine_motion(additive blend) +state->add_modifier(track for re_modify) - action:
clear_physics + remove_cyclic_anims + add_motion(link) + add_motion(current_substate)(overlay-with-restore)
The final result is a single CSequence carrying:
- One looping substate cycle (animation + velocity/omega contribution)
- Zero or more queued action cycles (one-shot anims; auto-pop via
MotionState::remove_action_headon completion) - Zero or more modifier cycles (additive velocity/omega; usually no animation content)
There is no priority pick. There is no Frame-level layering —
all three are blended into the single CSequence's velocity/omega
fields by add_motion/combine_motion and the result is integrated
once per physics tick.
G.3 — Does the RunForward → WalkForward → Ready fallback chain exist?
No. GetObjectSequence has only one fallback: when the cycle for
the current style isn't found, fall back to default_style's version
(line 298842 in style-change branch, line 298872-298886 in action
branch via style_defaults lookup). If neither exists, return 0 and
the call has no effect.
The acdream fallback (RunForward → WalkForward → Ready) is a
port artifact that papers over the fact that we're not using
MotionTableManager — we're synthesizing cycle-anim association
directly from a hardcoded enum. In a faithful port this fallback
goes away.
G.4 — For Action overlay packets, does retail leave the substate cycle running?
Yes, exactly. D.3 above:
add_motion(sequence, link, speed_mod); // one-shot transition
add_motion(sequence, current_substate_md, state->substate_mod); // re-add running cycle
The MotionState::action_head queue tracks the active actions; the
sequence has both the action's transition anim AND the substate cycle
re-applied. When the action's one-shot anim completes,
CSequence::CheckForCompletedMotions (in CPhysicsObj) pops the
action and re-runs apply_interpreted_movement to restore pure
substate state.
H. Acdream port implications
-
Delete the priority cycle-picker in
OnLiveMotionUpdated. Replace with a faithful port ofapply_interpreted_movement: 4 sequentialMotionTableManager.PerformMovementcalls (current_style, forward, sidestep, turn) per UM. -
Delete the
RunForward → WalkForward → Readyfallback chain entirely. If a MotionTable doesn't have a cycle, retail just silently fails to transition — there is no fallback. Our fallback is masking missing animation data. -
Port
MotionTableManagerso we have an actualMotionState(style + substate + substate_mod + modifier_head + action_head) per remote object, and aCMotionTablelookup chain (cycles/modifiers/links/style_defaults). The current approach of "pick one cycle per UM and play it" cannot represent modifier overlay correctly. -
Run-detection: WalkForward+HoldKey.Run → RunForward must happen in
adjust_motionBEFORE the routing. Acdream'sAnimationCommandRouter.Classifyruns after this transform — correct in concept, but only if our outbound and inbound both apply the transform consistently. (ACE does this on the outbound, so inbound0x07 RunForwardis post-adjusted.) -
Modifier physics:
combine_motionblends velocity AND omega into a singleCSequence. Acdream'sObservedOmegaworkaround (audit doc 06 line 83) is a symptom of not blending omega into the per-tick velocity properly. OnceMotionTableManageris ported, omega comes fromcombine_motionof TurnLeft's modifier cycle and theupdate_objectMinQuantum hack disappears. -
Sidestep direction collapse: retail collapses
SidestepLeft → SidestepRight (negative speed)andTurnRight → TurnLeft (negative speed)inadjust_motion. The modifier list keys on the collapsed form. Acdream must do the same to match the modifier-table lookups.
I. Citation index
| Function | Address | File line |
|---|---|---|
CMotionInterp::DoMotion |
00528d20 |
306159 |
CMotionInterp::DoInterpretedMotion |
00528360 |
305575 |
CMotionInterp::adjust_motion |
00528010 |
305343 |
CMotionInterp::apply_run_to_command |
00527be0 |
305062 |
CMotionInterp::apply_interpreted_movement |
00528600 |
305713 |
CMotionInterp::apply_raw_movement |
005287e0 |
305817 |
CMotionInterp::apply_current_movement |
00528870 |
305838 |
CPhysicsObj::DoInterpretedMotion |
0050ea70 |
276348 |
CPartArray::DoInterpretedMotion |
00518750 |
286772 |
MotionTableManager::PerformMovement |
0051c0b0 |
290906 |
MotionTableManager::initialize_state |
0051c030 |
290875 |
CMotionTable::GetObjectSequence |
00522860 |
298636 |
CMotionTable::DoObjectMotion |
00523e90 |
300045 |
CMotionTable::StopObjectMotion |
00523ec0 |
300053 |
CMotionTable::StopSequenceMotion |
00522fc0 |
298954 |
CMotionTable::SetDefaultState |
005230a0 |
299004 |
CMotionTable::is_allowed |
005226c0 |
298526 |
CMotionTable::get_link |
00522710 |
298552 |
CMotionTable::re_modify |
005222e0 |
298300 |
RawMotionState::ApplyMotion |
0051eb60 |
293630 |
InterpretedMotionState::ApplyMotion |
0051ea40 |
293531 |
MotionState::add_modifier |
00526340 |
303081 |
MotionState::add_modifier_no_check |
00525ff0 |
302772 |
MotionState::add_action |
005260a0 |
302828 |
MotionState::clear_modifiers |
00526070 |
302810 |
MotionState::remove_modifier |
00526040 |
302794 |
add_motion (free fn) |
005224b0 |
298437 |
combine_motion (free fn) |
00522580 |
298472 |
subtract_motion (free fn) |
00522600 |
298492 |
| Constant | Value | Meaning |
|---|---|---|
0x40000000 |
flag | substate class bit (forward axis) |
0x10000000 |
flag | action class bit |
0x20000000 |
flag | modifier class bit |
0x44000007 |
id | RunForward substate |
0x45000005 |
id | WalkForward substate |
0x45000006 |
id | WalkBackward substate (collapses to BackForward) |
0x40000011 |
id | (referenced in jump path) |
0x40000015 |
id | Stand substate |
0x41000003 |
id | Ready substate |
0x6500000d |
id | TurnLeft modifier |
0x6500000e |
id | TurnRight modifier (collapses to TurnLeft) |
0x6500000f |
id | SidestepRight modifier |
0x65000010 |
id | SidestepLeft modifier (collapses to SidestepRight) |
0x6500000f (jump-charge) |
id | charge_jump cycle |
0x8000003d |
id | "no style" sentinel (CombatMode_NonCombat default) |