diff --git a/changelog.md b/changelog.md index 5fb048db..e9a7cf88 100644 --- a/changelog.md +++ b/changelog.md @@ -4,6 +4,7 @@ - Fix - La montée en TMR fonctionne - ajout d'un status "Force insuffisante" +- clarification des maladresses à l'attaque (en demi surprise, ou à cause d'un échec total) - Nouvelle fenêtre de jets de dés - ajout du statut "Force insuffisante" aux acteurs si la force est insuffisante pour l'arme diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 142795ef..c7f068a3 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -19,6 +19,7 @@ import RollDialog from "./roll/roll-dialog.mjs"; import { PART_DEFENSE } from "./roll/roll-part-defense.mjs"; import { PART_ATTAQUE } from "./roll/roll-part-attaque.mjs"; import { RollDialogAdapter } from "./roll/roll-dialog-adapter.mjs"; +import { ROLL_MODE_ATTAQUE, ROLL_MODE_DEFENSE } from "./roll/roll-constants.mjs"; /* -------------------------------------------- */ const premierRoundInit = [ @@ -559,33 +560,42 @@ export class RdDCombat { /* -------------------------------------------- */ static isEchecTotal(rollData) { - if (!rollData.attackerRoll && rollData.ajustements.surprise.used) { - return rollData.rolled.isEchec && rollData.rolled.code != 'notSign'; + if (rollData.ids /* roll V2*/) { + // TODO: en cas de demi-surprise à l'attaque, tout échec est un echec total. + // TODO: en cas de demi-surprise en défense, pas de changement à la règle de base + return rollData.rolled.isETotal } - return rollData.rolled.isETotal; + if (rollData.mode == ROLL_MODE_ATTAQUE && rollData.surprise == 'demi'){ + // échec normal à l'attaque en demi surprise + return rollData.rolled.isEchec && rollData.rolled.code != 'notSign' + } + return rollData.rolled.isETotal } /* -------------------------------------------- */ static isParticuliere(rollData) { - if (rollData.ids) { + if (rollData.ids /* roll V2*/) { return rollData.rolled.isPart } - if (!rollData.attackerRoll && rollData.ajustements.surprise.used) { - return false; + if (rollData.attackerRoll || !rollData.ajustements.surprise.used) { + return rollData.rolled.isPart } - return rollData.rolled.isPart; + return false } /* -------------------------------------------- */ static isReussite(rollData) { - if (rollData.ids) { - return rollData.rolled.is + if (rollData.ids /* roll V2*/) { + return rollData.rolled.isSuccess + } + if (!rollData.ajustements.surprise.used) { + return rollData.rolled.isSuccess } switch (rollData.ajustements.surprise.used) { - case 'totale': return false; - case 'demi': return rollData.rolled.isSign; + case 'totale': return false + case 'demi': return rollData.rolled.isSign } - return rollData.rolled.isSuccess; + return rollData.rolled.isSuccess } /* -------------------------------------------- */ @@ -692,6 +702,7 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareAttaque(competence, arme) { let rollData = { + mode: ROLL_MODE_ATTAQUE, alias: this.attacker?.getAlias(), passeArme: foundry.utils.randomID(16), mortalite: arme?.system.mortalite, @@ -889,6 +900,7 @@ export class RdDCombat { const choixEchecTotal = await ChatMessage.create({ whisper: ChatUtility.getOwners(this.attacker), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.hbs', { + rolled: attackerRoll.rolled, attackerId: this.attackerId, attacker: this.attacker, attackerToken: this.attackerToken, @@ -984,8 +996,8 @@ export class RdDCombat { this.removeChatMessageActionsPasseArme(rd.passeArme) // defense: esquive / arme de parade / competence de défense if (!RdDCombat.isParticuliere(rd)) - await rd.active.actor.incDecItemUse(rd.current[PART_DEFENSE].defense?.id, ) - await this._onDefenseV2(rd) + await rd.active.actor.incDecItemUse(rd.current[PART_DEFENSE].defense?.id,) + await this._onDefense(rd) }] }) } @@ -994,6 +1006,7 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareParade(attackerRoll, armeParade, competenceParade) { let defenderRoll = { + mode: ROLL_MODE_DEFENSE, alias: this.defender?.getAlias(), passeArme: attackerRoll.passeArme, diffLibre: attackerRoll.diffLibre, @@ -1016,17 +1029,63 @@ export class RdDCombat { return defenderRoll; } - async _onParade(defenderRoll) { - if (RdDCombat.isReussite(defenderRoll)) { - await this._onParadeNormale(defenderRoll) - if (RdDCombat.isParticuliere(defenderRoll)) { - await this._onParadeParticuliere(defenderRoll) + async _onDefense(rollData) { + if (RdDCombat.isReussite(rollData)) { + await this._onDefenseNormale(rollData) + if (RdDCombat.isParticuliere(rollData)) { + await this._onDefenseParticuliere(rollData) } - return } - await this._onParadeEchec(defenderRoll) + else { + await this._onDefenseEchec(rollData) + } } - async _onDefenseV2(defenderRoll) { + + async _onDefenseParticuliere(rollData) { + console.log("RdDCombat._onDefenseParticuliere >>>", rollData); + if (/*TODO: parade?*/!rollData.attackerRoll?.isPart) { + // TODO: attaquant doit jouer résistance et peut être désarmé p132 + ChatUtility.createChatWithRollMode( + { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, + this.defender) + } + ChatUtility.createChatWithRollMode( + { content: "Vous pouvez esquiver une deuxième fois!" }, + this.defender); + } + + async _onDefenseNormale(rollData) { + console.log("RdDCombat._onDefenseNormale >>>", rollData); + // console.log("RdDCombat._onEsquiveNormal >>>", rollData); + // await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-esquive.hbs'); + // this.removeChatMessageActionsPasseArme(rollData.passeArme); + //TODO + await this.computeRecul(rollData); + await this.computeDeteriorationArme(rollData); + await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-parade.hbs'); + this.removeChatMessageActionsPasseArme(rollData.passeArme); + } + + async _onDefenseEchec(rollData) { + console.log("RdDCombat._onDefenseEchec >>>", rollData); + // console.log("RdDCombat._onEsquiveEchec >>>", rollData); + + // await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-esquive.hbs'); + + // this.removeChatMessageActionsPasseArme(rollData.passeArme); + // this._sendMessageDefense(rollData.attackerRoll, rollData, { defense: true }) + + await RdDRollResult.displayRollData(rollData, this.defender, 'chat-resultat-parade.hbs'); + + this.removeChatMessageActionsPasseArme(rollData.passeArme); + this._sendMessageDefense(rollData.attackerRoll, rollData, { defense: true }); + } + + + + + + async _onParade(defenderRoll) { if (RdDCombat.isReussite(defenderRoll)) { await this._onParadeNormale(defenderRoll) if (RdDCombat.isParticuliere(defenderRoll)) { @@ -1096,6 +1155,7 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareEsquive(attackerRoll, competence) { let rollData = { + mode: ROLL_MODE_DEFENSE, alias: this.defender.getAlias(), passeArme: attackerRoll.passeArme, diffLibre: attackerRoll.diffLibre, diff --git a/module/roll/roll-dialog-adapter.mjs b/module/roll/roll-dialog-adapter.mjs index 55cadde3..540962b5 100644 --- a/module/roll/roll-dialog-adapter.mjs +++ b/module/roll/roll-dialog-adapter.mjs @@ -4,8 +4,9 @@ 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 { RdDItemArme } from "../item/arme.js"; import { RdDBonus } from "../rdd-bonus.js"; +import { ROLL_MODE_ATTAQUE } from "./roll-constants.mjs"; /* -------------------------------------------- */ export class RollDialogAdapter { @@ -36,7 +37,9 @@ export class RollDialogAdapter { } async rollChances(rollData, chances) { - const rolled = await RdDResolutionTable.rollChances(chances, rollData.current.sign, rollData.current.resultat) + const rolled = await RdDResolutionTable.rollChances(chances, + rollData.current.sign, + rollData.current.resultat) rolled.caracValue = rollData.current.carac.value rolled.finalLevel = rollData.current.totaldiff rolled.bonus = rollData.current.bonus ?? 0 diff --git a/module/roll/roll-part-defense.mjs b/module/roll/roll-part-defense.mjs index cd40a957..dad5a4a6 100644 --- a/module/roll/roll-part-defense.mjs +++ b/module/roll/roll-part-defense.mjs @@ -47,6 +47,7 @@ export class RollPartDefense extends RollPartSelect { img: esquive.img, // TODO: carac pour créatures carac: defenseur.isPersonnage() ? CARACS.DEROBEE : esquive.name, + verb: "esquive", comp: esquive } } @@ -61,6 +62,7 @@ export class RollPartDefense extends RollPartSelect { img: armeDefense.img, // TODO: carac pour créatures carac: defenseur.isPersonnage() ? CARACS.MELEE : comp.name, + verb: "pare", comp: comp, arme: armeDefense, forceRequise: armeDefense ? RdDItemArme.valeurMain(armeDefense.system.force ?? 0, RdDItemArme.getMainAttaque(comp)) : 0, diff --git a/templates/chat-demande-attaque-etotal.hbs b/templates/chat-demande-attaque-etotal.hbs index 2364ddc5..ef751081 100644 --- a/templates/chat-demande-attaque-etotal.hbs +++ b/templates/chat-demande-attaque-etotal.hbs @@ -1,5 +1,11 @@
-

Echec total en attaque

+

Maladresse à l'attaque + {{#if rolled.isETotal}} + (échec total) + {{else}} + (échec en demi-surprise) + {{/if}} +


{{#if (eq attacker.type 'personnage')}} {{#unless essais.attaqueChance}} diff --git a/templates/chat-infojet.hbs b/templates/chat-infojet.hbs index f1c14ff5..696c607d 100644 --- a/templates/chat-infojet.hbs +++ b/templates/chat-infojet.hbs @@ -2,7 +2,6 @@ {{rolled.caracValue}} à {{plusMoins rolled.finalLevel}} - {{log rolled}} {{#if (and rolled.factorHtml (gt rolled.factorHtml 1))}} ×{{{rolled.factorHtml}}} = {{rolled.score}}%