Fenêtres Roll V2

Maintenant disponibles pour:
- méditation
- tâches
- soins
This commit is contained in:
2025-10-05 02:24:34 +02:00
parent 47c4478303
commit fa6769fcd7
28 changed files with 359 additions and 102 deletions

View File

@@ -42,10 +42,10 @@ import ChatRollResult from "./chat-roll-result.mjs";
import { renderTemplate } from "../constants.js";
import { RollTypeCuisine } from "./roll-type-cuisine.mjs";
import { RollPartCuisine } from "./roll-part-cuisine.mjs";
import { OptionsAvancees, ROLL_DIALOG_V2_TEST } from "../settings/options-avancees.js";
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api
const doNothing = (dialog) => { }
const ALL_ROLL_TYPES = [
new RollTypeComp(),
@@ -172,6 +172,14 @@ const ROLL_PARTS = [
/* -------------------------------------------- */
export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2)
{
static onRollDoneDoNothing(dialog) {
dialog.render()
}
static onRollDoneClose(dialog) {
if (!OptionsAvancees.isUsing(ROLL_DIALOG_V2_TEST))
dialog.close()
}
static init() {
}
@@ -275,9 +283,9 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
rollData.options = rollData.options ?? { 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.restore(rollData)
p.loadRefs(rollData)
p.prepareContext(rollData)
})
@@ -307,7 +315,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
...(rollOptions.callbacks ?? [])
],
customChatMessage: rollOptions.customChatMessage,
onRollDone: rollOptions.onRollDone ?? doNothing
onRollDone: rollOptions.onRollDone ?? RollDialog.onRollDoneDoNothing
}
this.chatRollResult = new ChatRollResult();
this.selectType()
@@ -328,16 +336,16 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
return ROLL_PARTS.filter(p => p.isActive(rollData))
}
// get title() {
// return this.rollData.title ?? `Jet de dés de ${this.rollData.active.actor.name}`
// }
rollTitle(rollData) {
return rollData.label ?? ROLL_PARTS
const title = rollData.label ?? ROLL_PARTS
.filter(it => it.section == ROLLDIALOG_SECTION.ACTION)
.filter(it => it.isActive(rollData))
.map(it => it.title(rollData))
.reduce(Misc.joining(' '))
.reduce(Misc.joining(' '));
if (this.rollOptions.title) {
return `${this.rollOptions.title} ${title}`
}
return title
}
async _onRender(context, options) {
@@ -428,15 +436,20 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
async roll() {
const roll = RollDialog.saveParts(this.rollData)
const selectedRollType = this.getSelectedType(roll);
RollDialog.loadRollData(roll)
roll.current.resultat = this.rollData.current[PART_TRICHER]?.resultat ?? -1
roll.choix = {}
roll.rolled = await RollDialogAdapter.rollDice(roll, this.rollTitle(roll))
roll.result = this.getSelectedType(roll).getResult(roll)
roll.result = selectedRollType.getResult(roll)
console.info('RollDialog.roll:', roll)
const callbacks = [
...this.rollOptions.callbacks,
...selectedRollType.callbacks(this.rollOptions),
]
await Promise.all(callbacks.map(async callback => await callback(roll)))
await this.chatRollResult.display(roll)
await Promise.all(this.rollOptions.callbacks.map(async callback => await callback(roll)))
this.rollOptions.onRollDone(this)
}

View File

@@ -28,9 +28,7 @@ export class RollPartCheckbox extends RollPart {
/* TODO: user setting? */
current.checked = true
}
if (current.value == undefined) {
current.value = this.getCheckboxValue(rollData)
}
current.value = this.getCheckboxValue(rollData)
current.icon = this.getCheckboxIcon(rollData)
}

View File

@@ -17,7 +17,14 @@ export class RollPartComp extends RollPartSelect {
loadRefs(rollData) {
const refs = this.getRefs(rollData)
const selected = this.getSelected(rollData)
refs.all = this.$getActorComps(rollData)
.filter(comp => !selected.forced ||
(selected.key ?
Grammar.includesLowerCaseNoAccent(comp.name, selected.key)
: comp.key == '')
)
refs.comps = refs.all
this.$selectComp(rollData)
}
@@ -49,7 +56,6 @@ export class RollPartComp extends RollPartSelect {
allowed = allowed.filter(it => it != undefined)
const refs = this.getRefs(rollData)
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
this.$selectComp(rollData)

View File

@@ -11,26 +11,41 @@ import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
export const PART_MEDITATION = "meditation"
const COMPORTEMENTS = ['isComportement', 'isHeure', 'isPurification', 'isVeture']
export class RollPartMeditation extends RollPartSelect {
get code() { return PART_MEDITATION }
get section() { return ROLLDIALOG_SECTION.CHOIX }
store(rollData, targetData) {
const current = this.getCurrent(rollData)
this.setSaved(targetData, {
key: current.key,
isComportement: current.isComportement,
isHeure: current.isHeure,
isPurification: current.isPurification,
isVeture: current.isVeture
})
}
isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() }
visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_MEDITATION) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
foundry.utils.mergeObject(refs,
{
meditations: rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
.map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
}
)
refs.meditations = rollData.active.actor.itemTypes[ITEM_TYPES.meditation]
.map(it => RollPartMeditation.$extractMeditation(it, rollData.active.actor))
if (refs.meditations.length > 0) {
this.$selectMeditation(rollData)
this.$selectConditionMeditation(rollData)
const selected = this.getSelected(rollData)
const current = this.getCurrent(rollData)
COMPORTEMENTS.filter(it => selected[it]).forEach(it => current[it] = selected[it])
}
}
choices(refs) { return refs.meditations }
static $extractMeditation(meditation, actor) {
@@ -48,12 +63,7 @@ export class RollPartMeditation extends RollPartSelect {
getMalusConditions(rollData) {
const current = this.getCurrent(rollData)
const conditionsManquantes = [
current.isComportement,
current.isHeure,
current.isPurification,
current.isVeture
].filter(it => !it).length
const conditionsManquantes = COMPORTEMENTS.filter(it => !current[it]).length
return -2 * conditionsManquantes
}
@@ -71,13 +81,18 @@ export class RollPartMeditation extends RollPartSelect {
const previous = this.getCurrent(rollData)
const current = this.selectByKey(rollData, key, 0)
if (current.key != previous.key) {
const heureMonde = RdDTimestamp.getWorldTime().heure
const heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure
current.isHeure = heureMeditation == heureMonde
current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord))
this.$selectConditionMeditation(rollData)
}
}
$selectConditionMeditation(rollData) {
const current = this.getCurrent(rollData)
current.heureMonde = RdDTimestamp.getWorldTime().heure
current.heureMeditation = RdDTimestamp.findHeure(current.meditation.system.heure)?.heure
current.isHeure = current.heureMeditation == current.heureMonde
current.isTMR = Grammar.equalsInsensitive(current.meditation.system.tmr, TMRUtility.getTMRType(rollData.active.actor.system.reve.tmrpos.coord))
}
async _onRender(rollDialog, context, options) {
const selectMeditation = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-meditation"]`)
@@ -88,10 +103,7 @@ export class RollPartMeditation extends RollPartSelect {
rollDialog.render()
})
this.setupListenerCondition(rollDialog, 'isComportement')
this.setupListenerCondition(rollDialog, 'isHeure')
this.setupListenerCondition(rollDialog, 'isPurification')
this.setupListenerCondition(rollDialog, 'isVeture')
COMPORTEMENTS.forEach(it => this.setupListenerCondition(rollDialog, it))
}
setupListenerCondition(rollDialog, inputName) {
@@ -108,7 +120,7 @@ export class RollPartMeditation extends RollPartSelect {
const current = this.getCurrent(rollData)
switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, [CARACS.INTELLECT])
case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
}
}
return undefined

View File

@@ -1,5 +1,4 @@
import { ITEM_TYPES } from "../constants.js"
import { Grammar } from "../grammar.js"
import { ROLL_TYPE_TACHE } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs"
@@ -18,13 +17,17 @@ export class RollPartTache extends RollPartSelect {
loadRefs(rollData) {
const refs = this.getRefs(rollData)
refs.taches = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
const selected = this.getSelected(rollData)
refs.all = rollData.active.actor.itemTypes[ITEM_TYPES.tache]
.filter(tache => !selected.forced || tache.id == selected.key)
.filter(tache => tache.system.points_de_tache_courant < tache.system.points_de_tache)
.map(tache => RollPartTache.$extractTache(tache, rollData.active.actor))
refs.taches = refs.all
if (refs.taches.length > 0) {
this.$selectTache(rollData)
}
}
choices(refs) { return refs.taches }
static $extractTache(tache, actor) {

View File

@@ -43,6 +43,7 @@ export class RollPart {
}
/** les informations minimales représentant la sélection dans le rollData permettant de restaurer la fenêtre */
getSelected(rollData) { return this.getSaved(rollData) }
getSaved(rollData) {
return rollData.selected[this.code] ?? {}
}
@@ -84,9 +85,9 @@ export class RollPart {
loadRefs(rollData) { }
prepareContext(rollData) { }
/** permet de sauvegarder dans rollData les informations (cas des champs edit) */
validate(rollData) {}
validate(rollData) { }
/** ---- cross roll-part filtering ---- */
applyImpact(rollData, filter) { }

View File

@@ -1,3 +1,4 @@
import { RdDItemSigneDraconique } from "../item/signedraconique.js"
import { DIFF, ROLL_TYPE_MEDITATION } from "./roll-constants.mjs"
import { PART_MEDITATION } from "./roll-part-meditation.mjs"
import { RollType } from "./roll-type.mjs"
@@ -16,4 +17,20 @@ export class RollTypeMeditation extends RollType {
onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN)
}
callbacks(rollOptions) { return [RollTypeMeditation.$onRollMeditation] }
static async $onRollMeditation(rollData) {
const actor = rollData.active.actor
const meditation = rollData.current.meditation.meditation
const rolled = rollData.rolled
if (meditation && rolled) {
if (rolled.isSuccess) {
await actor.createEmbeddedDocuments("Item", [RdDItemSigneDraconique.prepareSigneDraconiqueMeditation(meditation, rolled)])
}
if (rolled.isEPart) {
await actor.updateEmbeddedDocuments('Item', [{ _id: meditation._id, 'system.malus': meditation.system.malus - 1 }])
}
await actor.santeIncDec("fatigue", 2)
}
}
}

View File

@@ -1,3 +1,5 @@
import { ITEM_TYPES } from "../constants.js"
import { ReglesOptionnelles } from "../settings/regles-optionnelles.js"
import { DIFF, ROLL_TYPE_TACHE } from "./roll-constants.mjs"
import { PART_TACHE } from "./roll-part-tache.mjs"
import { RollType } from "./roll-type.mjs"
@@ -16,4 +18,26 @@ export class RollTypeTache extends RollType {
onSelect(rollData) {
this.setDiffType(rollData, DIFF.AUCUN)
}
callbacks(rollOptions) { return [ async r => await RollTypeTache.$onRollTache(r, rollOptions)] }
static async $onRollTache(rollData, rollOptions) {
const actor = rollData.active.actor
const tache = rollData.current[PART_TACHE].tache
if (ReglesOptionnelles.isUsing("appliquer-fatigue")) {
await actor.santeIncDec("fatigue", tache.system.fatigue)
}
rollData.current[PART_TACHE].tache = await tache.update({
'system.points_de_tache_courant': tache.system.points_de_tache_courant + rollData.rolled.ptTache,
'system.nb_jet_succes': tache.system.nb_jet_succes + (rollData.rolled.isSuccess ? 1 : 0),
'system.nb_jet_echec': tache.system.nb_jet_echec + (rollData.rolled.isSuccess ? 0 : 1),
'system.difficulte': tache.system.difficulte - (rollData.rolled.isETotal ? 1 : 0),
}, {render:true})
if (rollOptions?.onRollAutomate) {
await rollOptions.onRollAutomate(rollData)
}
}
}

View File

@@ -18,7 +18,6 @@ export class RollType {
isAllowed(rollData) { return rollData.type.allowed == undefined || rollData.type.allowed.includes(this.code) }
visible(rollData) { return true }
title(rollData) { return this.code }
isSelected(rollData) { return rollData.type.current == this.code }
@@ -52,7 +51,7 @@ export class RollType {
this.setRollDataType(rollData)
}
getResult(rollData) {
return undefined
}
callbacks(rollOptions) { return [] }
getResult(rollData) { return undefined }
}