fix(G.3): recenter streaming onto the spawn landblock at login (#133)
A character saved inside a far dungeon hung at the #107 auto-entry hold because the streaming center was fixed at the startup default and the login spawn never recentered it, so the dungeon never streamed. Mirror the teleport-arrival recenter on the login player-spawn path: when the player's spawn landblock differs from the current center, recenter before translating the spawn position (landblock-local -> new-center frame). No-op for a same-landblock (normal Holtburg) login. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
95d9dab4bb
commit
47ae237e7b
1 changed files with 34 additions and 0 deletions
|
|
@ -2436,6 +2436,40 @@ public sealed class GameWindow : IDisposable
|
|||
// landblock; each neighbor landblock is offset by 192 units per step.
|
||||
int lbX = (int)((p.LandblockId >> 24) & 0xFFu);
|
||||
int lbY = (int)((p.LandblockId >> 16) & 0xFFu);
|
||||
|
||||
// G.3 (#133): recenter streaming onto the player's spawn landblock at
|
||||
// login. The streaming center (_liveCenterX/_liveCenterY) is pinned to
|
||||
// the startup default (Holtburg, 0xA9B4) and is otherwise only moved by
|
||||
// the teleport-arrival path (OnLivePositionUpdated, ~line 4901). A
|
||||
// character saved INSIDE a far dungeon spawns with that dungeon's
|
||||
// landblock id, but the center never followed it, so the dungeon (tens
|
||||
// of km away in world space) never streamed and the #107 auto-entry
|
||||
// gate's SampleTerrainZ(pe.Position) waited forever — the player hung
|
||||
// frozen at login. Mirror the teleport-arrival recenter HERE, for the
|
||||
// PLAYER's spawn only, BEFORE the world-space translation below: when
|
||||
// the spawn landblock differs from the current center, move the center
|
||||
// onto it so the spawn maps to (PositionX, PositionY, PositionZ) in the
|
||||
// new center frame (identical to the teleport path's
|
||||
// `newWorldPos = new Vector3(p.PositionX, p.PositionY, p.PositionZ)`),
|
||||
// and the next StreamingController.Tick observes the new center and
|
||||
// streams the spawn landblock.
|
||||
//
|
||||
// No-op for a normal Holtburg login: the saved spawn landblock equals
|
||||
// the default center, so the guard is false and origin/worldPos are
|
||||
// byte-identical to the pre-fix path. Gated on the player guid so NPC /
|
||||
// object spawns never move the center. Idempotent + thrash-free: a
|
||||
// re-sent CreateObject for the same spawn landblock leaves the center
|
||||
// already-equal, so the guard is false on every repeat.
|
||||
if (spawn.Guid == _playerServerGuid
|
||||
&& (lbX != _liveCenterX || lbY != _liveCenterY))
|
||||
{
|
||||
Console.WriteLine(
|
||||
$"live: login spawn — recentering streaming from ({_liveCenterX},{_liveCenterY}) " +
|
||||
$"to ({lbX},{lbY}) for player spawn @0x{p.LandblockId:X8}");
|
||||
_liveCenterX = lbX;
|
||||
_liveCenterY = lbY;
|
||||
}
|
||||
|
||||
var origin = new System.Numerics.Vector3(
|
||||
(lbX - _liveCenterX) * 192f,
|
||||
(lbY - _liveCenterY) * 192f,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue