forked from public/foundryvtt-reve-de-dragon
		
	Gestion des maladresses #68
This commit is contained in:
		| @@ -71,7 +71,7 @@ export class RdDItemArme extends Item { | |||||||
|   static mainsNues() { |   static mainsNues() { | ||||||
|     const mainsNues = { |     const mainsNues = { | ||||||
|       name: "Mains nues", |       name: "Mains nues", | ||||||
|       data: { unemain: true, deuxmains: false, dommages: 0, dommagesReels: 0, mortalite: 'non-mortel', competence: 'Corps à corps' } |       data: { unemain: true, deuxmains: false, dommages: 0, dommagesReels: 0, mortalite: 'non-mortel', competence: 'Corps à corps', sansArme:true } | ||||||
|     }; |     }; | ||||||
|     return mainsNues |     return mainsNues | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import { Misc } from "./misc.js"; | |||||||
| import { RdDBonus } from "./rdd-bonus.js"; | import { RdDBonus } from "./rdd-bonus.js"; | ||||||
| import { RdDResolutionTable } from "./rdd-resolution-table.js"; | import { RdDResolutionTable } from "./rdd-resolution-table.js"; | ||||||
| import { RdDRoll } from "./rdd-roll.js"; | import { RdDRoll } from "./rdd-roll.js"; | ||||||
|  | import { RdDRollTables } from "./rdd-rolltables.js"; | ||||||
|  |  | ||||||
| export class RdDCombat { | export class RdDCombat { | ||||||
|  |  | ||||||
| @@ -135,8 +136,10 @@ export class RdDCombat { | |||||||
|     console.log("RdDCombat.attaque >>>", rollData); |     console.log("RdDCombat.attaque >>>", rollData); | ||||||
|  |  | ||||||
|     const dialog = await RdDRoll.create(this.attacker, rollData, |     const dialog = await RdDRoll.create(this.attacker, rollData, | ||||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html', |       { | ||||||
|         options: { height: 540 } }, { |         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html', | ||||||
|  |         options: { height: 540 } | ||||||
|  |       }, { | ||||||
|       name: 'jet-attaque', |       name: 'jet-attaque', | ||||||
|       label: 'Attaque: ' + (arme ? arme.name : competence.name), |       label: 'Attaque: ' + (arme ? arme.name : competence.name), | ||||||
|       callbacks: [ |       callbacks: [ | ||||||
| @@ -146,7 +149,7 @@ export class RdDCombat { | |||||||
|         { condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) }, |         { condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) }, | ||||||
|         { condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) }, |         { condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) }, | ||||||
|       ] |       ] | ||||||
|     } ); |     }); | ||||||
|     dialog.render(true); |     dialog.render(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -230,9 +233,9 @@ export class RdDCombat { | |||||||
|     // Final chat message |     // Final chat message | ||||||
|     let chatOptions = { |     let chatOptions = { | ||||||
|       content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" |       content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" | ||||||
|       + "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat |         + "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat | ||||||
|       + RdDResolutionTable.explain(rollData.rolled) |         + RdDResolutionTable.explain(rollData.rolled) | ||||||
|       + explications |         + explications | ||||||
|     } |     } | ||||||
|     ChatUtility.chatWithRollMode(chatOptions, this.attacker.name) |     ChatUtility.chatWithRollMode(chatOptions, this.attacker.name) | ||||||
|  |  | ||||||
| @@ -309,11 +312,11 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _onAttaqueEchecTotal(rollData) { |   async _onAttaqueEchecTotal(rollData) { | ||||||
|     console.log("RdDCombat.onEchecTotal >>>", rollData); |     console.log("RdDCombat.onEchecTotal >>>", rollData); | ||||||
|     // TODO: proposer un résultat d'échec total |  | ||||||
|     let chatOptions = { |     let chatOptions = { | ||||||
|       content: "<strong>Echec total à l'attaque!</strong>" |       content: "<strong>Echec total à l'attaque!</strong> " | ||||||
|  |         + await RdDRollTables.getMaladresse({ arme: rollData.arme && !rollData.arme.data.sansArme }) | ||||||
|     } |     } | ||||||
|     ChatUtility.chatWithRollMode(chatOptions, this.attacker.name) |     ChatUtility.chatWithRollMode(chatOptions, this.attacker.name) | ||||||
|   } |   } | ||||||
| @@ -347,8 +350,10 @@ export class RdDCombat { | |||||||
|     let rollData = this._prepareParade(attackerRoll, arme); |     let rollData = this._prepareParade(attackerRoll, arme); | ||||||
|  |  | ||||||
|     const dialog = await RdDRoll.create(this.defender, rollData, |     const dialog = await RdDRoll.create(this.defender, rollData, | ||||||
|       { html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html', |       { | ||||||
|         options: { height: 540 } }, { |         html: 'systems/foundryvtt-reve-de-dragon/templates/dialog-competence.html', | ||||||
|  |         options: { height: 540 } | ||||||
|  |       }, { | ||||||
|       name: 'jet-parade', |       name: 'jet-parade', | ||||||
|       label: 'Parade: ' + (arme ? arme.name : rollData.competence.name), |       label: 'Parade: ' + (arme ? arme.name : rollData.competence.name), | ||||||
|       callbacks: [ |       callbacks: [ | ||||||
| @@ -358,7 +363,7 @@ export class RdDCombat { | |||||||
|         { condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) }, |         { condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) }, | ||||||
|         { condition: RdDCombat.isEchecTotal, action: r => this._onParadeEchecTotal(r) }, |         { condition: RdDCombat.isEchecTotal, action: r => this._onParadeEchecTotal(r) }, | ||||||
|       ] |       ] | ||||||
|     } ); |     }); | ||||||
|     dialog.render(true); |     dialog.render(true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -432,9 +437,9 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|     let chatOptions = { |     let chatOptions = { | ||||||
|       content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" |       content: "<strong>Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + "</strong>" | ||||||
|       + "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat |         + "<br>Difficultés <strong>libre : " + rollData.diffLibre + "</strong> / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat | ||||||
|       + RdDResolutionTable.explain(rollData.rolled) |         + RdDResolutionTable.explain(rollData.rolled) | ||||||
|       + "<br><strong>Attaque parée!</strong>" |         + "<br><strong>Attaque parée!</strong>" | ||||||
|     } |     } | ||||||
|     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) |     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) | ||||||
|     await this.computeRecul(rollData, false); |     await this.computeRecul(rollData, false); | ||||||
| @@ -442,11 +447,11 @@ export class RdDCombat { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _onParadeEchecTotal(rollData) { |   async _onParadeEchecTotal(rollData) { | ||||||
|     console.log("RdDCombat._onParadeEchecTotal >>>", rollData); |     console.log("RdDCombat._onParadeEchecTotal >>>", rollData); | ||||||
|     // TODO: proposer un résultat d'échec total |  | ||||||
|     let chatOptions = { |     let chatOptions = { | ||||||
|       content: "<strong>Echec total à la parade!</strong>" |       content: "<strong>Echec total à la parade!</strong> " | ||||||
|  |         + await RdDRollTables.getMaladresse({ arme: rollData.arme && !rollData.arme.data.sansArme }) | ||||||
|     } |     } | ||||||
|     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) |     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) | ||||||
|   } |   } | ||||||
| @@ -536,15 +541,15 @@ export class RdDCombat { | |||||||
|         + RdDResolutionTable.explain(rollData.rolled) |         + RdDResolutionTable.explain(rollData.rolled) | ||||||
|         + "<br><strong>Attaque esquivée!</strong>" |         + "<br><strong>Attaque esquivée!</strong>" | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) |     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   _onEsquiveEchecTotal(rollData) { |   async _onEsquiveEchecTotal(rollData) { | ||||||
|     console.log("RdDCombat._onEsquiveEchecTotal >>>", rollData); |     console.log("RdDCombat._onEsquiveEchecTotal >>>", rollData); | ||||||
|     // TODO: proposer un résultat d'échec total |  | ||||||
|     let chatOptions = { |     let chatOptions = { | ||||||
|       content: "<strong>Echec total à l'esquive'!</strong>" |       content: "<strong>Echec total à l'esquive'!</strong> " | ||||||
|  |         + await RdDRollTables.getMaladresse({ arme: false }) | ||||||
|     } |     } | ||||||
|     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) |     ChatUtility.chatWithRollMode(chatOptions, this.defender.name) | ||||||
|   } |   } | ||||||
| @@ -573,12 +578,12 @@ export class RdDCombat { | |||||||
|  |  | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async computeDeteriorationArme( rollData ) { |   async computeDeteriorationArme(rollData) { | ||||||
|     const attackerRoll = rollData.attackerRoll; |     const attackerRoll = rollData.attackerRoll; | ||||||
|     if (rollData.arme && attackerRoll) { // C'est une parade |     if (rollData.arme && attackerRoll) { // C'est une parade | ||||||
|       // Est-ce que l'attaque est une particulière, en force ou charge et que l'attaque n'en est pas une ? |       // Est-ce que l'attaque est une particulière, en force ou charge et que l'attaque n'en est pas une ? | ||||||
|       if ( (rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.tactique == 'charge') |       if ((rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.tactique == 'charge') | ||||||
|       && !rollData.rolled.isPart ) { |         && !rollData.rolled.isPart) { | ||||||
|         const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor; |         const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor; | ||||||
|         let resistance = Misc.toInt(rollData.arme.data.resistance); |         let resistance = Misc.toInt(rollData.arme.data.resistance); | ||||||
|         let msg = ""; |         let msg = ""; | ||||||
| @@ -586,44 +591,49 @@ export class RdDCombat { | |||||||
|         let resistRoll = await RdDResolutionTable.rollData({ |         let resistRoll = await RdDResolutionTable.rollData({ | ||||||
|           caracValue: resistance, |           caracValue: resistance, | ||||||
|           finalLevel: - dmg, |           finalLevel: - dmg, | ||||||
|           showDice: false}); |           showDice: false | ||||||
|  |         }); | ||||||
|         if (resistRoll.isSuccess) { // Perte de résistance |         if (resistRoll.isSuccess) { // Perte de résistance | ||||||
|           msg = "Votre " + rollData.arme.name + " tient le choc de la parade. " |           msg = "Votre " + rollData.arme.name + " tient le choc de la parade. " | ||||||
|         } else { |         } else { | ||||||
|           resistance -= dmg; |           resistance -= dmg; | ||||||
|           if ( resistance <= 0 ) { |           if (resistance <= 0) { | ||||||
|             this.defender.deleteEmbeddedEntity("OwnedItem", rollData.arme._id); |             this.defender.deleteEmbeddedEntity("OwnedItem", rollData.arme._id); | ||||||
|             msg = "Sous la violence de la parade, votre " + rollData.arme.name + " s'est brisée sous le coup!"; |             msg = "Sous la violence de la parade, votre " + rollData.arme.name + " s'est brisée sous le coup!"; | ||||||
|           } else { |           } else { | ||||||
|             this.defender.updateEmbeddedEntity("OwnedItem", {_id: rollData.arme._id, 'data.resistance': resistance });  |             this.defender.updateEmbeddedEntity("OwnedItem", { _id: rollData.arme._id, 'data.resistance': resistance }); | ||||||
|             msg = "En parant, vous endommagez votre " + rollData.arme.name + ", qui perd  " + dmg + " de résistance. "; |             msg = "En parant, vous endommagez votre " + rollData.arme.name + ", qui perd  " + dmg + " de résistance. "; | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         // Jet de désarmement |         // Jet de désarmement | ||||||
|         if (resistance > 0 && !rollData.arme.name.toLowerCase().includes('bouclier') ) { // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) |         if (resistance > 0 && !rollData.arme.name.toLowerCase().includes('bouclier')) { // Si l'arme de parade n'est pas un bouclier, jet de désarmement (p.132) | ||||||
|           let desarme = await RdDResolutionTable.rollData({ |           let desarme = await RdDResolutionTable.rollData({ | ||||||
|             caracValue: this.defender.data.data.carac.force.value, |             caracValue: this.defender.data.data.carac.force.value, | ||||||
|             finalLevel: Misc.toInt(rollData.competence.data.niveau) - dmg, |             finalLevel: Misc.toInt(rollData.competence.data.niveau) - dmg, | ||||||
|             showDice: false}); |             showDice: false | ||||||
|           if ( desarme.isEchec) { |           }); | ||||||
|  |           if (desarme.isEchec) { | ||||||
|             msg += "Vous ne parvenez pas à garder votre arme en main, elle tombe au sol à vos pieds"; |             msg += "Vous ne parvenez pas à garder votre arme en main, elle tombe au sol à vos pieds"; | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         ChatMessage.create( { content: msg, |         ChatMessage.create({ | ||||||
|                               user: game.user._id, |           content: msg, | ||||||
|                               whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM") ] } ); |           user: game.user._id, | ||||||
|  |           whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM")] | ||||||
|  |         }); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   async computeRecul( rollData, encaisser = undefined ) { // Calcul du recul (p. 132) |   async computeRecul(rollData, encaisser = undefined) { // Calcul du recul (p. 132) | ||||||
|     if ( rollData.arme || encaisser ) {  |     if (rollData.arme || encaisser) { | ||||||
|       if ( (rollData.attackerRoll.particuliereAttaque && rollData.attackerRoll.particuliereAttaque == 'force') || rollData.attackerRoll.tactique == 'charge') { |       if ((rollData.attackerRoll.particuliereAttaque && rollData.attackerRoll.particuliereAttaque == 'force') || rollData.attackerRoll.tactique == 'charge') { | ||||||
|         let reculNiveau = Misc.toInt(this.defender.data.data.carac.taille.value) - (rollData.attackerRoll.forceValue+rollData.attackerRoll.arme.data.dommagesReels); |         let reculNiveau = Misc.toInt(this.defender.data.data.carac.taille.value) - (rollData.attackerRoll.forceValue + rollData.attackerRoll.arme.data.dommagesReels); | ||||||
|         let recul = await RdDResolutionTable.rollData({ |         let recul = await RdDResolutionTable.rollData({ | ||||||
|           caracValue: 10, |           caracValue: 10, | ||||||
|           finalLevel: reculNiveau, |           finalLevel: reculNiveau, | ||||||
|           showDice: false}); |           showDice: false | ||||||
|  |         }); | ||||||
|  |  | ||||||
|         let msg = ""; |         let msg = ""; | ||||||
|         if (recul.isSuccess) { |         if (recul.isSuccess) { | ||||||
| @@ -632,16 +642,19 @@ export class RdDCombat { | |||||||
|           let chute = await RdDResolutionTable.rollData({ |           let chute = await RdDResolutionTable.rollData({ | ||||||
|             caracValue: this.defender.data.data.carac.agilite.value, |             caracValue: this.defender.data.data.carac.agilite.value, | ||||||
|             finalLevel: reculNiveau, |             finalLevel: reculNiveau, | ||||||
|             showDice: false}); |             showDice: false | ||||||
|           if ( !chute.isSuccess || recul.isETotal ) { |           }); | ||||||
|  |           if (!chute.isSuccess || recul.isETotal) { | ||||||
|             msg = "Sous la violence du coup, vous reculez et chutez au sol ! Vous ne pouvez plus attaquer ce round."; |             msg = "Sous la violence du coup, vous reculez et chutez au sol ! Vous ne pouvez plus attaquer ce round."; | ||||||
|           } else { |           } else { | ||||||
|             msg = "La violence du choc vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round."; |             msg = "La violence du choc vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round."; | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|         ChatMessage.create( {content: msg,  |         ChatMessage.create({ | ||||||
|                       user: game.user._id, |           content: msg, | ||||||
|                       whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM") ] } ); |           user: game.user._id, | ||||||
|  |           whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM")] | ||||||
|  |         }); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -8,7 +8,6 @@ export class RdDRollTables { | |||||||
|     const table = await pack.getEntity(entry._id); |     const table = await pack.getEntity(entry._id); | ||||||
|     const draw = await table.draw({ displayChat: toChat }); |     const draw = await table.draw({ displayChat: toChat }); | ||||||
|     console.log("RdDRollTables", tableName, toChat, ":", draw); |     console.log("RdDRollTables", tableName, toChat, ":", draw); | ||||||
|     console.log("RdDRollTables", tableName, toChat, ":", draw.roll, draw.results); |  | ||||||
|     return draw; |     return draw; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -16,9 +15,25 @@ export class RdDRollTables { | |||||||
|   static async drawItemFromRollTable(tableName, toChat) { |   static async drawItemFromRollTable(tableName, toChat) { | ||||||
|     const draw = await RdDRollTables.genericGetTableResult(tableName, toChat); |     const draw = await RdDRollTables.genericGetTableResult(tableName, toChat); | ||||||
|     const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined; |     const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined; | ||||||
|     const pack = game.packs.get(drawnItemRef.collection); |     if (drawnItemRef.collection) { | ||||||
|     return await pack.getEntity(drawnItemRef.resultId); |       const pack = game.packs.get(drawnItemRef.collection); | ||||||
|  |       return await pack.getEntity(drawnItemRef.resultId); | ||||||
|  |     } | ||||||
|  |     ui.notifications.warn("le tirage ne correspond pas à une entrée d'un Compendium") | ||||||
|  |     return drawnItemRef.text; | ||||||
|   } |   } | ||||||
|  |    | ||||||
|  |   /* -------------------------------------------- */ | ||||||
|  |   static async drawTextFromRollTable(tableName, toChat) { | ||||||
|  |     const draw = await RdDRollTables.genericGetTableResult(tableName, toChat); | ||||||
|  |     const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined; | ||||||
|  |     if (drawnItemRef.collection) { | ||||||
|  |       ui.notifications.warn("le tirage correspond à une entrée d'un Compendium, on attendait un texte") | ||||||
|  |       return await pack.getEntity(drawnItemRef.resultId); | ||||||
|  |     } | ||||||
|  |     return drawnItemRef.text; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /* -------------------------------------------- */ |   /* -------------------------------------------- */ | ||||||
|   static async getSouffle(toChat = true) { |   static async getSouffle(toChat = true) { | ||||||
|     return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat); |     return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat); | ||||||
| @@ -48,4 +63,10 @@ export class RdDRollTables { | |||||||
|   static async getTarot(toChat = true) { |   static async getTarot(toChat = true) { | ||||||
|     return await RdDRollTables.drawItemFromRollTable("Tarot Draconique", toChat); |     return await RdDRollTables.drawItemFromRollTable("Tarot Draconique", toChat); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   static async getMaladresse(options = {toChat: false, arme: false}) { | ||||||
|  |     return await RdDRollTables.drawTextFromRollTable( | ||||||
|  |       options.arme ? "Maladresse armé" : "Maladresses non armé", | ||||||
|  |       options.toChat); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user