Nouveau roll-dialog: mode attaque / defense
This commit is contained in:
@@ -4,6 +4,8 @@ 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 { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js";
|
||||
import { RdDBonus } from "../rdd-bonus.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
export class RollDialogAdapter {
|
||||
@@ -87,4 +89,29 @@ export class RollDialogAdapter {
|
||||
rollData.show.title = rollTitle
|
||||
}
|
||||
|
||||
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,
|
||||
attaque: {
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -187,7 +187,12 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
foundry.applications.handlebars.loadTemplates(ROLL_PARTS.map(p => p.template))
|
||||
ROLL_PARTS.forEach(p => p.onReady())
|
||||
|
||||
Handlebars.registerHelper('roll-centered-array', (base, show) => RollDialog.centeredArray(base, show))
|
||||
Handlebars.registerHelper('roll-centered-array', (base, show) => {
|
||||
show = Math.abs(show)
|
||||
const start = base - show
|
||||
return [...Array(2 * show + 1).keys()].map(it => start + it)
|
||||
})
|
||||
|
||||
Handlebars.registerHelper('roll-list-item-value', (list, key, path = undefined) => {
|
||||
const selected = list.find(p => p.key == key)
|
||||
if (selected && path && path != '') {
|
||||
@@ -195,6 +200,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
}
|
||||
return selected
|
||||
})
|
||||
|
||||
Handlebars.registerHelper('roll-part-context', (rollData, code) => {
|
||||
const rollPart = ROLL_PARTS.find(it => it.code == code)
|
||||
if (rollPart == undefined) {
|
||||
@@ -211,12 +217,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
})
|
||||
}
|
||||
|
||||
static centeredArray(base, show) {
|
||||
show = Math.abs(show)
|
||||
const start = base - show
|
||||
return [...Array(2 * show + 1).keys()].map(it => start + it)
|
||||
}
|
||||
|
||||
|
||||
static async create(rollData, rollOptions = {}) {
|
||||
const rollDialog = new RollDialog(rollData, rollOptions)
|
||||
rollDialog.render(true)
|
||||
@@ -267,30 +268,33 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
/** pre-configure les paramètres des différentes parties de la fenêtre (par exemple, prépare les listes de caractéristiques/compétences */
|
||||
$loadParts() {
|
||||
const rollData = this.rollData;
|
||||
const loadedMode = rollData.mode?.current
|
||||
rollData.current = rollData.current ?? {}
|
||||
rollData.selected = rollData.selected ?? {}
|
||||
rollData.mode = rollData.mode ?? {}
|
||||
rollData.mode.retry = rollData.mode.retry ?? false
|
||||
BASIC_PARTS.restore(rollData)
|
||||
|
||||
const loadedMode = ROLL_MODE_TABS.find(m => m.code == rollData.mode?.current)?.code
|
||||
const allowedModes = ROLL_MODE_TABS.filter(m => m.isAllowed(rollData) && m.visible(rollData)).map(m => m.code)
|
||||
|
||||
rollData.mode.allowed = rollData.mode.retry ? [loadedMode] : rollData.mode.allowed ?? ROLL_MODE_TABS.map(m => m.code)
|
||||
rollData.mode.current = loadedMode ?? ROLL_MODE_TABS.find(m => m.isAllowed(rollData) && m.visible(rollData))?.code ?? ROLL_MODE_COMP
|
||||
rollData.mode.current = allowedModes.find(m => m == rollData.mode?.current) ?? (allowedModes.length > 0 ? allowedModes[0] : ROLL_MODE_COMP)
|
||||
|
||||
this.getSelectedMode().setRollDataMode(rollData)
|
||||
|
||||
|
||||
rollData.refs = this.$prepareRefs(rollData)
|
||||
rollData.options = rollData.options ?? { showDice: true, rollMode: game.settings.get("core", "rollMode") }
|
||||
|
||||
|
||||
ROLL_PARTS.forEach(p => p.initialize(rollData))
|
||||
ROLL_PARTS.forEach(p => p.restore(rollData))
|
||||
ROLL_PARTS.filter(p => p.isValid(rollData))
|
||||
.forEach(p => {
|
||||
p.loadRefs(rollData)
|
||||
p.prepareContext(rollData)
|
||||
})
|
||||
.forEach(p => {
|
||||
p.loadRefs(rollData)
|
||||
p.prepareContext(rollData)
|
||||
})
|
||||
this.selectMode();
|
||||
}
|
||||
|
||||
|
||||
selectMode() {
|
||||
this.rollData.mode.label = this.getSelectedMode().title(this.rollData)
|
||||
this.getSelectedMode().setRollDataMode(this.rollData)
|
||||
@@ -360,7 +364,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
|
||||
this.setModeTitle()
|
||||
|
||||
const visibleRollParts = this.getActiveParts()
|
||||
visibleRollParts.forEach(p => p.setExternalFilter(visibleRollParts, rollData))
|
||||
visibleRollParts.forEach(p => p.applyExternalImpacts(visibleRollParts, rollData))
|
||||
|
||||
this.setSpecialComp(visibleRollParts);
|
||||
|
||||
|
@@ -5,7 +5,7 @@ export class RollModeDefense extends RollMode {
|
||||
get code() { return ROLL_MODE_DEFENSE }
|
||||
get name() { return `Se défendre` }
|
||||
|
||||
title(rollData) { return `se défend${rollData.attacker ? ' de' : ''}` }
|
||||
title(rollData) { return `se défend${rollData.opponent ? ' de' : ''}` }
|
||||
|
||||
getOpponent(rollData) {
|
||||
return rollData.attacker
|
||||
|
@@ -37,6 +37,7 @@ export class RollPartAppelMoral extends RollPartCheckbox {
|
||||
}
|
||||
return '<i class="fa-regular fa-face-meh"></i>'
|
||||
}
|
||||
|
||||
getCheckboxLabel(rollData) { return "Appel au moral" }
|
||||
getCheckboxValue(rollData) { return 1 }
|
||||
}
|
||||
|
@@ -1,12 +1,16 @@
|
||||
import { Grammar } from "../grammar.js"
|
||||
import { RdDBonus } from "../rdd-bonus.js"
|
||||
import { StatusEffects } from "../settings/status-effects.js"
|
||||
import { ROLL_MODE_ATTAQUE } from "./roll-constants.mjs"
|
||||
import { PART_CARAC } from "./roll-part-carac.mjs"
|
||||
import { PART_COMP } from "./roll-part-comp.mjs"
|
||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
|
||||
import { PART_SIGN } from "./roll-part-sign.mjs"
|
||||
import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||
|
||||
export const PART_ATTAQUE = 'attaque'
|
||||
|
||||
const TACTIQUES = RdDBonus.tactiques.filter(it => it.isTactique)
|
||||
|
||||
export class RollPartAttaque extends RollPartSelect {
|
||||
|
||||
get code() { return PART_ATTAQUE }
|
||||
@@ -18,29 +22,71 @@ export class RollPartAttaque extends RollPartSelect {
|
||||
const refs = this.getRefs(rollData)
|
||||
const attaques = rollData.active.actor.listAttaques()
|
||||
refs.attaques = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor))
|
||||
if (refs.attaques.length>0){
|
||||
refs.tactiques = TACTIQUES
|
||||
if (refs.attaques.length > 0) {
|
||||
this.$selectAttaque(rollData)
|
||||
}
|
||||
}
|
||||
|
||||
choices(refs) { return refs.attaques }
|
||||
|
||||
static $extractAttaque(action, actor) {
|
||||
static $extractAttaque(attaque, actor) {
|
||||
return {
|
||||
key: `${action.action}::${action.arme.id}::${action.comp.id}`,
|
||||
label: action.name,
|
||||
action: action,
|
||||
arme: action.arme,
|
||||
comp: action.comp,
|
||||
key: `${attaque.action}::${attaque.name}`,
|
||||
label: attaque.name,
|
||||
attaque: attaque,
|
||||
tactique: TACTIQUES[0],
|
||||
}
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.defenseur = StatusEffects.getActorEffetSurprise(rollData.opponent?.actor, 0)
|
||||
current.attaquant = StatusEffects.getActorEffetSurprise(rollData.active.actor, current.attaque.forceRequise)
|
||||
current.dmg = this.$dmgRollV2(rollData, current)
|
||||
}
|
||||
|
||||
$dmgRollV2(rollData, current) {
|
||||
const actor = rollData.active.actor
|
||||
const defender = rollData.opponent?.actor
|
||||
const dmgArme = RdDBonus.dmgArme(current.attaque.arme, current.attaque.dommagesArme)
|
||||
const dmg = {
|
||||
total: 0,
|
||||
dmgArme: dmgArme,
|
||||
penetration: current.attaque.arme.penetration(),
|
||||
dmgTactique: current.tactique?.dmg ?? 0,
|
||||
dmgParticuliere: 0, // TODO RdDBonus._dmgParticuliere(rollData),
|
||||
dmgSurprise: current.surpriseDefenseur?.dmg ?? 0,
|
||||
mortalite: RdDBonus.mortalite(current.dmg?.mortalite, current.attaque.arme.system.mortalite, defender?.isEntite()),
|
||||
dmgActor: RdDBonus.bonusDmg(actor, current.attaque.carac.key, dmgArme, current.attaque.forceRequise),
|
||||
dmgForceInsuffisante: Math.min(0, actor.getForce() - current.attaque.forceRequise)
|
||||
}
|
||||
dmg.total = dmg.dmgSurprise + dmg.dmgTactique + dmg.dmgArme + dmg.dmgActor + dmg.dmgParticuliere + dmg.dmgForceInsuffisante
|
||||
return dmg
|
||||
}
|
||||
|
||||
getAjustements(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
const ajustements = []
|
||||
if (current.tactique) {
|
||||
ajustements.push({ label: current.tactique.label, diff: current.tactique.attaque })
|
||||
}
|
||||
if (current.surpriseDefenseur) {
|
||||
ajustements.push({ label: current.surpriseDefenseur.label, diff: current.surpriseDefenseur.attaque })
|
||||
}
|
||||
return ajustements
|
||||
}
|
||||
|
||||
|
||||
$selectAttaque(rollData, key) {
|
||||
this.selectByKey(rollData, key, 0)
|
||||
this.selectByKey(rollData, key)
|
||||
}
|
||||
|
||||
async _onRender(rollDialog, context, options) {
|
||||
const selectAttaque = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-attaque"]`)
|
||||
const selectTactique = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-tactique"]`)
|
||||
const checkMortalite = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="check-mortalite"]`)
|
||||
const current = this.getCurrent(rollDialog.rollData)
|
||||
|
||||
selectAttaque.addEventListener("change", e => {
|
||||
const selectOptions = e.currentTarget.options
|
||||
@@ -49,18 +95,29 @@ export class RollPartAttaque extends RollPartSelect {
|
||||
rollDialog.setModeTitle()
|
||||
rollDialog.render()
|
||||
})
|
||||
|
||||
selectTactique.addEventListener("change", e => {
|
||||
const selectOptions = e.currentTarget.options
|
||||
const index = selectOptions.selectedIndex
|
||||
current.tactique = RdDBonus.find(selectOptions[index]?.value)
|
||||
rollDialog.render()
|
||||
})
|
||||
|
||||
checkMortalite?.addEventListener("change", e => {
|
||||
current.dmg.mortalite = (e.currentTarget.checked ? 'mortel' : 'non-mortel')
|
||||
rollDialog.render()
|
||||
})
|
||||
}
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) {
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (partCode) {
|
||||
case PART_CARAC: return p => Grammar.equalsInsensitive(current.action.carac.key, p.key)
|
||||
case PART_COMP: return p => p.label == current.comp?.name
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [current.attaque.carac.key])
|
||||
case PART_COMP: return part.filterComps(rollData, [current.attaque.comp?.name])
|
||||
case PART_SIGN: return part.setArme(rollData, current.attaque.forceRequise, false)
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -36,9 +36,13 @@ export class RollPartCarac extends RollPartSelect {
|
||||
}
|
||||
}
|
||||
|
||||
setFilter(rollData, filter) {
|
||||
filterCaracs(rollData, allowed) {
|
||||
allowed = allowed.filter(it => it != undefined)
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.caracs = refs.all.filter(filter)
|
||||
refs.caracs = allowed.length > 0
|
||||
// ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.key)))
|
||||
? refs.all.filter(it => allowed.includes(it.key))
|
||||
: refs.all
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
|
@@ -18,8 +18,8 @@ export class RollPartCheckbox extends RollPart {
|
||||
}
|
||||
|
||||
loadRefs(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.label = this.getCheckboxLabel(rollData)
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.label = this.getCheckboxLabel(rollData)
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
@@ -43,7 +43,7 @@ export class RollPartCheckbox extends RollPart {
|
||||
}
|
||||
|
||||
getCheckboxLabelAjustement(rollData) {
|
||||
return `${this.getCheckboxIcon(rollData)} ${this.getCurrent(rollData).label}`
|
||||
return `${this.getCheckboxIcon(rollData)} ${this.getRefs(rollData).label}`
|
||||
}
|
||||
|
||||
async _onRender(rollDialog, context, options) {
|
||||
|
@@ -45,9 +45,13 @@ export class RollPartComp extends RollPartSelect {
|
||||
}
|
||||
}
|
||||
|
||||
setFilter(rollData, filter) {
|
||||
filterComps(rollData, allowed) {
|
||||
allowed = allowed.filter(it => it != undefined)
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.comps = refs.all.filter(filter)
|
||||
refs.comps = allowed.length > 0
|
||||
// ? refs.all.filter(it => allowed.includes(Grammar.toLowerCaseNoAccent(it.label)))
|
||||
? refs.all.filter(it => allowed.includes(it.label))
|
||||
: refs.all
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
|
@@ -1,17 +1,133 @@
|
||||
import { ROLL_MODE_DEFENSE } from "./roll-constants.mjs"
|
||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { Grammar } from "../grammar.js"
|
||||
import { ATTAQUE_TYPE, RdDItemArme } from "../item/arme.js"
|
||||
import { RdDBonus } from "../rdd-bonus.js"
|
||||
import { CARACS } from "../rdd-carac.js"
|
||||
import { StatusEffects } from "../settings/status-effects.js"
|
||||
import { DIFF_MODE, ROLL_MODE_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 } from "./roll-part.mjs"
|
||||
|
||||
export const PART_DEFENSE = 'defense'
|
||||
|
||||
export class RollPartDefense extends RollPart {
|
||||
export class RollPartDefense extends RollPartSelect {
|
||||
|
||||
get code() { return PART_DEFENSE }
|
||||
get section() { return ROLLDIALOG_SECTION.CHOIX }
|
||||
visible(rollData) { return this.isRollMode(rollData, ROLL_MODE_DEFENSE) }
|
||||
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.defenses =[]
|
||||
static getDiffAttaque(attackerRoll) {
|
||||
// TODO: rollDataV2?
|
||||
return attackerRoll.diffLibre;
|
||||
}
|
||||
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
const attaque = rollData.attaque
|
||||
const defenseur = rollData.active.actor
|
||||
refs.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attaque?.main)
|
||||
const esquives = refs.isDistance == ATTAQUE_TYPE.TIR ? [] : defenseur.getCompetencesEsquive()
|
||||
.map(it => RollPartDefense.$extractEsquive(it, defenseur))
|
||||
|
||||
const parades = defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
|
||||
.map(it => RollPartDefense.$extractParade(it, attaque?.attaque.arme, defenseur))
|
||||
|
||||
refs.defenses = [...esquives, ...parades].filter(it => it != undefined)
|
||||
this.$selectDefense(rollData)
|
||||
}
|
||||
|
||||
static $extractEsquive(esquive, defenseur) {
|
||||
return {
|
||||
key: esquive.id,
|
||||
label: esquive.name,
|
||||
img: esquive.img,
|
||||
// TODO: carac pour créatures
|
||||
carac: defenseur.isPersonnage() ? CARACS.DEROBEE : esquive.name,
|
||||
comp: esquive
|
||||
}
|
||||
}
|
||||
|
||||
static $extractParade(armeDefense, armeAttaque, defenseur) {
|
||||
const comp = (ITEM_TYPES.competencecreature == armeDefense.type)
|
||||
? armeDefense
|
||||
: defenseur.getCompetence(armeDefense.system.competence)
|
||||
return {
|
||||
key: armeDefense.id,
|
||||
label: 'Parade ' + armeDefense.name,
|
||||
img: armeDefense.img,
|
||||
// TODO: carac pour créatures
|
||||
carac: defenseur.isPersonnage() ? CARACS.MELEE : comp.name,
|
||||
comp: comp,
|
||||
arme: armeDefense,
|
||||
forceRequise: armeDefense ? RdDItemArme.valeurMain(armeDefense.system.force ?? 0, RdDItemArme.getMainAttaque(comp)) : 0,
|
||||
typeParade: armeAttaque ? RdDItemArme.defenseArmeParade(armeDefense, armeAttaque) : 'norm'
|
||||
}
|
||||
}
|
||||
|
||||
prepareContext(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.defenseur = StatusEffects.getActorEffetSurprise(rollData.active.actor, current.forceRequise)
|
||||
|
||||
// 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.setModeTitle()
|
||||
rollDialog.render()
|
||||
})
|
||||
}
|
||||
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [current.carac])
|
||||
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||
case PART_DIFF: return part.setDiff(rollData, this.getDiffDefense(rollData))
|
||||
case PART_SIGN: return part.setArme(rollData, current.forceRequise, this.isArmeDisparate(rollData))
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
isArmeDisparate(rollData) {
|
||||
const armeDefense = this.getCurrent(rollData).arme
|
||||
if (armeDefense) {
|
||||
const armeAttaque = rollData.attaque?.attaque.arme
|
||||
return RdDItemArme.defenseArmeParade(armeAttaque, armeDefense) == 'sign'
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
getDiffDefense(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
const refs = this.getRefs(rollData)
|
||||
if (refs.isDistance) {
|
||||
// Déterminer la difficulté de parade
|
||||
return { diff: 0, mode: DIFF_MODE.LIBRE }
|
||||
}
|
||||
else {
|
||||
return { diff: rollData.attaque.diff, mode: DIFF_MODE.DEFENSE }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,6 +50,12 @@ export class RollPartDiff extends RollPart {
|
||||
)
|
||||
}
|
||||
|
||||
setDiff(rollData, diffDefense) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.value = diffDefense.diff
|
||||
current.mode = diffDefense.mode
|
||||
}
|
||||
|
||||
getAjustements(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
return [{
|
||||
@@ -67,4 +73,5 @@ export class RollPartDiff extends RollPart {
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -91,12 +91,12 @@ export class RollPartJeu extends RollPartSelect {
|
||||
})
|
||||
}
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) {
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (partCode) {
|
||||
case PART_CARAC: return p => current.caracs?.includes(Grammar.toLowerCaseNoAccent(p.key))
|
||||
case PART_COMP: return p => p.label == current.comp?.name
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
|
||||
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { ITEM_TYPES } from "../constants.js"
|
||||
import { Grammar } from "../grammar.js"
|
||||
import { RdDCarac } from "../rdd-carac.js"
|
||||
import { CARACS, RdDCarac } from "../rdd-carac.js"
|
||||
import { RdDTimestamp } from "../time/rdd-timestamp.js"
|
||||
import { TMRUtility } from "../tmr-utility.js"
|
||||
import { ROLL_MODE_MEDITATION } from "./roll-constants.mjs"
|
||||
@@ -104,12 +104,12 @@ export class RollPartMeditation extends RollPartSelect {
|
||||
})
|
||||
}
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) {
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (partCode) {
|
||||
case PART_CARAC: return p => RdDCarac.isIntellect(p.key)
|
||||
case PART_COMP: return p => p.label == current.comp?.name
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT])
|
||||
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -43,15 +43,15 @@ export class RollPartOeuvre extends RollPartSelect {
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.oeuvres = rollData.active.actor.items
|
||||
.filter(it => it.isOeuvre() && RollPartOeuvre.getArt(it))
|
||||
.map(it => RollPartOeuvre.$extractOeuvre(it, rollData.active.actor))
|
||||
.filter(it => it.isOeuvre() && RollPartOeuvre.getArt(it))
|
||||
.map(it => RollPartOeuvre.$extractOeuvre(it, rollData.active.actor))
|
||||
if (refs.oeuvres.length > 0) {
|
||||
this.$selectOeuvre(rollData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
choices(refs) { return refs.oeuvres }
|
||||
|
||||
|
||||
static $extractOeuvre(oeuvre, actor) {
|
||||
const art = RollPartOeuvre.getArt(oeuvre)
|
||||
return {
|
||||
@@ -64,7 +64,7 @@ export class RollPartOeuvre extends RollPartSelect {
|
||||
comp: actor.getCompetence(art.competence(oeuvre))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static getArt(oeuvre) {
|
||||
return ARTS.find(it => it.type == oeuvre.type)
|
||||
}
|
||||
@@ -85,12 +85,12 @@ export class RollPartOeuvre extends RollPartSelect {
|
||||
})
|
||||
}
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) {
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (partCode) {
|
||||
case PART_CARAC: return p => current.caracs?.includes(Grammar.toLowerCaseNoAccent(p.key))
|
||||
case PART_COMP: return p => p.label == current.comp?.name
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
|
||||
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -27,7 +27,7 @@ export class RollPartSelect extends RollPart {
|
||||
const current = this.getCurrent(rollData)
|
||||
const newChoice = (choices.length == 0)
|
||||
? { key: '', value: defValue }
|
||||
: this.$getSelectedChoice(choices, key ?? current?.key ?? refs.key ?? '')
|
||||
: this.$getSelectedChoice(choices, key ?? current?.key ?? refs?.key ?? '')
|
||||
this.setCurrent(rollData, newChoice)
|
||||
return newChoice
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { Misc } from "../misc.js"
|
||||
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
|
||||
import { StatusEffects } from "../settings/status-effects.js"
|
||||
import { ROLL_MODE_ATTAQUE, ROLL_MODE_DEFENSE } from "./roll-constants.mjs"
|
||||
import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
|
||||
@@ -22,11 +23,6 @@ export class RollPartSign extends RollPart {
|
||||
this.setSaved(targetData, this.getCurrent(rollData))
|
||||
}
|
||||
|
||||
// visible(rollData) {
|
||||
// const current = this.getCurrent(rollData)
|
||||
// return current.surprise != ''
|
||||
// }
|
||||
|
||||
isCombat(rollData) {
|
||||
return [ROLL_MODE_ATTAQUE, ROLL_MODE_DEFENSE].includes(rollData.mode.current) || rollData.mode.isCombat
|
||||
}
|
||||
@@ -42,41 +38,61 @@ export class RollPartSign extends RollPart {
|
||||
const actor = rollData.active.actor;
|
||||
const isCombat = this.isCombat(rollData)
|
||||
const current = this.getCurrent(rollData)
|
||||
current.armeDisparate = isCombat && current.armeDisparate
|
||||
current.forceRequise = current.forceRequise ?? 0
|
||||
current.surprise = actor.getSurprise(isCombat)
|
||||
current.reasons = actor.getEffects(it => StatusEffects.niveauSurprise(it) > 0).map(it => it.name)
|
||||
current.diviseur = 1
|
||||
if (isCombat && actor.isDemiReve()) {
|
||||
current.reasons.push('Demi-rêve en combat')
|
||||
}
|
||||
if (current.surprise == 'demi') {
|
||||
current.diviseur *= 2
|
||||
}
|
||||
|
||||
if (this.isAttaqueFinesse(rollData)) {
|
||||
current.diviseur *= 2
|
||||
current.reasons.push('Attaque en finesse')
|
||||
if (isCombat && actor.isDemiReve()) {
|
||||
current.reasons.push('Demi-rêve en combat')
|
||||
}
|
||||
if (this.isForceInsuffisante(rollData)) {
|
||||
if (this.isParadeArmeDisparate(current)) {
|
||||
current.diviseur *= 2
|
||||
current.reasons.push('Armes disparates')
|
||||
}
|
||||
if (this.isForceInsuffisante(actor, current)) {
|
||||
current.diviseur *= 2
|
||||
current.reasons.push('Force insuffisante')
|
||||
}
|
||||
if (this.isAttaqueFinesse(rollData)) {
|
||||
current.diviseur *= 2
|
||||
current.reasons.push('Particulière en finesse')
|
||||
}
|
||||
|
||||
if (!ReglesOptionnelles.isUsing('tripleSignificative')) {
|
||||
current.diviseur = Math.min(current.diviseur, 4);
|
||||
}
|
||||
|
||||
current.reason = current.reasons.join(', ')
|
||||
}
|
||||
|
||||
isForceInsuffisante(rollData) {
|
||||
//this.isCombat(rollData) && ... arme avec force min
|
||||
return this.isCombat(rollData) && true
|
||||
isAttaqueFinesse(rollData) {
|
||||
return ROLL_MODE_DEFENSE == rollData.mode.current && rollData.attaque.particuliere == 'finesse'
|
||||
}
|
||||
|
||||
isAttaqueFinesse(rollData) {
|
||||
// this.rollData.selected[PART_DEFENSE] && attaquant avec particulière en finesse
|
||||
return ROLL_MODE_DEFENSE == rollData.mode.current && true
|
||||
isForceInsuffisante(actor, current) {
|
||||
if (actor?.isPersonnage()) {
|
||||
const requise = current.forceRequise
|
||||
const force = parseInt(actor.system.carac.force.value)
|
||||
return requise > force
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
isParadeArmeDisparate(current) {
|
||||
return current.armeDisparate
|
||||
}
|
||||
|
||||
getAjustements(rollData) {
|
||||
const current = this.getCurrent(rollData)
|
||||
if (current.surprise == 'demi') {
|
||||
return [{ label: 'Significative requise ' + Misc.getFractionOneN(current.diviseur), diff: undefined }]
|
||||
return [
|
||||
{ label: 'Significative requise ' + Misc.getFractionOneN(current.diviseur), diff: undefined },
|
||||
...current.reasons.map(it => { return { label: '<i class="fa-solid fa-triangle-exclamation"></i> ' + it, diff: undefined } })
|
||||
]
|
||||
}
|
||||
return []
|
||||
}
|
||||
@@ -90,4 +106,9 @@ export class RollPartSign extends RollPart {
|
||||
})
|
||||
}
|
||||
|
||||
setArme(rollData, forceRequise, armeDisparate) {
|
||||
const current = this.getCurrent(rollData)
|
||||
current.armeDisparate = armeDisparate
|
||||
current.forceRequise = forceRequise
|
||||
}
|
||||
}
|
@@ -6,6 +6,7 @@ import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
|
||||
import { TMRUtility } from "../tmr-utility.js"
|
||||
import { RdDItemSort } from "../item-sort.js"
|
||||
import { RollPartSelect } from "./roll-part-select.mjs"
|
||||
import { CARACS } from "../rdd-carac.js"
|
||||
|
||||
export const PART_SORT = "sort"
|
||||
|
||||
@@ -115,12 +116,12 @@ export class RollPartSort extends RollPartSelect {
|
||||
})
|
||||
}
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) {
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (partCode) {
|
||||
case PART_CARAC: return p => p.key == 'reve'
|
||||
case PART_COMP: return p => current.draconics?.includes(p.label)
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.REVE])
|
||||
case PART_COMP: return part.filterComps(rollData,current.draconics ?? [])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -19,14 +19,14 @@ export class RollPartTache extends RollPartSelect {
|
||||
loadRefs(rollData) {
|
||||
const refs = this.getRefs(rollData)
|
||||
refs.taches = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
|
||||
.filter(tache => tache.system.points_de_tache_courant < tache.system.points_de_tache)
|
||||
.map(tache => RollPartTache.$extractTache(tache, rollData.active.actor))
|
||||
.filter(tache => tache.system.points_de_tache_courant < tache.system.points_de_tache)
|
||||
.map(tache => RollPartTache.$extractTache(tache, rollData.active.actor))
|
||||
if (refs.taches.length > 0) {
|
||||
this.$selectTache(rollData)
|
||||
}
|
||||
}
|
||||
choices(refs) { return refs.taches }
|
||||
|
||||
|
||||
static $extractTache(tache, actor) {
|
||||
return {
|
||||
key: tache.id,
|
||||
@@ -53,12 +53,12 @@ export class RollPartTache extends RollPartSelect {
|
||||
})
|
||||
}
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) {
|
||||
impactOtherPart(part, rollData) {
|
||||
if (this.visible(rollData)) {
|
||||
const current = this.getCurrent(rollData)
|
||||
switch (partCode) {
|
||||
case PART_CARAC: return p => Grammar.equalsInsensitive(p.key, current?.tache.system.carac)
|
||||
case PART_COMP: return p => p.label == current?.comp.name
|
||||
switch (part.code) {
|
||||
case PART_CARAC: return part.filterCaracs(rollData, [current?.tache.system.carac])
|
||||
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
|
@@ -72,16 +72,14 @@ export class RollPart {
|
||||
prepareContext(rollData) { }
|
||||
|
||||
/** ---- cross roll-part filtering ---- */
|
||||
setFilter(rollData, filter) { }
|
||||
applyImpact(rollData, filter) { }
|
||||
getSpecialComp(rollData) { return [] }
|
||||
setSpecialComp(comps) { }
|
||||
|
||||
getExternalPartsFilter(partCode, rollData) { return undefined }
|
||||
setExternalFilter(visibleRollParts, rollData) {
|
||||
const predicate = Misc.and(
|
||||
visibleRollParts.map(p => p.getExternalPartsFilter(this.code, rollData)).filter(f => f != undefined)
|
||||
)
|
||||
this.setFilter(rollData, predicate);
|
||||
impactOtherPart(partCode, rollData) { }
|
||||
|
||||
applyExternalImpacts(rollParts, rollData) {
|
||||
rollParts.forEach(part => part.impactOtherPart(this, rollData))
|
||||
}
|
||||
|
||||
toTemplateData() {
|
||||
|
Reference in New Issue
Block a user