fix(anim): Phase L.1c route creature actions and despawns

Handle retail ObjectDelete (0xF747) using CM_Physics::DispatchSB_DeleteObject 0x006AC6A0 / SmartBox::HandleDeleteObject 0x00451EA0 and ACE GameMessageDeleteObject so dead creatures are removed when corpses spawn.

Route action-class ForwardCommand values through AnimationCommandRouter/PlayAction instead of SetCycle so creature attack commands 0x51/0x52/0x53 survive the immediate Ready echo, matching CMotionTable::GetObjectSequence 0x00522860 / ACE MotionTable.GetObjectSequence.

Use server-authoritative UpdatePosition velocity, or observed server position delta for non-player entities when HasVelocity is absent, to reduce monster/NPC chase lag without applying player RUM prediction to server-controlled creatures.
This commit is contained in:
Erik 2026-04-28 19:21:02 +02:00
parent 4874d8595a
commit b96b680a20
5 changed files with 235 additions and 21 deletions

View file

@ -61,6 +61,16 @@ public sealed class WorldSession : IDisposable
/// <summary>Fires when the session finishes parsing a CreateObject.</summary>
public event Action<EntitySpawn>? EntitySpawned;
/// <summary>
/// Fires when the session parses a 0xF747 ObjectDelete game message.
/// Retail routes this through
/// <c>CM_Physics::DispatchSB_DeleteObject</c> 0x006AC6A0 →
/// <c>SmartBox::HandleDeleteObject</c> 0x00451EA0; ACE emits it when
/// an object leaves the world, including the living creature object
/// after its corpse is created.
/// </summary>
public event Action<DeleteObject.Parsed>? EntityDeleted;
/// <summary>
/// Payload for <see cref="MotionUpdated"/>: the server guid of the entity
/// whose motion changed and its new server-side stance + forward command.
@ -641,6 +651,12 @@ public sealed class WorldSession : IDisposable
parsed.Value.MotionTableId));
}
}
else if (op == DeleteObject.Opcode)
{
var parsed = DeleteObject.TryParse(body);
if (parsed is not null)
EntityDeleted?.Invoke(parsed.Value);
}
else if (op == UpdateMotion.Opcode)
{
// Phase 6.6: the server sends UpdateMotion (0xF74C) whenever an