feat(vfx): port retail hidden and teleport presentation

Preserve canonical live-object ownership across Hidden transitions and remote teleport placement so effects, collision, streaming, and targeting remain synchronized.
This commit is contained in:
Erik 2026-07-14 14:59:48 +02:00
parent a51ebc66e9
commit 1e98d81448
46 changed files with 4883 additions and 127 deletions

View file

@ -103,6 +103,19 @@ public sealed class EntityEffectController : IAnimationHookSink
/// original mixed F754/F755 order.
/// </summary>
public bool OnLiveEntityReady(uint serverGuid)
{
if (!PrepareLiveEntityOwner(serverGuid))
return false;
ReplayPendingForLiveEntity(serverGuid);
return true;
}
/// <summary>
/// Registers the local effect owner without replaying pre-create packets.
/// Production uses this narrow barrier so constructor/set_description
/// state effects can run before SmartBox replays queued network blobs.
/// </summary>
public bool PrepareLiveEntityOwner(uint serverGuid)
{
if (!_liveEntities.TryGetRecord(serverGuid, out LiveEntityRecord record)
|| record.WorldEntity is not { } entity
@ -116,7 +129,15 @@ public sealed class EntityEffectController : IAnimationHookSink
_profilesByLocalId[entity.Id] = profile;
_runner.SetOwnerAnchor(entity.Id, entity.Position);
_ownerSoundTableChanged(entity.Id, profile.CurrentSoundTableDid);
TryReplayPending(serverGuid, entity.Id);
return true;
}
/// <summary>Replays the mixed F754/F755 FIFO after full object construction.</summary>
public bool ReplayPendingForLiveEntity(uint serverGuid)
{
if (!TryGetReadyLocalId(serverGuid, out uint localId))
return false;
TryReplayPending(serverGuid, localId);
return true;
}