diff --git a/module/item-arme.js b/module/item-arme.js
index ce733b5b..026af806 100644
--- a/module/item-arme.js
+++ b/module/item-arme.js
@@ -71,7 +71,7 @@ export class RdDItemArme extends Item {
static mainsNues() {
const mainsNues = {
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
}
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 296f8638..55b6a2f8 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -5,6 +5,7 @@ import { Misc } from "./misc.js";
import { RdDBonus } from "./rdd-bonus.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDRoll } from "./rdd-roll.js";
+import { RdDRollTables } from "./rdd-rolltables.js";
export class RdDCombat {
@@ -99,7 +100,7 @@ export class RdDCombat {
}
return rollData.rolled.isEchec;
}
-
+
/* -------------------------------------------- */
static isEchecTotal(rollData) {
if (rollData.arme && rollData.surprise == 'demi') {
@@ -107,7 +108,7 @@ export class RdDCombat {
}
return rollData.rolled.isETotal;
}
-
+
/* -------------------------------------------- */
static isParticuliere(rollData) {
if (rollData.arme && rollData.surprise) {
@@ -115,7 +116,7 @@ export class RdDCombat {
}
return rollData.rolled.isPart;
}
-
+
/* -------------------------------------------- */
static isReussite(rollData) {
switch (rollData.surprise) {
@@ -135,8 +136,10 @@ export class RdDCombat {
console.log("RdDCombat.attaque >>>", 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',
label: 'Attaque: ' + (arme ? arme.name : competence.name),
callbacks: [
@@ -146,7 +149,7 @@ export class RdDCombat {
{ condition: RdDCombat.isEchec, action: r => this._onAttaqueEchec(r) },
{ condition: RdDCombat.isEchecTotal, action: r => this._onAttaqueEchecTotal(r) },
]
- } );
+ });
dialog.render(true);
}
@@ -213,15 +216,15 @@ export class RdDCombat {
let explications = "";
rollData.dmg = RdDBonus.dmg(rollData, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
-
+
if (this.target) {
explications += "
Cible : " + this.defender.data.name;
}
explications += "
Encaissement à " + Misc.toSignedString(rollData.dmg.total) + " (" + rollData.dmg.loc.label + ")";
-
+
// Save rollData for defender
game.system.rdd.rollDataHandler[this.attackerId] = duplicate(rollData);
-
+
// Message spécial pour la rapidité, qui reste difficile à gérer automatiquement
if (rollData.particuliereAttaque == 'rapidite') {
explications += "
Vous avez attaqué en Rapidité. Vous pourrez faire une deuxième attaque, ou utiliser votre arme pour vous défendre.";
@@ -230,12 +233,12 @@ export class RdDCombat {
// Final chat message
let chatOptions = {
content: "Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + ""
- + "
Difficultés libre : " + rollData.diffLibre + " / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat
- + RdDResolutionTable.explain(rollData.rolled)
- + explications
+ + "
Difficultés libre : " + rollData.diffLibre + " / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat
+ + RdDResolutionTable.explain(rollData.rolled)
+ + explications
}
ChatUtility.chatWithRollMode(chatOptions, this.attacker.name)
-
+
if (this.target) {
this._messageDefenseur(rollData);
}
@@ -309,11 +312,11 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- _onAttaqueEchecTotal(rollData) {
+ async _onAttaqueEchecTotal(rollData) {
console.log("RdDCombat.onEchecTotal >>>", rollData);
- // TODO: proposer un résultat d'échec total
let chatOptions = {
- content: "Echec total à l'attaque!"
+ content: "Echec total à l'attaque! "
+ + await RdDRollTables.getMaladresse({ arme: rollData.arme && !rollData.arme.data.sansArme })
}
ChatUtility.chatWithRollMode(chatOptions, this.attacker.name)
}
@@ -347,8 +350,10 @@ export class RdDCombat {
let rollData = this._prepareParade(attackerRoll, arme);
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',
label: 'Parade: ' + (arme ? arme.name : rollData.competence.name),
callbacks: [
@@ -358,7 +363,7 @@ export class RdDCombat {
{ condition: RdDCombat.isEchec, action: r => this._onParadeEchec(r) },
{ condition: RdDCombat.isEchecTotal, action: r => this._onParadeEchecTotal(r) },
]
- } );
+ });
dialog.render(true);
}
@@ -368,7 +373,7 @@ export class RdDCombat {
return armeItem.data;
}
- return RdDItemArme.mainsNues()
+ return RdDItemArme.mainsNues()
}
_prepareParade(attackerRoll, armeParade) {
@@ -376,7 +381,7 @@ export class RdDCombat {
const compName = isCreature ? armeParade.name : armeParade.data.competence;
const competence = this.defender.getCompetence(compName);
const armeAttaque = attackerRoll.arme;
-
+
if (compName != competence.name) {
// TODO: toujours utiliser competence.name ...
ui.notifications.warn("Différence entre compétence " + competence.name + " et compétence de l'arme " + compName);
@@ -429,12 +434,12 @@ export class RdDCombat {
/* -------------------------------------------- */
async _onParadeNormale(rollData) {
console.log("RdDCombat._onParadeNormale >>>", rollData);
-
+
let chatOptions = {
content: "Test : " + rollData.selectedCarac.label + " / " + rollData.competence.name + ""
- + "
Difficultés libre : " + rollData.diffLibre + " / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat
- + RdDResolutionTable.explain(rollData.rolled)
- + "
Attaque parée!"
+ + "
Difficultés libre : " + rollData.diffLibre + " / conditions : " + Misc.toSignedString(rollData.diffConditions) + " / état : " + rollData.etat
+ + RdDResolutionTable.explain(rollData.rolled)
+ + "
Attaque parée!"
}
ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
await this.computeRecul(rollData, false);
@@ -442,11 +447,11 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- _onParadeEchecTotal(rollData) {
+ async _onParadeEchecTotal(rollData) {
console.log("RdDCombat._onParadeEchecTotal >>>", rollData);
- // TODO: proposer un résultat d'échec total
let chatOptions = {
- content: "Echec total à la parade!"
+ content: "Echec total à la parade! "
+ + await RdDRollTables.getMaladresse({ arme: rollData.arme && !rollData.arme.data.sansArme })
}
ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
}
@@ -536,15 +541,15 @@ export class RdDCombat {
+ RdDResolutionTable.explain(rollData.rolled)
+ "
Attaque esquivée!"
}
-
ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
}
+
/* -------------------------------------------- */
- _onEsquiveEchecTotal(rollData) {
+ async _onEsquiveEchecTotal(rollData) {
console.log("RdDCombat._onEsquiveEchecTotal >>>", rollData);
- // TODO: proposer un résultat d'échec total
let chatOptions = {
- content: "Echec total à l'esquive'!"
+ content: "Echec total à l'esquive'! "
+ + await RdDRollTables.getMaladresse({ arme: false })
}
ChatUtility.chatWithRollMode(chatOptions, this.defender.name)
}
@@ -571,14 +576,14 @@ export class RdDCombat {
this.encaisser(rollData.attackerRoll);
}
-
+
/* -------------------------------------------- */
- async computeDeteriorationArme( rollData ) {
+ async computeDeteriorationArme(rollData) {
const attackerRoll = rollData.attackerRoll;
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 ?
- if ( (rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.tactique == 'charge')
- && !rollData.rolled.isPart ) {
+ if ((rollData.needResist || attackerRoll.particuliereAttaque == 'force' || attackerRoll.tactique == 'charge')
+ && !rollData.rolled.isPart) {
const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor;
let resistance = Misc.toInt(rollData.arme.data.resistance);
let msg = "";
@@ -586,44 +591,49 @@ export class RdDCombat {
let resistRoll = await RdDResolutionTable.rollData({
caracValue: resistance,
finalLevel: - dmg,
- showDice: false});
+ showDice: false
+ });
if (resistRoll.isSuccess) { // Perte de résistance
msg = "Votre " + rollData.arme.name + " tient le choc de la parade. "
} else {
resistance -= dmg;
- if ( resistance <= 0 ) {
+ if (resistance <= 0) {
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!";
} 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. ";
}
}
// 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({
caracValue: this.defender.data.data.carac.force.value,
finalLevel: Misc.toInt(rollData.competence.data.niveau) - dmg,
- showDice: false});
- if ( desarme.isEchec) {
+ showDice: false
+ });
+ if (desarme.isEchec) {
msg += "Vous ne parvenez pas à garder votre arme en main, elle tombe au sol à vos pieds";
}
}
- ChatMessage.create( { content: msg,
- user: game.user._id,
- whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM") ] } );
+ ChatMessage.create({
+ content: msg,
+ user: game.user._id,
+ whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM")]
+ });
}
}
}
/* -------------------------------------------- */
- async computeRecul( rollData, encaisser = undefined ) { // Calcul du recul (p. 132)
- if ( rollData.arme || encaisser ) {
- 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);
+ async computeRecul(rollData, encaisser = undefined) { // Calcul du recul (p. 132)
+ if (rollData.arme || encaisser) {
+ 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 recul = await RdDResolutionTable.rollData({
caracValue: 10,
finalLevel: reculNiveau,
- showDice: false});
+ showDice: false
+ });
let msg = "";
if (recul.isSuccess) {
@@ -632,16 +642,19 @@ export class RdDCombat {
let chute = await RdDResolutionTable.rollData({
caracValue: this.defender.data.data.carac.agilite.value,
finalLevel: reculNiveau,
- showDice: false});
- if ( !chute.isSuccess || recul.isETotal ) {
+ showDice: false
+ });
+ if (!chute.isSuccess || recul.isETotal) {
msg = "Sous la violence du coup, vous reculez et chutez au sol ! Vous ne pouvez plus attaquer ce round.";
} else {
msg = "La violence du choc vous fait reculer de quelques mètres ! Vous ne pouvez plus attaquer ce round.";
}
- }
- ChatMessage.create( {content: msg,
- user: game.user._id,
- whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM") ] } );
+ }
+ ChatMessage.create({
+ content: msg,
+ user: game.user._id,
+ whisper: [game.user._id, ChatMessage.getWhisperRecipients("GM")]
+ });
}
}
}
diff --git a/module/rdd-rolltables.js b/module/rdd-rolltables.js
index 3e2c3ea2..480b4f13 100644
--- a/module/rdd-rolltables.js
+++ b/module/rdd-rolltables.js
@@ -8,7 +8,6 @@ export class RdDRollTables {
const table = await pack.getEntity(entry._id);
const draw = await table.draw({ displayChat: toChat });
console.log("RdDRollTables", tableName, toChat, ":", draw);
- console.log("RdDRollTables", tableName, toChat, ":", draw.roll, draw.results);
return draw;
}
@@ -16,9 +15,25 @@ export class RdDRollTables {
static async drawItemFromRollTable(tableName, toChat) {
const draw = await RdDRollTables.genericGetTableResult(tableName, toChat);
const drawnItemRef = draw.results.length > 0 ? draw.results[0] : undefined;
- const pack = game.packs.get(drawnItemRef.collection);
- return await pack.getEntity(drawnItemRef.resultId);
+ if (drawnItemRef.collection) {
+ 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) {
return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat);
@@ -48,4 +63,10 @@ export class RdDRollTables {
static async getTarot(toChat = true) {
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);
+ }
}