fix(portal): synchronize destination presentation state
This commit is contained in:
parent
4b1bceefbb
commit
e95f55f25b
42 changed files with 2815 additions and 288 deletions
|
|
@ -200,19 +200,63 @@ public sealed class PhysicsBody
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Commits the position and full cell returned by a successful transition.
|
||||
/// Retail <c>CPhysicsObj::SetPositionInternal(CTransition const*)</c>
|
||||
/// (<c>0x00515330</c>) always commits both
|
||||
/// <c>sphere_path.curr_pos.objcell_id</c> and its frame, including EnvCells.
|
||||
/// The ordinary <see cref="Position"/> setter first carries the accepted world
|
||||
/// displacement into the landblock-relative frame; this method then adopts the
|
||||
/// resolver's exact cell identity. Outdoor frames are canonicalized across 24 m
|
||||
/// cells and 192 m landblock boundaries. Indoor frames retain their carried
|
||||
/// landblock-relative origin and adopt the resolved EnvCell id.
|
||||
/// </summary>
|
||||
public void CommitTransitionPosition(uint resolvedCellId, Vector3 worldPosition)
|
||||
{
|
||||
Position = worldPosition;
|
||||
|
||||
if (CellPosition.ObjCellId == 0 || resolvedCellId == 0)
|
||||
return;
|
||||
|
||||
uint cell = resolvedCellId;
|
||||
Vector3 local = CellPosition.Frame.Origin;
|
||||
if ((cell & 0xFFFFu) is >= 1u and <= 0x40u
|
||||
&& !LandDefs.AdjustToOutside(ref cell, ref local))
|
||||
{
|
||||
// At the map edge retail's transition does not yield a successful
|
||||
// outside cell. Preserve the carried frame instead of inventing one.
|
||||
return;
|
||||
}
|
||||
|
||||
CellPosition = new Position(
|
||||
cell,
|
||||
new CellFrame(local, CellPosition.Frame.Orientation));
|
||||
}
|
||||
|
||||
// Mirror a world-position translation into the cell-relative frame. Velocity is
|
||||
// frame-invariant under translation, so the same delta applies to the local origin.
|
||||
// AdjustToOutside then recomputes the cell index from the local (intra-landblock 24 m
|
||||
// cell crossings) AND wraps + bumps the landblock on a 192 m crossing — the outdoor
|
||||
// membership + canonicalization in one call (get_outside_lcoord + lcoord_to_gid +
|
||||
// [0,192) wrap). Idempotent within a cell. Runs only for a SEEDED OUTDOOR cell;
|
||||
// unseeded bodies (ObjCellId==0, e.g. remote entities) and indoor cells are skipped.
|
||||
// [0,192) wrap). Idempotent within a cell. A SEEDED indoor body carries the same
|
||||
// landblock-relative delta but keeps its EnvCell identity until the transition result
|
||||
// commits the exact destination via CommitTransitionPosition. Unseeded bodies are skipped.
|
||||
private void SyncCellPositionDelta(Vector3 delta)
|
||||
{
|
||||
uint cell = CellPosition.ObjCellId;
|
||||
if ((cell & 0xFFFFu) is not (>= 1u and <= 0x40u))
|
||||
if (cell == 0)
|
||||
return;
|
||||
|
||||
Vector3 local = CellPosition.Frame.Origin + delta;
|
||||
|
||||
if ((cell & 0xFFFFu) is not (>= 1u and <= 0x40u))
|
||||
{
|
||||
CellPosition = new Position(
|
||||
cell,
|
||||
new CellFrame(local, CellPosition.Frame.Orientation));
|
||||
return;
|
||||
}
|
||||
|
||||
uint adjusted = cell;
|
||||
if (LandDefs.AdjustToOutside(ref adjusted, ref local))
|
||||
CellPosition = new Position(adjusted, new CellFrame(local, CellPosition.Frame.Orientation));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue