import screens _DEFAULT_OBJECT_LABELS = {"personnage": "Personnage", "fond": "Fond"} _COLLISION_EXCLUDED_KINDS = ("fond", "dialogue_box", "quiz_box", "score_widget") def build_collision_rule_objects(objects): """Une carte "🧩 Collision" (voir templates/scene_edit.html) par objet ÉLIGIBLE (jamais un "fond", jamais le personnage "joueur" — ce sont TOUJOURS les AUTRES objets qui réagissent à SA présence, voir screens/rendering/collision_rules.py) — factorisé ici plutôt que dupliqué : utilisé au premier rendu de la page (routes/scenes/ scene_edit_view.py) ET par l'endpoint AJAX ci-dessous (appelé après ajout/suppression/changement de rôle ou de nom, voir static/js/scenes/ scene-editor.js) pour reconstruire la liste SANS recharger la page. `objects` doit déjà porter "rendered_html" (voir screens.render_scene_object) sur chaque élément. resolve_personnage_role retombe sur "joueur" pour TOUT personnage sans rôle explicitement enregistré (voir screens/rendering/ personnage_role.py — comportement voulu pour une scène à un seul personnage, posé avant l'ajout de ce réglage). Appliqué tel quel, ÇA CASSE dès qu'une scène a plusieurs personnages sans rôle explicite (le cas de toute scène créée avant ce réglage — un personnage ajouté depuis l'éditeur reçoit maintenant TOUJOURS un rôle "pnj" explicite, voir add_scene_object.py) : ils retomberaient TOUS sur "joueur" et disparaîtraient donc TOUS de cette liste. On ne considère donc comme "joueur" implicite QUE LE PREMIER personnage sans rôle explicite (le plus ancien, z_index croissant comme `objects`) — les suivants sans rôle explicite sont traités comme "pnj" ici, sans rien réécrire en base.""" implicit_joueur_claimed = any( (o.get("attributes") or {}).get("_personnage_role") == "joueur" for o in objects if o["kind"] == "personnage" ) result = [] for o in objects: if o["kind"] in _COLLISION_EXCLUDED_KINDS: continue role = None if o["kind"] == "personnage": explicit_role = (o.get("attributes") or {}).get("_personnage_role") if explicit_role in screens.PERSONNAGE_ROLES: role = explicit_role elif not implicit_joueur_claimed: role = "joueur" implicit_joueur_claimed = True else: role = "pnj" if role == "joueur": continue result.append({ "id": o["id"], "name": o.get("name") or _DEFAULT_OBJECT_LABELS.get(o["kind"], "Décor"), "kind": o["kind"], "role": role, "thumbnail_html": o["rendered_html"], "rules": screens.resolve_collision_rules(o), }) return result