Add docs file explaining how to use battle system for now

This commit is contained in:
TheThomaas 2026-10-11 21:37:12 +02:00
parent dfa5a48888
commit eb6432e7a0

80
game/battle/battle.md Normal file
View file

@ -0,0 +1,80 @@
# Gérer l'équipe d'un PNJ ou d'un Pokémon sauvage
*Tales of Pokémon · système de combat*
## Principe
Tout se décrit avec des ressources, sans écrire de code :
- **`TrainerPartyEntry`** : un Pokémon « modèle » (espèce, niveau, surnom, nature, capacités).
- **`TrainerData`** : un dresseur PNJ, avec une liste de `TrainerPartyEntry` (6 maximum).
- **`BattleEncounter`** : la rencontre complète (qui est en face, format du combat, règles).
- **`AimTarget`** : la cible du monde. Son champ `Encounter` contient le `BattleEncounter`, et son champ `World Actor` le node visible dans le monde (caché pendant le combat).
Ces ressources sont des modèles : à chaque combat, de **vrais Pokémon neufs** sont créés à partir d'elles. Un PNJ retrouve donc son équipe intacte à chaque revanche, et un même `BattleEncounter` peut être partagé entre plusieurs cibles.
Pour créer une ressource : clic droit dans le dock Système de fichiers > *Nouvelle ressource…*, choisir le type, puis l'enregistrer en `.tres`.
## Un Pokémon sauvage (1 contre 1)
1. Crée un `TrainerPartyEntry` : choisis l'**espèce** et le **niveau**.
2. Crée un `BattleEncounter` et ajoute l'entrée à `Wild Pokemon`.
3. Sur l'`AimTarget` de l'ennemi : assigne le `BattleEncounter` à `Encounter` et le node de l'ennemi à `World Actor`.
4. Laisse `Can Flee` coché : le joueur peut fuir un Pokémon sauvage.
Un Pokémon sauvage n'a pas de banc, il ne change donc jamais de Pokémon.
## Plusieurs Pokémon sauvages (1 contre plusieurs)
Ajoute **plusieurs entrées** dans `Wild Pokemon` : chacune devient un adversaire à part entière avec son propre emplacement (3 entrées = 1 contre 3). Chaque adversaire attaque, et peut être ciblé, séparément.
## Un dresseur PNJ
1. Crée un `TrainerData` : renseigne `Id`, `Names` (un nom par langue, par exemple `fr` et `en`) et ajoute ses Pokémon dans `Party` (6 maximum, dans l'ordre d'envoi).
2. Crée un `BattleEncounter` : assigne le `Trainer`, et **décoche `Can Flee`** (on ne fuit pas un dresseur).
3. Sur son `AimTarget` : `Encounter` et `World Actor`, comme pour un sauvage.
Son premier Pokémon (puis le suivant, pour un combat double) entre en combat, et les autres restent sur son banc. Il en envoie un autre quand le sien est KO, ou parfois de lui-même quand son Pokémon est très désavantagé face au tien.
## Combat double, boss et autres formats
Le format vient uniquement du nombre d'emplacements :
| Format | Réglage du `BattleEncounter` |
| --- | --- |
| 1 contre 1 sauvage | 1 entrée dans `Wild Pokemon` |
| 1 contre plusieurs | plusieurs entrées dans `Wild Pokemon` |
| Dresseur, combat simple | `Trainer`, `Trainer Slots` = 1 |
| Combat double | `Player Slots` = 2 et `Trainer Slots` = 2 |
| Plusieurs contre 1 (boss) | `Player Slots` = 3 et un seul adversaire (une entrée sauvage, ou un dresseur avec `Trainer Slots` = 1) |
`Player Slots` et `Trainer Slots` vont de 1 à 3. Si le joueur a moins de Pokémon aptes que d'emplacements, il en envoie moins.
## Capacités et nature
Pour chaque `TrainerPartyEntry` :
- **Capacités** : si `Forced Moves` est vide, le Pokémon connaît les capacités apprises par montée de niveau jusqu'à son niveau, et équipe les 4 dernières. Sinon, les capacités listées (4 maximum) sont équipées à la place.
- **Nature** : `Random Nature` coché tire une nature au hasard à chaque combat. Décoche-le et choisis `Nature` pour la fixer.
- **Surnom** : s'il est vide, le nom de l'espèce s'affiche.
## Quel Pokémon du joueur combat ?
- Si le joueur **lance** un Pokémon sur la cible, c'est lui qui entre en premier, puis les suivants de l'équipe pour un combat double.
- Si le **dresseur défie** le joueur (dialogue, zone de détection), c'est le premier Pokémon apte de l'équipe, puis le deuxième, etc. Pour cela, appelle depuis ton code :
```gdscript
launcher.start_encounter(encounter, position_du_dresseur, null, world_actor)
```
## Après le combat
- Si `Remove World Actor On Win` est coché, le `World Actor` disparaît après une victoire. Sinon il réapparaît.
- Le signal `battle_finished(outcome)` de l'`AimTarget` (et `GameData.battle_finished`) donne le résultat, une valeur de `Battle.Outcome` : `PLAYER_WON`, `PLAYER_LOST`, `FLED` ou `DRAW`. Branche-y tes dialogues, tes récompenses ou la suite de l'histoire.
- Après une défaite, l'équipe du joueur est soignée automatiquement (option `Heal Team On Defeat` sur le `BattleLauncher`). C'est provisoire, en attendant ton propre écran de défaite.
## Bon à savoir
- Un `TrainerData` ne doit pas dépasser 6 Pokémon : les suivants sont ignorés, avec un avertissement dans la console.
- Une entrée sans espèce est ignorée. Si un camp n'a plus aucun Pokémon, le combat ne démarre pas, et la console l'indique.
- Pas encore implémentés : les effets des capacités de statut, les objets, le gain d'XP et d'argent, et la capture.