using Theriapolis.Core.Rules.Combat; namespace Theriapolis.Core.Entities.Ai; /// /// One NPC behavior — what does this NPC do on its turn? Behaviors are /// dispatched by id (the template's behavior field) via /// . Each behavior must produce its turn's /// actions within bounded time — no recursion, no while-true loops; if no /// valid action is available, end the turn. /// public interface INpcBehavior { /// /// Take one turn for . Behaviors call into /// to mutate the encounter, then return — the /// caller (typically 's turn pump) calls /// after this returns. /// void TakeTurn(Combatant self, AiContext ctx); } /// /// Maps behavior ids (the strings in npc_templates.json's /// behavior field) to their /// implementation. Phase 5 M5 ships three: brigand, /// wild_animal, poi_guard. Unknown ids fall back to /// brigand with a debug log. /// public static class BehaviorRegistry { private static readonly System.Collections.Generic.Dictionary _impls = new(System.StringComparer.OrdinalIgnoreCase) { ["brigand"] = new BrigandBehavior(), ["wild_animal"] = new WildAnimalBehavior(), ["poi_guard"] = new PoiGuardBehavior(), ["patrol"] = new BrigandBehavior(), // patrol shares brigand combat behavior }; public static INpcBehavior For(string id) { return _impls.TryGetValue(id, out var b) ? b : _impls["brigand"]; } }