using System.Numerics; using DatReaderWriter.Types; namespace AcDream.Core.Physics; /// /// Phase E.1 — the consumption point for hooks that /// emits during each Advance tick. /// /// /// The sequencer mirrors ACE's Sequence.execute_hooks / /// PhysicsObj.add_anim_hook by collecting all hooks that fire at /// each crossed frame boundary; a per-entity tick loop drains /// and forwards each /// hook to an IAnimationHookSink implementation. /// /// /// /// In production the sink fans hooks out to downstream subsystems: /// /// /// / / /// → Phase E.2 audio engine /// (OpenAL voice allocation + 3D positional playback). /// /// /// / /// / / /// / / /// → Phase E.3 particle system. /// /// /// → Phase E.4 combat dispatcher /// (animation-hook frame = damage frame for melee / thrown). /// /// /// , /// , /// , /// , /// , /// , /// , /// , /// → /// GfxObjMesh / renderer state mutations on the target entity. /// /// /// → UI / controller notifications /// ("emote finished", "attack animation complete"). /// /// /// /// /// /// A is provided for headless tests and /// for offline mode where audio/particles aren't desired. /// /// public interface IAnimationHookSink { /// /// Called for each hook produced by . /// /// /// Local WorldEntity id that produced this hook. The sink can use this /// to attach side-effects to the right entity (e.g. 3D-positional /// audio at that entity's world position). /// /// /// Current world-space position of the entity, captured at tick time. /// Pre-computed for the sink so each implementation doesn't have to /// resolve it independently. /// /// The hook (a typed subclass of AnimationHook). void OnHook(uint entityId, Vector3 entityWorldPosition, AnimationHook hook); } /// /// No-op — discards every hook. /// Used for tests + headless renders. /// public sealed class NullAnimationHookSink : IAnimationHookSink { public static readonly NullAnimationHookSink Instance = new(); private NullAnimationHookSink() { } public void OnHook(uint entityId, Vector3 entityWorldPosition, AnimationHook hook) { } }