diff --git a/docs/creation-jeu.md b/docs/creation-jeu.md index e3ddcae..9c7cd49 100644 --- a/docs/creation-jeu.md +++ b/docs/creation-jeu.md @@ -248,6 +248,7 @@ Le score de la manche = **somme des catégories**. | `label` | Libellé affiché. | | `icon` | *(optionnel)* nom d'icône **lucide** affichée à côté de la catégorie. | | `color` | *(optionnel)* teinte hex de l'icône. | +| `requiresOption` | *(optionnel)* `id` d'une option booléenne : la catégorie n'apparaît (et n'est comptée) **que si cette option est activée**. Idéal pour un mode/extension (ex : « Animaux spirituels »). | > Généralement associé à `fixedRounds: 1` (un seul décompte final réparti en > catégories). diff --git a/public/game-templates/harmonies-esprits.json b/public/game-templates/harmonies-esprits.json new file mode 100644 index 0000000..eaa3579 --- /dev/null +++ b/public/game-templates/harmonies-esprits.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "id": "harmonies-esprits", + "name": "Harmonies — Esprits", + "minPlayers": 1, + "maxPlayers": 4, + "scoreType": "positive", + "scoreFormula": { "strategy": "sum_rounds" }, + "fixedRounds": 1, + "description": "Harmonies avec le mode alternatif « Esprits de la nature » (activable avant la partie).", + "icon": "TreePine", + "colors": { "primary": "#065f46" }, + "options": [ + { + "id": "esprits_nature", + "label": "Mode : Esprits de la nature", + "type": "boolean", + "defaultValue": false + } + ], + "scoringCategories": [ + { "id": "arbres", "label": "Arbres", "icon": "TreePine", "color": "#16a34a" }, + { "id": "montagnes", "label": "Montagnes", "icon": "Mountain", "color": "#64748b" }, + { "id": "champs", "label": "Champs", "icon": "Wheat", "color": "#d97706" }, + { "id": "batiments", "label": "Bâtiments", "icon": "Building2", "color": "#dc2626" }, + { "id": "eau", "label": "Rivière", "icon": "Waves", "color": "#0ea5e9" }, + { "id": "animaux", "label": "Animaux", "icon": "Rabbit", "color": "#a16207" }, + { + "id": "animaux_spirituels", + "label": "Animaux spirituels", + "icon": "Sparkles", + "color": "#8b5cf6", + "requiresOption": "esprits_nature" + } + ] +} diff --git a/src/types/index.ts b/src/types/index.ts index c378c9e..662cba8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -6,6 +6,7 @@ export interface ScoringCategory { label: string; icon?: string; // nom d'icône lucide (ex: "TreePine") — visuel de la catégorie color?: string; // teinte d'accent hex pour l'icône + requiresOption?: string; // n'apparaît que si cette option (booléenne) est activée } export interface GameConfig { diff --git a/src/utils/gameImportAdapter.ts b/src/utils/gameImportAdapter.ts index 443d430..dc90d2d 100644 --- a/src/utils/gameImportAdapter.ts +++ b/src/utils/gameImportAdapter.ts @@ -7,6 +7,7 @@ const scoringCategorySchema = z.object({ label: z.string(), icon: z.string().max(40).optional(), color: z.string().max(30).optional(), + requiresOption: z.string().max(60).optional(), }); const gameOptionSchema = z.object({ @@ -132,6 +133,14 @@ export function toGameConfig(def: ImportedGameDefinition): GameConfig { } } + // Option-dependent categories (e.g. an alternative game mode). If any category + // is gated by an option, expose them through getScoringCategories. + if (def.scoringCategories?.some((c) => c.requiresOption)) { + const cats = def.scoringCategories; + config.getScoringCategories = (options) => + cats.filter((c) => !c.requiresOption || !!options?.[c.requiresOption]); + } + // Score aggregation if (def.scoreFormula.strategy === "sum_rounds_with_reset") { const { resetThreshold, resetTo, oncePerPlayer } = def.scoreFormula;