127 lines
4.9 KiB
JavaScript
127 lines
4.9 KiB
JavaScript
import { MournbladeUtility } from "../mournblade-utility.js"
|
|
|
|
export default class MournbladeInvocationDialog {
|
|
|
|
static async create(actor, rollData) {
|
|
const ameDisponible = Math.max(0, (actor.system.ame.currentmax - actor.system.ame.value))
|
|
const maxExtra = Math.max(0, ameDisponible - 15)
|
|
|
|
// Detect elemental pacte bonus — the bonus is always available,
|
|
// but we display it dynamically based on chosen element.
|
|
// We pass the pactes to let JS listeners detect the match.
|
|
const pactes = actor.getPactes().map(p => ({
|
|
name: p.name,
|
|
allegeance: (p.system.allegeance || "").toLowerCase()
|
|
}))
|
|
|
|
const hautParlerComp = actor.items.find(c => c.type == "competence" && c.name.toLowerCase() == "savoir : haut-parler")
|
|
const seigneursElemComp = actor.items.find(c => c.type == "competence" && c.name.toLowerCase() == "savoir : seigneurs élémentaires")
|
|
|
|
const context = {
|
|
...rollData,
|
|
img: actor.img,
|
|
name: actor.name,
|
|
ameDisponible,
|
|
ameExtraOptions: Array.from({ length: maxExtra + 1 }, (_, i) => i),
|
|
modOptions: Array.from({ length: 21 }, (_, i) => i - 10),
|
|
hautParlerNiveau: hautParlerComp ? hautParlerComp.system.niveau : null,
|
|
seigneursElemNiveau: seigneursElemComp ? seigneursElemComp.system.niveau : null,
|
|
bonusPacte: false,
|
|
pactes,
|
|
}
|
|
|
|
const content = await foundry.applications.handlebars.renderTemplate(
|
|
"systems/fvtt-mournblade/templates/dialog-invocation-elementaire.hbs",
|
|
context
|
|
)
|
|
|
|
Hooks.once("renderDialogV2", (_app, html) => {
|
|
const form = html.querySelector ? html : html[0]
|
|
MournbladeInvocationDialog._attachListeners(form, pactes)
|
|
})
|
|
|
|
return foundry.applications.api.DialogV2.wait({
|
|
window: { title: "Invoquer un Élémentaire", icon: "fa-solid fa-wind" },
|
|
classes: ["mournblade-roll-dialog"],
|
|
position: { width: 480 },
|
|
modal: false,
|
|
content,
|
|
buttons: [
|
|
{
|
|
action: "invoquer",
|
|
label: "Invoquer",
|
|
icon: "fa-solid fa-wind",
|
|
default: true,
|
|
callback: (event, button, dialog) => {
|
|
MournbladeInvocationDialog._updateRollData(rollData, button.form.elements, actor, pactes)
|
|
MournbladeUtility.rollInvocationElementaire(rollData)
|
|
}
|
|
},
|
|
],
|
|
rejectClose: false,
|
|
})
|
|
}
|
|
|
|
static _elementKeywords = {
|
|
air: ["air", "vent", "sylphe", "seigneur de l'air"],
|
|
terre: ["terre", "gnome", "seigneur de la terre"],
|
|
feu: ["feu", "flamme", "salamandre", "seigneur du feu"],
|
|
eau: ["eau", "ondine", "seigneur de l'eau"],
|
|
}
|
|
|
|
static _hasPacteBonus(element, pactes) {
|
|
const keywords = MournbladeInvocationDialog._elementKeywords[element] || []
|
|
return pactes.some(p => keywords.some(kw => p.allegeance.includes(kw)))
|
|
}
|
|
|
|
static _attachListeners(html, pactes) {
|
|
const tierSeuils = { mineur: 15, median: 20, majeur: 25 }
|
|
const tierTemps = { mineur: "1 tour", median: "1 minute", majeur: "1 heure" }
|
|
|
|
const recalculate = () => {
|
|
const element = html.querySelector('[name="element"]')?.value ?? "air"
|
|
const tier = html.querySelector('[name="tier"]')?.value ?? "mineur"
|
|
const ameExtra = parseInt(html.querySelector('[name="ameExtra"]')?.value ?? 0)
|
|
|
|
const seuilBase = tierSeuils[tier] ?? 15
|
|
const seuil = seuilBase + ameExtra
|
|
const hasPacte = MournbladeInvocationDialog._hasPacteBonus(element, pactes)
|
|
|
|
const seuilEl = html.querySelector('#invoc-seuil')
|
|
const coutEl = html.querySelector('#invoc-cout')
|
|
const tempsEl = html.querySelector('#invoc-temps')
|
|
const pacteBanner = html.querySelector('.invoc-bonus-pacte')
|
|
|
|
if (seuilEl) seuilEl.textContent = seuil + (hasPacte ? " (-5 avec bonus Pacte)" : "")
|
|
if (coutEl) coutEl.textContent = seuil
|
|
if (tempsEl) tempsEl.textContent = tierTemps[tier] ?? "1 tour"
|
|
if (pacteBanner) pacteBanner.style.display = hasPacte ? "" : "none"
|
|
}
|
|
|
|
html.querySelectorAll('[name="element"], [name="tier"], [name="ameExtra"]').forEach(el => {
|
|
el.addEventListener('change', recalculate)
|
|
})
|
|
recalculate()
|
|
}
|
|
|
|
static _updateRollData(rollData, formElements, actor, pactes) {
|
|
const element = formElements['element']?.value ?? "air"
|
|
const tier = formElements['tier']?.value ?? "mineur"
|
|
const ameExtra = parseInt(formElements['ameExtra']?.value ?? 0)
|
|
const modificateur = parseInt(formElements['modificateur']?.value ?? 0)
|
|
|
|
const tierSeuils = { mineur: 15, median: 20, majeur: 25 }
|
|
const seuilBase = tierSeuils[tier] ?? 15
|
|
const seuil = seuilBase + ameExtra
|
|
|
|
rollData.invocationElement = element
|
|
rollData.invocationTier = tier
|
|
rollData.invocationSeuil = seuil
|
|
rollData.invocationAmeExtra = ameExtra
|
|
rollData.invocationSoulCost = seuil
|
|
rollData.difficulte = seuil
|
|
rollData.modificateur = modificateur
|
|
rollData.bonusPacte = MournbladeInvocationDialog._hasPacteBonus(element, pactes) ? 5 : 0
|
|
}
|
|
}
|