feat(vfx): port retail hidden and teleport presentation
Preserve canonical live-object ownership across Hidden transitions and remote teleport placement so effects, collision, streaming, and targeting remain synchronized.
This commit is contained in:
parent
a51ebc66e9
commit
1e98d81448
46 changed files with 4883 additions and 127 deletions
|
|
@ -45,6 +45,70 @@ public static class PhysicsObjUpdate
|
|||
body.calc_acceleration();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commits the contact/walkable/collision-response tail of retail
|
||||
/// <c>CPhysicsObj::SetPositionInternal</c> (<c>0x00515330</c>) in its
|
||||
/// original order. The pre-transition flags are explicit because a
|
||||
/// deferred placement may temporarily park the body without contact while
|
||||
/// still needing the source edge when its destination cell becomes ready.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Retail writes Contact and recalculates acceleration, calls
|
||||
/// <c>set_on_walkable</c> (which invokes HitGround/LeaveGround), then calls
|
||||
/// <c>handle_all_collisions</c> at <c>0x005154FE</c>. Collision response
|
||||
/// must therefore observe any velocity change made by the movement
|
||||
/// callback; moving that callback after reflection changes the result.
|
||||
/// </remarks>
|
||||
public static void CommitSetPositionTransition(
|
||||
PhysicsBody body,
|
||||
bool inContact,
|
||||
bool onWalkable,
|
||||
bool collisionNormalValid,
|
||||
Vector3 collisionNormal,
|
||||
bool previousContact,
|
||||
bool previousOnWalkable,
|
||||
Action? hitGround = null,
|
||||
Action? leaveGround = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(body);
|
||||
|
||||
// SetPositionInternal replaces Contact first but retains the source
|
||||
// OnWalkable bit through its first calc_acceleration call. A deferred
|
||||
// teleport may have parked the live body with both bits cleared, so
|
||||
// restore the captured source bit explicitly before reproducing that
|
||||
// ordering.
|
||||
if (previousOnWalkable)
|
||||
body.TransientState |= TransientStateFlags.OnWalkable;
|
||||
else
|
||||
body.TransientState &= ~TransientStateFlags.OnWalkable;
|
||||
|
||||
if (inContact)
|
||||
body.TransientState |= TransientStateFlags.Contact;
|
||||
else
|
||||
body.TransientState &= ~TransientStateFlags.Contact;
|
||||
body.calc_acceleration();
|
||||
|
||||
bool finalOnWalkable = inContact && onWalkable;
|
||||
if (finalOnWalkable)
|
||||
body.TransientState |= TransientStateFlags.OnWalkable;
|
||||
else
|
||||
body.TransientState &= ~TransientStateFlags.OnWalkable;
|
||||
|
||||
if (!previousOnWalkable && finalOnWalkable)
|
||||
hitGround?.Invoke();
|
||||
else if (previousOnWalkable && !finalOnWalkable)
|
||||
leaveGround?.Invoke();
|
||||
body.calc_acceleration();
|
||||
|
||||
HandleAllCollisions(
|
||||
body,
|
||||
collisionNormalValid,
|
||||
collisionNormal,
|
||||
previousContact,
|
||||
previousOnWalkable,
|
||||
finalOnWalkable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// retail <c>handle_all_collisions</c> (0x00514780). Reflects or zeros the body's
|
||||
/// <see cref="PhysicsBody.Velocity"/> (retail m_velocityVector) based on
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue