using System.Collections.Generic; using System.Numerics; using AcDream.Core.Physics; using DatReaderWriter.Types; namespace AcDream.Core.Lighting; /// /// Routes animation hooks to the /// — when a torch lights / extinguishes via /// an animation frame, flip the corresponding /// latch. Per r13 §2 the hook is AC's /// way of saying "this Setup's baked-in LightInfo is now active". /// /// /// Registration: at entity spawn time the caller walks the Setup's /// Lights dictionary and registers a /// per LightInfo, tagging it with the owning entity id. When a /// hook fires later, we look up every light tagged to that owner and /// flip them all together (retail's SetLightHook is a per-setup /// boolean, not per-light). /// /// public sealed class LightingHookSink : IAnimationHookSink { private readonly LightManager _lights; // Index owner → the set of LightSource instances they registered. // Maintained lazily — populated on first RegisterLight for that owner. private readonly Dictionary> _byOwner = new(); public LightingHookSink(LightManager lights) { _lights = lights ?? throw new System.ArgumentNullException(nameof(lights)); } /// /// Register a light with the manager + track it by owner so later /// SetLightHook / Unregister calls can reach it. /// public void RegisterOwnedLight(LightSource light) { System.ArgumentNullException.ThrowIfNull(light); _lights.Register(light); if (!_byOwner.TryGetValue(light.OwnerId, out var list)) { list = new List(); _byOwner[light.OwnerId] = list; } list.Add(light); } /// Drop every light tagged to this owner (despawn / unload). public void UnregisterOwner(uint ownerId) { if (!_byOwner.TryGetValue(ownerId, out var list)) return; foreach (var l in list) _lights.Unregister(l); _byOwner.Remove(ownerId); } /// /// Get the set of registered lights for an owner — exposed so /// callers can reposition them (torch on hand follows hand part). /// public IReadOnlyList? GetOwnedLights(uint ownerId) { return _byOwner.TryGetValue(ownerId, out var list) ? list : null; } public void OnHook(uint entityId, Vector3 entityWorldPosition, AnimationHook hook) { if (hook is not SetLightHook slh) return; if (!_byOwner.TryGetValue(entityId, out var list)) return; foreach (var light in list) light.IsLit = slh.LightsOn; } }