feat: alliés présents dans les rencontres (#53) #63

Merged
Reliodas merged 1 commit from feature/53-combat-allies into develop 2026-06-22 06:21:01 +00:00
Owner

Closes #53.

Étend la sélection des participants pour inclure les membres du groupe réellement présents, à leurs positions du monde. Cinquième pierre du jalon 0.16.0 (dépend de #49, s'intègre avec #52). Les alliés rejoignent l'initiative et le champ tactique sur l'équipe du héros ; leur pilotage (joueur/IA) arrivera avec #54 et #56. Le cas solo 0.15.0 reste strictement inchangé.

Changements

  • EncounterSetup.select_allies() (PURE, sans dépendre de GameState ni d'aucun Node) : à partir des membres présents (hors héros) et de leurs cases courantes, construit les entrées d'allié { member_id, creature, control_mode, cell }. Filtre les indisponibles (Creature nulle, morte, sans position) et préserve l'ordre (indépendant des dictionnaires).
  • CombatController : allies + add_ally() / place_ally(). Les alliés sont inscrits sur l'équipe du héros (HERO_TEAM) — affectée à tous les alliés de la même façon, jamais déduite du mode de contrôle (qui reste porté par le PartyMember). start() compose l'initiative [héros] + alliés + ennemis dans un ordre stable.
  • Tour d'un allié : en #53, un allié (même équipe) n'est jamais joué par l'IA d'attaque (qui frappe le héros) — son tour est passé. Le pilotage multi-acteurs est #54, l'IA alliée #56. Garde-fou : la chute du héros termine le combat (politique 0.15.0) pour éviter un combat sans fin (héros mort + allié vivant + alliés encore inertes) ; la résolution par équipe/survivants viendra avec #55.
  • World : transmet les alliés présents (hors protagoniste, à leur case de jeton suiveur courante) à EncounterFlow.begin_encounter(), et libère leurs cases de la grille après le combat.

Critères d'acceptation

  • l'initiative contient exactement les alliés et hostiles présents ;
  • chaque Creature commence sur sa position du monde ;
  • aucun membre du roster absent de la zone ne rejoint le combat ;
  • équipes et contrôle sont conservés sans dépendre de l'ordre d'inscription ;
  • le cas solo 0.15.0 reste fonctionnel ;
  • EncounterSetup et le flux World sont couverts par des tests.

Tests

Suite GUT complète verte : 249 tests / 801 assertions (depuis 241 / 778).

  • tests/unit/test_encounter_allies.gd : select_allies (ordre, exclusion des morts/non-positionnés) ; allié sur l'équipe du héros, initiative à 3, placement sur la case du monde, allié jamais inscrit comme ennemi ; combat complet héros + allié vs gobelin prouvant que le tour de l'allié est passé (allié intact, aucun tir ami, victoire par élimination de l'équipe adverse) ; flux World (les alliés présents rejoignent la rencontre).
Closes #53. Étend la sélection des participants pour inclure les membres du groupe réellement présents, à leurs positions du monde. Cinquième pierre du jalon 0.16.0 (dépend de #49, s'intègre avec #52). Les alliés rejoignent l'initiative et le champ tactique sur l'équipe du héros ; leur pilotage (joueur/IA) arrivera avec #54 et #56. Le cas solo 0.15.0 reste strictement inchangé. ## Changements - **`EncounterSetup.select_allies()`** (PURE, sans dépendre de `GameState` ni d'aucun Node) : à partir des membres présents (hors héros) et de leurs cases courantes, construit les entrées d'allié `{ member_id, creature, control_mode, cell }`. Filtre les indisponibles (Creature nulle, morte, sans position) et **préserve l'ordre** (indépendant des dictionnaires). - **`CombatController`** : `allies` + `add_ally()` / `place_ally()`. Les alliés sont inscrits sur **l'équipe du héros** (`HERO_TEAM`) — affectée à **tous** les alliés de la même façon, **jamais** déduite du mode de contrôle (qui reste porté par le `PartyMember`). `start()` compose l'initiative `[héros] + alliés + ennemis` dans un ordre stable. - **Tour d'un allié** : en #53, un allié (même équipe) n'est **jamais** joué par l'IA d'attaque (qui frappe le héros) — son tour est passé. Le pilotage multi-acteurs est #54, l'IA alliée #56. Garde-fou : la chute du héros termine le combat (politique 0.15.0) pour éviter un combat sans fin (héros mort + allié vivant + alliés encore inertes) ; la résolution par équipe/survivants viendra avec #55. - **`World`** : transmet les alliés présents (hors protagoniste, à leur case de jeton suiveur courante) à `EncounterFlow.begin_encounter()`, et **libère leurs cases** de la grille après le combat. ## Critères d'acceptation - [x] l'initiative contient exactement les alliés et hostiles présents ; - [x] chaque Creature commence sur sa position du monde ; - [x] aucun membre du roster absent de la zone ne rejoint le combat ; - [x] équipes et contrôle sont conservés sans dépendre de l'ordre d'inscription ; - [x] le cas solo 0.15.0 reste fonctionnel ; - [x] EncounterSetup et le flux World sont couverts par des tests. ## Tests Suite GUT complète verte : **249 tests / 801 assertions** (depuis 241 / 778). - `tests/unit/test_encounter_allies.gd` : `select_allies` (ordre, exclusion des morts/non-positionnés) ; allié sur l'équipe du héros, initiative à 3, placement sur la case du monde, allié jamais inscrit comme ennemi ; **combat complet** héros + allié vs gobelin prouvant que le tour de l'allié est passé (allié intact, aucun tir ami, victoire par élimination de l'équipe adverse) ; flux `World` (les alliés présents rejoignent la rencontre).
feat: assembler les alliés présents dans les rencontres (#53)
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/pr/woodpecker Pipeline was successful
ci/woodpecker/pull_request_closed/woodpecker Pipeline was successful
18c4d43d3c
EncounterSetup.select_allies assemble (de façon pure, sans GameState) les
compagnons présents et vivants à leurs cases courantes, en préservant
l'ordre et le mode de contrôle.

CombatController gagne add_ally/place_ally et la liste allies : les alliés
rejoignent l'initiative sur l'équipe du héros (HERO_TEAM, jamais déduite du
mode de contrôle) et démarrent à leur position du monde. World transmet les
alliés présents (hors protagoniste) à EncounterFlow.begin_encounter et
libère leurs cases après le combat.

En #53 le tour d'un allié est passé automatiquement (jamais joué comme un
ennemi : il n'attaquerait pas le héros) ; le pilotage multi-acteurs (#54)
et l'IA alliée (#56) suivront. La chute du héros termine encore le combat
(politique 0.15.0) en attendant la résolution par équipe du #55. Cas solo
0.15.0 inchangé.

Tests : test_encounter_allies.gd (sélection pure, équipe/initiative/placement,
allié jamais joué comme ennemi sur un combat complet, flux World). Suite 249.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reliodas merged commit 4488579eb4 into develop 2026-06-22 06:21:01 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: jeux/beaulieu-sur-brume#63
No description provided.