feat(slice2): wire outdoorReady into TeleportArrivalReadiness (GameWindow)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b47b21570a
commit
b745850ab8
1 changed files with 24 additions and 9 deletions
|
|
@ -5471,6 +5471,7 @@ public sealed class GameWindow : IDisposable
|
||||||
// impossible claim / timeout. PortalSpace keeps input frozen meanwhile.
|
// impossible claim / timeout. PortalSpace keeps input frozen meanwhile.
|
||||||
EnsureTeleportArrivalController();
|
EnsureTeleportArrivalController();
|
||||||
_pendingTeleportRot = rot;
|
_pendingTeleportRot = rot;
|
||||||
|
_lastArrivalVerdict = AcDream.App.World.ArrivalReadiness.NotReady; // reset probe state for each new hold
|
||||||
_teleportArrival!.BeginArrival(newWorldPos, p.LandblockId);
|
_teleportArrival!.BeginArrival(newWorldPos, p.LandblockId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5481,6 +5482,8 @@ public sealed class GameWindow : IDisposable
|
||||||
// runtime deps are wired by then).
|
// runtime deps are wired by then).
|
||||||
private AcDream.App.World.TeleportArrivalController? _teleportArrival;
|
private AcDream.App.World.TeleportArrivalController? _teleportArrival;
|
||||||
private System.Numerics.Quaternion _pendingTeleportRot = System.Numerics.Quaternion.Identity;
|
private System.Numerics.Quaternion _pendingTeleportRot = System.Numerics.Quaternion.Identity;
|
||||||
|
// §3.4 arrival-gate probe: tracks previous verdict so we log only the flip.
|
||||||
|
private AcDream.App.World.ArrivalReadiness _lastArrivalVerdict = AcDream.App.World.ArrivalReadiness.NotReady;
|
||||||
|
|
||||||
// #145: the LANDBLOCK-relative (cell-local) position used to SEED the player
|
// #145: the LANDBLOCK-relative (cell-local) position used to SEED the player
|
||||||
// body's cell-relative CellPosition. This is the ONE place the streaming center
|
// body's cell-relative CellPosition. This is the ONE place the streaming center
|
||||||
|
|
@ -5509,24 +5512,36 @@ public sealed class GameWindow : IDisposable
|
||||||
// Reuses the #107 login readiness triplet (GameWindow.cs:1010-1024), evaluated
|
// Reuses the #107 login readiness triplet (GameWindow.cs:1010-1024), evaluated
|
||||||
// against the teleport's (destPos, destCell): an impossible indoor claim short-
|
// against the teleport's (destPos, destCell): an impossible indoor claim short-
|
||||||
// circuits to immediate placement; otherwise hold until terrain is sampled and,
|
// circuits to immediate placement; otherwise hold until terrain is sampled and,
|
||||||
// for an indoor cell, the cell struct has hydrated.
|
// for an indoor cell, the cell struct has hydrated. For an outdoor cell, hold
|
||||||
|
// until the physics landblock is registered (§3.4 #145 residual fix).
|
||||||
private AcDream.App.World.ArrivalReadiness TeleportArrivalReadiness(
|
private AcDream.App.World.ArrivalReadiness TeleportArrivalReadiness(
|
||||||
System.Numerics.Vector3 destPos, uint destCell)
|
System.Numerics.Vector3 destPos, uint destCell)
|
||||||
{
|
{
|
||||||
bool claimUnhydratable = IsSpawnClaimUnhydratable(destCell);
|
bool claimUnhydratable = IsSpawnClaimUnhydratable(destCell);
|
||||||
|
|
||||||
// #135: an INDOOR destination (sealed dungeon / building interior) gates on the
|
|
||||||
// EnvCell FLOOR hydrating. Retail places on the cell floor. An OUTDOOR destination
|
|
||||||
// places immediately on the server-authoritative position — see TeleportArrivalRules
|
|
||||||
// (#145: holding is futile because streaming doesn't progress during a PortalSpace
|
|
||||||
// hold; the stale source landblock is dropped at recenter so the resolve trusts the
|
|
||||||
// server cell until the destination streams in).
|
|
||||||
bool indoor = (destCell & 0xFFFFu) >= 0x0100u;
|
bool indoor = (destCell & 0xFFFFu) >= 0x0100u;
|
||||||
bool indoorCellReady = indoor && !claimUnhydratable
|
bool indoorCellReady = indoor && !claimUnhydratable
|
||||||
&& _physicsEngine.IsSpawnCellReady(destCell);
|
&& _physicsEngine.IsSpawnCellReady(destCell);
|
||||||
|
// §3.4: for outdoor arrivals, gate on the physics landblock being resident.
|
||||||
|
// The landblock id is the high 16 bits of the cell id (i.e. destCell & 0xFFFF0000).
|
||||||
|
// Streaming progresses during the hold because the streaming controller runs before
|
||||||
|
// TeleportArrivalController.Tick. The 10 s _maxHoldFrames safety-net remains active.
|
||||||
|
bool outdoorReady = !indoor
|
||||||
|
&& _physicsEngine.IsLandblockLoaded(destCell & 0xFFFF0000u);
|
||||||
|
|
||||||
return AcDream.App.World.TeleportArrivalRules.Decide(
|
var verdict = AcDream.App.World.TeleportArrivalRules.Decide(
|
||||||
claimUnhydratable, indoor, indoorCellReady);
|
claimUnhydratable, indoor, indoorCellReady, outdoorReady);
|
||||||
|
|
||||||
|
if (AcDream.Core.Physics.PhysicsDiagnostics.ProbeArrivalGateEnabled
|
||||||
|
&& verdict != _lastArrivalVerdict
|
||||||
|
&& verdict != AcDream.App.World.ArrivalReadiness.NotReady)
|
||||||
|
{
|
||||||
|
Console.WriteLine(System.FormattableString.Invariant(
|
||||||
|
$"[arrival-gate] destCell=0x{destCell:X8} landblock=0x{(destCell & 0xFFFF0000u):X8} verdict={verdict} indoor={indoor} landblockCount={_physicsEngine.LandblockCount}"));
|
||||||
|
}
|
||||||
|
_lastArrivalVerdict = verdict;
|
||||||
|
|
||||||
|
return verdict;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The deferred snap (the original OnLivePositionUpdated steps 2-5), now run only
|
// The deferred snap (the original OnLivePositionUpdated steps 2-5), now run only
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue