'})
}
}
static isOwnerPlayer(document) {
- return document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
+ return document && document.testUserPermission && document.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)
}
static isFirstOwnerPlayer(document) {
- if (!document.testUserPermission) {
+ if (!document?.testUserPermission) {
return false
}
return game.users.find(u => document.testUserPermission(u, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) == game.user
@@ -252,15 +249,15 @@ export class Misc {
* @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id
*/
static isFirstConnectedGM() {
- return game.user == Misc.firstConnectedGM();
+ return game.user == game.users.activeGM
}
static hasConnectedGM() {
- return Misc.firstConnectedGM();
+ return game.users.activeGM
}
static firstConnectedGMId() {
- return Misc.firstConnectedGM()?.id;
+ return game.users.activeGM?.id;
}
/* -------------------------------------------- */
diff --git a/module/moral/apprecier.mjs b/module/moral/apprecier.mjs
index 38d77895..384b4baf 100644
--- a/module/moral/apprecier.mjs
+++ b/module/moral/apprecier.mjs
@@ -1,3 +1,4 @@
+import { ChatUtility } from "../chat-utility.js"
import { ITEM_TYPES } from "../constants.js"
import { SANS_COMPETENCE } from "../item/base-items.js"
import { Misc } from "../misc.js"
@@ -149,7 +150,8 @@ export class Apprecier {
callbacks: [
async r => await this.onRollAppreciation(r),
...rollCallbacks
- ]
+ ],
+ onRollDone: RollDialog.onRollDoneClose
})
}
@@ -166,7 +168,10 @@ export class Apprecier {
async rollMoral(moral = undefined) {
if (this.raisons.length > 0) {
- ui.notifications.info('Pas de jet de moral:' + Misc.concat(this.raisons.map(r => `
- ${r}`)))
+ ChatMessage.create({
+ whisper: ChatUtility.getOwners(this.actor),
+ content: 'Pas de jet de moral:' + Misc.concat(this.raisons.map(r => `
- ${r}`))
+ })
return
}
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 80e85b56..8bfe4dfb 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -19,6 +19,7 @@ import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll/roll-constants.mjs"
import { OptionsAvancees, ROLL_DIALOG_V2 } from "./settings/options-avancees.js";
import { MappingCreatureArme } from "./item/mapping-creature-arme.mjs";
import { RollBasicParts } from "./roll/roll-basic-parts.mjs";
+import { Distance } from "./combat/distance.mjs";
/* -------------------------------------------- */
const premierRoundInit = [
@@ -153,7 +154,7 @@ export class RdDCombatManager extends Combat {
alias: combatant.token?.name,
sound: CONFIG.sounds.dice,
},
- flavor: `${combatant.token?.name} a une initiatyive de ${init.value} : ${messageOptions.info}
`
+ flavor: `${combatant.token?.name} a une initiative de ${init.value} : ${messageOptions.info}
`
},
messageOptions);
init.roll.toMessage(messageData, { rollMode, create: true });
@@ -625,63 +626,22 @@ export class RdDCombat {
}
else {
const defenderToken = canvas.tokens.get(this.defenderTokenId)
- const dist = this.distance(_token, defenderToken)
- const isVisible = this.isVisible(_token, defenderToken)
- const portee = this._ajustementPortee(dist, rollData.arme)
- const taille = this._ajustementTaille(this.defender)
- const activite = this._ajustementMouvement(this.defender)
- const total = [portee, taille, activite].map(it => it.diff).filter(d => !Number.isNaN(d)).reduce(Misc.sum(), 0)
- ChatMessage.create({
- content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.hbs', {
+ const info = foundry.utils.mergeObject(
+ {
rollData: rollData,
attacker: _token,
- isVisible: isVisible,
defender: defenderToken,
- distance: dist,
- portee: portee,
- taille: taille,
- activite: activite,
- total: total
- }),
+ },
+ Distance.ajustements(_token, defenderToken, { arme: rollData.arme, main: rollData.competence.system.categorie })
+ )
+ ChatMessage.create({
+ content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-info-distance.hbs', info),
whisper: ChatUtility.getGMs()
})
}
}
}
- isVisible(token, defenderToken) {
- return canvas.effects.visibility.testVisibility(defenderToken.center, { object: token })
- }
-
- distance(token, defenderToken) {
- return Number(canvas.grid.measureDistances([{ ray: new Ray(token.center, defenderToken.center) }], { gridSpaces: false })).toFixed(1);
- }
-
- _ajustementPortee(dist, arme) {
- if (dist <= arme.system.portee_courte) return { msg: "courte", diff: 0 };
- if (dist <= arme.system.portee_moyenne) return { msg: "moyenne", diff: -3 };
- if (dist <= arme.system.portee_extreme) return { msg: "extrême", diff: -5 };
- return { msg: "inatteignable", diff: -10 };
- }
-
- _ajustementTaille(actor) {
- if (actor.isVehicule()) return { msg: "véhicule", diff: 0 }
- const taille = actor.getCaracByName('TAILLE')?.value ?? 1;
- if (taille <= 1) return { msg: "souris", diff: -8 };
- if (taille <= 3) return { msg: "chat", diff: -4 };
- if (taille <= 5) return { msg: "chien", diff: -2 };
- if (taille <= 15) return { msg: "humanoïde", diff: 0 };
- if (taille <= 20) return { msg: "ogre", diff: 2 };
- return { msg: "gigantesque", diff: 4 };
- }
-
- _ajustementMouvement(defender) {
- if (defender.getSurprise(true) != '') return { msg: "immobile (surprise)", diff: 0 };
- if (game.combat?.combatants.find(it => it.actorId == defender.id)) return { msg: "en mouvement (combat)", diff: -4 };
- return { msg: "à déterminer (0 immobile, -3 actif, -4 en mouvement, -5 en zig-zag)", diff: -3 };
- }
-
-
async attaqueV2() {
if (!await this.attacker.accorder(this.defender, 'avant-attaque')) {
return
@@ -699,7 +659,6 @@ export class RdDCombat {
}
async doRollAttaque(rollData, callbacks = []) {
- // TODO V2 await this.proposerAjustementTirLancer(rollData)
return await RollDialog.create(rollData, {
onRollDone: RollDialog.onRollDoneClose,
callbacks: [
@@ -740,7 +699,7 @@ export class RdDCombat {
}
_socketSendMessageDefenseV2(paramChatDefense) {
- game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_defense_v2", data: {paramChatDefense} })
+ game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_defense_v2", data: { paramChatDefense } })
}
static async onMsgDefenseV2(msg) {
@@ -1084,7 +1043,7 @@ export class RdDCombat {
}
async defenseV2(attackerRoll, callbacks = []) {
- // this._prepareParade(attackerRoll, arme, competence);
+
await this.doRollDefense({
ids: {
actorId: this.defender.id,
diff --git a/module/rdd-possession-v2.mjs b/module/rdd-possession-v2.mjs
index b1594dad..bd83ab11 100644
--- a/module/rdd-possession-v2.mjs
+++ b/module/rdd-possession-v2.mjs
@@ -178,7 +178,7 @@ export class RdDPossessionV2 {
static async onRollDefense(defense) {
if (defense.rolled.isEchec) {
- await RdDPossessionV2.addPointPossession(defense.opponent.actor, defense.active.actor)
+ await RdDPossessionV2.addPointPossession(defense.opponent, defense.active)
}
RdDPossessionV2.resetPossession(defense)
}
diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js
index 1303882a..652359a8 100644
--- a/module/rdd-tmr-dialog.js
+++ b/module/rdd-tmr-dialog.js
@@ -13,7 +13,6 @@ import { Draconique } from "./tmr/draconique.js";
import { HtmlUtility } from "./html-utility.js";
import { ReglesOptionnelles } from "./settings/regles-optionnelles.js";
import { RdDDice } from "./rdd-dice.js";
-import { STATUSES } from "./settings/status-effects.js";
import { RdDRencontre } from "./item/rencontre.js";
import { ITEM_TYPES } from "./constants.js";
import { Misc } from "./misc.js";
@@ -187,7 +186,9 @@ export class RdDTMRDialog extends Dialog {
async restoreTMRAfterAction() {
this.subdialog = undefined
await this.maximize()
- this.bringToFront()
+ if (this.rendered) {
+ this.bringToFront()
+ }
}
forceTMRContinueAction() {
@@ -348,10 +349,10 @@ export class RdDTMRDialog extends Dialog {
return false
}
this.descenteTMR = true
- await await this.actor.quitterTMR(message, this.viewOnly, this.cumulFatigue)
- this.pixiTMR.close();
+ await await this.actor?.quitterTMR(message, this.viewOnly, this.cumulFatigue)
+ this.pixiTMR?.close()
this.pixiTMR = undefined
- await super.close();
+ await super.close()
return true
}
diff --git a/module/roll/chat-roll-result.mjs b/module/roll/chat-roll-result.mjs
index 14512801..5fc2eece 100644
--- a/module/roll/chat-roll-result.mjs
+++ b/module/roll/chat-roll-result.mjs
@@ -162,12 +162,18 @@ export default class ChatRollResult {
return undefined
}
+ getActiveActor(roll) {
+ return roll.active?.actor ?? (roll.ids?.actorId ? game.actors.get(roll.ids.actorId) : undefined)
+ }
+
async saveChatMessageRoll(chatMessage, savedRoll) {
await ChatUtility.setMessageData(chatMessage, 'rollData', savedRoll)
}
loadChatMessageRoll(chatMessage) {
- return ChatUtility.getMessageData(chatMessage, 'rollData')
+ const savedRoll = ChatUtility.getMessageData(chatMessage, 'rollData')
+ RollBasicParts.restore(savedRoll)
+ return savedRoll
}
async updateChatMessage(chatMessage, savedRoll) {
@@ -184,21 +190,19 @@ export default class ChatRollResult {
event.preventDefault()
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- const actor = game.actors.get(savedRoll.ids.actorId)
+ const actor = this.getActiveActor(savedRoll)
Misc.doIfOwner(actor, it => it.rollAppelChance(
() => this.onAppelChanceSuccess(savedRoll, chatMessage),
() => this.onAppelChanceEchec(savedRoll, chatMessage))
)
}
- async onAppelChanceSuccess(savedRoll, chatMessage) {
- const reRoll = foundry.utils.duplicate(savedRoll)
- console.log('onAppelChanceSuccess savedRoll', savedRoll)
+ async onAppelChanceSuccess(reRoll, chatMessage) {
reRoll.type.retry = true
await this.updateChatMessage(chatMessage, reRoll)
- const callbacks = [ChatUtility.remover(chatMessage)]
- // TODO: annuler les effets
+ const callbacks = [ChatUtility.remover(chatMessage)]
+ // TODO: annuler les effets...
switch (reRoll.type.current) {
case ROLL_TYPE_DEFENSE:
this.getCombat(reRoll)?.doRollDefense(reRoll, callbacks)
@@ -212,9 +216,9 @@ export default class ChatRollResult {
}
}
- async onAppelChanceEchec(savedRoll, chatMessage) {
- savedRoll.type.retry = true
- await this.updateChatMessage(chatMessage, savedRoll)
+ async onAppelChanceEchec(reRoll, chatMessage) {
+ reRoll.type.retry = true
+ await this.updateChatMessage(chatMessage, reRoll)
}
onClickAppelDestinee(event) {
@@ -222,7 +226,7 @@ export default class ChatRollResult {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- const actor = game.actors.get(savedRoll.ids.actorId)
+ const actor = this.getActiveActor(savedRoll)
Misc.doIfOwner(actor, it => it.appelDestinee(async () => {
const reRoll = foundry.utils.duplicate(savedRoll)
@@ -235,36 +239,41 @@ export default class ChatRollResult {
async onClickDefense(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- RollBasicParts.restore(savedRoll)
- const attackerRoll = savedRoll.attackerRoll
- RollDialog.loadRollData(attackerRoll)
- this.getCombat(attackerRoll)?.defenseV2(attackerRoll,
- [ChatUtility.remover(chatMessage)]
- )
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, it => {
+ const attackerRoll = savedRoll.attackerRoll
+ RollDialog.loadRollData(attackerRoll)
+ this.getCombat(attackerRoll)?.defenseV2(attackerRoll,
+ [ChatUtility.remover(chatMessage)]
+ )
+ })
}
async onClickDefensePossession(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- await RdDPossessionV2.rollDefensePossession(savedRoll, chatMessage)
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, it => RdDPossessionV2.rollDefensePossession(savedRoll, chatMessage))
}
async onClickMarquerPointPossession(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- RollBasicParts.restore(savedRoll)
- await RdDPossessionV2.onMarquerPointPossession(savedRoll)
- ChatUtility.remover(chatMessage)()
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async it => {
+ await RdDPossessionV2.onMarquerPointPossession(savedRoll)
+ ChatUtility.remover(chatMessage)()
+ })
}
async onClickEncaissement(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const isMessageDemande = ChatUtility.getMessageData(chatMessage, 'demande-defense')
const savedRoll = this.loadChatMessageRoll(chatMessage)
- const attaque = savedRoll.attackerRoll
- const defenderToken = savedRoll.ids.actorTokenId ? canvas.tokens.get(savedRoll.ids.actorTokenId) : undefined
- const defender = defenderToken?.actor ?? game.actors.get(savedRoll.ids.actorId)
- Misc.doIfOwner(defender, async defender => {
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async defender => {
+ const defenderToken = savedRoll.active.token
+ const attaque = savedRoll.attackerRoll
const attackerToken = savedRoll.ids.opponentTokenId ? canvas.tokens.get(savedRoll.ids.opponentTokenId) : undefined
const attacker = attackerToken?.actor ?? game.actors.get(savedRoll.ids.opponentId)
switch (attaque.dmg.mortalite) {
@@ -290,9 +299,8 @@ export default class ChatRollResult {
async onClickRecul(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- // TODO: gestion sur token non liés?
- const defender = game.actors.get(savedRoll.ids.actorId)
- Misc.doIfOwner(defender, async defender => {
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async defender => {
const attacker = game.actors.get(savedRoll.ids.opponentId)
savedRoll.done.recul = await defender.encaisserRecul(attacker.getForce(), savedRoll.attackerRoll.dmg.dmgArme)
await this.updateChatMessage(chatMessage, savedRoll)
@@ -303,42 +311,54 @@ export default class ChatRollResult {
const choix = event.currentTarget.attributes['data-particuliere'].value
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- savedRoll.particuliere = choix
- savedRoll.particulieres = [RDD_CONFIG.particuliere[choix]]
- await this.updateChatMessage(chatMessage, savedRoll)
- await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll)
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async it => {
+ savedRoll.particuliere = choix
+ savedRoll.particulieres = [RDD_CONFIG.particuliere[choix]]
+ await this.updateChatMessage(chatMessage, savedRoll)
+ await this.getCombat(savedRoll)?.onAttaqueV2(savedRoll)
+ })
}
async onClickFaireGouter(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- if (!savedRoll.type.retry) {
- savedRoll.type.retry = true
- await this.updateChatMessage(chatMessage, savedRoll)
- }
- await new RollTypeCuisine().onFaireGouter(savedRoll)
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async it => {
+ if (!savedRoll.type.retry) {
+ savedRoll.type.retry = true
+ await this.updateChatMessage(chatMessage, savedRoll)
+ }
+ await new RollTypeCuisine().onFaireGouter(savedRoll)
+ })
}
async onClickApprecier(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- await Apprecier.onClickApprecier(savedRoll)
+ Apprecier.onClickApprecier(savedRoll)
}
async onClickMonteeTMR(event, mode) {
const chatMessage = ChatUtility.getChatMessage(event)
const savedRoll = this.loadChatMessageRoll(chatMessage)
- if (await new RollTypeMeditation().onMonteeTMR(savedRoll, mode)) {
- savedRoll.done.meditation = true
- await this.updateChatMessage(chatMessage, savedRoll)
- }
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async it => {
+ if (await new RollTypeMeditation().onMonteeTMR(savedRoll, mode)) {
+ savedRoll.done.meditation = true
+ await this.updateChatMessage(chatMessage, savedRoll)
+ }
+ })
}
async onClickTirerMaladresse(event) {
const chatMessage = ChatUtility.getChatMessage(event)
const typeMaladresse = event.currentTarget.attributes['data-maladresse'].value
const savedRoll = this.loadChatMessageRoll(chatMessage)
- savedRoll.maladresse = await RdDRollTables.getMaladresse({ arme: typeMaladresse == 'avec-arme', toChat: false })
- savedRoll.type.retry = true
- await this.updateChatMessage(chatMessage, savedRoll)
+ const actor = this.getActiveActor(savedRoll)
+ Misc.doIfOwner(actor, async it => {
+ savedRoll.maladresse = await RdDRollTables.getMaladresse({ arme: typeMaladresse == 'avec-arme', toChat: false })
+ savedRoll.type.retry = true
+ await this.updateChatMessage(chatMessage, savedRoll)
+ })
}
}
diff --git a/module/roll/roll-constants.mjs b/module/roll/roll-constants.mjs
index 4e2103af..ac77d16f 100644
--- a/module/roll/roll-constants.mjs
+++ b/module/roll/roll-constants.mjs
@@ -13,8 +13,7 @@ export const ROLL_TYPE_TACHE = 'tache'
export const ATTAQUE_ROLL_TYPES = [ROLL_TYPE_ATTAQUE]
export const COMBAT_ROLL_TYPES = [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE]
export const DEMIREVE_ROLL_TYPES = [ROLL_TYPE_SORT]
-export const DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_ATTAQUE, ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_JEU]
-
+export const DEFAULT_ROLL_TYPES = [ROLL_TYPE_COMP, ROLL_TYPE_TACHE, ROLL_TYPE_MEDITATION, ROLL_TYPE_CUISINE, ROLL_TYPE_OEUVRE, ROLL_TYPE_JEU]
export const DIFF = {
LIBRE: 'libre',
diff --git a/module/roll/roll-dialog-adapter.mjs b/module/roll/roll-dialog-adapter.mjs
index 21c7c0b4..1f620f1d 100644
--- a/module/roll/roll-dialog-adapter.mjs
+++ b/module/roll/roll-dialog-adapter.mjs
@@ -50,7 +50,7 @@ export class RollDialogAdapter {
rolled.factorHtml = Misc.getFractionOneN(rollData.current.sign.diviseur)
if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rolled.caracValue, rolled.roll)
- rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
+ rolled.ajustementNecessaire = rolled.niveauNecessaire - rolled.finalLevel
}
return rolled
}
@@ -92,10 +92,6 @@ export class RollDialogAdapter {
if (rollData.current[PART_APPELMORAL]?.checked) {
rollData.use.moral = true
}
- if (ReglesOptionnelles.isUsing("afficher-colonnes-reussite")) {
- rolled.niveauNecessaire = RdDResolutionTable.findNiveauNecessaire(rollData.selectedCarac.value, rolled.roll)
- rolled.ajustementNecessaire = rolled.niveauNecessaire - diff
- }
rollData.ajustements = rollData.ajustements.map(a => { return { label: a.label, value: a.value } })
}
diff --git a/module/roll/roll-dialog.mjs b/module/roll/roll-dialog.mjs
index 6076d4e9..d57af4f7 100644
--- a/module/roll/roll-dialog.mjs
+++ b/module/roll/roll-dialog.mjs
@@ -310,8 +310,10 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
rollData.refs = foundry.utils.mergeObject(rollData.refs ?? {}, Object.fromEntries(ROLL_PARTS.map(p => [p.code, {}])));
rollData.options = rollData.options ?? { rollMode: game.settings.get("core", "rollMode") }
- ROLL_PARTS.forEach(p => p.initialize(rollData))
- ROLL_PARTS.filter(p => p.isValid(rollData))
+ ROLL_PARTS.forEach(p => RollDialog.$initializeRollPart(rollData, p.code))
+ ROLL_PARTS
+ .filter(p => RollDialog.$isIntersecting(allowed, p.rollTypes))
+ .filter(p => p.isValid(rollData))
.forEach(p => {
p.restore(rollData)
p.loadRefs(rollData)
@@ -320,6 +322,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
return rollData
}
+ static $initializeRollPart(rollData, code) {
+ rollData.refs[code] = rollData.refs[code] ?? {}
+ rollData.current[code] = rollData.current[code] ?? {}
+ rollData.selected[code] = rollData.selected[code] ?? {}
+ }
+
+ static $isIntersecting(allowed, included) { return included ? included.find(it => allowed.includes(it)) : true }
+
static saveParts(rollData, impacts = undefined) {
if (rollData == undefined) {
return undefined
@@ -327,6 +337,7 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
function saveBasics(from, to) {
if (from) {
+ to.ids = from.ids
to.passeArme = from.passeArme
to.rolled = from.rolled
to.particuliere = from.particuliere
@@ -337,15 +348,14 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
to.attackerRoll = {}
saveBasics(from.attackerRoll, to.attackerRoll)
}
+ if (from.current) {
+ // stockage de current
+ ROLL_PARTS.filter(p => p.isActive(from))
+ .forEach(p => p.storeClean(from, target))
+ }
}
}
-
const target = RollBasicParts.initFrom(rollData)
- if (rollData.current) {
- // stockage de current
- ROLL_PARTS.filter(p => p.isActive(rollData))
- .forEach(p => p.storeClean(rollData, target))
- }
saveBasics(rollData, target)
if (impacts) {
target.reverse = {
@@ -540,6 +550,9 @@ export default class RollDialog extends HandlebarsApplicationMixin(ApplicationV2
static loadRollData(roll) {
RollDialog.$prepareRollData(roll)
+ if (roll.attackerRoll) {
+ RollDialog.$prepareRollData(roll.attackerRoll)
+ }
RollDialog.calculAjustement(roll)
roll.v2 = true
return roll
diff --git a/module/roll/roll-part-attaque.mjs b/module/roll/roll-part-attaque.mjs
index 40cd8924..8c869f3a 100644
--- a/module/roll/roll-part-attaque.mjs
+++ b/module/roll/roll-part-attaque.mjs
@@ -1,3 +1,4 @@
+import { Distance } from "../combat/distance.mjs"
import { RDD_CONFIG } from "../constants.js"
import { ATTAQUE_TYPE_MELEE } from "../item/arme.js"
import { RdDBonus } from "../rdd-bonus.js"
@@ -10,7 +11,7 @@ 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"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_ATTAQUE = 'attaque'
@@ -25,12 +26,14 @@ export class RollPartAttaque extends RollPartSelect {
get code() { return PART_ATTAQUE }
get section() { return ROLLDIALOG_SECTION.CHOIX }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_ATTAQUE) }
+ get rollTypes() { return [ROLL_TYPE_ATTAQUE] }
+
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_ATTAQUE) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
const attaques = rollData.active.actor.listAttaques()
- refs.all = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData.active.actor))
+ refs.all = attaques.map(it => RollPartAttaque.$extractAttaque(it, rollData))
this.filterAttaquesEmpoignade(rollData)
refs.tactiques = TACTIQUES
if (refs.attaques.length > 0) {
@@ -64,10 +67,11 @@ export class RollPartAttaque extends RollPartSelect {
choices(refs) { return refs.attaques }
- static $extractAttaque(attaque, actor) {
+ static $extractAttaque(attaque, rollData) {
attaque.key = `${attaque.action}::${attaque.label}`
attaque.tactique = TACTIQUES[0]
attaque.initialDiff = attaque.comp?.system.default_diffLibre ?? 0
+ attaque.distance = Distance.ajustements(rollData.active?.token, rollData.opponent?.token, attaque)
return attaque
}
@@ -102,20 +106,22 @@ export class RollPartAttaque extends RollPartSelect {
}
async _onRender(rollDialog, context, options) {
+ const inputDiff = rollDialog.element.querySelector(`roll-section[name="diff"] input[name="diff"]`)
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 utiliserDagueEmpoignade = rollDialog.element.querySelector(`roll-section[name="${this.code}"] a.utiliser-dague-empoignade`)
- const current = this.getCurrent(rollDialog.rollData)
+ const rollData = rollDialog.rollData
+ const current = this.getCurrent(rollData)
- selectAttaque.addEventListener("change", e => {
+ selectAttaque?.addEventListener("change", e => {
const selectOptions = e.currentTarget.options
const index = selectOptions.selectedIndex
- this.$selectAttaque(rollDialog.rollData, selectOptions[index]?.value)
+ this.$selectAttaque(rollData, selectOptions[index]?.value)
rollDialog.render()
})
- selectTactique.addEventListener("change", e => {
+ selectTactique?.addEventListener("change", e => {
const selectOptions = e.currentTarget.options
const index = selectOptions.selectedIndex
current.tactique = RdDBonus.find(selectOptions[index]?.value)
@@ -128,9 +134,11 @@ export class RollPartAttaque extends RollPartSelect {
})
utiliserDagueEmpoignade?.addEventListener("click", e => {
e.preventDefault()
- const rollData = rollDialog.rollData
this.utiliserDagueEmpoignade(rollData)
})
+ inputDiff?.addEventListener("input", e => {
+ this.getRefs(rollData).all.forEach(attaque => attaque.initialDiff = undefined)
+ })
}
utiliserDagueEmpoignade(rollData) {
@@ -153,8 +161,11 @@ export class RollPartAttaque extends RollPartSelect {
case PART_CARAC: return part.filterCaracs(rollData, [current.carac.key])
case PART_COMP: return part.filterComps(rollData, [current.comp.name])
case PART_DIFF: {
- if (current.initialDiff) {
- part.setDiff(rollData, { type: DIFF.ATTAQUE, value: current.initialDiff })
+ if (Distance.typeAttaqueDistance(current)) {
+ part.setDiff(rollData, { type: DIFF.DEFAUT })
+ }
+ else {
+ part.setDiff(rollData, { type: DIFF.ATTAQUE, diff: current.initialDiff })
current.initialDiff = undefined
}
break
diff --git a/module/roll/roll-part-cuisine.mjs b/module/roll/roll-part-cuisine.mjs
index cedfaef9..17e33c63 100644
--- a/module/roll/roll-part-cuisine.mjs
+++ b/module/roll/roll-part-cuisine.mjs
@@ -4,7 +4,7 @@ import { ROLL_TYPE_CUISINE } 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 } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_CUISINE = "cuisine"
@@ -16,8 +16,10 @@ export class RollPartCuisine extends RollPartSelect {
get code() { return PART_CUISINE }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ get rollTypes() { return [ROLL_TYPE_CUISINE] }
+
isValid(rollData) { return rollData.active.actor.isPersonnage() }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_CUISINE) }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_CUISINE) }
restore(rollData) {
super.restore(rollData)
diff --git a/module/roll/roll-part-defense.mjs b/module/roll/roll-part-defense.mjs
index ab13927e..5add0f61 100644
--- a/module/roll/roll-part-defense.mjs
+++ b/module/roll/roll-part-defense.mjs
@@ -1,4 +1,5 @@
-import { ITEM_TYPES, RDD_CONFIG } from "../constants.js"
+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"
@@ -7,7 +8,7 @@ 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"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_DEFENSE = 'defense'
@@ -16,56 +17,59 @@ export class RollPartDefense extends RollPartSelect {
get code() { return PART_DEFENSE }
get section() { return ROLLDIALOG_SECTION.CHOIX }
- isValid(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) && rollData.attackerRoll != undefined }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_DEFENSE) && rollData.attackerRoll != undefined }
-
- static getDiffAttaque(attackerRoll) {
- // TODO: rollDataV2?
- return attackerRoll.diffLibre;
- }
+ 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.isDistance = [ATTAQUE_TYPE.TIR, ATTAQUE_TYPE.LANCER].find(it => it == attackerRoll?.main)
+ 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.isDistance == ATTAQUE_TYPE.TIR || isEmpoignadeEnCours)
+ const esquives = (refs.distance?.typeAttaque == ATTAQUE_TYPE.TIR || isEmpoignadeEnCours)
? []
: defenseur.getCompetencesEsquive()
const parades = isEmpoignade
? [RdDItemArme.empoignade(defenseur)]
- : defenseur.items.filter(it => it.isParade() && (!refs.isDistance || it.isBouclier()))
+ : defenseur.items.filter(it => it.isParade() && (!refs.distance || it.isBouclier()))
refs.defenses = [
- ...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur)),
- ...parades.map(it => RollPartDefense.$extractParade(it, attackerRoll?.arme, defenseur))
+ ...esquives.map(it => RollPartDefense.$extractEsquive(it, defenseur, attackerRoll)),
+ ...parades.map(it => RollPartDefense.$extractParade(it, defenseur, attackerRoll))
]
this.$selectDefense(rollData)
}
- static $extractEsquive(esquive, defenseur) {
- return {
+ static $extractEsquive(esquive, defenseur, attackerRoll) {
+ const defense = {
key: esquive.id,
label: esquive.name,
img: esquive.img,
- // TODO: carac pour créatures
+ // 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, armeAttaque, defenseur) {
+ static $extractParade(armeDefense, defenseur, attackerRoll) {
+ const armeAttaque = attackerRoll?.arme
const comp = (ITEM_TYPES.competencecreature == armeDefense.type)
? armeDefense
: defenseur.getCompetence(armeDefense.system.competence)
- return {
+ const defense = {
key: armeDefense.id,
label: 'Parade ' + armeDefense.name,
img: armeDefense.img,
@@ -78,6 +82,13 @@ export class RollPartDefense extends RollPartSelect {
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) {
@@ -107,10 +118,11 @@ export class RollPartDefense extends RollPartSelect {
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, [current.carac])
- case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
+ 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.isArmeDisparate(rollData), current.forceRequise)
}
@@ -129,16 +141,19 @@ export class RollPartDefense extends RollPartSelect {
getDiffDefense(rollData) {
const refs = this.getRefs(rollData)
- if (refs.isDistance || !rollData.attackerRoll) {
- // TODO: Déterminer la difficulté de parade
- return { diff: 0, type: DIFF.LIBRE }
+ 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 }
}
- else {
+ 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 }
}
}
diff --git a/module/roll/roll-part-ecailles.mjs b/module/roll/roll-part-ecailles.mjs
index af09a27d..99659bbf 100644
--- a/module/roll/roll-part-ecailles.mjs
+++ b/module/roll/roll-part-ecailles.mjs
@@ -3,6 +3,7 @@ import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
import { RollPartCheckbox } from "./roll-part-checkbox.mjs"
import { PART_DEFENSE } from "./roll-part-defense.mjs"
+import { RollPart } from "./roll-part.mjs"
const ECAILLES = "ecailles"
@@ -10,8 +11,9 @@ export class RollPartEcailles extends RollPartCheckbox {
get code() { return ECAILLES }
+ get rollTypes() { return [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE] }
isValid(rollData) {
- return this.isRollType(rollData, ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE)
+ return RollPart.isRollType(rollData, ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE)
}
visible(rollData) {
@@ -25,9 +27,9 @@ export class RollPartEcailles extends RollPartCheckbox {
}
getArme(rollData) {
- return this.isRollType(rollData, ROLL_TYPE_ATTAQUE)
+ return RollPart.isRollType(rollData, ROLL_TYPE_ATTAQUE)
? rollData.current[PART_ATTAQUE]?.arme
- : this.isRollType(rollData, ROLL_TYPE_DEFENSE)
+ : RollPart.isRollType(rollData, ROLL_TYPE_DEFENSE)
? rollData.current[PART_DEFENSE]?.arme
: undefined
}
diff --git a/module/roll/roll-part-empoignade-taille.mjs b/module/roll/roll-part-empoignade-taille.mjs
index 80779522..bebce150 100644
--- a/module/roll/roll-part-empoignade-taille.mjs
+++ b/module/roll/roll-part-empoignade-taille.mjs
@@ -1,7 +1,8 @@
import { RDD_CONFIG } from "../constants.js"
import { RdDEmpoignade } from "../rdd-empoignade.js"
-import { COMBAT_ROLL_TYPES } from "./roll-constants.mjs"
+import { COMBAT_ROLL_TYPES, ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { RollPartCheckbox } from "./roll-part-checkbox.mjs"
+import { RollPart } from "./roll-part.mjs"
const EMPOIGNADE_TAILLE = "empoignade-taille"
@@ -9,6 +10,7 @@ export class RollPartEmpoignadeTaille extends RollPartCheckbox {
get code() { return EMPOIGNADE_TAILLE }
+ get rollTypes() { return [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE] }
isValid(rollData) {
return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId)
}
diff --git a/module/roll/roll-part-empoignade.mjs b/module/roll/roll-part-empoignade.mjs
index fd7a5f0f..f0cf4827 100644
--- a/module/roll/roll-part-empoignade.mjs
+++ b/module/roll/roll-part-empoignade.mjs
@@ -1,9 +1,10 @@
import { RDD_CONFIG } from "../constants.js"
import { ATTAQUE_TYPE_MELEE } from "../item/arme.js"
import { RdDEmpoignade } from "../rdd-empoignade.js"
-import { ROLL_TYPE_ATTAQUE } from "./roll-constants.mjs"
+import { ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE } from "./roll-constants.mjs"
import { PART_ATTAQUE } from "./roll-part-attaque.mjs"
import { RollPartCheckbox } from "./roll-part-checkbox.mjs"
+import { RollPart } from "./roll-part.mjs"
const EMPOIGNADE = "empoignade"
@@ -11,6 +12,7 @@ export class RollPartEmpoignade extends RollPartCheckbox {
get code() { return EMPOIGNADE }
+ get rollTypes() { return [ROLL_TYPE_ATTAQUE, ROLL_TYPE_DEFENSE] }
isValid(rollData) {
return RdDEmpoignade.isCombatantEmpoignade(rollData.ids.opponentId, rollData.ids.opponentTokenId) &&
!RdDEmpoignade.isCombatantEmpoignade(rollData.ids.actorId, rollData.ids.actorTokenId)
diff --git a/module/roll/roll-part-jeu.mjs b/module/roll/roll-part-jeu.mjs
index f20d13b5..7405c6b5 100644
--- a/module/roll/roll-part-jeu.mjs
+++ b/module/roll/roll-part-jeu.mjs
@@ -4,9 +4,10 @@ import { ROLL_TYPE_JEU } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP, RollPartComp } from "./roll-part-comp.mjs"
import { RollPartSelect } from "./roll-part-select.mjs"
-import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
import { RdDItem } from "../item.js"
import { Misc } from "../misc.js"
+import { Grammar } from "../grammar.js"
export const PART_JEU = "jeu"
@@ -17,8 +18,9 @@ export class RollPartJeu extends RollPartSelect {
get code() { return PART_JEU }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ get rollTypes() { return [ROLL_TYPE_JEU] }
isValid(rollData) { return rollData.active.actor.isPersonnage() }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_JEU) }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_JEU) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
@@ -88,14 +90,19 @@ export class RollPartJeu extends RollPartSelect {
static forceCompJeu(rollData) {
const jeu = rollData.current[PART_JEU].base ?? rollData.current[PART_JEU].comp
- rollData.refs[PART_COMP].comps = [jeu].map(it => RollPartComp.extractComp(it))
+ if (jeu){
+ rollData.refs[PART_COMP].comps = [jeu].map(it => RollPartComp.extractComp(it))
+ }
+ else {
+ rollData.refs[PART_COMP].comps = rollData.refs[PART_COMP].all.filter(comp => comp.label == 'Jeu')
+ }
rollData.current[PART_COMP] = rollData.refs[PART_COMP].comps[0]
}
async _onRender(rollDialog, context, options) {
const selectjeu = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-jeu"]`)
- selectjeu.addEventListener("change", e => {
+ selectjeu?.addEventListener("change", e => {
const selectOptions = e.currentTarget.options
const index = selectOptions.selectedIndex
this.$selectJeu(rollDialog.rollData, selectOptions[index]?.value)
diff --git a/module/roll/roll-part-meditation.mjs b/module/roll/roll-part-meditation.mjs
index 6c93f33d..1a14be8d 100644
--- a/module/roll/roll-part-meditation.mjs
+++ b/module/roll/roll-part-meditation.mjs
@@ -4,10 +4,10 @@ import { CARACS } from "../rdd-carac.js"
import { RdDTimestamp } from "../time/rdd-timestamp.js"
import { TMRUtility } from "../tmr-utility.js"
import { ROLL_TYPE_MEDITATION } from "./roll-constants.mjs"
-import { PART_CARAC, RollPartCarac } from "./roll-part-carac.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 } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_MEDITATION = "meditation"
@@ -18,6 +18,10 @@ export class RollPartMeditation extends RollPartSelect {
get code() { return PART_MEDITATION }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ get rollTypes() { return [ROLL_TYPE_MEDITATION] }
+ isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_MEDITATION) }
+
store(rollData, targetData) {
const current = this.getCurrent(rollData)
this.setSaved(targetData, {
@@ -29,9 +33,6 @@ export class RollPartMeditation extends RollPartSelect {
})
}
- 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)
const actor = rollData.active.actor
@@ -69,7 +70,7 @@ export class RollPartMeditation extends RollPartSelect {
}
getMalusEchecs(rollData) {
- return this.getCurrent(rollData).meditation.system.malus
+ return this.getCurrent(rollData).meditation?.system.malus ?? 0
}
getAjustements(rollData) {
@@ -89,16 +90,18 @@ export class RollPartMeditation extends RollPartSelect {
$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))
+ if (current.meditation){
+ 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"]`)
- selectMeditation.addEventListener("change", e => {
+ selectMeditation?.addEventListener("change", e => {
const selectOptions = e.currentTarget.options
const index = selectOptions.selectedIndex
this.$selectMeditation(rollDialog.rollData, selectOptions[index]?.value)
@@ -110,7 +113,7 @@ export class RollPartMeditation extends RollPartSelect {
setupListenerCondition(rollDialog, inputName) {
const checkbox = rollDialog.element.querySelector(`roll-section[name="${this.code}"] input[name="${inputName}"]`)
- checkbox.addEventListener("change", e => {
+ checkbox?.addEventListener("change", e => {
const current = this.getCurrent(rollDialog.rollData)
current[inputName] = e.currentTarget.checked
rollDialog.render()
diff --git a/module/roll/roll-part-oeuvre.mjs b/module/roll/roll-part-oeuvre.mjs
index a8dd637a..60f8e940 100644
--- a/module/roll/roll-part-oeuvre.mjs
+++ b/module/roll/roll-part-oeuvre.mjs
@@ -5,7 +5,7 @@ import { ROLL_TYPE_OEUVRE } 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 } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_OEUVRE = "oeuvre"
@@ -35,8 +35,9 @@ export class RollPartOeuvre extends RollPartSelect {
get code() { return PART_OEUVRE }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ get rollTypes() { return [ROLL_TYPE_OEUVRE] }
isValid(rollData) { return rollData.active.actor.isPersonnage() }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_OEUVRE) }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_OEUVRE) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
@@ -75,7 +76,7 @@ export class RollPartOeuvre extends RollPartSelect {
async _onRender(rollDialog, context, options) {
const selectOeuvre = rollDialog.element.querySelector(`roll-section[name="${this.code}"] select[name="select-oeuvre"]`)
- selectOeuvre.addEventListener("change", e => {
+ selectOeuvre?.addEventListener("change", e => {
const selectOptions = e.currentTarget.options
const index = selectOptions.selectedIndex
this.$selectOeuvre(rollDialog.rollData, selectOptions[index]?.value)
@@ -88,7 +89,7 @@ export class RollPartOeuvre extends RollPartSelect {
const current = this.getCurrent(rollData)
switch (part.code) {
case PART_CARAC: return part.filterCaracs(rollData, current.caracs)
- case PART_COMP: return part.filterComps(rollData,[current.comp?.name])
+ case PART_COMP: return part.filterComps(rollData, [current.comp?.name])
}
}
return undefined
diff --git a/module/roll/roll-part-possession.mjs b/module/roll/roll-part-possession.mjs
index 7e146ddd..6e3ae905 100644
--- a/module/roll/roll-part-possession.mjs
+++ b/module/roll/roll-part-possession.mjs
@@ -5,7 +5,7 @@ import { ROLL_TYPE_POSSESSION } 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 } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_POSSESSION = "possession"
@@ -17,7 +17,8 @@ export class RollPartPossession extends RollPartSelect {
get name() { return 'Possession' }
get section() { return ROLLDIALOG_SECTION.CHOIX }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_POSSESSION) }
+ get rollTypes() { return [ROLL_TYPE_POSSESSION] }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_POSSESSION) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
@@ -61,10 +62,10 @@ export class RollPartPossession extends RollPartSelect {
rollDialog.render()
})
button?.addEventListener("click", async e => {
- e.preventDefault()
- await RdDPossessionV2.createPossessionIfMissing(rollData.active, rollData.opponent)
- rollDialog.render()
- })
+ e.preventDefault()
+ await RdDPossessionV2.createPossessionIfMissing(rollData.active, rollData.opponent)
+ rollDialog.render()
+ })
}
$selectPossession(rollData, key) {
diff --git a/module/roll/roll-part-sort.mjs b/module/roll/roll-part-sort.mjs
index 182f7e79..97e3c5ea 100644
--- a/module/roll/roll-part-sort.mjs
+++ b/module/roll/roll-part-sort.mjs
@@ -2,7 +2,7 @@ import { ITEM_TYPES } from "../constants.js"
import { ROLL_TYPE_SORT } from "./roll-constants.mjs"
import { PART_CARAC } from "./roll-part-carac.mjs"
import { PART_COMP } from "./roll-part-comp.mjs"
-import { ROLLDIALOG_SECTION } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
import { TMRUtility } from "../tmr-utility.js"
import { RdDItemSort } from "../item-sort.js"
import { RollPartSelect } from "./roll-part-select.mjs"
@@ -19,8 +19,9 @@ export class RollPartSort extends RollPartSelect {
get code() { return PART_SORT }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ get rollTypes() { return [ROLL_TYPE_SORT] }
isValid(rollData) { return rollData.active.actor.isPersonnage() && rollData.active.actor.isHautRevant() }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_SORT) }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_SORT) }
restore(rollData) {
const saved = this.getSaved(rollData)
diff --git a/module/roll/roll-part-tache.mjs b/module/roll/roll-part-tache.mjs
index cfde3f82..bd8fcd97 100644
--- a/module/roll/roll-part-tache.mjs
+++ b/module/roll/roll-part-tache.mjs
@@ -3,7 +3,7 @@ import { ROLL_TYPE_TACHE } 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 } from "./roll-part.mjs"
+import { ROLLDIALOG_SECTION, RollPart } from "./roll-part.mjs"
export const PART_TACHE = "tache"
@@ -12,8 +12,9 @@ export class RollPartTache extends RollPartSelect {
get code() { return PART_TACHE }
get section() { return ROLLDIALOG_SECTION.CHOIX }
+ get rollTypes() { return [ROLL_TYPE_TACHE] }
isValid(rollData) { return rollData.active.actor.isPersonnage() }
- visible(rollData) { return this.isRollType(rollData, ROLL_TYPE_TACHE) }
+ visible(rollData) { return RollPart.isRollType(rollData, ROLL_TYPE_TACHE) }
loadRefs(rollData) {
const refs = this.getRefs(rollData)
diff --git a/module/roll/roll-part.mjs b/module/roll/roll-part.mjs
index a76611eb..bd4c30d9 100644
--- a/module/roll/roll-part.mjs
+++ b/module/roll/roll-part.mjs
@@ -1,3 +1,5 @@
+import { ALL_ROLL_TYPES } from "./roll-dialog.mjs"
+
export const ROLLDIALOG_SECTION = {
ACTION: 'action',
CARAC: 'carac',
@@ -19,17 +21,6 @@ export class RollPart {
/** le template handlebars pour affichage */
get template() { return `systems/foundryvtt-reve-de-dragon/templates/roll/roll-part-${this.code}.hbs` }
- initialize(rollData) {
- if (rollData.refs[this.code] == undefined) {
- rollData.refs[this.code] = {}
- }
- if (rollData.current[this.code] == undefined) {
- rollData.current[this.code] = {}
- }
- if (rollData.selected[this.code] == undefined) {
- rollData.selected[this.code] = {}
- }
- }
/** l'acteur actif du jet */
getActor(rollData) { return rollData.active.actor }
/** le conteneur de données du RollPart */
@@ -78,8 +69,8 @@ export class RollPart {
* @returns une chaîne vide si rien ne doit être affiché
*/
title() { return '' }
- isRollType(rollData, ...type) { return type.includes(rollData.type.current)}
-
+ static isRollType(rollData, ...type) { return type.includes(rollData.type.current) }
+ get rollTypes() { return undefined }
isActive(rollData) { return this.isValid(rollData) && this.visible(rollData) }
isValid(rollData) { return true }
visible(rollData) { return true }
diff --git a/module/roll/roll-type-meditation.mjs b/module/roll/roll-type-meditation.mjs
index c3238487..7d0f6879 100644
--- a/module/roll/roll-type-meditation.mjs
+++ b/module/roll/roll-type-meditation.mjs
@@ -11,7 +11,7 @@ export class RollTypeMeditation extends RollType {
visible(rollData) { return rollData.active.actor.isHautRevant() }
title(rollData) {
const current = rollData.current[PART_MEDITATION]
- const theme = current?.meditation.system.theme
+ const theme = current?.meditation?.system.theme
return theme ? 'médite sur ' + theme : 'médite'
}
@@ -23,7 +23,7 @@ export class RollTypeMeditation extends RollType {
static async $onRollMeditation(rollData) {
const actor = rollData.active.actor
- const meditation = rollData.current.meditation.meditation
+ const meditation = rollData.current.meditation?.meditation
const rolled = rollData.rolled
if (meditation && rolled) {
if (rolled.isSuccess) {
diff --git a/module/roll/roll-type-oeuvre.mjs b/module/roll/roll-type-oeuvre.mjs
index b3680308..a7410b22 100644
--- a/module/roll/roll-type-oeuvre.mjs
+++ b/module/roll/roll-type-oeuvre.mjs
@@ -10,7 +10,10 @@ export class RollTypeOeuvre extends RollType {
visible(rollData) { return rollData.active.actor.isPersonnage() }
title(rollData) {
const current = rollData.current[PART_OEUVRE]
- return `${current.art.action} ${current.label}`
+ if (current.art) {
+ return `${current.art.action} ${current.label}`
+ }
+ return 'interprête une oeuvre'
}
onSelect(rollData) {
diff --git a/module/time/rdd-timestamp.js b/module/time/rdd-timestamp.js
index bdf4107a..3353af37 100644
--- a/module/time/rdd-timestamp.js
+++ b/module/time/rdd-timestamp.js
@@ -173,10 +173,10 @@ export class RdDTimestamp {
}
filtered = DEFINITION_HEURES.filter(it => Grammar.toLowerCaseNoAccentNoSpace(it.label).includes(heure));
if (filtered.length > 0) {
- filtered.sort(Misc.ascending(h => h.label.length));
+ filtered.sort(Misc.ascending(h => h.label.length))
return filtered[0]
}
- return undefined;
+ return undefined
}
/**
diff --git a/packs_src/voyageurs/personnage_le_Cuisinier_Haut_R_vant_X9d5McdSAT1Ivp39.yml b/packs_src/voyageurs/personnage_le_Cuisinier_Haut_R_vant_X9d5McdSAT1Ivp39.yml
index 4cf35f3c..08cd61d8 100644
--- a/packs_src/voyageurs/personnage_le_Cuisinier_Haut_R_vant_X9d5McdSAT1Ivp39.yml
+++ b/packs_src/voyageurs/personnage_le_Cuisinier_Haut_R_vant_X9d5McdSAT1Ivp39.yml
@@ -3344,7 +3344,7 @@ items:
- _id: yQ5mkpLoQH0g9g5P
name: Huile
type: munition
- img: systems/foundryvtt-reve-de-dragon/icons/liquides/liquide__neutre.webp
+ img: systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_neutre.webp
effects: []
folder: null
sort: 300001
diff --git a/packs_src/voyageurs/personnage_le_Haut_R_vant_Dilettante_4bI9HX4oomMEXrOT.yml b/packs_src/voyageurs/personnage_le_Haut_R_vant_Dilettante_4bI9HX4oomMEXrOT.yml
index 41e6bad5..4fa15e49 100644
--- a/packs_src/voyageurs/personnage_le_Haut_R_vant_Dilettante_4bI9HX4oomMEXrOT.yml
+++ b/packs_src/voyageurs/personnage_le_Haut_R_vant_Dilettante_4bI9HX4oomMEXrOT.yml
@@ -3634,7 +3634,7 @@ items:
name: Décoction de méritoine
type: munition
sort: 300001
- img: systems/foundryvtt-reve-de-dragon/icons/liquides/liquide__neutre.webp
+ img: systems/foundryvtt-reve-de-dragon/icons/liquides/liquide_neutre.webp
effects: []
system:
description: 1 mesure (20cl) de décoction de Méritoine.
diff --git a/templates/chat-demande-defense.hbs b/templates/chat-demande-defense.hbs
index 28ef4eb6..a62f515f 100644
--- a/templates/chat-demande-defense.hbs
+++ b/templates/chat-demande-defense.hbs
@@ -31,8 +31,8 @@
Se défendre
- {{#if (or (eq attackerRoll.attaqueCategorie 'tir') (eq attackerRoll.attaqueCategorie 'lancer'))}}
- (difficulté à déterminer)
+ {{#if attackerRoll.current.attaque.isDistance}}
+ (à distance)
{{else}}
à {{attackerRoll.current.diff.value}}
{{/if}}
diff --git a/templates/roll/result/partial-infojet.hbs b/templates/roll/result/partial-infojet.hbs
index 18992ba5..316d27e0 100644
--- a/templates/roll/result/partial-infojet.hbs
+++ b/templates/roll/result/partial-infojet.hbs
@@ -26,7 +26,8 @@
{{/if}}
{{rolled.roll}} : {{rolled.quality}}
- {{#if rolled.ajustementNecessaire}}
- (Réussite si {{plusMoins rolled.niveauNecessaire}} / avec niveau {{plusMoins rolled.ajustementNecessaire}})
+ {{log 'rolled' rolled}}
+ {{#if (regle-optionnelle 'afficher-colonnes-reussite')}}
+ (Réussite colonne {{plusMoins rolled.niveauNecessaire}} / avec ajustement {{plusMoins rolled.ajustementNecessaire}})
{{/if}}
\ No newline at end of file
diff --git a/templates/roll/roll-part-attaque.hbs b/templates/roll/roll-part-attaque.hbs
index 2b1bf3e9..c5dc9af7 100644
--- a/templates/roll/roll-part-attaque.hbs
+++ b/templates/roll/roll-part-attaque.hbs
@@ -9,12 +9,14 @@
{{/if}}
+ {{#unless current.distance}}
+ {{/unless}}
{{#if (and refs.isEmpoignadeEnCours (eq current.arme.system.competence 'Dague'))}}
@@ -63,7 +65,24 @@
{{/if}}
+ {{#if current.distance}}
+
-
+
+ Attaque à distance {{current.main}} difficulté proposée de {{current.distance.total}} à valider par le Gardien
+
+
+
+
+ - Avec les murs et la lumière, la cible
+ {{#if current.distance.isVisible}}est{{else}}n'est pas{{/if}} visible.
+
+ - La cible est à une distance {{#if (lt current.distance.distance 0)}}indéterminée{{else}}indicative de {{numberFormat current.distance.distance decimals=1}} mètres{{/if}}.
+ - Portée {{current.distance.portee.msg}} : {{current.distance.portee.diff}}
+ - Taille {{current.distance.taille.msg}}: {{current.distance.taille.diff}}
+ - Mouvement {{current.distance.activite.msg}}: {{current.distance.activite.diff}}
+
+
+ {{/if}}
\ No newline at end of file
diff --git a/templates/roll/roll-part-defense.hbs b/templates/roll/roll-part-defense.hbs
index e2d7e59d..0680fb19 100644
--- a/templates/roll/roll-part-defense.hbs
+++ b/templates/roll/roll-part-defense.hbs
@@ -3,10 +3,27 @@
-
+ {{#if refs.defenses.length}}
+
+ {{else}}
+
+ Aucune défense disponible {{#if refs.distance}}contre cette attaque à distance {{refs.distance.typeAttaque}}{{/if}}
+
+ {{/if}}
+ {{#if refs.distance}}
+ Défense contre une attaque à distance {{refs.distance.typeAttaque}}
+ {{log 'defense' this}}
+ {{#if current.distance.ajustementDefense}}
+ {{current.distance.ajustementDefense.label}}: {{current.distance.ajustementDefense.value}}
+ {{/if}}
+ {{#if current.distance.ajustementBouclier}}
+ {{current.distance.ajustementBouclier.label}}: {{current.distance.ajustementBouclier.value}}
+ {{/if}}
+ Activité du défenseur: 0 si immobile et prêt, -3 si actif (à ajouter manuellement aux conditions)
+ {{/if}}
{{#if rollData.active.effets}}
diff --git a/templates/roll/roll-part-jeu.hbs b/templates/roll/roll-part-jeu.hbs
index 4e32398a..79cb87ac 100644
--- a/templates/roll/roll-part-jeu.hbs
+++ b/templates/roll/roll-part-jeu.hbs
@@ -2,6 +2,7 @@
+ {{#if refs.jeux}}
\ No newline at end of file
diff --git a/templates/roll/roll-part-meditation.hbs b/templates/roll/roll-part-meditation.hbs
index f9be4cbf..e842058b 100644
--- a/templates/roll/roll-part-meditation.hbs
+++ b/templates/roll/roll-part-meditation.hbs
@@ -2,6 +2,7 @@
+{{#if refs.meditations}}
Rêve actuel: {{rollData.active.actor.system.reve.reve.value}}
@@ -71,4 +72,9 @@
{{current.meditation.system.veture}}
+ {{else}}
+
+ Le haut-rêvant ne connait aucune méditation
+
+ {{/if}}
diff --git a/templates/roll/roll-part-oeuvre.hbs b/templates/roll/roll-part-oeuvre.hbs
index 887b70f7..459c0cbe 100644
--- a/templates/roll/roll-part-oeuvre.hbs
+++ b/templates/roll/roll-part-oeuvre.hbs
@@ -2,15 +2,21 @@
-
-
+ {{#if refs.oeuvres}}
+
+
+ {{#if current.oeuvre}}
+ {{plusMoins current.value}}
+ {{/if}}
+
{{#if current.oeuvre}}
- {{plusMoins current.value}}
+ {{> (concat 'roll-oeuvre-' current.oeuvre.type)}}
{{/if}}
-
- {{#if current.oeuvre}}
- {{> (concat 'roll-oeuvre-' current.oeuvre.type)}}
+ {{else}}
+
+ Le personnage ne connait aucune œuvre à interpréter
+
{{/if}}
\ No newline at end of file