fix: bouton Épreuve basé sur les cartes de tarot (pas de dés)
Remplace le jet de dés par un vrai dialogue d'épreuve Hamalron : - Sélection d'une carte dans la main du personnage - Choix de la difficulté (table standard) - Calcul réussi/échec basé sur la valeur de la carte - La carte est défaussée et remplacée depuis le deck
This commit is contained in:
+5
-3
@@ -237,9 +237,11 @@ function addChatTools() {
|
|||||||
game.system.api.openActionComplexe()
|
game.system.api.openActionComplexe()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
addBtn("fas fa-dice", "Épreuve", "Lancer une épreuve standard", () => {
|
addBtn("fas fa-cards", "Épreuve", "Lancer une épreuve (choisir une carte)", async () => {
|
||||||
const actor = game.user?.character || game.actors?.find(a => a.type === "personnage")
|
const actor = game.user?.character || game.actors?.find(a => a.type === "personnage" && a.testUserPermission(game.user, "OWNER"))
|
||||||
if (actor) actor.system?.roll?.("stat", { name: "Épreuve", value: 0 })
|
if (!actor) { ui.notifications.warn("Aucun personnage trouvé"); return }
|
||||||
|
const { default: HamalronTirageTarot } = await import("./module/documents/tirage-tarot.mjs")
|
||||||
|
await HamalronTirageTarot.promptEpreuve(actor)
|
||||||
})
|
})
|
||||||
|
|
||||||
controls.parentNode.insertBefore(tools, controls)
|
controls.parentNode.insertBefore(tools, controls)
|
||||||
|
|||||||
@@ -90,6 +90,138 @@ export default class HamalronTirageTarot extends Roll {
|
|||||||
ui.notifications.info(`Le Mat ! Toutes vos cartes ont été défaussées et vous recevez 7 nouvelles cartes. Le deck a été mélangé.`)
|
ui.notifications.info(`Le Mat ! Toutes vos cartes ont été défaussées et vous recevez 7 nouvelles cartes. Le deck a été mélangé.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Carte de symbole par défaut pour les épreuves sans compétence
|
||||||
|
static async promptEpreuve(actor) {
|
||||||
|
const tarotCards = actor.items.filter(i => i.type === "tarot")
|
||||||
|
if (tarotCards.length === 0) {
|
||||||
|
ui.notifications.warn(game.i18n.localize("HAMALRON.Notifications.noTarotCards"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const cardData = tarotCards.map(c => ({
|
||||||
|
id: c.id,
|
||||||
|
name: c.name,
|
||||||
|
img: c.img,
|
||||||
|
valeur: c.system.valeur,
|
||||||
|
symbole: c.system.symbole,
|
||||||
|
type: c.system.type,
|
||||||
|
valeurNumerique: HamalronTirageTarot.#vNumerique(c.system.valeur),
|
||||||
|
}))
|
||||||
|
|
||||||
|
const content = `
|
||||||
|
<div class="fvtt-hamalron-roll-dialog">
|
||||||
|
<fieldset>
|
||||||
|
<legend>${game.i18n.localize("HAMALRON.Label.selectTarotCard")}</legend>
|
||||||
|
<div class="tarot-hand">
|
||||||
|
${cardData.map(c => `
|
||||||
|
<div class="tarot-card-select" data-card-id="${c.id}" data-card-value="${c.valeurNumerique}">
|
||||||
|
<img src="${c.img}" alt="${c.name}" />
|
||||||
|
<span class="card-name">${c.name}</span>
|
||||||
|
<span class="card-value-display">${c.valeurNumerique}</span>
|
||||||
|
</div>
|
||||||
|
`).join("")}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset>
|
||||||
|
<legend>${game.i18n.localize("HAMALRON.Label.difficulty")}</legend>
|
||||||
|
<div class="difficulty-row">
|
||||||
|
<select class="difficulty-select-epreuve">
|
||||||
|
${Object.entries(SYSTEM.DIFFICULTY_CHOICES).filter(([k]) => k !== "soustension_oppose").map(([k, v]) =>
|
||||||
|
`<option value="${v.standard}">${v.label} (${v.standard})</option>`
|
||||||
|
).join("")}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="dialog-result">
|
||||||
|
<legend>${game.i18n.localize("HAMALRON.Label.total")}</legend>
|
||||||
|
<div class="total-display">
|
||||||
|
<span id="card-value-display">+ 0</span>
|
||||||
|
<span>=</span>
|
||||||
|
<span id="total-value">0</span>
|
||||||
|
</div>
|
||||||
|
<div class="difficulty-info">
|
||||||
|
<span>${game.i18n.localize("HAMALRON.Label.targetScore")}: <span id="target-score">3</span></span>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
</div>`
|
||||||
|
|
||||||
|
const result = await foundry.applications.api.DialogV2.wait({
|
||||||
|
window: { title: game.i18n.localize("HAMALRON.Label.titleStandard") },
|
||||||
|
classes: ["fvtt-hamalron"],
|
||||||
|
position: { width: 420 },
|
||||||
|
content,
|
||||||
|
buttons: [{ action: "roll", label: game.i18n.localize("HAMALRON.Roll.roll"), default: true, callback: (e, btn) => {
|
||||||
|
const selected = btn.form.querySelector('.tarot-card-select.selected')
|
||||||
|
if (!selected) return null
|
||||||
|
return {
|
||||||
|
cardId: selected.dataset.cardId,
|
||||||
|
cardValue: Number(selected.dataset.cardValue) || 0,
|
||||||
|
difficulty: Number(btn.form.querySelector('.difficulty-select-epreuve')?.value || 3),
|
||||||
|
}
|
||||||
|
}}, { action: "cancel", label: game.i18n.localize("HAMALRON.Roll.cancel") }],
|
||||||
|
rejectClose: false,
|
||||||
|
render: () => {
|
||||||
|
$(document).off(".epreuve")
|
||||||
|
$(document).on("click.epreuve", ".tarot-card-select", function () {
|
||||||
|
$(".tarot-card-select").removeClass("selected")
|
||||||
|
$(this).addClass("selected")
|
||||||
|
const val = Number($(this).data("cardValue")) || 0
|
||||||
|
$("#card-value-display").text(`+ ${val}`)
|
||||||
|
$("#total-value").text(String(val))
|
||||||
|
})
|
||||||
|
$(document).on("change.epreuve", ".difficulty-select-epreuve", function () {
|
||||||
|
$("#target-score").text($(this).val())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!result) return
|
||||||
|
|
||||||
|
const cardItem = actor.items.get(result.cardId)
|
||||||
|
const isSuccess = result.cardValue >= result.difficulty
|
||||||
|
|
||||||
|
// Card used: move to discard
|
||||||
|
const deckModule = await import("../applications/tarot-deck-manager.mjs")
|
||||||
|
const DM = deckModule.default
|
||||||
|
if (DM._instance) {
|
||||||
|
DM._instance.addToDiscard({
|
||||||
|
id: cardItem.id, name: cardItem.name, img: cardItem.img,
|
||||||
|
symbole: cardItem.system.symbole, valeur: cardItem.system.valeur,
|
||||||
|
type: cardItem.system.type,
|
||||||
|
})
|
||||||
|
await DM._instance.saveDeckState()
|
||||||
|
}
|
||||||
|
if (cardItem) await actor.deleteEmbeddedDocuments("Item", [cardItem.id])
|
||||||
|
|
||||||
|
// Draw replacement
|
||||||
|
if (DM._instance?.deck?.length > 0) {
|
||||||
|
const drawn = DM._instance.drawCards(1)
|
||||||
|
if (drawn.length > 0) {
|
||||||
|
const orig = await HamalronUtils.findTarotItem(drawn[0])
|
||||||
|
if (orig) await actor.createEmbeddedDocuments("Item", [orig.toObject()])
|
||||||
|
}
|
||||||
|
await DM._instance.saveDeckState()
|
||||||
|
}
|
||||||
|
|
||||||
|
ChatMessage.create({
|
||||||
|
user: game.user.id,
|
||||||
|
speaker: ChatMessage.getSpeaker({ actor }),
|
||||||
|
content: `<div class="fvtt-hamalron epreuve-result">
|
||||||
|
<h3>${game.i18n.localize("HAMALRON.Label.titleStandard")}</h3>
|
||||||
|
<p><strong>${cardItem?.name}</strong>: ${result.cardValue}</p>
|
||||||
|
<p>${game.i18n.localize("HAMALRON.Label.difficulty")}: ${result.difficulty}</p>
|
||||||
|
<p class="${isSuccess ? "result-success" : "result-failure"}">
|
||||||
|
${isSuccess ? game.i18n.localize("HAMALRON.Label.success") : game.i18n.localize("HAMALRON.Label.failure")}
|
||||||
|
</p>
|
||||||
|
</div>`,
|
||||||
|
style: CONST.CHAT_MESSAGE_STYLES.OTHER,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static #vNumerique(valeur) {
|
||||||
|
return SYSTEM.TAROT_VALEURS[valeur]?.value ?? (Number.parseInt(valeur) || 0)
|
||||||
|
}
|
||||||
|
|
||||||
static async prompt(options = {}) {
|
static async prompt(options = {}) {
|
||||||
let formula = `3D6 + 0D6KH - 0D6KH + ${options?.rollItem?.value}`
|
let formula = `3D6 + 0D6KH - 0D6KH + ${options?.rollItem?.value}`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user