# Mapping des touches

Décisions de l'auteur du 10/10/2026, dans la feuille « menu et fonction bigg
egg » (onglets Feuille 1 = manette, Clavier, Règles) :
https://docs.google.com/spreadsheets/d/17psjKX1V6SEm1mWzitRDgnbGWPfLyIsaybPpvSksMrE

Chantier en cinq étapes, ligne 73 du Sheet de suivi. Ce document dit ce que le
code fait déjà et comment brancher un menu neuf ; la feuille reste la référence
de conception.

## Où vivent les touches

- `scripts/core/input_scheme.gd` : la table `BINDINGS`, installée par
  `GameState._ready()`. Elle remplace les touches de `project.godot`, que
  l'éditeur ouvert réécrit. Une touche se change ici, pas dans le projet.
- `ui_cancel` (Retour) : Retour arrière, clic droit, B. Échap n'en est plus.
- `pause` : Échap et Start.

## Les trois gestes en jeu (étape 1a)

- `attack` : clic gauche, ZR. En combat, le clic attaque et rien d'autre.
- `action` : clic gauche, A. Agir sur la cible (travailler, prendre, servir).
- `interact` : F, Y. Ouvrir l'interface de la cible (four, console) ou parler.
- `secondary_action` : clic droit, R. L'arme de la main gauche (voir le
  berimbau plus bas).

## La manette complète (étape 2)

- Visée : le stick droit (`aim_*`) oriente le héros ; la souris, son pointeur ;
  sinon il regarde où il marche et `Player.assist_aim()` cale la visée sur la
  bête la plus proche devant lui, dans un cône. Deux réglages d'auteur dans le
  maître : `aim_assist_angle` (demi-angle en degrés, 50 ; zéro coupe
  l'assistance) et `aim_assist_range` (360).
- En donjon : R, la molette et L passent à l'arme principale suivante
  (`GameState.cycle_active_weapon`) ; T et croix bas à l'arme secondaire
  suivante, berimbau compris (`cycle_secondary_weapon`) ; Q/E et croix
  gauche/droite déplacent la case de plat préparé (`cycle_consumable_slot`,
  cadre doré dans le HUD) ; Shift et ZL la déclenchent. Les touches 1 à 8
  restent directes.
- Menus : Q/E et L/R (`tab_prev`, `tab_next`) changent d'onglet à la console.
- Aménagement : le stick gauche (ou les flèches) mène un curseur au sol ; A
  prend le meuble dessous puis le pose, Y le range, L/R (Q/E) le tournent ; la
  souris reprend la main dès qu'elle bouge.
- Carte : le stick fait défiler la colonne active, gauche et droite changent
  de colonne.
- Accueil : Retour à la racine demande aussi de quitter.
- Rappel : le second argument de `GameState.resolve_game_variable` remplace
  la base de la variable ; ce n'est pas une valeur par défaut.

## Les invites selon l'appareil (étape 5a)

- `Stage` suit le dernier appareil touché : `input_device` ("keyboard" ou
  "pad"), `pad_family` (xbox, playstation, switch, d'après le nom de la
  manette ; une inconnue prend les noms Xbox), `pad_known`, et le signal
  `input_device_changed`.
- `scripts/core/input_prompts.gd` lit l'InputMap vivante : `label(action)`
  (nom court, traduit : `ui.key.*`, `ui.pad.*`), `icon(action)` (pack
  « Input Prompts » de Kenney, CC0, `assets/ui/input_prompts/`, licence à
  côté), `event_label(event, avec_position)`. Une lettre se lit selon la
  disposition du clavier (Q physique : A sur un AZERTY ; sans fenêtre, la
  touche physique). Les boutons de face d'une manette inconnue disent aussi
  leur position (bas, droite, gauche, haut).
- Les textes portent des gabarits que `Loc.ui` remplit : `{attack}`, ou
  `{interact|action}` (une action au clavier, une autre à la manette). Un
  gabarit qui ne nomme aucune action reste tel quel. Ne plus écrire de touche
  en dur dans un texte.
- Icônes : cases du HUD (`key_icon`), invite d'action, anneau de plongée.
  Les phrases gardent des noms courts.
- Migration : `migrate_device_prompts_20261011.php`.

## L'écran des commandes (étape 5b)

- Options › Commandes (`scripts/core/controls_menu.gd`, bâti par le code) :
  une ligne par action (`InputScheme.REMAPPABLE`, dans l'ordre affiché), une
  colonne clavier et souris, une colonne manette, avec icônes et position des
  boutons de face. Choisir une case, puis appuyer sur la nouvelle touche ;
  Échap ou Start annulent la capture ; « Valeurs par défaut » efface tout ;
  Retour ferme l'écran.
- Fixes (décision du 11/10) : la pause et Retour (`InputScheme.FIXED`), et la
  navigation des menus (`ui_*`, hors schéma). Les axes de visée n'ont pas de
  case clavier (`PAD_ONLY`).
- Chaque action se remappe seule, même quand elle partage une touche avec une
  autre dans un autre contexte.
- Les choix vivent dans les réglages (`GameState.input_overrides`, fichier
  `user://settings.json`) : `{action: {"keyboard"|"pad": liaison}}`.
  `InputScheme.install(overrides)` pose le schéma puis les remplace, au
  démarrage et à chaque choix ; une liaison qui ne tient plus tombe à la
  relecture.
- Migration des textes : `migrate_controls_screen_20261011.php`.

## Les deux menus (12/10/2026, ligne 25 du suivi)

Un seul composant (`scripts/restaurant/recipe_menu.gd`), trois usages : le four
(`COOK`), la gestion du resto (`CONSOLE`) et le menu joueur (`PLAYER`). Même
fenêtre, même barre d'onglets (Q/E, L/R), mêmes gestes ; les deux menus
arrêtent le temps.

| Menu | S'ouvre | Onglets |
|---|---|---|
| Menu joueur | Tab, Select ; partout, plongée comprise (le HUD en porte un exemplaire) | Héros, Équipement, Ingrédients, Objets, Quêtes |
| Gestion | Q, L de partout au resto, ou devant la console ; au resto seulement | Carte, Recettes, Brigade, Comptoir, Ingrédients, Armurerie |

- **Équipement** (joueur) : équiper armes, équipement et cases de plats, partout.
- **Armurerie** (gestion, l'ancien Arsenal) : acheter ce qu'on n'a pas, cuisiner
  les plats de combat.
- **Ingrédients** (joueur) : en plongée, le sac (ce qui est ramassé depuis le
  départ), la réserve du resto et le total ; au resto, la réserve.
  **Ingrédients** (gestion) : la réserve et la vente au marché.
- Contrôle : `input_scheme_check` section 10.

## Les gestes maintenus (étape 3)

- Un anneau (`scripts/core/hold_ring.gd`) montre un geste maintenu ;
  `hold_press.gd` l'accroche à un bouton : il se remplit tant que le bouton
  reste enfoncé (clic, A, Entrée) et émet `held` au bout de 0,6 s. Relâcher
  avant ne fait rien. L'Étal achète ainsi.
- L'arbre des améliorations : un appui choisit le nœud et montre sa fiche ;
  maintenir le clic ou A 0,6 s achète, anneau autour du nœud.
- Au resto : B et le clic droit (`cancel_task`) annulent la cuisson du poste
  ciblé, ingrédients rendus ; Q/L (`open_console`) ouvrent la console de
  partout, E/R (`open_upgrades`) l'arbre ; Shift ou ZL (`dive_hold`)
  maintenus une seconde lancent la plongée, anneau au-dessus du héros. La
  porte du donjon garde son appui. Le clic droit n'utilise plus l'arme de la
  main gauche hors combat.
- Temps arrêté : le four et la console figent le resto tant qu'ils sont
  ouverts (le menu vit en `PROCESS_MODE_ALWAYS`) et rendent l'état d'avant.
  L'arbre des améliorations ne fige le resto que sans brigade (décision du
  11/10) : avec des employés, la salle vit hors champ.

## Les interfaces (étape 1b)

Le régisseur (`scripts/core/stage.gd`, autoload `Stage`) tient une pile
d'interfaces à côté du plateau. Seule celle du dessus lit les touches.

Un menu neuf :

1. `Stage.push_interface(self)` en s'ouvrant, `Stage.pop_interface(self)` en
   se fermant. Une interface cachée ou sortie de l'arbre tombe d'elle-même de
   la pile, mais le retrait explicite reste la règle.
2. Dans son gestionnaire d'entrée : `if not Stage.accepts_input(self): return`.
   C'est indispensable pour un écran en `PROCESS_MODE_ALWAYS` (carte, boutique,
   scène, question), qui continue d'entendre les touches sous la pause. Un menu
   pausable se tait déjà quand la pause fige l'arbre.
3. Retour : `Stage.is_back(event)` (il ignore Retour arrière dans un champ de
   saisie). Il recule d'un cran, ou ferme le menu à sa racine.
4. Tab et Select (`console_toggle`) ferment le menu.
5. Ne jamais lire `pause` : Échap et Start appartiennent à la pause, qui
   s'ouvre par-dessus tout et rend en se fermant le menu d'avant, son focus et
   l'état figé ou non du jeu.
6. Un clic n'agit que sous le pointeur : ignorer `InputEventMouseButton` avant
   de confirmer l'élément sélectionné sur `action` ou `ui_accept`.
7. Un choix obligatoire (choix de scène, bonus, question oui/non) ne répond pas
   à Retour.

Un écran qui doit passer devant ce qui est ouvert prend
`Stage.layer_above_interfaces(LAYER)` pour calque (la pause, la carte).

La pause masque « Sauvegarder et quitter », « Fin de plongée » et la carte
quand une séquence tient le plateau (bilan, cinématique, avis). Sur une scène
qu'on peut passer, elle propose « Passer la scène ». Sans pause dans l'arbre
(l'intro), Échap passe encore la scène directement.

À l'accueil, Start valide, Échap pose la question de quitter et la retire au
second appui, Retour recule d'un écran.

## Les maintiens

Un bouton enfoncé pendant qu'une interface tenait l'écran, ou d'une scène à
l'autre, ne compte qu'une fois relâché. Le jeu lit donc les gestes par
`Stage.gesture_held(action)` et `Stage.gesture_just_pressed(action)`, pas par
`Input` directement (joueur, postes du resto, invite du HUD).

## Le berimbau (étape 4)

- Une fiche d'arme `berimbau`, emplacement secondaire, avec deux champs du
  schéma des armes (PHP, `data_catalog.gd`, formulaire du gestionnaire) :
  `special_action: "berimbau"` (l'écho au lieu d'un geste ; le pattern devient
  facultatif) et `key_item: "berimbau"`.
- Une arme liée à un objet clé est possédée tant que l'objet l'est
  (`GameState.weapon_is_owned`) : une seule vérité, celle que lisent déjà les
  conditions d'histoire. Elle ne s'achète pas, ne tombe pas d'un monstre, et
  l'effet `weapons.<id>.owned` l'ignore.
- `Player.use_secondary()` (R, clic droit) : berimbau en main, l'écho
  (`try_echo`, avec ses trois pouvoirs : éclairer le noir, révéler, faire
  danser) ; dans une salle noire, l'écho quelle que soit l'arme, même sans
  l'instrument ; sinon, l'arme de la main gauche tire.
- « Main gauche » a quitté l'achat : comme la danse du berimbau, c'est un
  cadeau d'histoire (portée méta, sans coût, visible avec l'instrument). Les
  deux réparations du Saule (D3, D4) la cochent juste avant de rendre le
  berimbau, qui s'équipe alors tout seul si la main gauche est libre. Perdre
  l'instrument le retire de la main.
- Migration : `migrate_berimbau_weapon_20261010.php`.

## Contrôle

`python tools/dev/dev.py check --area input_scheme` : les touches, les gestes
en donjon, Y au resto, la pause en couche, Retour, Tab, la question, la carte
sous la pause, les maintiens, l'accueil, le berimbau, la manette (visée,
assistance, croix, onglets, aménagement, carte), les gestes maintenus (anneau,
annulation, console de partout, temps arrêté, achat maintenu, plongée), les
invites selon l'appareil, l'écran des commandes. Le
clic droit qui éclaire une salle noire est dans `d4_engine` ; l'achat maintenu
à l'Étal dans `d2_engine`.

## Restent hors du chantier

Les cinq étapes sont faites (11/10/2026).

- Le dévoilement du texte des scènes (A, B, B maintenu) : fait le 12/10, voir
  `docs/devoilement-texte.md`.
- La carte reste une liste que la manette fait défiler ; la carte en vue
  latérale, avec curseur de nœud en nœud, est un chantier à part (ligne 74 du
  Sheet de suivi).
