Port retail's radius-aware placement ring so a relogging player is seated beside creatures occupying the saved location, and register the local body in the shared resolved-shadow pipeline. Route new forward movement and jump through AbortAutomaticAttack so repeat combat cancels immediately on movement. Co-Authored-By: Codex <codex@openai.com>
39 lines
1.1 KiB
C#
39 lines
1.1 KiB
C#
using System.Numerics;
|
|
using AcDream.Core.Physics;
|
|
|
|
namespace AcDream.App.Physics;
|
|
|
|
/// <summary>
|
|
/// Shared host adapter for retail's moved-object shadow re-registration
|
|
/// (<c>CPhysicsObj::SetPositionInternal</c> 0x00515330). Both the local body
|
|
/// and remote dead-reckoning bodies publish their resolved position through
|
|
/// this one cell-offset calculation.
|
|
/// </summary>
|
|
internal static class ShadowPositionSynchronizer
|
|
{
|
|
public static void Sync(
|
|
ShadowObjectRegistry registry,
|
|
uint entityId,
|
|
Vector3 position,
|
|
Quaternion orientation,
|
|
uint cellId,
|
|
int liveCenterX,
|
|
int liveCenterY)
|
|
{
|
|
if (cellId == 0)
|
|
return;
|
|
|
|
int landblockX = (int)((cellId >> 24) & 0xFFu);
|
|
int landblockY = (int)((cellId >> 16) & 0xFFu);
|
|
float worldOffsetX = (landblockX - liveCenterX) * 192f;
|
|
float worldOffsetY = (landblockY - liveCenterY) * 192f;
|
|
registry.UpdatePosition(
|
|
entityId,
|
|
position,
|
|
orientation,
|
|
worldOffsetX,
|
|
worldOffsetY,
|
|
cellId,
|
|
seedCellId: cellId);
|
|
}
|
|
}
|