Ajoute la fonctionnalite quiz autonome/plein ecran a la boite a quiz
Build and deploy / test-python (push) Successful in 12m10s
Build and deploy / test-js (push) Successful in 1m27s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped

Introduit la double categorie de modeles (boite de dialogue / page de
quiz plein ecran) avec plein ecran, minuteur, score integre et ecran de
resultat pour les modeles page ; ajoute les modeles "Manga" (boite et
page) et "Classique" (page), pilotables aussi par l'assistant IA Ruby.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-13 15:07:23 +02:00
co-authored by Claude Sonnet 5
parent 559331f9cf
commit 7db4803b93
26 changed files with 3173 additions and 60 deletions
+51
View File
@@ -40,6 +40,9 @@ _CONDITION_OPERATORS = sorted(CONDITION_OPERATOR_KEYS)
_DATA_OPERATIONS = sorted(DATA_OPERATION_LABELS)
_PERSONNAGE_ROLES = list(screens.PERSONNAGE_ROLES)
_COLLISION_SHAPES = list(screens.COLLISION_SHAPES)
_QUIZ_BOX_TIMER_MODES = list(screens.TIMER_MODES)
_QUIZ_BOX_DIALOG_TEMPLATES = list(screens.QUIZ_BOX_DIALOG_TEMPLATES)
_QUIZ_BOX_PAGE_TEMPLATES = list(screens.QUIZ_BOX_PAGE_TEMPLATES)
_GLOBAL_VARIABLE_TYPES = sorted(db.GLOBAL_VARIABLE_TYPES)
# Catalogue COMPLET (public + admin-only, voir core/sprite_gate.py) —
# Claude doit connaître les slugs valides pour ne jamais en deviner un
@@ -210,6 +213,32 @@ TOOLS = [
"required": ["object_id"],
},
},
{
"name": "set_quiz_box_config",
"description": (
"Règle les options d'une \"❓ Boîte à quiz\" pensées pour un quiz AUTONOME "
"(RH/formation) : plein écran, minuteur (jamais imposé — \"aucun\" par défaut, "
"au choix du créateur : \"question\" redémarre à chaque question, \"quiz\" est un "
"seul compte à rebours pour tout le quiz), et DEUX modèles visuels INDÉPENDANTS "
"(les deux réglages sont conservés en même temps, jamais l'un n'écrase l'autre) : "
"dialog_template (visible SEULEMENT hors plein écran — variantes de forme/couleur "
"sur une structure proche de \"Classique\") et page_template (visible SEULEMENT en "
"plein écran — thème complet et autonome, structure HTML propre à chaque modèle). "
"En plein écran, le score se retrouve affiché directement dans la boîte."
),
"input_schema": {
"type": "object",
"properties": {
"object_id": {"type": "integer"},
"fullscreen": {"type": "boolean"},
"timer_mode": {"type": "string", "enum": _QUIZ_BOX_TIMER_MODES},
"timer_seconds": {"type": "integer", "description": "Durée du minuteur (3 à 600s), ignorée si timer_mode=\"aucun\"."},
"dialog_template": {"type": "string", "enum": _QUIZ_BOX_DIALOG_TEMPLATES, "description": "Modèle \"boîte de dialogue\" — ne s'affiche que si fullscreen=false."},
"page_template": {"type": "string", "enum": _QUIZ_BOX_PAGE_TEMPLATES, "description": "Modèle \"page de quiz\" — ne s'affiche que si fullscreen=true."},
},
"required": ["object_id"],
},
},
{
"name": "create_global_variable",
"description": "Crée une variable globale (idempotent par nom) — utilisable ensuite dans les déclencheurs/conditions.",
@@ -502,6 +531,27 @@ def _dispatch_set_object_collision(slug, screen_id, user_id, object_id, enabled=
return {"ok": True}
def _dispatch_set_quiz_box_config(slug, screen_id, user_id, object_id, fullscreen=False,
timer_mode="aucun", timer_seconds=20,
dialog_template="defaut", page_template="classique"):
# Même forme que screens.set_scene_object_quiz_config (remplacement
# complet des réglages, jamais un merge partiel) — screens.py sanitize
# de toute façon toute valeur hors énumération, ce garde-fou ici sert
# juste à ne jamais transmettre None à sanitize_quiz_box_config.
# dialog_template/page_template sont conservés INDÉPENDAMMENT (voir
# screens/rendering/quiz_box_config.py) : Ruby peut en régler un seul
# sans jamais écraser l'autre.
config = {
"fullscreen": bool(fullscreen),
"timer_mode": timer_mode if timer_mode in _QUIZ_BOX_TIMER_MODES else "aucun",
"timer_seconds": timer_seconds or 20,
"dialog_template": dialog_template if dialog_template in _QUIZ_BOX_DIALOG_TEMPLATES else "defaut",
"page_template": page_template if page_template in _QUIZ_BOX_PAGE_TEMPLATES else "classique",
}
screens.set_scene_object_quiz_config(slug, object_id, config)
return {"ok": True}
def _dispatch_create_global_variable(slug, screen_id, user_id, name, var_type="texte", default_value="", per_player=True):
variable_id = db.create_global_variable(slug, name, var_type=var_type, default_value=default_value, per_player=per_player)
return {"variable_id": variable_id}
@@ -571,6 +621,7 @@ _DISPATCH = {
"set_object_name": _dispatch_set_object_name,
"set_object_role": _dispatch_set_object_role,
"set_object_collision": _dispatch_set_object_collision,
"set_quiz_box_config": _dispatch_set_quiz_box_config,
"create_global_variable": _dispatch_create_global_variable,
"set_collision_rules": _dispatch_set_collision_rules,
"append_action_to_trigger": _dispatch_append_action_to_trigger,