Import de jeu : catégories conditionnelles (mode alternatif)
Build and Publish Docker Image / build-and-push-image (push) Successful in 1m2s
Build and Publish Docker Image / build-and-push-image (push) Successful in 1m2s
- ScoringCategory.requiresOption : une catégorie n'apparaît/compte que si l'option booléenne correspondante est activée (mode/extension déclaratif) - toGameConfig génère getScoringCategories filtrant selon les options - Gabarit harmonies-esprits.json : mode "Esprits de la nature" activable ajoutant la catégorie "Animaux spirituels" au décompte - Doc à jour Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -248,6 +248,7 @@ Le score de la manche = **somme des catégories**.
|
|||||||
| `label` | Libellé affiché. |
|
| `label` | Libellé affiché. |
|
||||||
| `icon` | *(optionnel)* nom d'icône **lucide** affichée à côté de la catégorie. |
|
| `icon` | *(optionnel)* nom d'icône **lucide** affichée à côté de la catégorie. |
|
||||||
| `color` | *(optionnel)* teinte hex de l'icône. |
|
| `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
|
> Généralement associé à `fixedRounds: 1` (un seul décompte final réparti en
|
||||||
> catégories).
|
> catégories).
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ export interface ScoringCategory {
|
|||||||
label: string;
|
label: string;
|
||||||
icon?: string; // nom d'icône lucide (ex: "TreePine") — visuel de la catégorie
|
icon?: string; // nom d'icône lucide (ex: "TreePine") — visuel de la catégorie
|
||||||
color?: string; // teinte d'accent hex pour l'icône
|
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 {
|
export interface GameConfig {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ const scoringCategorySchema = z.object({
|
|||||||
label: z.string(),
|
label: z.string(),
|
||||||
icon: z.string().max(40).optional(),
|
icon: z.string().max(40).optional(),
|
||||||
color: z.string().max(30).optional(),
|
color: z.string().max(30).optional(),
|
||||||
|
requiresOption: z.string().max(60).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const gameOptionSchema = z.object({
|
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
|
// Score aggregation
|
||||||
if (def.scoreFormula.strategy === "sum_rounds_with_reset") {
|
if (def.scoreFormula.strategy === "sum_rounds_with_reset") {
|
||||||
const { resetThreshold, resetTo, oncePerPlayer } = def.scoreFormula;
|
const { resetThreshold, resetTo, oncePerPlayer } = def.scoreFormula;
|
||||||
|
|||||||
Reference in New Issue
Block a user