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.
|
// landblock; each neighbor landblock is offset by 192 units per step.
|
||||||
int lbX = (int)((p.LandblockId >> 24) & 0xFFu);
|
int lbX = (int)((p.LandblockId >> 24) & 0xFFu);
|
||||||
int lbY = (int)((p.LandblockId >> 16) & 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(
|
var origin = new System.Numerics.Vector3(
|
||||||
(lbX - _liveCenterX) * 192f,
|
(lbX - _liveCenterX) * 192f,
|
||||||
(lbY - _liveCenterY) * 192f,
|
(lbY - _liveCenterY) * 192f,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue