Reduce GameWindow.OnUpdate to one typed orchestration call and remove transitive window callbacks from teardown, liveness, teleport placement, live presentation, auto-entry, and entity packet routing. Preserve the frozen retail object/network order while making the production owner graph explicit and testable.
68 lines
2.1 KiB
C#
68 lines
2.1 KiB
C#
using System.Numerics;
|
|
|
|
namespace AcDream.App.World;
|
|
|
|
/// <summary>
|
|
/// Session-scoped owner of the landblock origin used to translate retail
|
|
/// full-cell coordinates into the current streamed world coordinate system.
|
|
/// A placeholder can exist before the first authoritative player position;
|
|
/// <see cref="IsKnown"/> distinguishes it from a server-confirmed origin.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This owner is update/render-thread confined with the rest of live world
|
|
/// mutation. It intentionally exposes no cross-thread snapshot contract.
|
|
/// </remarks>
|
|
internal sealed class LiveWorldOriginState
|
|
{
|
|
public int CenterX { get; private set; }
|
|
public int CenterY { get; private set; }
|
|
public bool IsKnown { get; private set; }
|
|
|
|
public void SetPlaceholder(int centerX, int centerY)
|
|
{
|
|
CenterX = centerX;
|
|
CenterY = centerY;
|
|
IsKnown = false;
|
|
}
|
|
|
|
public bool TryInitialize(int centerX, int centerY)
|
|
{
|
|
if (IsKnown)
|
|
return false;
|
|
|
|
CenterX = centerX;
|
|
CenterY = centerY;
|
|
IsKnown = true;
|
|
return true;
|
|
}
|
|
|
|
public void Recenter(int centerX, int centerY)
|
|
{
|
|
CenterX = centerX;
|
|
CenterY = centerY;
|
|
}
|
|
|
|
public (int X, int Y) GetCenter() => (CenterX, CenterY);
|
|
|
|
/// <summary>
|
|
/// Converts the streamed render frame back into retail's landblock-local
|
|
/// physics frame at the one placement seed boundary.
|
|
/// </summary>
|
|
public Vector3 CellLocalForSeed(Vector3 worldPosition, uint cellId)
|
|
{
|
|
int landblockX = (int)((cellId >> 24) & 0xFFu);
|
|
int landblockY = (int)((cellId >> 16) & 0xFFu);
|
|
var origin = new Vector3(
|
|
(landblockX - CenterX) * 192f,
|
|
(landblockY - CenterY) * 192f,
|
|
0f);
|
|
return worldPosition - origin;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends the accepted-origin lifetime while retaining the last coordinates
|
|
/// as the next placeholder. Consumers must gate them on
|
|
/// <see cref="IsKnown"/> until the next accepted player position.
|
|
/// </summary>
|
|
public void Reset() => IsKnown = false;
|
|
}
|