import { RdDItemArme } from "./item/arme.js"; import { RdDPossession } from "./rdd-possession.js"; import { ReglesOptionnelles } from "./settings/regles-optionnelles.js"; const conditionsTactiques = [ { key: '', label: '', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false }, { key: 'normale', label: 'Attaque normale', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: true }, { key: 'charge', label: 'Charge', dmg: 2, attaque: 4, parade: -4, esquive: false, isTactique: true }, { key: 'feinte', label: 'Feinte', dmg: 1, attaque: 1, parade: 0, esquive: true, isTactique: true }, { key: 'pret', label: 'prêt', dmg: 0, attaque: 0, parade: 0, esquive: true, isTactique: false }, { key: 'demi', label: 'Demi-surprise', dmg: 1, attaque: 0, parade: 0, esquive: true, isTactique: false }, { key: 'totale', label: 'Surprise totale', dmg: 10, attaque: 6, parade: 0, esquive: true, isTactique: false }, ]; /* -------------------------------------------- */ export class RdDBonus { static get tactiques() { return conditionsTactiques.filter(it => it.isTactique) } /* -------------------------------------------- */ static find(condition) { return conditionsTactiques.find(e => e.key == condition) || conditionsTactiques[0]; } /* -------------------------------------------- */ static isDefenseAttaqueFinesse(rollData) { if (rollData.isEmpoignade && rollData.rolled?.isPart) { return true } if (RdDPossession.isDefensePossession(rollData)) { return RdDPossession.isPossessionFinesse(rollData) } return rollData.attackerRoll?.particuliere == 'finesse'; } /* -------------------------------------------- */ static dmg(rollData, actor, isEntiteIncarnee = false) { const diff = rollData.diffLibre; const dmgArme = RdDBonus.dmgArme(rollData.arme, rollData.arme?.system.dommagesReels) const forceRequise = rollData.arme ? RdDItemArme.valeurMain(rollData.arme.system.force ?? 0, RdDItemArme.getMainAttaque(rollData.competence)) : 0 let dmg = { total: 0, dmgArme: dmgArme, diff: diff, dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(diff ?? 0) : 0, penetration: RdDBonus._peneration(rollData), dmgTactique: RdDBonus.dmgBonus(rollData.tactique), dmgParticuliere: RdDBonus._dmgParticuliere(rollData), dmgSurprise: RdDBonus.dmgBonus(rollData.ajustements?.attaqueDefenseurSurpris.used), mortalite: RdDBonus._calculMortalite(rollData, isEntiteIncarnee), dmgActor: RdDBonus.bonusDmg(actor, rollData.selectedCarac?.label.toLowerCase(), dmgArme), dmgForceInsuffisante: Math.min(0, actor.getForce() - forceRequise) } dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante return dmg; } static dmgRollV2(rollData, attaque) { const actor = rollData.active.actor const arme = attaque.arme const dmgArme = RdDBonus.dmgArme(arme, attaque.dommagesArme) const dmg = { total: 0, dmgArme: dmgArme, penetration: arme?.penetration() ?? 0, diff: attaque.diff, dmgTactique: attaque.tactique?.dmg ?? 0, dmgParticuliere: RdDBonus._dmgParticuliere(rollData), dmgSurprise: rollData.opponent?.surprise?.dmg ?? 0, mortalite: RdDBonus.mortalite(attaque.dmg?.mortalite, arme?.system.mortalite, rollData.opponent?.actor?.isEntite()), dmgActor: RdDBonus.bonusDmg(actor, attaque.carac.key, dmgArme, attaque.forceRequise), dmgForceInsuffisante: Math.min(0, actor.getForce() - attaque.forceRequise), dmgDiffLibre: ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(attaque.diff ?? 0) : 0 } dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante + dmg.dmgDiffLibre return dmg } /* -------------------------------------------- */ static description(condition) { return RdDBonus.find(condition).label } /* -------------------------------------------- */ static dmgBonus(condition) { return RdDBonus.find(condition).dmg } /* -------------------------------------------- */ static bonusAttaque(condition) { return RdDBonus.find(condition).attaque } /* -------------------------------------------- */ static _calculMortalite(rollData, isEntiteIncarnee) { return RdDBonus.mortalite(rollData.dmg?.mortalite, rollData.arme?.system.mortalite, isEntiteIncarnee) } static mortalite(mortaliteSelect, mortaliteArme, isEntiteIncarnee) { return isEntiteIncarnee ? "entiteincarnee" : mortaliteSelect ?? mortaliteArme ?? "mortel"; } /* -------------------------------------------- */ static dmgArme(arme, dommagesMain) { if (arme) { let dmgBase = dommagesMain ?? Number(arme.system.dommages ?? 0); //Le bonus dégats magiques ne peut pas faire dépasser le bonus de l'arme (cf p.278) return dmgBase + Math.min(dmgBase, arme.system.magique ? arme.system.ecaille_efficacite : 0); } return 0; } /* -------------------------------------------- */ static _peneration(rollData) { return parseInt(rollData.arme?.system.penetration ?? 0); } /* -------------------------------------------- */ static bonusDmg(actor, categorie, dmgArme) { if (categorie == undefined) { return 0 } const dmgActor = actor.getBonusDegat() switch (categorie) { case "(tir)": case "tir": return 0 case "(lancer)": case "lancer": return Math.max(0, Math.min(dmgArme, dmgActor)); } return dmgActor; } /* -------------------------------------------- */ static _dmgParticuliere(rollData) { return rollData.particuliere == 'force' ? 5 : 0; } }