fix(world): retire motion links at hidden transitions
Port CPhysicsObj::set_hidden's PartArray HandleEnterWorld boundary on both Hidden and UnHide. This strips linked recall/casting animations and aborts their pending completions before cell visibility changes, preventing spell-recall tails after portal travel without arrival resets or action classifiers.\n\nCo-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
parent
75acae02d6
commit
bfb4b26dff
6 changed files with 185 additions and 21 deletions
|
|
@ -300,21 +300,45 @@ SmartBox.UseTime:
|
|||
|
||||
The exact call sites are `Client::UseTime` `0x00411C40` and
|
||||
`SmartBox::UseTime` `0x00455410`, and `CommandInterpreter::UseTime`
|
||||
`0x006B3BF0`. `SmartBox::DoSetState` `0x004520D0`
|
||||
applies Hidden directly and does not advance or reset animation. Separately,
|
||||
`0x006B3BF0`. `SmartBox::DoSetState` `0x004520D0` applies the accepted
|
||||
state through `CPhysicsObj::set_state` `0x00514DD0`. Separately,
|
||||
`CPhysicsObj::UpdatePositionInternal` `0x00512C30` skips `CPartArray::Update`
|
||||
while Hidden. Therefore the ordering boundary is load-bearing: the current
|
||||
frame's animation must advance before an inbound Hidden transition can freeze
|
||||
it.
|
||||
while Hidden, so ordinary animation never advances behind the portal viewport.
|
||||
|
||||
ACE schedules lifestone recall teleport after the MotionTable-reported action
|
||||
length. With the installed human DATs, the boundary is about 15.06024 seconds;
|
||||
floating-point conversion can leave acdream at frame 149.999998 of the
|
||||
0..149 recall node if it dispatches Hidden before the current object tick. On
|
||||
UnHide that microscopic remainder becomes a visible destination-side recall
|
||||
tail. Retail's object-before-network order retires the node first. The faithful
|
||||
fix is that frame barrier, never an arrival-only Ready/reset command and never
|
||||
advancing PartArray while Hidden.
|
||||
tail if Hidden only suppresses drawing. Retail has a second, decisive boundary:
|
||||
`CPhysicsObj::set_hidden` `0x00514C60` invokes
|
||||
`CPartArray::HandleEnterWorld` `0x00517D70` on **both** Hidden and UnHide.
|
||||
That delegates to `MotionTableManager::HandleEnterWorld` `0x0051BDD0`, which
|
||||
removes every link animation from the sequence and drains every pending
|
||||
completion as aborted. On the Hidden edge it runs after the Hidden PES, child
|
||||
NoDraw propagation, collision stop, and cell hide. On UnHide it runs after
|
||||
collision restoration and before the cell becomes visible. A casting recoil,
|
||||
recall remainder, or authored stance transition therefore cannot resume after
|
||||
portal space.
|
||||
|
||||
ACE also has timing differences when recall starts in combat. Its
|
||||
`Player_Location` handlers call `SetCombatMode(NonCombat)` and immediately send
|
||||
the NonCombat/Ready/recall command state. House, Lifestone, Allegiance Hometown,
|
||||
and PK Arena schedule `Teleport` using only
|
||||
`MotionTable.GetAnimationLength(recall)`. Retail
|
||||
`MovementManager::unpack_movement` (`0x00524440`) and
|
||||
`CMotionInterp::move_to_interpreted_state` (`0x005289C0`) preserve the authored
|
||||
combat-to-NonCombat link before the recall action. For a human leaving Magic
|
||||
stance that link is about 0.31 seconds, but ACE does not add it to the teleport
|
||||
delay. The retail Hidden boundary intentionally tolerates that: whichever
|
||||
authored links remain when teleport begins are retired by `set_hidden`, not
|
||||
carried through the tunnel.
|
||||
|
||||
Marketplace is a separate ACE residual: its handler deliberately uses a fixed
|
||||
14-second delay and comments out `GetAnimationLength` because the installed
|
||||
animation is approximately 18.4 seconds. That can shorten the visible source-
|
||||
side action, but the client must still apply the same retail Hidden teardown;
|
||||
no Marketplace-specific classifier or portal-exit behavior is required.
|
||||
|
||||
## acdream integration translation
|
||||
|
||||
|
|
@ -355,6 +379,11 @@ advancing PartArray while Hidden.
|
|||
by that inbound pass is likewise projected without receiving a late physics
|
||||
tick; its first normal object tick occurs on the next update.
|
||||
This is update-loop ordering, not portal-specific animation logic.
|
||||
- `LiveEntityPresentationController` owns the complete accepted Hidden/UnHide
|
||||
side-effect order. Both edges route the current local entity to its existing
|
||||
`AnimationSequencer.Manager.HandleEnterWorld`, matching retail's PartArray
|
||||
boundary for player, creature, and object animations without classifying the
|
||||
preceding action.
|
||||
- Destination residency remains acdream's asynchronous adaptation. It supplies
|
||||
the same `EndTeleportAnimation` edge retail receives when its blocking cell
|
||||
load completes; it does not alter presentation ordering.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue