Potions et élémentaires
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user