From 29b93b5ed1967e4e715d4fd60d8583dd9a0702de Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Fri, 10 Jul 2026 23:49:31 +0200 Subject: [PATCH] feat: tarot deck auto-import depuis compendium/data JSON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit resetDeck() cherche les cartes dans cet ordre : 1. game.items (items monde existants) 2. Compendium système fvtt-hamalron.hamalron-items 3. assets/data/tarot.json (création automatique) Ajout de assets/data/tarot.json : 78 cartes standard --- assets/data/tarot.json | 548 +++++++++++++++++++++ module/applications/tarot-deck-manager.mjs | 81 ++- 2 files changed, 606 insertions(+), 23 deletions(-) create mode 100644 assets/data/tarot.json diff --git a/assets/data/tarot.json b/assets/data/tarot.json new file mode 100644 index 0000000..dbc0cb1 --- /dev/null +++ b/assets/data/tarot.json @@ -0,0 +1,548 @@ +[ + { + "name": "Le Bateleur", + "type": "atout", + "symbole": "coupe", + "valeur": "1", + "description": "

Le Bateleur

" + }, + { + "name": "La Papesse", + "type": "atout", + "symbole": "coupe", + "valeur": "2", + "description": "

La Papesse

" + }, + { + "name": "L'Impératrice", + "type": "atout", + "symbole": "coupe", + "valeur": "3", + "description": "

L'Impératrice

" + }, + { + "name": "L'Empereur", + "type": "atout", + "symbole": "coupe", + "valeur": "4", + "description": "

L'Empereur

" + }, + { + "name": "Le Pape", + "type": "atout", + "symbole": "coupe", + "valeur": "5", + "description": "

Le Pape

" + }, + { + "name": "L'Amoureux", + "type": "atout", + "symbole": "coupe", + "valeur": "6", + "description": "

L'Amoureux

" + }, + { + "name": "Le Chariot", + "type": "atout", + "symbole": "coupe", + "valeur": "7", + "description": "

Le Chariot

" + }, + { + "name": "La Justice", + "type": "atout", + "symbole": "coupe", + "valeur": "8", + "description": "

La Justice

" + }, + { + "name": "L'Hermite", + "type": "atout", + "symbole": "coupe", + "valeur": "9", + "description": "

L'Hermite

" + }, + { + "name": "La Roue de Fortune", + "type": "atout", + "symbole": "coupe", + "valeur": "10", + "description": "

La Roue de Fortune

" + }, + { + "name": "La Force", + "type": "atout", + "symbole": "coupe", + "valeur": "11", + "description": "

La Force

" + }, + { + "name": "Le Pendu", + "type": "atout", + "symbole": "coupe", + "valeur": "12", + "description": "

Le Pendu

" + }, + { + "name": "L'Arcane sans Nom", + "type": "atout", + "symbole": "coupe", + "valeur": "13", + "description": "

L'Arcane sans Nom

" + }, + { + "name": "La Tempérance", + "type": "atout", + "symbole": "coupe", + "valeur": "14", + "description": "

La Tempérance

" + }, + { + "name": "Le Diable", + "type": "atout", + "symbole": "coupe", + "valeur": "15", + "description": "

Le Diable

" + }, + { + "name": "La Maison Dieu", + "type": "atout", + "symbole": "coupe", + "valeur": "16", + "description": "

La Maison Dieu

" + }, + { + "name": "L'Étoile", + "type": "atout", + "symbole": "coupe", + "valeur": "17", + "description": "

L'Étoile

" + }, + { + "name": "La Lune", + "type": "atout", + "symbole": "coupe", + "valeur": "18", + "description": "

La Lune

" + }, + { + "name": "Le Soleil", + "type": "atout", + "symbole": "coupe", + "valeur": "19", + "description": "

Le Soleil

" + }, + { + "name": "Le Jugement", + "type": "atout", + "symbole": "coupe", + "valeur": "20", + "description": "

Le Jugement

" + }, + { + "name": "Le Monde", + "type": "atout", + "symbole": "coupe", + "valeur": "21", + "description": "

Le Monde

" + }, + { + "name": "Le Mat", + "type": "atout", + "symbole": "coupe", + "valeur": "lemat", + "description": "

Le Mat

" + }, + { + "name": "As de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "1", + "description": "

As de Bâton

" + }, + { + "name": "2 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "2", + "description": "

2 de Bâton

" + }, + { + "name": "3 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "3", + "description": "

3 de Bâton

" + }, + { + "name": "4 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "4", + "description": "

4 de Bâton

" + }, + { + "name": "5 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "5", + "description": "

5 de Bâton

" + }, + { + "name": "6 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "6", + "description": "

6 de Bâton

" + }, + { + "name": "7 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "7", + "description": "

7 de Bâton

" + }, + { + "name": "8 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "8", + "description": "

8 de Bâton

" + }, + { + "name": "9 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "9", + "description": "

9 de Bâton

" + }, + { + "name": "10 de Bâton", + "type": "numéro", + "symbole": "baton", + "valeur": "10", + "description": "

10 de Bâton

" + }, + { + "name": "As de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "1", + "description": "

As de Coupe

" + }, + { + "name": "2 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "2", + "description": "

2 de Coupe

" + }, + { + "name": "3 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "3", + "description": "

3 de Coupe

" + }, + { + "name": "4 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "4", + "description": "

4 de Coupe

" + }, + { + "name": "5 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "5", + "description": "

5 de Coupe

" + }, + { + "name": "6 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "6", + "description": "

6 de Coupe

" + }, + { + "name": "7 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "7", + "description": "

7 de Coupe

" + }, + { + "name": "8 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "8", + "description": "

8 de Coupe

" + }, + { + "name": "9 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "9", + "description": "

9 de Coupe

" + }, + { + "name": "10 de Coupe", + "type": "numéro", + "symbole": "coupe", + "valeur": "10", + "description": "

10 de Coupe

" + }, + { + "name": "As de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "1", + "description": "

As de Denier

" + }, + { + "name": "2 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "2", + "description": "

2 de Denier

" + }, + { + "name": "3 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "3", + "description": "

3 de Denier

" + }, + { + "name": "4 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "4", + "description": "

4 de Denier

" + }, + { + "name": "5 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "5", + "description": "

5 de Denier

" + }, + { + "name": "6 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "6", + "description": "

6 de Denier

" + }, + { + "name": "7 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "7", + "description": "

7 de Denier

" + }, + { + "name": "8 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "8", + "description": "

8 de Denier

" + }, + { + "name": "9 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "9", + "description": "

9 de Denier

" + }, + { + "name": "10 de Denier", + "type": "numéro", + "symbole": "denier", + "valeur": "10", + "description": "

10 de Denier

" + }, + { + "name": "As d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "1", + "description": "

As d'Épée

" + }, + { + "name": "2 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "2", + "description": "

2 d'Épée

" + }, + { + "name": "3 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "3", + "description": "

3 d'Épée

" + }, + { + "name": "4 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "4", + "description": "

4 d'Épée

" + }, + { + "name": "5 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "5", + "description": "

5 d'Épée

" + }, + { + "name": "6 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "6", + "description": "

6 d'Épée

" + }, + { + "name": "7 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "7", + "description": "

7 d'Épée

" + }, + { + "name": "8 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "8", + "description": "

8 d'Épée

" + }, + { + "name": "9 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "9", + "description": "

9 d'Épée

" + }, + { + "name": "10 d'Épée", + "type": "numéro", + "symbole": "epee", + "valeur": "10", + "description": "

10 d'Épée

" + }, + { + "name": "Valet de Bâton", + "type": "figure", + "symbole": "baton", + "valeur": "valet", + "description": "

Valet de Bâton

" + }, + { + "name": "Cavalier de Bâton", + "type": "figure", + "symbole": "baton", + "valeur": "cavalier", + "description": "

Cavalier de Bâton

" + }, + { + "name": "Reine de Bâton", + "type": "figure", + "symbole": "baton", + "valeur": "reine", + "description": "

Reine de Bâton

" + }, + { + "name": "Roi de Bâton", + "type": "figure", + "symbole": "baton", + "valeur": "roi", + "description": "

Roi de Bâton

" + }, + { + "name": "Valet de Coupe", + "type": "figure", + "symbole": "coupe", + "valeur": "valet", + "description": "

Valet de Coupe

" + }, + { + "name": "Cavalier de Coupe", + "type": "figure", + "symbole": "coupe", + "valeur": "cavalier", + "description": "

Cavalier de Coupe

" + }, + { + "name": "Reine de Coupe", + "type": "figure", + "symbole": "coupe", + "valeur": "reine", + "description": "

Reine de Coupe

" + }, + { + "name": "Roi de Coupe", + "type": "figure", + "symbole": "coupe", + "valeur": "roi", + "description": "

Roi de Coupe

" + }, + { + "name": "Valet de Denier", + "type": "figure", + "symbole": "denier", + "valeur": "valet", + "description": "

Valet de Denier

" + }, + { + "name": "Cavalier de Denier", + "type": "figure", + "symbole": "denier", + "valeur": "cavalier", + "description": "

Cavalier de Denier

" + }, + { + "name": "Reine de Denier", + "type": "figure", + "symbole": "denier", + "valeur": "reine", + "description": "

Reine de Denier

" + }, + { + "name": "Roi de Denier", + "type": "figure", + "symbole": "denier", + "valeur": "roi", + "description": "

Roi de Denier

" + }, + { + "name": "Valet d'Épée", + "type": "figure", + "symbole": "epee", + "valeur": "valet", + "description": "

Valet d'Épée

" + }, + { + "name": "Cavalier d'Épée", + "type": "figure", + "symbole": "epee", + "valeur": "cavalier", + "description": "

Cavalier d'Épée

" + }, + { + "name": "Reine d'Épée", + "type": "figure", + "symbole": "epee", + "valeur": "reine", + "description": "

Reine d'Épée

" + }, + { + "name": "Roi d'Épée", + "type": "figure", + "symbole": "epee", + "valeur": "roi", + "description": "

Roi d'Épée

" + } +] diff --git a/module/applications/tarot-deck-manager.mjs b/module/applications/tarot-deck-manager.mjs index a1b5588..920145d 100644 --- a/module/applications/tarot-deck-manager.mjs +++ b/module/applications/tarot-deck-manager.mjs @@ -5,7 +5,7 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin super(options) this.deck = [] this.discard = [] - this.loadDeckState() + this.loadDeckState().catch(e => console.warn("Deck init error:", e)) } /** @override */ @@ -58,46 +58,81 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin /** * Load the deck state from settings */ - loadDeckState() { + async loadDeckState() { const state = game.settings.get("fvtt-hamalron", "tarotDeckState") if (state && state.deck && state.deck.length > 0) { this.deck = state.deck this.discard = state.discard || [] - console.log("Deck state loaded:", state) } else { - // Si aucun état sauvegardé, initialiser un nouveau deck - this.resetDeck() + await this.resetDeck() } } /** * Reset the deck to a full tarot deck */ - resetDeck() { + async resetDeck() { this.deck = [] this.discard = [] - // Créer toutes les cartes du jeu de tarot - const items = game.items.filter(i => i.type === "tarot") + let items = game.items.filter(i => i.type === "tarot") - if (items.length > 0) { - // Utiliser les items existants - this.deck = items.map(item => ({ - id: item.id, - name: item.name, - img: item.img, - symbole: item.system.symbole, - valeur: item.system.valeur, - type: item.system.type, - description: item.system.description, - })) - } else { - ui.notifications.warn("HAMALRON.TarotDeck.NoCardsFound", { localize: true }) + // Si aucune carte dans le monde, importer depuis le compendium système + if (items.length === 0) { + const pack = game.packs.get("fvtt-hamalron.hamalron-items") + if (pack) { + const docs = await pack.getDocuments() + const tarotDocs = docs.filter(d => d.type === "tarot") + if (tarotDocs.length > 0) { + for (const doc of tarotDocs) { + const imported = await Item.create(doc.toObject(), { temporary: false }) + if (imported) items.push(imported) + } + } + } } + // Dernier recours : créer les cartes depuis les données JSON + if (items.length === 0) { + try { + const resp = await fetch("systems/fvtt-hamalron/assets/data/tarot.json") + const data = await resp.json() + if (Array.isArray(data) && data.length > 0) { + for (const card of data) { + const created = await Item.create({ + name: card.name, + type: "tarot", + img: "icons/svg/treasure.svg", + system: { + type: card.type, + symbole: card.symbole, + valeur: card.valeur, + description: card.description || `

${card.name}

`, + image: "icons/svg/treasure.svg", + }, + }) + if (created) items.push(created) + } + } + } catch (e) { + console.warn("Hamalron | Failed to load tarot.json:", e) + } + } + + // Construire le deck + this.deck = items.map(item => ({ + id: item.id, + name: item.name, + img: item.img, + symbole: item.system.symbole, + valeur: item.system.valeur, + type: item.system.type, + description: item.system.description, + })) + // Mélanger le deck this.shuffleDeck() - this.saveDeckState() + await this.saveDeckState() this.render() } @@ -186,7 +221,7 @@ export default class HamalronTarotDeckManager extends HandlebarsApplicationMixin }) if (confirmed) { - this.resetDeck() + await this.resetDeck() ui.notifications.info("HAMALRON.TarotDeck.DeckReset", { localize: true }) } }