import json from ..labels.sprite_library import SPRITE_LIBRARY _DEFAULT_PERSONNAGE_DATA = {"source": "forge", "forge_character": "male-adventurer"} def resolve_personnage_data(el): """Décode attributes._personnage_data (voir set_personnage_data.py) en dict Python, jamais None — un attribut absent/corrompu retombe sur le défaut posé à la création (default_style_for_widget.py).""" raw = (el.get("attributes") or {}).get("_personnage_data") if not raw: return dict(_DEFAULT_PERSONNAGE_DATA) try: data = json.loads(raw) except (TypeError, ValueError): return dict(_DEFAULT_PERSONNAGE_DATA) return data if isinstance(data, dict) else dict(_DEFAULT_PERSONNAGE_DATA) def resolve_personnage_animations(el): """{nom_animation: [urls...]} pour cet élément personnage, quelle que soit sa source — Forge (SPRITE_LIBRARY) ou sprites propres au créateur (ses propres frames importées, voir personnage-panel.js).""" data = resolve_personnage_data(el) if data.get("source") == "custom": return data.get("animations") or {} character = SPRITE_LIBRARY.get(data.get("forge_character")) return character["animations"] if character else {} def resolve_personnage_idle_frame(el): """Première image de l'animation "idle" (ou, à défaut, de la première animation disponible) — utilisée pour le rendu serveur ET l'aperçu animé de l'éditeur, jamais vide tant qu'au moins une frame existe.""" animations = resolve_personnage_animations(el) frames = animations.get("idle") or (next(iter(animations.values())) if animations else None) return frames[0] if frames else ""