import { Distance } from "../combat/distance.mjs" import { ITEM_TYPES } from "../constants.js" import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js" import { CARACS } from "../rdd-carac.js" import { DIFF, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs" import { PART_CARAC } from "./roll-part-carac.mjs" import { PART_COMP } from "./roll-part-comp.mjs" import { PART_DIFF } from "./roll-part-diff.mjs" import { RollPartSelect } from "./roll-part-select.mjs" import { PART_SIGN } from "./roll-part-sign.mjs" import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs" export const PART_DEFENSE = 'defense' export class RollPartDefense extends RollPartSelect { get code() { return PART_DEFENSE } get section() { return ROLLDIALOG_SECTION.CHOIX } get rollTypes() { return [ROLL_TYPE_DEFENSE] } isValid(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_DEFENSE) && rollData.attackerRoll != undefined } visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_DEFENSE) && rollData.attackerRoll != undefined } loadRefs(rollData) { const refs = this.getRefs(rollData) const attackerRoll = rollData.attackerRoll const defenseur = rollData.active.actor refs.distance = rollData.attackerRoll.current?.attaque?.distance const isEmpoignade = attackerRoll.dmg.isEmpoignade const isEmpoignadeEnCours = isEmpoignade && defenseur.itemTypes[ITEM_TYPES.empoignade].find(it => [it.system.empoigneurid, it.system.empoigneid].includes(rollData.ids.opponentId) && it.system.pointsemp != 0) const esquives = (refs.distance?.typeAttaque == ATTAQUE_TYPE.TIR || isEmpoignadeEnCours) ? [] : defenseur.getCompetencesEsquive() const parades = isEmpoignade ? [RdDItemArme.empoignade(defenseur)] : this.$getParades(defenseur, attackerRoll, refs.distance) refs.defenses = [ ...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur, attackerRoll)), ...parades.map(it => RollPartDefense.$extractParade(it, defenseur, attackerRoll)) ] this.$selectDefense(rollData) } $getParades(defenseur, attackerRoll, distance) { const parades = defenseur.items.filter(it => it.isParade() && (!distance || it.isBouclier())) const armeAttaque = attackerRoll?.current?.attaque?.arme return armeAttaque ? parades.filter(armeDefense => RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) != 'impossible') : parades } static $extractEsquive(esquive, defenseur, attackerRoll) { const defense = { key: esquive.id, label: esquive.name, img: esquive.img, // TODO: carac pour créatures à vérifier carac: defenseur.isPersonnage() ? CARACS.DEROBEE : esquive.name, verb: "esquive", comp: esquive, isEsquive: true } if (attackerRoll.current?.attaque?.distance) { defense.distance = { ajustementDefense: Distance.ajustementDefense(attackerRoll.current.attaque), } } return defense } static $extractParade(armeDefense, defenseur, attackerRoll) { const armeAttaque = attackerRoll?.arme const comp = (ITEM_TYPES.competencecreature == armeDefense.type) ? armeDefense : defenseur.getCompetence(armeDefense.system.competence) const defense = { key: armeDefense.id, label: 'Parade ' + armeDefense.name, img: armeDefense.img, // TODO: carac pour créatures carac: defenseur.isPersonnage() ? CARACS.MELEE : comp.name, verb: "pare", comp: comp, arme: armeDefense, forceRequise: armeDefense ? RdDItemArme.valeurMain(armeDefense.system.force ?? 0, RdDItemArme.getMainAttaque(comp)) : 0, typeParade: armeAttaque ? RdDItemArme.defenseArmeParade(armeDefense, armeAttaque) : 'norm', isEsquive: false } if (attackerRoll.current?.attaque?.distance) { defense.distance = { ajustementBouclier: Distance.ajustementBouclier(armeDefense), ajustementDefense: Distance.ajustementDefense(attackerRoll.current.attaque), } } return defense } prepareContext(rollData) { // current.dmg = this.$dmgRollV2(rollData, current) } getAjustements(rollData) { return [] } choices(refs) { return refs.defenses } $selectDefense(rollData, key) { this.selectByKey(rollData, key) } async _onRender(rollDialog, context, options) { const selectDefense = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-defense"]`) selectDefense.addEventListener("change", e => { const selectOptions = e.currentTarget.options const index = selectOptions.selectedIndex this.$selectDefense(rollDialog.rollData, selectOptions[index]?.value) rollDialog.render() }) } impactOtherPart(part, rollData) { if (this.visible(rollData)) { const refs = this.getRefs(rollData) const current = this.getCurrent(rollData) switch (part.code) { case PART_CARAC: return part.filterCaracs(rollData, refs.defenses.length > 0 ? [current.carac] : ['impossible']) case PART_COMP: return part.filterComps(rollData, refs.defenses.length > 0 ? [current.comp?.name] : ['impossible']) case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData)) case PART_SIGN: return part.setArme(rollData, this.getArmeDisparate(rollData), current.forceRequise) } } return undefined } getArmeDisparate(rollData) { const armeDefense = this.getCurrent(rollData).arme if (armeDefense) { const armeAttaque = rollData.attackerRoll?.current.attaque.arme return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) } return 'norm' } getDiffDefense(rollData) { const refs = this.getRefs(rollData) if (refs.distance) { const current = this.getCurrent(rollData) const diff = (current.distance?.ajustementBouclier?.value ?? 0) + (current.distance?.ajustementDefense?.value ?? 0) return { diff: diff, type: DIFF.DEFENSE } } if (rollData.attackerRoll) { const attackerRoll = rollData.attackerRoll const diff = attackerRoll.v2 ? attackerRoll.selected.diff.value : attackerRoll.diff return { diff: diff ?? 0, type: DIFF.DEFENSE } } return { diff: 0, type: DIFF.LIBRE } } }