import { Misc } from "../misc.js"; import { PART_APPELMORAL } from "./roll-part-appelmoral.mjs"; import { PART_COMP } from "./roll-part-comp.mjs"; import { RdDResolutionTable } from "../rdd-resolution-table.js"; import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"; import { PART_OEUVRE } from "./roll-part-oeuvre.mjs"; import { RdDItemArme } from "../item/arme.js"; import { RdDBonus } from "../rdd-bonus.js"; import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"; import { CARACS } from "../rdd-carac.js"; import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"; import { PART_ATTAQUE } from "./roll-part-attaque.mjs"; /* -------------------------------------------- */ export class RollDialogAdapter { static async rollDice(rollData, rollTitle) { const chances = RollDialogAdapter.computeChances({ carac: rollData.current.carac.value, diff: rollData.current.totaldiff, bonus: rollData.current.bonus, showDice: rollData.options.showDice, rollMode: rollData.current.rollmode.key }) const rolled = await RollDialogAdapter.rollChances(rollData, chances) RollDialogAdapter.setRollDataRolled(rollData, rolled, rollTitle) RollDialogAdapter.adjustRollDataForV1(rollData) RollDialogAdapter.adjustAttaqueParticuliere(rollData) return rolled } static computeChances({ carac, diff, bonus, showDice, rollMode }) { const chances = foundry.utils.duplicate(RdDResolutionTable.computeChances(carac, diff)) RdDResolutionTable._updateChancesWithBonus(chances, bonus, diff) chances.showDice = showDice chances.rollMode = rollMode return chances } static async rollChances(rollData, chances) { const rolled = await RdDResolutionTable.rollChances(chances, rollData.current.sign.diviseur, rollData.current.resultat) rolled.caracValue = rollData.current.carac.value rolled.finalLevel = rollData.current.totaldiff rolled.bonus = rollData.current.bonus ?? 0 rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur) return rolled } static setRollDataRolled(rollData, rolled, rollTitle) { rollData.rolled = rolled rollData.choix = rollData.choix ?? {} rollData.show = rollData.show ?? {} rollData.show.title = rollTitle } static adjustRollDataForV1(rollData) { const rolled = rollData.rolled // temporaire pour être homogène roll v1 rollData.alias = rollData.active.actor.getAlias() // pour experience rollData.finalLevel = rollData.current.totaldiff if (rollData.use == undefined) { rollData.use = {} } if (rollData.ajustements == undefined) { rollData.ajustements = {} } rollData.selectedCarac = rollData.active.actor.getCaracByName(rollData.current.carac.key) const compKey = rollData.current.comp?.key if (compKey) { rollData.competence = rollData.refs[PART_COMP].all.find(it => it.key == compKey)?.comp rollData.jetResistance = rollData.type.jetResistance } const oeuvreKey = rollData.current.oeuvre?.key if (oeuvreKey) { const oeuvreCurrent = rollData.current[PART_OEUVRE]; rollData.oeuvre = oeuvreCurrent.oeuvre // rollData.oeuvre = rollData.refs[PART_OEUVRE].oeuvres.find(it => it.key == oeuvreKey)?.oeuvre rollData.art = oeuvreCurrent.art.type } // pour appel moral rollData.diviseurSignificative = rollData.current.sign if (rollData.current[PART_APPELMORAL]?.checked) { rollData.use.moral = true } if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) { rolled.niveauNecessaire = this.findNiveauNecessaire(carac, rolled.roll) rolled.ajustementNecessaire = rolled.niveauNecessaire - diff } rollData.ajustements = rollData.ajustements.map(aj => { return { used: true, label: aj.label, value: aj.diff, descr: aj.diff == undefined ? aj.label : undefined } }) } static adjustAttaqueParticuliere(rollData) { if (rollData.type.current != ROLL_TYPE_ATTAQUE || !rollData.rolled.isPart) { return } const attaque = rollData.current.attaque; const choix = [] const isEmpoignade = attaque.dmg.mortalite == 'empoignade'; const isCharge = attaque.tactique == 'charge' /* TODO: cas de créatures faisant des lancers, Glou, Glipzouk */ const isMeleeDiffNegative = (attaque.comp.type == ITEM_TYPES.competencecreature || rollData.current.carac.key == CARACS.MELEE) && rollData.current.diff.value < 0 // force toujours, sauf empoignade if (!isEmpoignade) { choix.push(RDD_CONFIG.particuliere.force) } // finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum if (!isCharge && (isEmpoignade || isMeleeDiffNegative)) { choix.push(RDD_CONFIG.particuliere.finesse) } // rapidité seulement en mêlée, si l'arme le permet, et si la difficulté libre est de -1 minimum if (!isCharge && !isEmpoignade && isMeleeDiffNegative && attaque.arme.system.rapide) { choix.push(RDD_CONFIG.particuliere.rapidite) } if (choix.length == 1) { rollData.particuliere = choix[0].key } rollData.particulieres = choix } static mapActionAttaque(attackerRoll) { if (attackerRoll.ids) { return attackerRoll.current[PART_ATTAQUE] } const label = attackerRoll.alias + ' ' + attackerRoll.arme.name; return { // correspond à l'attaque de RollPartAttaque (dans rollDta.current.attaque) label: label, // correspond aux actions d'attaques dans RdDActor.listActionsAttaque name: label, // action: 'attaque', arme: attackerRoll.arme, comp: attackerRoll.competence, main: RdDItemArme.getMainAttaque(attackerRoll.competence), equipe: attackerRoll.arme.system.equipe, // carac: { key: caracCode, value: caracValue }, // dommagesArme: dommagesArme, diff: attackerRoll.diffLibre, particuliere: attackerRoll.particuliere, tactique: RdDBonus.find(attackerRoll.tactique), dmg: attackerRoll.dmg, } } }