import { HeritiersUtility } from "../heritiers-utility.js" /** * Dialogue de jet de dé pour Les Héritiers - Version AppV2 */ export class HeritiersRollDialog { /** * Create and display the roll dialog * @param {HeritiersActor} actor - The actor making the roll * @param {Object} rollData - Data for the roll * @returns {Promise} - Returns a dialog-like object for compatibility */ static async create(actor, rollData) { // Préparer le contexte pour le template const context = { ...rollData, img: actor.img, name: actor.name, config: game.system.lesheritiers.config, } // Rendre le template en HTML const content = await foundry.applications.handlebars.renderTemplate( "systems/fvtt-les-heritiers/templates/roll-dialog-generic.hbs", context ) // Préparer les boutons selon le mode et le niveau const buttons = this._prepareButtons(rollData) // Lancer le dialog de manière asynchrone (sans attendre) setTimeout(() => { foundry.applications.api.DialogV2.wait({ window: { title: "Test de Capacité", icon: "fa-solid fa-dice" }, classes: ["heritiers-roll-dialog"], position: { width: 420, height: 'fit-content' }, modal: false, content, buttons, rejectClose: false, render: (event, html) => { this._activateListeners(html, rollData) } }) }, 0) // Retourner un objet avec une méthode render() vide pour compatibilité return { render: () => {} // No-op for compatibility with old code } } /** * Préparer les boutons selon le mode et le niveau de compétence * @param {Object} rollData - Data for the roll * @returns {Array} - Array of button configurations * @private */ static _prepareButtons(rollData) { const buttons = [] // Bouton d8 toujours disponible buttons.push({ action: "rolld8", label: "Lancer 1d8", icon: "fa-solid fa-dice-d8", default: true, callback: (event, button, dialog) => { this._updateRollDataFromForm(rollData, button.form.elements) this._executeRoll(rollData, "d8") } }) // Bouton d10 si niveau > 0 ou pouvoir const enableD10 = rollData.mode === "pouvoir" || rollData.competence?.system.niveau > 0 if (enableD10) { buttons.push({ action: "rolld10", label: "Lancer 1d10", icon: "fa-solid fa-dice-d10", callback: (event, button, dialog) => { this._updateRollDataFromForm(rollData, button.form.elements) this._executeRoll(rollData, "d10") } }) } // Bouton d12 si niveau > 1 ou pouvoir const enableD12 = rollData.mode === "pouvoir" || rollData.competence?.system.niveau > 1 if (enableD12) { buttons.push({ action: "rolld12", label: "Lancer 1d12", icon: "fa-solid fa-dice-d12", callback: (event, button, dialog) => { this._updateRollDataFromForm(rollData, button.form.elements) this._executeRoll(rollData, "d12") } }) } // Bouton Tricherie si disponible if (rollData.tricherie) { buttons.push({ action: "rollTricherie", label: "Lancer avec 1 Point de Tricherie", icon: "fa-solid fa-mask", callback: (event, button, dialog) => { this._updateRollDataFromForm(rollData, button.form.elements) this._executeRoll(rollData, "tricherie") } }) } // Bouton Héritage si disponible if (rollData.heritage) { buttons.push({ action: "rollHeritage", label: "Lancer avec 1 Point d'Héritage", icon: "fa-solid fa-crown", callback: (event, button, dialog) => { this._updateRollDataFromForm(rollData, button.form.elements) this._executeRoll(rollData, "heritage") } }) } // Si mode carac uniquement, on ne garde que d8 if (rollData.mode === "carac") { return [ { action: "rolld8", label: "Lancer 1d8", icon: "fa-solid fa-dice-d8", default: true, callback: (event, button, dialog) => { this._updateRollDataFromForm(rollData, button.form.elements) this._executeRoll(rollData, "d8") } } ] } return buttons } /** * Activer les listeners sur le formulaire * @param {HTMLElement} html - L'élément HTML du dialog * @param {Object} rollData - Data for the roll * @private */ static _activateListeners(html, rollData) { // Seuil de Difficulté const sdValue = html.querySelector('#sdValue') if (sdValue) { sdValue.addEventListener('change', (event) => { rollData.sdValue = Number(event.currentTarget.value) }) } // Caractéristique const caracKey = html.querySelector('#caracKey') if (caracKey) { caracKey.addEventListener('change', (event) => { rollData.caracKey = String(event.currentTarget.value) }) } // Bonus/Malus contextuel const bonusMalusContext = html.querySelector('#bonus-malus-context') if (bonusMalusContext) { bonusMalusContext.addEventListener('change', (event) => { rollData.bonusMalusContext = Number(event.currentTarget.value) }) } // Attaque à plusieurs const bonusAttaquePlusieurs = html.querySelector('#bonus-attaque-plusieurs') if (bonusAttaquePlusieurs) { bonusAttaquePlusieurs.addEventListener('change', (event) => { rollData.bonusAttaquePlusieurs = Number(event.currentTarget.value) }) } // Spécialité const useSpecialite = html.querySelector('#useSpecialite') if (useSpecialite) { useSpecialite.addEventListener('change', (event) => { rollData.useSpecialite = event.currentTarget.checked }) } // Points d'usage du pouvoir const pouvoirPointsUsage = html.querySelector('#pouvoirPointsUsage') if (pouvoirPointsUsage) { pouvoirPointsUsage.addEventListener('change', (event) => { rollData.pouvoirPointsUsage = Number(event.currentTarget.value) }) } // Attaque dans le dos const attaqueDos = html.querySelector('#attaqueDos') if (attaqueDos) { attaqueDos.addEventListener('change', (event) => { rollData.attaqueDos = event.currentTarget.checked }) } // Seconde arme const secondeArme = html.querySelector('#bonus-attaque-seconde-arme') if (secondeArme) { secondeArme.addEventListener('change', (event) => { rollData.secondeArme = String(event.currentTarget.value) }) } // Attaque ciblée const attaqueCible = html.querySelector('#attaque-cible') if (attaqueCible) { attaqueCible.addEventListener('change', (event) => { rollData.attaqueCible = String(event.currentTarget.value) }) } // Attaque à deux armes const attaqueDeuxArmes = html.querySelector('#bonus-attaque-deux-armes') if (attaqueDeuxArmes) { attaqueDeuxArmes.addEventListener('change', (event) => { rollData.attaqueDeuxArmes = Number(event.currentTarget.value) }) } } /** * Mettre à jour rollData avec les valeurs du formulaire * @param {Object} rollData - L'objet rollData à mettre à jour * @param {HTMLFormControlsCollection} formElements - Les éléments du formulaire * @private */ static _updateRollDataFromForm(rollData, formElements) { // Seuil de Difficulté if (formElements.sdValue) { rollData.sdValue = Number(formElements.sdValue.value) } // Caractéristique if (formElements.caracKey) { rollData.caracKey = String(formElements.caracKey.value) } // Bonus/Malus contextuel if (formElements['bonus-malus-context']) { rollData.bonusMalusContext = Number(formElements['bonus-malus-context'].value) } // Attaque à plusieurs if (formElements['bonus-attaque-plusieurs']) { rollData.bonusAttaquePlusieurs = Number(formElements['bonus-attaque-plusieurs'].value) } // Spécialité if (formElements.useSpecialite !== undefined) { rollData.useSpecialite = formElements.useSpecialite.checked } // Points d'usage du pouvoir if (formElements.pouvoirPointsUsage) { rollData.pouvoirPointsUsage = Number(formElements.pouvoirPointsUsage.value) } // Attaque dans le dos if (formElements.attaqueDos !== undefined) { rollData.attaqueDos = formElements.attaqueDos.checked } // Seconde arme if (formElements['bonus-attaque-seconde-arme']) { rollData.secondeArme = String(formElements['bonus-attaque-seconde-arme'].value) } // Attaque ciblée if (formElements['attaque-cible']) { rollData.attaqueCible = String(formElements['attaque-cible'].value) } // Attaque à deux armes if (formElements['bonus-attaque-deux-armes']) { rollData.attaqueDeuxArmes = Number(formElements['bonus-attaque-deux-armes'].value) } } /** * Exécuter le jet de dés * @param {Object} rollData - Data for the roll * @param {String} dice - Type de dé (d8, d10, d12, tricherie, heritage) * @private */ static _executeRoll(rollData, dice) { if (dice === "heritage") { rollData.useHeritage = true } else if (dice === "tricherie") { rollData.useTricherie = true } else { rollData.mainDice = dice } HeritiersUtility.rollHeritiers(rollData) } }