feat(physics): P5 commit 2 - arm the ConstraintManager leash on accepted positions (#167)
Wire ConstraintManager.ConstrainTo at every current acdream inbound-position acceptance seam, matching retail SmartBox::HandleReceivedPosition (0x00453fd0): - Remote (player + NPC): LiveEntityNetworkUpdateController arms right after the hard-teleport branch (remotePlacementRequired) returns - reaching that point already means MoveOrTeleport did NOT hard-place - anchored to the object's own live IPhysicsObjHost.Position. - Local player teleport: PlayerMovementController.SetPositionCore now runs UnConstrain (retail teleport_hook 0x00514ed0, previously a no-op because nothing armed the leash) then re-arms anchored to the just-snapped position, composing with the existing StopCompletelyAtPhysicsObjectBoundary velocity zero rather than duplicating it. CommitPreparedPosition mirrors the same pair for the deferred player-mode-entry commit path. - Local player ForcePosition: PlayerMovementController.BlipPosition arms with NO preceding UnConstrain (retail BlipPlayer/SetPositionSimple survives motion/velocity/stick, and the leash is no different). Push PhysicsBody.IsFullyConstrained from PositionManager.IsFullyConstrained at the SAME per-tick chokepoint each pump already runs AdjustOffset (PlayerMovementController.Update, RuntimeRemotePhysicsUpdater.Tick/TickHidden) so TS-35's read gate in jump_is_allowed sees live state instead of a stub that is never written. Tests: local-player arm/teardown/rearm/taper/jump-refusal (Runtime.Tests, PlayerMovementControllerTests), remote-tick IsFullyConstrained push (Runtime.Tests, RuntimePhysicsStateTests). Full Core/Runtime/App suites green with no regressions.
This commit is contained in:
parent
378d0b6ca0
commit
7719d25bc5
5 changed files with 330 additions and 3 deletions
|
|
@ -1353,6 +1353,30 @@ internal sealed class LiveEntityNetworkUpdateController
|
|||
return;
|
||||
}
|
||||
|
||||
// #167 (Campaign P P5): retail SmartBox::HandleReceivedPosition
|
||||
// (0x00453fd0) arms the ConstraintManager leash for every remote
|
||||
// MoveOrTeleport call that returns nonzero (did NOT hard-teleport —
|
||||
// the remotePlacementRequired branch above already handled and
|
||||
// returned on the hard-teleport case), anchored to the object's OWN
|
||||
// current position, generically for player AND NPC remotes (the
|
||||
// disassembly's "this == player" branch loads identical constants
|
||||
// either way — see ConstraintDistance). ConstraintManager.ConstrainTo
|
||||
// captures ConstraintPosOffset = distance(anchor, host.Position) at
|
||||
// call time; since the anchor here IS host.Position (read live,
|
||||
// matching every other PositionManager/TargetManager consumer's
|
||||
// notion of "this object's position"), this always (re)starts the
|
||||
// leash at zero displacement on a fresh accepted Position, matching
|
||||
// retail's per-packet re-anchor.
|
||||
// docs/research/2026-07-30-constraint-leash-constants.md §2/§3.2.
|
||||
if (rmState.Host is { } remoteConstraintHost)
|
||||
{
|
||||
AcDream.Core.Physics.Position anchor = remoteConstraintHost.Position;
|
||||
remoteConstraintHost.PositionManager.ConstrainTo(
|
||||
anchor,
|
||||
AcDream.Core.Physics.Motion.ConstraintDistance.GetStartConstraintDistance(anchor.ObjCellId),
|
||||
AcDream.Core.Physics.Motion.ConstraintDistance.GetMaxConstraintDistance(anchor.ObjCellId));
|
||||
}
|
||||
|
||||
// L.3 M2 (2026-05-05): retail-faithful MoveOrTeleport routing for
|
||||
// player remotes. Mirrors CPhysicsObj::MoveOrTeleport
|
||||
// (acclient @ 0x00516330) — airborne no-op, far-snap, near
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue