# ⚔️ Combat

Jitsuri peut gérer les combats de trois façons complémentaires :

- le **combat intelligent**, qui recherche automatiquement les monstres sélectionnés et construit une rotation entre leurs zones ;
- la **stratégie Jitsuri**, configurée visuellement avec une liste de sorts, des cibles et des règles de déplacement ;
- le **combat Lua avancé**, destiné aux donjons et aux stratégies qui doivent piloter précisément chaque personnage, tour, placement et sort.

!!!info À retenir
La recherche d'un groupe, le choix de la stratégie pendant le combat et le trajet sont trois éléments distincts. Un trajet peut trouver et lancer un combat, puis laisser Jitsuri ou le Lua jouer les tours.
!!!

## Combat intelligent

Dans **Récolte & Combat > Mode intelligent > Combat**, sélectionnez les monstres à rechercher. Jitsuri localise leurs cartes, prépare les zones accessibles et construit automatiquement une rotation.

### Sélection des monstres

- Le catalogue charge une première sélection rapidement.
- La recherche accepte le nom ou le GID et n'est pas sensible aux majuscules.
- Les monstres déjà sélectionnés restent affichés en tête de liste, même après avoir effacé la recherche.
- Les boss, monstres spéciaux et groupes limités aux salles de donjon sont exclus du catalogue automatique.
- Les cartes inaccessibles détectées pendant le contrôle préalable sont retirées du parcours.

### Règles des groupes

| Option | Effet |
| --- | --- |
| **Monstres minimum** | Taille minimale d'un groupe autorisé. |
| **Monstres maximum** | Taille maximale d'un groupe autorisé, jusqu'à 8. |
| **Forcer les monstres sélectionnés** | Le groupe doit contenir au moins un des GID sélectionnés. |
| **Suppression automatique** | Supprime les piles correspondant aux GID d'objets saisis lorsque le seuil de pods est atteint. |

Pour la suppression automatique, saisissez uniquement des GID positifs séparés par des virgules, par exemple `123,234,345`.

!!!danger Suppression définitive
Chaque GID indiqué dans **Suppression automatique** est supprimé entièrement de l'inventaire. Cette action n'est pas récupérable.
!!!

Le seuil de pods, la banque ou le stockage configuré, l'utilisation des zaaps et les contrôles d'accessibilité restent appliqués au mode Combat.

!!!info Récolte et combat
Le mode intelligent lance un plan **Récolte** ou un plan **Combat** à la fois. Pour récolter et combattre sur les mêmes cartes dans un seul trajet, utilisez un trajet Lua personnalisé avec `gather = true` et `fight = true`.
!!!

## Lancer des combats depuis un trajet Lua

Une action `fight = true` demande à Jitsuri d'attaquer un groupe compatible sur la carte. Les variables globales déterminent les groupes autorisés :

```lua
MIN_MONSTERS = 1
MAX_MONSTERS = 4
FORBIDDEN_MONSTERS = { 666, 999 }
FORCE_MONSTERS = { 490 }
MAX_PODS = 90
AUTO_DELETE = { 123, 234 }

function move()
    return {
        { map = "-26,33", fight = true, path = "bottom" },
    }
end
```

- `FORBIDDEN_MONSTERS` refuse un groupe contenant l'un des GID indiqués.
- `FORCE_MONSTERS` exige qu'au moins un des GID indiqués soit présent.
- Une liste `FORCE_MONSTERS` vide n'impose aucun monstre particulier.
- `MAX_PODS` déclenche le retour prévu par `bank()` ; `AUTO_DELETE` supprime d'abord les piles configurées.

Ces règles choisissent le **groupe à attaquer**. La stratégie Jitsuri ou les callbacks avancés choisissent ensuite **comment jouer le combat**.

## Configurer la stratégie Jitsuri

Ouvrez **Paramètres > Combat** pour choisir les sorts joués automatiquement. L'ordre de la liste correspond à leur priorité : Jitsuri essaie le premier sort, puis les suivants jusqu'à trouver une action valide.

Pour chaque sort, vous pouvez notamment définir :

- la cible et la méthode de sélection de cette cible ;
- le lancement sur soi-même ou l'obligation d'avoir un ennemi au corps à corps ;
- le nombre maximal de lancers par tour, la recharge et le premier tour d'utilisation ;
- la portée de clic et le décalage de la case d'impact autour de la cible ;
- les seuils de points de vie du lanceur et de la cible ;
- les GID de monstres à forcer ou à exclure ;
- le comportement d'un sort d'invocation et la position recherchée pour celle-ci.

La portée réelle du sort, sa ligne de vue, son coût en PA, les cellules occupées et les limites de lancer sont toujours contrôlés avant l'envoi.

Les invocations autonomes continuent de jouer seules. Lorsqu'une invocation contrôlable donne la main au joueur, Jitsuri passe actuellement son tour automatiquement : la configuration de ses propres sorts n'est pas encore disponible.

!!!warning États de combat
Les filtres d'état affichés dans l'éditeur sont encore informatifs. Pour une mécanique de donjon dépendant strictement d'un état, utilisez un script Lua prévu pour cette mécanique et vérifiez que chaque action a bien réussi avant de poursuivre.
!!!

### Déplacement en combat

Dans **Paramètres > Comportement**, choisissez la logique générale :

| Mode | Comportement |
| --- | --- |
| **Corps à corps** | Recherche d'abord une cellule permettant de lancer un sort, puis se rapproche. |
| **Distance** | Préserve les portées et lignes de vue tout en s'éloignant des ennemis. |
| **Hybride** | Reste dans la plage de distance minimale et maximale configurée. |
| **Immobile** | Ne fait pas de replacement de fin de tour ; un mouvement indispensable à un sort reste possible. |

La gestion du tacle propose également trois politiques :

- **Intelligent** : estime les PA/PM perdus avant de quitter le contact ;
- **Ne jamais détacler** : ne tente pas de déplacement volontaire au contact ;
- **Ignorer le tacle** : planifie sans anticiper les pertes, à réserver aux états ou équipements adaptés.

## Choisir le moteur des combats Lua avancés

Le réglage **Moteur des combats Lua avancés** apparaît dans **Paramètres > Combat > Comportement**. Il ne change rien pour un trajet qui ne déclare aucun callback de combat avancé.

| Moteur | Qui décide ? | Usage conseillé |
| --- | --- | --- |
| **Hybride** | Le Lua reçoit le tour et peut le déléguer à l'IA Jitsuri. | Recommandé pour mélanger salles normales et mécaniques spéciales. |
| **Jitsuri** | Les tours utilisent toujours les sorts configurés dans Jitsuri. | Trajet Lua, mais stratégie de combat entièrement visuelle. |
| **Lua** | Le script contrôle les sorts et les déplacements. | Donjon ou composition avec scénario précis. |

Le mode choisi est enregistré automatiquement pour chaque personnage.

### Cycle d'un combat avancé

Un script moderne peut déclarer les fonctions suivantes :

```lua
function onFightStart(context)
    -- Le combat vient de commencer.
end

function onPlacement(context)
    -- Choix facultatif d'une cellule de départ.
end

function onTurn(context)
    -- Appelé uniquement pour le personnage dont c'est le tour.
end

function onFightEnd(context)
    -- Nettoyage et reprise du trajet.
end
```

Le champ `context` fournit notamment le personnage courant, sa classe, la carte, le tour et les cellules de placement disponibles.

Les anciens scripts utilisant les callbacks suivants sont également reconnus :

```lua
function prefightManagement(challengersCells, defendersCells)
    -- Placement avant le combat.
end

function fightManagement()
    -- Gestion du tour courant.
end
```

!!!warning Fin de tour
Un callback de tour doit lancer une action, déléguer le tour ou appeler `fightAction:passTurn()`. Si le callback revient sans terminer le tour, Jitsuri le passe automatiquement afin d'éviter un blocage.
!!!

## Exemple Lua minimal

L'exemple suivant essaie un sort sur le premier ennemi vivant. Il sait lancer immédiatement, se déplacer puis lancer, ou progresser pendant plusieurs tours jusqu'à une future cellule de tir.

```lua
local SPELL_ID = 12797

local function firstEnemy()
    for _, entity in ipairs(fightAction:getAllEntities() or {}) do
        if entity.Team == true and entity.IsAlive ~= false then
            return entity
        end
    end
    return nil
end

function onPlacement(context)
    local cell = context.challengerCells and context.challengerCells[1]
    if cell then
        fightAction:chooseCell(cell)
    end
end

function onTurn(context)
    local enemy = firstEnemy()
    if not enemy then
        fightAction:passTurn()
        return
    end

    local plan = fightAction:getSpellCastPlan(SPELL_ID, enemy.CellId)

    if plan.status == "cast-now" then
        fightAction:castSpellOnCell(SPELL_ID, plan.castCell)
    elseif plan.status == "cast-after-move" then
        if fightAction:moveTowardCell(plan.moveCell) then
            fightAction:castSpellOnCell(SPELL_ID, plan.castCell)
        end
    elseif plan.status == "progress" then
        fightAction:moveTowardCell(plan.moveCell)
    else
        -- Fonctionne en Hybride ; renvoie false en mode Lua.
        fightBasic:playTurn(2)
    end

    fightAction:passTurn()
end
```

Le plan tactique ne demande jamais de marcher sur la cellule occupée par le monstre. Il cherche une cellule libre et accessible qui permet le lancer, ou un point de progression vers cette cellule si elle est trop éloignée pour le tour actuel.

## API Lua de combat

### Personnage courant

| Fonction | Retour |
| --- | --- |
| `fightCharacter:getBreed()` | Identifiant de la classe. |
| `fightCharacter:getCellId()` | Cellule actuelle. |
| `fightCharacter:isItMyTurn()` | `true` si le personnage doit jouer. |
| `fightCharacter:getKnownSpellIds()` | Sorts connus par le personnage. |
| `fightCharacter:getConfiguredSpellIds()` | Sorts présents dans la stratégie Jitsuri. |
| `fightCharacter:getActiveStateIds()` | États actuellement connus. |
| `fightCharacter:hasState(stateId)` | Présence d'un état connu. |
| `character:id()` | Identifiant du personnage courant. |
| `character:getInTeamIndex()` | Position du personnage dans l'équipe. |

### Actions et planification

| Fonction | Effet |
| --- | --- |
| `fightAction:chooseCell(cellId)` | Choisit une cellule de placement. |
| `fightAction:getAllEntities()` | Renvoie les entités avec leur ID, GID, cellule, équipe, vie et statut d'invocation. |
| `fightAction:getCurrentTurn()` | Numéro du tour courant. |
| `fightAction:getReachableCells()` | Cellules accessibles ce tour. |
| `fightAction:getRealReachableCells()` | Variante compatible avec les anciens scripts. |
| `fightAction:getSpellCastPlan(spellId, targetCellId)` | Calcule un plan `cast-now`, `cast-after-move`, `progress` ou `impossible`. |
| `fightAction:getBestCellToCastSpell(spellId, targetCellId)` | Renvoie la meilleure cellule de lancer atteignable, ou `-1`. |
| `fightAction:moveTowardCell(cellId)` | Se déplace vers une cellule et renvoie la confirmation. |
| `fightAction:castSpellOnCell(spellId, cellId)` | Lance un sort et renvoie la confirmation. |
| `fightAction:canCastSpellOnCell(fromCell, spellId, cellId)` | Renvoie `0` si le lancer est possible et `1` sinon. |
| `fightAction:passTurn()` | Termine le tour. |
| `fightBasic:playTurn(2)` | Demande à l'IA Jitsuri de jouer ce tour en mode Hybride. |

Le résultat de `getSpellCastPlan` inclut aussi `moveCell`, `castCell`, `futureCastCell`, `movementCost`, `remainingDistance`, `actionPointCost`, `score`, `reason`, les compteurs de lancer et la recharge restante.

### Compatibilité des scripts avancés

Les objets suivants sont disponibles pour faciliter l'adaptation d'anciens scripts avancés :

- `global` : délais, logs, arrêt, équipe, hasard et détection de boss ;
- `map` : map actuelle, déplacement, combat et interactions ;
- `inventory` : quantité, utilisation et équipement par GID ;
- `npc` : ouverture du dialogue et choix d'une réponse ;
- `jitsuriController` : mémoire partagée entre les callbacks ;
- `character` : classe, index d'équipe, variante de sort et améliorations compatibles ;
- `fightCharacter`, `fightAction` et `fightBasic` : lecture du combat, actions tactiques et délégation à l'IA Jitsuri.

## Combat en équipe

Lorsqu'un trajet avancé est lancé sur une équipe :

1. le chef charge une seule instance du script Lua ;
2. Jitsuri centralise les événements de placement et de tour ;
3. le personnage courant change automatiquement avant chaque callback ;
4. la mémoire `jitsuriController` reste commune à toute la stratégie ;
5. les actions des différents personnages restent coordonnées dans le bon ordre.

Lancez donc le trajet depuis le **chef d'équipe** prévu par le script. Pour une stratégie qui dépend d'une composition ou d'un ordre précis, vérifiez les classes et leur position avant le départ.

## Scripts de donjon et exemple Klime

Les scripts avancés de donjon peuvent maintenant combiner :

- des placements différents selon la salle et la classe ;
- des stratégies propres à chaque tour ;
- des changements d'équipement et de variante de sort ;
- des interactions PNJ et portes ;
- des sorts dépendant d'un état ou d'une variante ;
- une délégation à Jitsuri dans les salles sans mécanique spéciale.

Pour un script Klime prévu pour une équipe Pandawa, Eliotrope, Forgelance et Iop :

- placez le **Pandawa en chef d'équipe** si le script l'utilise comme index 1 ;
- vérifiez la présence exacte des quatre classes attendues ;
- équipez ou conservez dans l'inventaire tous les objets référencés par leur GID ;
- vérifiez les clés, consommables et variantes de sorts demandés ;
- choisissez **Hybride** pour déléguer les salles normales à Jitsuri et garder le boss piloté par le Lua ;
- choisissez **Lua** seulement si le script gère réellement tous les tours.

## Diagnostic

| Log ou symptôme | Interprétation | Vérification |
| --- | --- | --- |
| Le script avancé est détecté | La stratégie de combat est prête. | Vérifiez que la composition affichée correspond à votre équipe. |
| Aucun tour Lua n'est joué | Le mode Jitsuri est actif ou le script ne déclare pas de callback reconnu. | Contrôlez le moteur choisi et le nom de la fonction. |
| Un sort est refusé | L'action ne respecte pas une condition du combat. | Vérifiez variante active, état, PA, portée, ligne de vue et cellule ciblée. |
| `status=progress` | Aucun tir n'est possible ce tour, mais une route tactique existe. | Déplacez-vous vers `moveCell`, puis recalculer au tour suivant. |
| `status=impossible` | Aucun lancer ni chemin valide n'a été trouvé. | Consultez `reason`, la recharge et les limites de lancer du plan. |
| Passage automatique du tour | Le callback s'est terminé sans délégation ni `passTurn`. | Terminez explicitement chaque branche de `onTurn`. |
| Le trajet reprend après le combat | Fonctionnement normal après `onFightEnd`. | Aucune action nécessaire. |

Si un combat de donjon échoue, conservez le log complet depuis le début du combat : la dernière action réussie permet généralement d'identifier le placement, le sort ou l'état incorrect.

Pour la référence générale des trajets, consultez [les fonctions Lua](../Trajets/lua.md).
