Files
Forge-Engine/db/quests/sanitize_quest_dialogues.py
T
williamandClaude Sonnet 5 2347a70c45
Build and deploy / test-python (push) Successful in 11m32s
Build and deploy / test-js (push) Successful in 1m12s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Quêtes/collision : personnages nommés, dialogues qui parlent, boîte de dialogue en jeu
- "ℹ️ Informations" (propriétés d'un personnage) : nom éditable, réutilisé
  comme "qui parle" dans l'éditeur de dialogue de quête (menu déroulant,
  plus "Joueur" toujours disponible) — remplace l'ancien choix binaire
  joueur/pnj. db.sanitize_quest_dialogues accepte maintenant un nom libre.

- Nouveau menu "🖥️ Interface" (palette d'objets) avec le premier widget :
  "💬 Boîte de dialogue" (kind="dialogue_box", screens/rendering/
  dialogue_box_style.py) — position/taille comme tout objet de scène,
  panneau "🎨 Style" dédié (police, taille, épaisseur, couleur du texte,
  couleur header/body/footer). Rendu en <div> à 3 zones, jamais soumis à
  la collision ni à l'éditeur de collision (exclu partout : obstacles,
  liste des règles, payload). Rendu côté jeu dans .sceneUI, une couche
  FIXE au viewport (jamais .sceneWorld, qui défile avec la caméra).

- static/js/play/dialogue-box-controller.js : fait le lien moteur entre
  l'action "quete" de l'éditeur de collision et ce widget — affiche la
  réplique en cours du dialogue correspondant au STATUT ACTUEL de la
  quête (gameData.quests, désormais exposé game-wide par
  full_game_payload.py), avance au clic sur "Suivant" (header = qui
  parle, body = texte, footer = bouton), se masque à la dernière réplique.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 11:20:58 +02:00

38 lines
1.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from .constants import QUEST_STATUS_CHOICES
_MAX_LINES_PER_COLUMN = 200
_MAX_SPEAKER_LENGTH = 60
def sanitize_quest_dialogues(raw_dialogues):
"""Une réplique = {speaker: '<nom du personnage>', text: '...'} — le
nom vient du champ "ℹ️ Informations" d'un objet de scène kind=
"personnage" (voir screens/rendering/personnage_names.py), ou
"Joueur" (toujours proposé, voir static/js/quests/quest-editor.js) :
texte libre côté serveur (jamais un enum fixe — n'importe quel nom
donné à un personnage doit être accepté), juste borné en longueur.
Une colonne par statut de quête (voir QUEST_STATUS_CHOICES), même
esprit que resolve_collision_rules.sanitize_collision_rules : rejette
tout élément invalide plutôt que de lever, ne garde jamais un texte
ou un nom vide."""
result = {status: [] for status in QUEST_STATUS_CHOICES}
if not isinstance(raw_dialogues, dict):
return result
for status in QUEST_STATUS_CHOICES:
raw_lines = raw_dialogues.get(status)
if not isinstance(raw_lines, list):
continue
cleaned = []
for raw_line in raw_lines[:_MAX_LINES_PER_COLUMN]:
if not isinstance(raw_line, dict):
continue
speaker = raw_line.get("speaker")
text = raw_line.get("text")
if not isinstance(speaker, str) or not speaker.strip():
continue
if not isinstance(text, str) or not text.strip():
continue
cleaned.append({"speaker": speaker.strip()[:_MAX_SPEAKER_LENGTH], "text": text.strip()})
result[status] = cleaned
return result