titre: "Bibliothèque de modèles universels"

description: |
  6 modèles réutilisables plug-and-play pour tout type de jeu textuel.
  Chaque modèle est autonome et s'adapte à n'importe quel univers.

markdown: fix

# ══════════════════════════════════════════════════════════════════
# VARIABLES GLOBALES DE DÉMO (utilisées par les salles de test)
# ══════════════════════════════════════════════════════════════════
vars:
  # ── Combat ──
  pvhero:
    valeur: 100
    description: "PV du héros"
  pvheromax:
    valeur: 100
    description: "PV max du héros"
  mana:
    valeur: 30
    description: "Mana du héros"
  bouclier:
    valeur: 0
    description: "Dégâts absorbés ce tour"
  pvennemi:
    valeur: 60
    description: "PV de l'ennemi"
  atkennemi:
    valeur: 0
    description: "Dégâts infligés par l'ennemi"
  de6:
    valeur: 0
    description: "Jet de dé 1d6 interne"
  de20:
    valeur: 0
    description: "Jet de dé 1d20 interne"
  effethero:
    valeur: 0
    description: "Dégâts/soin du héros ce tour"

  # ── Dialogue ──
  sympathie:
    valeur: 0
    description: "Sympathie envers le PNJ (-5 hostile → +5 ami)"
  asalue:
    valeur: 0
    description: "1 si la salutation a déjà été faite"
  dlgtours:
    valeur: 0
    description: "Tours de dialogue écoulés"
  dlgtoursmax:
    valeur: 7
    description: "Budget max de tours avant que le PNJ parte"

  # ── Commerce ──
  or:
    valeur: 80
    description: "Or du joueur"
  achat1:
    valeur: 0
    description: "1 si l'article 1 est possédé"
  achat2:
    valeur: 0
    description: "1 si l'article 2 est possédé"
  achat3:
    valeur: 0
    description: "1 si l'article 3 est possédé"
  prix1:
    valeur: 20
    description: "Prix d'achat article 1"
  prix2:
    valeur: 10
    description: "Prix d'achat article 2"
  prix3:
    valeur: 35
    description: "Prix d'achat article 3"
  revente1:
    valeur: 10
    description: "Prix de revente article 1"
  revente2:
    valeur: 5
    description: "Prix de revente article 2"
  revente3:
    valeur: 17
    description: "Prix de revente article 3"

  # ── Jet de compétence ──
  modificateur:
    valeur: 2
    description: "Modificateur de compétence"
  seuil:
    valeur: 12
    description: "Seuil de réussite"

  # ── Défi progressif ──
  progression:
    valeur: 0
    description: "Avancement dans le défi (0 → objectif)"
  pression:
    valeur: 0
    description: "Complications accumulées"
  objectifdefi:
    valeur: 5
    description: "Étapes pour réussir"
  pressionmax:
    valeur: 3
    description: "Pression max avant échec"
  prepmax:
    valeur: 2
    description: "Préparations prudentes restantes"

  # ── Enquête ──
  indices:
    valeur: 0
    description: "Indices découverts"
  soupcons:
    valeur: 0
    description: "Niveau de méfiance des suspects"
  indicesneed:
    valeur: 3
    description: "Indices nécessaires pour accuser"
  soupconmax:
    valeur: 4
    description: "Soupçons max avant alerte"
  enqtours:
    valeur: 0
    description: "Tours d'enquête écoulés"
  enqtoursmax:
    valeur: 10
    description: "Limite de tours avant fuite du coupable"

vars_texte:
  # ── Combat ──
  nomhero:
    valeur: "Héros"
    description: "Nom du personnage joueur"
  nomennemi:
    valeur: "Gobelin"
    description: "Nom de l'adversaire"

  # ── Dialogue ──
  nompnj:
    valeur: "le garde"
    description: "Nom du PNJ"
  objectif:
    valeur: "obtenir un passage"
    description: "Objectif du dialogue"

  # ── Commerce ──
  nomarticle1:
    valeur: "Épée de fer"
    description: "Nom de l'article 1"
  nomarticle2:
    valeur: "Potion de vie"
    description: "Nom de l'article 2"
  nomarticle3:
    valeur: "Bouclier en bois"
    description: "Nom de l'article 3"

  # ── Jet ──
  nomcompetence:
    valeur: "Crochetage"
    description: "Nom de la compétence testée"

  # ── Défi ──
  nomdefi:
    valeur: "l'escalade du mur"
    description: "Description du défi"

  # ── Enquête ──
  nomenquete:
    valeur: "le vol au manoir"
    description: "Titre de l'affaire en cours"

tags:
  retour_menu:
    choix:
      - commande: menu
        bouton: "↩️ Retour au menu"
        vers: accueil

# ══════════════════════════════════════════════════════════════════
# MODÈLES
# ══════════════════════════════════════════════════════════════════
modeles:

  # ════════════════════════════════════════════════════════════════
  # MODÈLE 1 : combat_rpg  (8 salles)
  # ════════════════════════════════════════════════════════════════
  # Système de combat au tour par tour. 4 actions : attaque physique,
  # potion de soin, garde (absorbe les dégâts), sort offensif (mana).
  # UI immersive avec stats en temps réel, sons de combat inclus.
  #
  # VARIABLES À MAPPER :
  #   pvhero, pvheromax → PV du héros
  #   mana              → ressource magique
  #   bouclier          → dégâts absorbés au prochain tour ennemi
  #   pvennemi          → PV de l'adversaire
  #   de6, effethero, atkennemi → calculs internes (laisser à 0)
  #   nomhero, nomennemi        → noms affichés
  #
  # SORTIES :
  #   victoire → après avoir vaincu l'ennemi
  #   defaite  → quand le héros tombe à 0 PV
  #
  # EXEMPLE :
  #   - modele: combat_rpg
  #     variables:
  #       pvhero: pvhero
  #       pvheromax: pvheromax
  #       mana: mana
  #       bouclier: bouclier
  #       pvennemi: pvennemi
  #       de6: de6
  #       effethero: effethero
  #       atkennemi: atkennemi
  #       nomhero: nomhero
  #       nomennemi: nomennemi
  #     sorties:
  #       victoire: apres_combat
  #       defaite: game_over
  # ════════════════════════════════════════════════════════════════
  combat_rpg:
    variables:
      pvhero-g: 100
      pvheromax-g: 100
      mana-g: 30
      bouclier-g: 0
      pvennemi-g: 60
      de6-g: 0
      effethero-g: 0
      atkennemi-g: 0
      nomhero-g: "Héros"
      nomennemi-g: "Ennemi"
    sorties:
      victoire: fin_modele
      defaite: fin_modele
    salles:

      - id: hub_combat
        texte: |
          [[
          🧍 **t_nomhero-g_t**  ❤️ v_pvhero-g_v / v_pvheromax-g_v  •  💧 Mana v_mana-g_v  •  🛡️ Garde v_bouclier-g_v
          👾 **t_nomennemi-g_t**  ❤️ v_pvennemi-g_v
          ]]
        evenements:
          - si: "v_pvennemi-g_v <= 0"
            texte: "☠️ **t_nomennemi-g_t est vaincu !**"
            vers: victoire_c
          - si: "v_pvhero-g_v <= 0"
            texte: "💀 **t_nomhero-g_t tombe au combat...**"
            vers: defaite_c
        choix:
          - commande: attaquer
            bouton: "⚔️ Attaquer"
            vers: action_attaque
          - commande: soin
            bouton: "✨ Sort de soin (10 mana · +20-35 PV)"
            grise-si: "v_mana-g_v < 10"
            vers: action_soin
          - commande: garde
            bouton: "🛡️ Garde (aléatoire : contrer / parer / partiel / raté)"
            vers: action_garde
          - commande: sort
            bouton: "🔥 Sort offensif (15 mana · 20-35 dégâts)"
            grise-si: "v_mana-g_v < 15"
            vers: action_sort

      - id: action_attaque
        texte: "<<https://cyril-fiesta.fr/jdr-bot/scenarios/sounds/combat/kotor-hit.wav>>"
        init:
          - var: de6
            valeur: "%=1:6"
          - var: effethero
            valeur: 0
        evenements:
          - si: "v_de6-g_v >= 5"
            faire:
              - "effethero-g.=.v_de6-g_v"
              - "effethero-g.+.8"
              - "pvennemi-g.-.v_effethero-g_v"
              - "mana-g.+.5"
            texte: "⚔️ **Coup critique !** v_effethero-g_v dégâts sur t_nomennemi-g_t ! (+5 mana)"
            vers: tour_ennemi
          - si: "v_de6-g_v >= 3"
            faire:
              - "effethero-g.=.v_de6-g_v"
              - "effethero-g.+.3"
              - "pvennemi-g.-.v_effethero-g_v"
              - "mana-g.+.3"
            texte: "⚔️ Attaque solide — v_effethero-g_v dégâts sur t_nomennemi-g_t. (+3 mana)"
            vers: tour_ennemi
          - si: ~
            faire: "effethero-g.=.0"
            texte: "💨 t_nomennemi-g_t esquive. Aucun dégât."
            vers: tour_ennemi

      - id: action_soin
        texte: "null"
        init:
          - var: effethero
            valeur: "%=20:35"
        evenements:
          - si: "v_mana-g_v < 10"
            texte: "✨ Mana insuffisant pour le sort de soin !"
            vers: hub_combat
          - si: "v_pvhero-g_v >= v_pvheromax-g_v"
            texte: "✨ Vos PV sont déjà au maximum !"
            vers: hub_combat
          - si: ~
            faire:
              - "mana-g.-.10"
              - "pvhero-g.+.v_effethero-g_v"
            texte: "✨ **Sort de soin !** +v_effethero-g_v PV. (-10 mana)"
            vers: cap_soin

      - id: cap_soin
        texte: "null"
        evenements:
          - si: "v_pvhero-g_v > v_pvheromax-g_v"
            faire: "pvhero-g.=.v_pvheromax-g_v"
            vers: tour_ennemi
          - si: ~
            vers: tour_ennemi

      - id: action_garde
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
          - var: effethero
            valeur: "%=4:10"
        evenements:
          # 1-2 : contrer — annule + riposte
          - si: "v_de6-g_v <= 2"
            faire: "pvennemi-g.-.v_effethero-g_v"
            texte: "⚡ **Contre !** Vous déviez l'attaque et ripostez — v_effethero-g_v dégâts sur t_nomennemi-g_t ! (dé : v_de6-g_v)"
            vers: hub_combat
          # 3-4 : parade totale
          - si: "v_de6-g_v <= 4"
            faire: "bouclier-g.=.25"
            texte: "🛡️ **Parade parfaite.** Vous absorbez la prochaine attaque ennemie. (dé : v_de6-g_v)"
            vers: tour_ennemi
          # 5 : parade partielle — absorbe seulement une partie
          - si: "v_de6-g_v = 5"
            faire: "bouclier-g.=.10"
            texte: "🛡️ Garde partielle. Vous absorberez 10 des prochains dégâts. (dé : v_de6-g_v)"
            vers: tour_ennemi
          # 6 : garde ratée
          - si: ~
            texte: "💨 Votre garde est mal placée — aucun effet. (dé : v_de6-g_v)"
            vers: tour_ennemi

      - id: action_sort
        texte: "null"
        init:
          - var: effethero
            valeur: "%=20:35"
        evenements:
          - si: "v_mana-g_v < 15"
            texte: "✨ Mana insuffisant pour ce sort !"
            vers: hub_combat
          - si: ~
            faire:
              - "mana-g.-.15"
              - "pvennemi-g.-.v_effethero-g_v"
            texte: "✨ **Éclair foudroyant !** v_effethero-g_v dégâts magiques. (-15 mana)"
            vers: tour_ennemi

      - id: tour_ennemi
        texte: "<<https://cyril-fiesta.fr/jdr-bot/scenarios/sounds/combat/goblin.wav>>"
        init:
          - var: atkennemi
            valeur: "%=8:18"
        evenements:
          - si: "v_pvennemi-g_v <= 0"
            texte: "☠️ t_nomennemi-g_t est déjà vaincu. Le combat se termine."
            vers: hub_combat
          - si: "v_bouclier-g_v >= v_atkennemi-g_v"
            faire: "bouclier-g.=.0"
            texte: "🛡️ t_nomennemi-g_t attaque ! v_atkennemi-g_v dégâts absorbés par la garde."
            vers: hub_combat
          - si: "v_bouclier-g_v > 0"
            faire:
              - "atkennemi-g.-.v_bouclier-g_v"
              - "bouclier-g.=.0"
              - "pvhero-g.-.v_atkennemi-g_v"
            texte: "🛡️ Garde partiellement brisée — t_nomennemi-g_t inflige quand même v_atkennemi-g_v dégâts !"
            vers: hub_combat
          - si: ~
            faire: "pvhero-g.-.v_atkennemi-g_v"
            texte: "💢 t_nomennemi-g_t attaque ! v_atkennemi-g_v dégâts."
            vers: hub_combat

      - id: victoire_c
        texte: "<<https://cyril-fiesta.fr/jdr-bot/scenarios/sounds/chateau/congratulations.ogg>>"
        evenements:
          - si: ~
            vers: victoire

      - id: defaite_c
        texte: "<<https://cyril-fiesta.fr/jdr-bot/scenarios/sounds/combat/goblin-die.wav>>"
        evenements:
          - si: ~
            vers: defaite


  # ════════════════════════════════════════════════════════════════
  # MODÈLE 2 : dialogue_influence  (9 salles)
  # ════════════════════════════════════════════════════════════════
  # Système de diplomatie/persuasion. Gagner la sympathie d'un PNJ
  # via 5 approches : saluer (1 fois), argumenter, questionner,
  # flatter (risqué), provoquer (pression — peut forcer une conclusion
  # anticipée si sympathie >= 2, mais risque hostile si dé bas).
  # Budget de tours. 3 issues : succès, échec, hostile.
  #
  # VARIABLES À MAPPER :
  #   sympathie        → score d'affinité (seuil succès : >= 4)
  #   asalue           → flag salutation (0/1, une seule fois)
  #   dlgtours         → tours écoulés
  #   dlgtoursmax      → budget max (défaut 7)
  #   nompnj           → nom du PNJ
  #   objectif          → enjeu du dialogue (affiché)
  #
  # SORTIES :
  #   succes  → objectif atteint
  #   echec   → échec diplomatique
  #   hostile → le PNJ devient hostile (sympathie <= -3)
  #
  # EXEMPLE :
  #   - modele: dialogue_influence
  #     variables:
  #       sympathie: sympathie
  #       asalue: asalue
  #       dlgtours: dlgtours
  #       dlgtoursmax: dlgtoursmax
  #       nompnj: nompnj
  #       objectif: objectif
  #       de6: de6
  #     sorties:
  #       succes: scene_accord
  #       echec: scene_refus
  #       hostile: scene_altercation
  # ════════════════════════════════════════════════════════════════
  dialogue_influence:
    variables:
      sympathie-g: 0
      asalue-g: 0
      dlgtours-g: 0
      dlgtoursmax-g: 7
      nompnj-g: "l'inconnu"
      objectif-g: "obtenir ce que vous voulez"
      de6-g: 0
    sorties:
      succes: fin_modele
      echec: fin_modele
      hostile: fin_modele
    salles:

      - id: hub_dialogue
        texte:
          - texte: "💬 **Dialogue avec t_nompnj-g_t**"
            si: "v_dlgtours-g_v.=.0"
          - "[[+n+Objectif : t_objectif-g_t+n+Sympathie : v_sympathie-g_v / 4  •  Tours restants : v_dlgtours-g_v / v_dlgtoursmax-g_v+n+]]"
        evenements:
          - si: "v_sympathie-g_v <= -3"
            texte: "😠 t_nompnj-g_t est furieux. La conversation est terminée."
            vers: fin_hostile
          - si: "v_dlgtours-g_v >= v_dlgtoursmax-g_v"
            texte: "⌛ t_nompnj-g_t prend congé. Le temps a manqué."
            vers: fin_echec
        choix:
          - commande: saluer
            bouton: "👋 Saluer (+1 sympathie, une fois)"
            visible-si: "v_asalue-g_v = 0"
            vers: rep_saluer
          - commande: argumenter
            bouton: "🗣️ Argumenter (d6 ≥ 4 : +2 sympathie)"
            vers: rep_argumenter
          - commande: questionner
            bouton: "❓ Questionner (+1 sympathie assuré)"
            vers: rep_questionner
          - commande: flatter
            bouton: "😊 Flatter (chance : +1 / risque : -1)"
            vers: rep_flatter
          - commande: provoquer
            bouton: "😤 Provoquer (pression — risqué, peut forcer conclusion)"
            vers: rep_provoquer
          - commande: conclure
            bouton: "✅ Conclure le dialogue"
            vers: rep_conclure

      - id: rep_saluer
        texte: "null"
        evenements:
          - si: ~
            faire:
              - "sympathie-g.+.1"
              - "asalue-g.=.1"
              - "dlgtours-g.+.1"
            texte: "👋 Vous saluez t_nompnj-g_t avec chaleur. Un sourire poli en retour. (+1 sympathie)"
            vers: hub_dialogue

      - id: rep_argumenter
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
        evenements:
          - si: "v_de6-g_v >= 4"
            faire:
              - "sympathie-g.+.2"
              - "dlgtours-g.+.1"
            texte: "🗣️ Votre argument fait mouche. t_nompnj-g_t acquiesce. (+2 sympathie · dé : v_de6-g_v)"
            vers: hub_dialogue
          - si: ~
            faire: "dlgtours-g.+.1"
            texte: "🗣️ t_nompnj-g_t écoute mais reste sceptique. (dé : v_de6-g_v)"
            vers: hub_dialogue

      - id: rep_questionner
        texte: "null"
        evenements:
          - si: ~
            faire:
              - "sympathie-g.+.1"
              - "dlgtours-g.+.1"
            texte: "❓ Votre question est pertinente. t_nompnj-g_t apprécie l'intérêt. (+1 sympathie)"
            vers: hub_dialogue

      - id: rep_flatter
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
        evenements:
          - si: "v_de6-g_v >= 5"
            faire:
              - "sympathie-g.+.1"
              - "dlgtours-g.+.1"
            texte: "😊 La flatterie fonctionne — t_nompnj-g_t est visiblement touché. (+1 sympathie · dé : v_de6-g_v)"
            vers: hub_dialogue
          - si: ~
            faire:
              - "sympathie-g.-.1"
              - "dlgtours-g.+.1"
            texte: "😬 t_nompnj-g_t perçoit la flatterie comme de la manipulation. (-1 sympathie · dé : v_de6-g_v)"
            vers: hub_dialogue

      - id: rep_provoquer
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
        evenements:
          # Pression forte + sympathie suffisante → conclusion forcée (gain de temps)
          - si: "v_de6-g_v >= 5 v_sympathie-g_v >= 2"
            faire: "dlgtours-g.+.3"
            texte: "😤 Votre pression fait craquer t_nompnj-g_t — il capitule. (dé : v_de6-g_v)"
            vers: fin_succes
          # Pression trop forte → hostile
          - si: "v_de6-g_v <= 2"
            faire:
              - "sympathie-g.-.3"
              - "dlgtours-g.+.1"
            texte: "😠 t_nompnj-g_t perd patience. Vous êtes allé trop loin. (dé : v_de6-g_v)"
            vers: hub_dialogue
          # Résultat neutre → déstabilise, coûte seulement 1 tour
          - si: ~
            faire:
              - "sympathie-g.-.1"
              - "dlgtours-g.+.1"
            texte: "😤 t_nompnj-g_t est agacé mais tient bon. (-1 sympathie · dé : v_de6-g_v)"
            vers: hub_dialogue

      - id: rep_conclure
        texte: "null"
        evenements:
          - si: "v_sympathie-g_v >= 4"
            texte: "🤝 t_nompnj-g_t accepte. Vous avez réussi à t_objectif-g_t."
            vers: fin_succes
          - si: ~
            texte: "🙅 t_nompnj-g_t décline. La sympathie était insuffisante (v_sympathie-g_v / 4)."
            vers: fin_echec

      - id: fin_succes
        texte: "null"
        evenements:
          - si: ~
            vers: succes

      - id: fin_echec
        texte: "null"
        evenements:
          - si: ~
            vers: echec

      - id: fin_hostile
        texte: "null"
        evenements:
          - si: ~
            vers: hostile


  # ════════════════════════════════════════════════════════════════
  # MODÈLE 3 : boutique  (8 salles)
  # ════════════════════════════════════════════════════════════════
  # Commerce avec 3 articles achetables ET revendables.
  # Boutons dynamiques : achat visible si non possédé, revente si possédé.
  # Articles dans l'inventaire, retirés à la revente. Prix modifiables.
  #
  # VARIABLES À MAPPER :
  #   or               → monnaie du joueur
  #   achat1/2/3       → flags de possession (0 = non possédé)
  #   prix1/2/3        → prix d'achat de chaque article
  #   revente1/2/3     → prix de revente de chaque article
  #   nomarticle1/2/3  → noms affichés (vars texte)
  #
  # SORTIES :
  #   quitter → salle après fermeture de la boutique
  #
  # EXEMPLE :
  #   - modele: boutique
  #     variables:
  #       or: or
  #       achat1: achat1
  #       achat2: achat2
  #       achat3: achat3
  #       prix1: prix1
  #       prix2: prix2
  #       prix3: prix3
  #       revente1: revente1
  #       revente2: revente2
  #       revente3: revente3
  #       nomarticle1: nomarticle1
  #       nomarticle2: nomarticle2
  #       nomarticle3: nomarticle3
  #     sorties:
  #       quitter: retour_village
  # ════════════════════════════════════════════════════════════════
  boutique:
    variables:
      or-g: 80
      achat1-g: 0
      achat2-g: 0
      achat3-g: 0
      prix1-g: 20
      prix2-g: 10
      prix3-g: 35
      revente1-g: 10
      revente2-g: 5
      revente3-g: 17
      nomarticle1-g: "Article 1"
      nomarticle2-g: "Article 2"
      nomarticle3-g: "Article 3"
    sorties:
      quitter: fin_modele
    salles:

      - id: vitrine
        texte: |
          🏪 **Boutique** — 💰 v_or-g_v pièces d'or
          [[
          ⚔️  t_nomarticle1-g_t  —  achat : v_prix1-g_v or  ·  revente : v_revente1-g_v or
          🧪  t_nomarticle2-g_t  —  achat : v_prix2-g_v or  ·  revente : v_revente2-g_v or
          🛡️  t_nomarticle3-g_t  —  achat : v_prix3-g_v or  ·  revente : v_revente3-g_v or
          ]]
        choix:
          - commande: acheter1
            bouton: "🛒 Acheter t_nomarticle1-g_t (v_prix1-g_v or)"
            visible-si: "v_achat1-g_v = 0"
            grise-si: "v_or-g_v < v_prix1-g_v"
            vers: achat_1
          - commande: revendre1
            bouton: "💰 Revendre t_nomarticle1-g_t (+v_revente1-g_v or)"
            visible-si: "v_achat1-g_v = 1"
            vers: revente_1
          - commande: acheter2
            bouton: "🛒 Acheter t_nomarticle2-g_t (v_prix2-g_v or)"
            visible-si: "v_achat2-g_v = 0"
            grise-si: "v_or-g_v < v_prix2-g_v"
            vers: achat_2
          - commande: revendre2
            bouton: "💰 Revendre t_nomarticle2-g_t (+v_revente2-g_v or)"
            visible-si: "v_achat2-g_v = 1"
            vers: revente_2
          - commande: acheter3
            bouton: "🛒 Acheter t_nomarticle3-g_t (v_prix3-g_v or)"
            visible-si: "v_achat3-g_v = 0"
            grise-si: "v_or-g_v < v_prix3-g_v"
            vers: achat_3
          - commande: revendre3
            bouton: "💰 Revendre t_nomarticle3-g_t (+v_revente3-g_v or)"
            visible-si: "v_achat3-g_v = 1"
            vers: revente_3
          - commande: quitter
            bouton: "🚪 Quitter la boutique"
            vers: quitter_boutique

      - id: achat_1
        texte: "null"
        evenements:
          - si: "v_or-g_v < v_prix1-g_v"
            texte: "💸 Pas assez d'or ! (besoin : v_prix1-g_v · vous avez : v_or-g_v)"
            vers: vitrine
          - si: ~
            faire:
              - "or-g.-.v_prix1-g_v"
              - "achat1-g.=.1"
              - "article1&&inventaire&&t_nomarticle1-g_t"
            texte: "✅ t_nomarticle1-g_t acheté ! (-v_prix1-g_v or · Restant : v_or-g_v)"
            vers: vitrine

      - id: achat_2
        texte: "null"
        evenements:
          - si: "v_or-g_v < v_prix2-g_v"
            texte: "💸 Pas assez d'or ! (besoin : v_prix2-g_v · vous avez : v_or-g_v)"
            vers: vitrine
          - si: ~
            faire:
              - "or-g.-.v_prix2-g_v"
              - "achat2-g.=.1"
              - "article2&&inventaire&&t_nomarticle2-g_t"
            texte: "✅ t_nomarticle2-g_t acheté ! (-v_prix2-g_v or · Restant : v_or-g_v)"
            vers: vitrine

      - id: achat_3
        texte: "null"
        evenements:
          - si: "v_or-g_v < v_prix3-g_v"
            texte: "💸 Pas assez d'or ! (besoin : v_prix3-g_v · vous avez : v_or-g_v)"
            vers: vitrine
          - si: ~
            faire:
              - "or-g.-.v_prix3-g_v"
              - "achat3-g.=.1"
              - "article3&&inventaire&&t_nomarticle3-g_t"
            texte: "✅ t_nomarticle3-g_t acheté ! (-v_prix3-g_v or · Restant : v_or-g_v)"
            vers: vitrine

      - id: revente_1
        texte: "null"
        evenements:
          - si: ~
            faire:
              - "or-g.+.v_revente1-g_v"
              - "achat1-g.=.0"
              - "-article1&&inventaire&&t_nomarticle1-g_t"
            texte: "💰 t_nomarticle1-g_t revendu. (+v_revente1-g_v or · Total : v_or-g_v)"
            vers: vitrine

      - id: revente_2
        texte: "null"
        evenements:
          - si: ~
            faire:
              - "or-g.+.v_revente2-g_v"
              - "achat2-g.=.0"
              - "-article2&&inventaire&&t_nomarticle2-g_t"
            texte: "💰 t_nomarticle2-g_t revendu. (+v_revente2-g_v or · Total : v_or-g_v)"
            vers: vitrine

      - id: revente_3
        texte: "null"
        evenements:
          - si: ~
            faire:
              - "or-g.+.v_revente3-g_v"
              - "achat3-g.=.0"
              - "-article3&&inventaire&&t_nomarticle3-g_t"
            texte: "💰 t_nomarticle3-g_t revendu. (+v_revente3-g_v or · Total : v_or-g_v)"
            vers: vitrine

      - id: quitter_boutique
        texte: "null"
        evenements:
          - si: ~
            vers: quitter


  # ════════════════════════════════════════════════════════════════
  # MODÈLE 4 : jet_competence  (6 salles)
  # ════════════════════════════════════════════════════════════════
  # Jet de d20 + modificateur vs seuil. 4 degrés de résultat :
  # échec critique (nat. 1), échec, succès, succès critique (nat. 20).
  # Classique des LDVEH, D&D, appels de Cthulhu, etc.
  #
  # VARIABLES À MAPPER :
  #   de20          → résultat du dé (calculé automatiquement)
  #   modificateur  → bonus du personnage
  #   seuil         → difficulté (ex : 12 = moyen, 16 = difficile)
  #   effethero     → variable temporaire de calcul (laisser à 0)
  #   nomcompetence → nom de la compétence testée (var texte)
  #
  # SORTIES :
  #   critique_succes → nat. 20
  #   succes          → jet + mod >= seuil
  #   echec           → jet + mod < seuil
  #   critique_echec  → nat. 1
  #
  # EXEMPLE :
  #   - modele: jet_competence
  #     variables:
  #       de20: de20
  #       modificateur: modificateur
  #       seuil: seuil
  #       effethero: effethero
  #       nomcompetence: nomcompetence
  #     sorties:
  #       critique_succes: salle_exploit
  #       succes: salle_reussite
  #       echec: salle_echec
  #       critique_echec: salle_catastrophe
  # ════════════════════════════════════════════════════════════════
  jet_competence:
    variables:
      de20-g: 0
      modificateur-g: 2
      seuil-g: 12
      effethero-g: 0
      nomcompetence-g: "Compétence"
    sorties:
      critique_succes: fin_modele
      succes: fin_modele
      echec: fin_modele
      critique_echec: fin_modele
    salles:

      - id: jet
        texte: "🎲 **Test de t_nomcompetence-g_t** (seuil : v_seuil-g_v · mod : +v_modificateur-g_v)"
        init:
          - var: de20
            valeur: "%=1:20"
        evenements:
          - si: "v_de20-g_v = 1"
            texte: "🎲 Résultat : **1** — Échec critique !"
            vers: echec_critique
          - si: "v_de20-g_v = 20"
            texte: "🎲 Résultat : **20** — Succès critique !"
            vers: succes_critique
          - si: ~
            texte: "🎲 Résultat : v_de20-g_v (+ v_modificateur-g_v de modificateur)"
            vers: check_jet

      - id: check_jet
        texte: "null"
        init:
          - var: effethero
            valeur: "v_de20-g_v"
        evenements:
          - si: ~
            faire: "effethero-g.+.v_modificateur-g_v"
            vers: dispatch_jet

      - id: dispatch_jet
        texte: "null"
        evenements:
          - si: "v_effethero-g_v >= v_seuil-g_v"
            texte: "✅ **Succès !** (total : v_effethero-g_v vs seuil v_seuil-g_v)"
            vers: succes_jet
          - si: ~
            texte: "❌ **Échec.** (total : v_effethero-g_v vs seuil v_seuil-g_v)"
            vers: echec_jet

      - id: succes_critique
        texte: "⭐ **Succès critique !** t_nomcompetence-g_t maîtrisé à la perfection."
        evenements:
          - si: ~
            vers: critique_succes

      - id: succes_jet
        texte: "null"
        evenements:
          - si: ~
            vers: succes

      - id: echec_jet
        texte: "null"
        evenements:
          - si: ~
            vers: echec

      - id: echec_critique
        texte: "💥 **Échec critique !** Quelque chose tourne très mal..."
        evenements:
          - si: ~
            vers: critique_echec


  # ════════════════════════════════════════════════════════════════
  # MODÈLE 5 : defi_progressif  (5 salles)
  # ════════════════════════════════════════════════════════════════
  # Défi en plusieurs étapes : escalader un mur, crocheter une serrure,
  # traverser un marais, réparer un moteur... Deux approches :
  # - Tenter (risqué : d6 ≥ 4 = +2 progression, sinon +1 complication)
  # - Préparer (sûr : +1 progression garanti, plus lent)
  # Réussi quand progression >= objectif. Échoué si complications >= max.
  #
  # VARIABLES À MAPPER :
  #   progression, objectifdefi  → avancement (0 → objectif)
  #   pression, pressionmax     → complications tolérées
  #   de6                       → jet interne
  #   nomdefi                   → description du défi (var texte)
  #
  # SORTIES :
  #   succes → défi relevé
  #   echec  → trop de complications ou abandon
  #
  # EXEMPLE :
  #   - modele: defi_progressif
  #     variables:
  #       progression: progression
  #       objectifdefi: objectifdefi
  #       pression: pression
  #       pressionmax: pressionmax
  #       prepmax: prepmax
  #       de6: de6
  #       nomdefi: nomdefi
  #     sorties:
  #       succes: scene_passage
  #       echec: scene_blocage
  # ════════════════════════════════════════════════════════════════
  defi_progressif:
    variables:
      progression-g: 0
      objectifdefi-g: 5
      pression-g: 0
      pressionmax-g: 3
      prepmax-g: 2
      de6-g: 0
      nomdefi-g: "le défi"
    sorties:
      succes: fin_modele
      echec: fin_modele
    salles:

      - id: hub_defi
        texte: |
          🎯 **t_nomdefi-g_t**
          [[
          Progression : v_progression-g_v / v_objectifdefi-g_v  •  Complications : v_pression-g_v / v_pressionmax-g_v  •  Préparations restantes : v_prepmax-g_v
          ]]
        evenements:
          - si: "v_progression-g_v >= v_objectifdefi-g_v"
            texte: "✅ Défi relevé !"
            vers: succes_defi
          - si: "v_pression-g_v >= v_pressionmax-g_v"
            texte: "⛔ Trop de complications. Vous abandonnez."
            vers: echec_defi
        choix:
          - commande: tenter
            bouton: "💪 Tenter (d6 ≥ 4 : +2 progression · sinon +1 complication)"
            vers: tenter_defi
          - commande: preparer
            bouton: "🧠 Préparer (+1 progression garanti, 2 max)"
            grise-si: "v_prepmax-g_v <= 0"
            vers: preparer_defi
          - commande: abandonner
            bouton: "🏳️ Abandonner"
            vers: echec_defi

      - id: tenter_defi
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
        evenements:
          - si: "v_de6-g_v >= 4"
            faire: "progression-g.+.2"
            texte: "💪 Succès ! (dé : v_de6-g_v) +2 progression."
            vers: hub_defi
          - si: ~
            faire: "pression-g.+.1"
            texte: "😬 Raté. (dé : v_de6-g_v) +1 complication."
            vers: hub_defi

      - id: preparer_defi
        texte: "null"
        evenements:
          - si: "v_prepmax-g_v <= 0"
            texte: "🧠 Vous avez déjà épuisé vos préparations."
            vers: hub_defi
          - si: ~
            faire:
              - "progression-g.+.1"
              - "prepmax-g.-.1"
            texte: "🧠 Vous progressez prudemment. +1 progression. (v_prepmax-g_v préparations restantes)"
            vers: hub_defi

      - id: succes_defi
        texte: "null"
        evenements:
          - si: ~
            vers: succes

      - id: echec_defi
        texte: "null"
        evenements:
          - si: ~
            vers: echec


  # ════════════════════════════════════════════════════════════════
  # MODÈLE 6 : enquete  (6 salles)
  # ════════════════════════════════════════════════════════════════
  # Système d'investigation. Trouver des indices avant d'être repéré.
  # Inspiré des LDVEH policiers et détectives (Sherlock Holmes, Cluedo).
  # 3 actions : fouiller (risqué), interroger (sûr mais visible),
  # déduire (gratuit si assez d'indices). Accuser quand prêt.
  #
  # VARIABLES À MAPPER :
  #   indices, indicesneed   → indices trouvés vs nécessaires
  #   soupcons, soupconmax   → méfiance des suspects
  #   de6                    → jet interne
  #   nomenquete             → titre de l'affaire (var texte)
  #
  # SORTIES :
  #   resolu    → assez d'indices, accusation possible
  #   decouvert → soupçons max, le joueur est repéré
  #
  # EXEMPLE :
  #   - modele: enquete
  #     variables:
  #       indices: indices
  #       indicesneed: indicesneed
  #       soupcons: soupcons
  #       soupconmax: soupconmax
  #       enqtours: enqtours
  #       enqtoursmax: enqtoursmax
  #       de6: de6
  #       nomenquete: nomenquete
  #     sorties:
  #       resolu: scene_accusation
  #       decouvert: scene_fuite
  #       fuite: scene_disparition
  # ════════════════════════════════════════════════════════════════
  enquete:
    variables:
      indices-g: 0
      indicesneed-g: 3
      soupcons-g: 0
      soupconmax-g: 4
      enqtours-g: 0
      enqtoursmax-g: 10
      de6-g: 0
      nomenquete-g: "l'affaire"
    sorties:
      resolu: fin_modele
      decouvert: fin_modele
      fuite: fin_modele
    salles:

      - id: hub_enquete
        texte: |
          🔍 **Enquête — t_nomenquete-g_t**
          [[
          Indices : v_indices-g_v / v_indicesneed-g_v  •  Soupçons : v_soupcons-g_v / v_soupconmax-g_v  •  Temps : v_enqtours-g_v / v_enqtoursmax-g_v
          ]]
        evenements:
          - si: "v_soupcons-g_v >= v_soupconmax-g_v"
            texte: "🚨 Vous avez été repéré ! Il faut fuir."
            vers: decouvert_enquete
          - si: "v_enqtours-g_v >= v_enqtoursmax-g_v"
            texte: "⏳ Trop tard — le coupable a eu le temps de disparaître."
            vers: fuite_enquete
        choix:
          - commande: fouiller
            bouton: "🔎 Fouiller (d6 ≥ 4 : +indice · 1 : +soupçon)"
            vers: fouiller_scene
          - commande: interroger
            bouton: "🗣️ Interroger un témoin (+1 indice · +1 soupçon)"
            vers: interroger_temoin
          - commande: deduire
            bouton: "🧠 Déduire (d6 ≥ 3 : +indice · sinon +soupçon)"
            grise-si: "v_indices-g_v < 2"
            vers: deduire_scene
          - commande: accuser
            bouton: "⚖️ Accuser"
            grise-si: "v_indices-g_v < v_indicesneed-g_v"
            vers: resolu_enquete

      - id: fouiller_scene
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
        evenements:
          - si: "v_de6-g_v >= 4"
            faire:
              - "indices-g.+.1"
              - "enqtours-g.+.1"
            texte: "🔎 Trouvé ! Un nouvel indice. (+1 indice · dé : v_de6-g_v)"
            vers: hub_enquete
          - si: "v_de6-g_v = 1"
            faire:
              - "soupcons-g.+.1"
              - "enqtours-g.+.1"
            texte: "😬 Maladroit — quelqu'un vous a remarqué. (+1 soupçon · dé : v_de6-g_v)"
            vers: hub_enquete
          - si: ~
            faire: "enqtours-g.+.1"
            texte: "🔎 Rien de concluant. (dé : v_de6-g_v)"
            vers: hub_enquete

      - id: interroger_temoin
        texte: "null"
        evenements:
          - si: ~
            faire:
              - "indices-g.+.1"
              - "soupcons-g.+.1"
              - "enqtours-g.+.1"
            texte: "🗣️ Le témoin parle — un indice utile, mais votre curiosité attire les regards. (+1 indice · +1 soupçon)"
            vers: hub_enquete

      - id: deduire_scene
        texte: "null"
        init:
          - var: de6
            valeur: "%=1:6"
        evenements:
          - si: "v_indices-g_v < 2"
            texte: "🧠 Pas encore assez d'indices pour déduire quoi que ce soit."
            vers: hub_enquete
          - si: "v_de6-g_v >= 3"
            faire:
              - "indices-g.+.1"
              - "enqtours-g.+.1"
            texte: "🧠 En recoupant vos indices, une nouvelle piste se dessine. (+1 indice · dé : v_de6-g_v)"
            vers: hub_enquete
          - si: ~
            faire:
              - "soupcons-g.+.1"
              - "enqtours-g.+.1"
            texte: "🧠 Votre raisonnement à voix haute attire l'attention. (+1 soupçon · dé : v_de6-g_v)"
            vers: hub_enquete

      - id: resolu_enquete
        texte: "null"
        evenements:
          - si: ~
            vers: resolu

      - id: decouvert_enquete
        texte: "null"
        evenements:
          - si: ~
            vers: decouvert

      - id: fuite_enquete
        texte: "null"
        evenements:
          - si: ~
            vers: fuite


# ══════════════════════════════════════════════════════════════════
# SALLES DE TEST (lancer ce fichier en standalone pour tester)
# ══════════════════════════════════════════════════════════════════
salles:

  - id: accueil
    texte: |
      📚 **Bibliothèque de modèles universels**
      [[
      Choisissez un modèle à tester :
      ]]
    choix:
      - commande: combat
        bouton: "⚔️ Combat RPG"
        vers: test_combat
      - commande: dialogue
        bouton: "💬 Dialogue & Influence"
        vers: test_dialogue
      - commande: boutique
        bouton: "🏪 Commerce"
        vers: test_boutique
      - commande: jet
        bouton: "🎲 Jet de compétence"
        vers: test_jet
      - commande: defi
        bouton: "🎯 Défi progressif"
        vers: test_defi
      - commande: enquete
        bouton: "🔍 Enquête"
        vers: test_enquete

  # ── Test Combat ───────────────────────────────────────────────────
  - id: test_combat
    texte: "Un gobelin surgit de l'ombre !"
    init:
      - var: pvennemi
        valeur: 60
      - var: pvhero
        valeur: 100
      - var: mana
        valeur: 30
      - var: bouclier
        valeur: 0
    modeles:
      - modele: combat_rpg
        variables:
          pvhero: pvhero
          pvheromax: pvheromax
          mana: mana
          bouclier: bouclier
          pvennemi: pvennemi
          de6: de6
          effethero: effethero
          atkennemi: atkennemi
          nomhero: nomhero
          nomennemi: nomennemi
        sorties:
          victoire: victoire_combat
          defaite: defaite_combat

  - id: victoire_combat
    tag-apres: [retour_menu]
    texte: |
      🏆 **Victoire !** t_nomennemi_t est vaincu.
      PV restants : v_pvhero_v / v_pvheromax_v

  - id: defaite_combat
    tag-apres: [retour_menu]
    texte: "💀 **Défaite.** t_nomhero_t est tombé au combat."

  # ── Test Dialogue ─────────────────────────────────────────────────
  - id: test_dialogue
    texte: "Un garde vous barre le passage. Vous devez le convaincre de vous laisser entrer."
    init:
      - var: sympathie
        valeur: 0
      - var: asalue
        valeur: 0
      - var: dlgtours
        valeur: 0
    modeles:
      - modele: dialogue_influence
        variables:
          sympathie: sympathie
          asalue: asalue
          dlgtours: dlgtours
          dlgtoursmax: dlgtoursmax
          nompnj: nompnj
          objectif: objectif
          de6: de6
        sorties:
          succes: dialogue_succes
          echec: dialogue_echec
          hostile: dialogue_hostile

  - id: dialogue_succes
    tag-apres: [retour_menu]
    texte: "✅ Le garde s'écarte. Vous passez."

  - id: dialogue_echec
    tag-apres: [retour_menu]
    texte: "🙅 Le garde refuse. Il faudra trouver un autre chemin."

  - id: dialogue_hostile
    tag-apres: [retour_menu]
    texte: "😠 Le garde appelle des renforts. Mauvaise idée."

  # ── Test Commerce ─────────────────────────────────────────────────
  - id: test_boutique
    texte: "Vous entrez dans la forge du village."
    modeles:
      - modele: boutique
        variables:
          or: or
          achat1: achat1
          achat2: achat2
          achat3: achat3
          prix1: prix1
          prix2: prix2
          prix3: prix3
          revente1: revente1
          revente2: revente2
          revente3: revente3
          nomarticle1: nomarticle1
          nomarticle2: nomarticle2
          nomarticle3: nomarticle3
        sorties:
          quitter: apres_boutique

  - id: apres_boutique
    tag-apres: [retour_menu]
    texte: "Vous quittez la boutique. 💰 Or restant : v_or_v"

  # ── Test Jet ──────────────────────────────────────────────────────
  - id: test_jet
    texte: "La serrure est complexe. Tentez un jet de Crochetage."
    init:
      - var: modificateur
        valeur: 2
      - var: seuil
        valeur: 12
    modeles:
      - modele: jet_competence
        variables:
          de20: de20
          modificateur: modificateur
          seuil: seuil
          effethero: effethero
          nomcompetence: nomcompetence
        sorties:
          critique_succes: jet_exploit
          succes: jet_reussite
          echec: jet_echec
          critique_echec: jet_catastrophe

  - id: jet_exploit
    tag-apres: [retour_menu]
    texte: "⭐ La serrure s'ouvre en un clin d'œil. Un chef-d'œuvre !"

  - id: jet_reussite
    tag-apres: [retour_menu]
    texte: "✅ La serrure cède après quelques instants de travail."

  - id: jet_echec
    tag-apres: [retour_menu]
    texte: "❌ La serrure résiste. Il faudra trouver une autre solution."

  - id: jet_catastrophe
    tag-apres: [retour_menu]
    texte: "💥 L'outil se brise dans la serrure. La situation est pire qu'avant."

  # ── Test Défi ─────────────────────────────────────────────────────
  - id: test_defi
    texte: "Un haut mur vous barre la route."
    init:
      - var: progression
        valeur: 0
      - var: pression
        valeur: 0
      - var: objectifdefi
        valeur: 5
      - var: pressionmax
        valeur: 3
      - var: prepmax
        valeur: 2
    modeles:
      - modele: defi_progressif
        variables:
          progression: progression
          objectifdefi: objectifdefi
          pression: pression
          pressionmax: pressionmax
          prepmax: prepmax
          de6: de6
          nomdefi: nomdefi
        sorties:
          succes: defi_succes
          echec: defi_echec

  - id: defi_succes
    tag-apres: [retour_menu]
    texte: "🏆 Vous atteignez le sommet. De l'autre côté, la liberté."

  - id: defi_echec
    tag-apres: [retour_menu]
    texte: "🏳️ Vous abandonnez. Il faudra contourner."

  # ── Test Enquête ──────────────────────────────────────────────────
  - id: test_enquete
    texte: "Un vol a eu lieu au manoir. Vous êtes chargé de l'enquête."
    init:
      - var: indices
        valeur: 0
      - var: soupcons
        valeur: 0
      - var: indicesneed
        valeur: 3
      - var: soupconmax
        valeur: 4
      - var: enqtours
        valeur: 0
      - var: enqtoursmax
        valeur: 10
    modeles:
      - modele: enquete
        variables:
          indices: indices
          indicesneed: indicesneed
          soupcons: soupcons
          soupconmax: soupconmax
          enqtours: enqtours
          enqtoursmax: enqtoursmax
          de6: de6
          nomenquete: nomenquete
        sorties:
          resolu: enquete_resolue
          decouvert: enquete_decouverte
          fuite: enquete_fuite

  - id: enquete_resolue
    tag-apres: [retour_menu]
    texte: "⚖️ Vous désignez le coupable. L'affaire est classée."

  - id: enquete_decouverte
    tag-apres: [retour_menu]
    texte: "🚨 Vous avez été repéré. Le coupable prend la fuite !"

  - id: enquete_fuite
    tag-apres: [retour_menu]
    texte: "⏳ Trop tard. Le coupable a eu le temps de disparaître dans la nature."
