init commit
This commit is contained in:
72
app/utils/catalogs/race_catalog.py
Normal file
72
app/utils/catalogs/race_catalog.py
Normal file
@@ -0,0 +1,72 @@
|
||||
# race_catalog.py
|
||||
from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Any
|
||||
import yaml
|
||||
|
||||
|
||||
from app.models.enums import Race
|
||||
from app.models.primitives import Attributes, Resources
|
||||
from app.models.races import RaceSheet, RacialTrait
|
||||
from app.utils.hero_catalog import SkillDef, SpellDef
|
||||
|
||||
class RaceDataRegistry:
|
||||
"""
|
||||
In-memory catalog of YAML-defined race sheets.
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
self._by_race: Dict[Race, RaceSheet] = {}
|
||||
# promoted global catalogs for cross-use at runtime (optional)
|
||||
self._skills: Dict[str, SkillDef] = {}
|
||||
self._spells: Dict[str, SpellDef] = {}
|
||||
|
||||
def load_dir(self, directory: str | Path) -> None:
|
||||
directory = Path(directory)
|
||||
for path in sorted(directory.glob("*.y*ml")):
|
||||
with path.open("r", encoding="utf-8") as f:
|
||||
raw = yaml.safe_load(f) or {}
|
||||
|
||||
key_raw = raw.get("key")
|
||||
if not key_raw:
|
||||
raise ValueError(f"{path.name}: missing required 'key'")
|
||||
race = Race(key_raw) # validates enum
|
||||
|
||||
base_attributes = Attributes(**(raw.get("base_attributes") or {}))
|
||||
starting_resources = Resources(**(raw.get("starting_resources") or {}))
|
||||
|
||||
sheet = RaceSheet(
|
||||
key=race,
|
||||
display_name=raw.get("display_name", race.value.title()),
|
||||
base_attributes=base_attributes,
|
||||
starting_resources=starting_resources,
|
||||
starting_skills=list(raw.get("starting_skills") or []),
|
||||
starting_spells=list(raw.get("starting_spells") or []),
|
||||
)
|
||||
|
||||
# Local skill/spell catalogs (optional)
|
||||
for sid, sdef in (raw.get("skills") or {}).items():
|
||||
s = SkillDef.from_yaml(sid, sdef)
|
||||
sheet.skills[sid] = s
|
||||
self._skills[sid] = s
|
||||
|
||||
for spid, spdef in (raw.get("spells") or {}).items():
|
||||
sp = SpellDef.from_yaml(spid, spdef)
|
||||
sheet.spells[spid] = sp
|
||||
self._spells[spid] = sp
|
||||
|
||||
# Traits
|
||||
traits_raw = raw.get("traits") or []
|
||||
for t in traits_raw:
|
||||
sheet.traits.append(RacialTrait(id=t.get("id"), data=dict(t.get("data") or {})))
|
||||
|
||||
self._by_race[race] = sheet
|
||||
|
||||
def for_race(self, race: Race) -> RaceSheet:
|
||||
if race not in self._by_race:
|
||||
raise KeyError(f"No race sheet loaded for {race.value}")
|
||||
return self._by_race[race]
|
||||
|
||||
# Optional global lookups (if you want to fetch a skill from race-only files)
|
||||
def get_skill(self, skill_id: str) -> SkillDef: return self._skills[skill_id]
|
||||
def get_spell(self, spell_id: str) -> SpellDef: return self._spells[spell_id]
|
||||
Reference in New Issue
Block a user