From 8c3e7e24453809073c8ce830fc9e7666adeec26b Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 8 Oct 2021 23:25:50 +0200 Subject: [PATCH 01/11] Ajout de Misc.findFirstLike MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Méthode de recherche de valeur "proche" dans une liste. Cherche un élément correspondant strictement, sinon cherche les éléments contenant la valeur, et retourne le premier. Notification si plusieurs valeurs peuvent correspondre. --- module/actor.js | 13 ++----------- module/item-competence.js | 15 +-------------- module/misc.js | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/module/actor.js b/module/actor.js index c5014b77..132d668b 100644 --- a/module/actor.js +++ b/module/actor.js @@ -3020,17 +3020,8 @@ export class RdDActor extends Actor { case 'chance-actuelle': case 'chance actuelle': return carac.chance; } - const keys = Object.entries(carac) - .filter(it => it[0].includes(name) || Grammar.toLowerCaseNoAccent(it[1].label).includes(name)) - .map(it => it[0]); - if (keys.length > 1) { - const names = keys.reduce((a, b) => `${a}
${b}`); - ui.notifications.info(`Plusieurs caractéristiques possibles:
${names}
La première sera choisie.`); - } - if (keys.length > 0) { - return carac[keys[0]]; - } - return undefined; // Per default + let entry = Misc.findFirstLike(name, Object.entries(carac), it => it[1].label, 'caractéristiques'); + return entry.length>0 ? carac[entry[0]] : undefined; } /* -------------------------------------------- */ diff --git a/module/item-competence.js b/module/item-competence.js index 03939d03..c2355ab1 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -209,20 +209,7 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static findCompetence(list, name) { - name = Grammar.toLowerCaseNoAccent(name); - const competences = list.filter(it => Grammar.toLowerCaseNoAccent(it.name).includes(name) && (it.type == "competence" || it.type == "competencecreature")); - if (competences.length == 0) { - return undefined; - } - let competence = competences.find(it => Grammar.toLowerCaseNoAccent(it.name) == name); - if (!competence) { - competence = competences[0]; - if (competences.length > 1) { - const names = competences.map(it => it.name).reduce((a, b) => `${a}
${b}`); - ui.notifications.info(`Plusieurs compétences possibles:
${names}
La première sera choisie: ${competence.name}`); - } - } - return competence; + return Misc.findFirstLike(name, list, it => it.name, 'compétences'); } /* -------------------------------------------- */ diff --git a/module/misc.js b/module/misc.js index da74c589..ea0d7aa1 100644 --- a/module/misc.js +++ b/module/misc.js @@ -1,3 +1,4 @@ +import { Grammar } from "./grammar.js"; import { RdDDice } from "./rdd-dice.js"; /** @@ -131,4 +132,22 @@ export class Misc { static isElectedUser() { return game.user.id == Misc.connectedGMOrUser(); } + + /* -------------------------------------------- */ + static findFirstLike(value, elements, mapper = it=>it.name, description = 'valeurs') { + value = Grammar.toLowerCaseNoAccent(value); + const subset = elements.filter(it => Grammar.toLowerCaseNoAccent(mapper(it)).includes(value)); + if (subset.length == 0) { + return undefined; + } + let single = subset.find(it => Grammar.toLowerCaseNoAccent(mapper(it)) == value); + if (!single) { + single = subset[0]; + if (subset.length > 1) { + const choices = subset.map(it => mapper(it)).reduce((a, b) => `${a}
${b}`); + ui.notifications.info(`Plusieurs choix de ${description} possibles:
${choices}
Le premier sera choisi: ${mapper(single)}`); + } + } + return single; + } } \ No newline at end of file From 41c6270bf1058bf0240e6e961d783efde42a8643 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 8 Oct 2021 23:26:10 +0200 Subject: [PATCH 02/11] cleanup imports --- module/dialog-create-signedraconique.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/dialog-create-signedraconique.js b/module/dialog-create-signedraconique.js index acbcc916..57d17d3a 100644 --- a/module/dialog-create-signedraconique.js +++ b/module/dialog-create-signedraconique.js @@ -2,8 +2,7 @@ import { ChatUtility } from "./chat-utility.js"; import { HtmlUtility } from "./html-utility.js"; import { RdDItemSigneDraconique } from "./item-signedraconique.js"; import { Misc } from "./misc.js"; -import { RdDRollTables } from "./rdd-rolltables.js"; -import { TMRType, TMRUtility } from "./tmr-utility.js"; +import { TMRUtility } from "./tmr-utility.js"; export class DialogCreateSigneDraconique extends Dialog { From 1efdca028ce119312ee4409f1d1d1b7cafdd51cd Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 8 Oct 2021 23:28:55 +0200 Subject: [PATCH 03/11] =?UTF-8?q?Stress=20am=C3=A9lior=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commande: /stress Ouvre une fenêtre pour gérer finement le stress (ou l'expérience) Commande: /stress Stress donné à un acteur/joueur avec un nom proche Notifications des joueurs qui reçoivent du stress --- module/actor.js | 27 +++++++++++--- module/dialog-stress.js | 72 ++++++++++++++++++++++++++++++++++++ module/misc.js | 10 +++++ module/rdd-commands.js | 48 +++++++++++++++++++++--- module/rdd-utility.js | 26 ------------- templates/dialog-stress.html | 24 ++++++++++++ 6 files changed, 171 insertions(+), 36 deletions(-) create mode 100644 module/dialog-stress.js create mode 100644 templates/dialog-stress.html diff --git a/module/actor.js b/module/actor.js index 132d668b..57e34ce6 100644 --- a/module/actor.js +++ b/module/actor.js @@ -1002,17 +1002,34 @@ export class RdDActor extends Actor { /* -------------------------------------------- */ async updateCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { await this.update({ [`data.compteurs.${fieldName}.value`]: fieldValue }); - if (fieldName == 'stress') { - await this.updateExperienceLog('stress', fieldValue, raison); - } + await this.addStressExperienceLog(fieldName, fieldValue, 'forcé: '+raison); } /* -------------------------------------------- */ async addCompteurValue(fieldName, fieldValue, raison = 'Inconnue') { let oldValue = (Misc.templateData(this)).compteurs[fieldName].value; await this.update({ [`data.compteurs.${fieldName}.value`]: Number(oldValue) + Number(fieldValue) }); - if (fieldName == 'stress') { - await this.updateExperienceLog('stress', fieldValue, raison); + await this.addStressExperienceLog(fieldName, fieldValue, raison); + } + + async addStressExperienceLog(fieldName, fieldValue, raison) { + switch (fieldName) { + case 'stress': case 'experience': + await this.updateExperienceLog(fieldName, fieldValue, raison); + } + } + + /* -------------------------------------------- */ + distribuerStress(compteur, stress, motif) { + if (game.user.isGM && this.hasPlayerOwner && this.isPersonnage()) { + switch (compteur) { + case 'stress': case 'experience': + const message = `${this.name} a reçu ${stress} points ${compteur == 'stress' ? "de stress" : "d'expérience"} (raison : ${motif})`; + this.addCompteurValue(compteur, stress, motif); + ui.notifications.info(message); + game.users.players.filter(player => player.active && player.character?.id == this.id) + .forEach(player => ChatUtility.notifyUser(player.id, 'info', message)); + } } } diff --git a/module/dialog-stress.js b/module/dialog-stress.js new file mode 100644 index 00000000..210b9918 --- /dev/null +++ b/module/dialog-stress.js @@ -0,0 +1,72 @@ +import { Misc } from "./misc.js"; + +export class DialogStress extends Dialog { + + static async distribuerStress() { + let dialogData = { + motif: "Motif", + stress: 10, + immediat: false, + actors: game.actors.filter(actor => actor.hasPlayerOwner && actor.isPersonnage()) + .map(actor => { + let actorData = duplicate(Misc.data(actor)); + actorData.selected = actor.hasPlayerOwner; + return actorData; + }) + }; + + const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/dialog-stress.html", dialogData); + new DialogStress(dialogData, html) + .render(true); + } + + constructor(dialogData, html) { + let options = { classes: ["DialogStress"], width: 400, height: 320, 'z-index': 99999 }; + let conf = { + title: "Donner du stress", + content: html, + buttons: { + "Stress": { label: "Stress !", callback: it => { this._onStress(); } } + } + }; + super(conf, options); + this.dialogData = dialogData; + } + + async _onStress() { + this.validerStress(); + const compteur = this.dialogData.immediat ? 'experience' : 'stress'; + const stress = this.dialogData.stress; + const motif = this.dialogData.motif; + + this.dialogData.actors.filter(it => it.selected) + .map(it => game.actors.get(it._id)) + .forEach(actor => actor.distribuerStress(compteur, stress, motif)); + } + + + validerStress() { + this.dialogData.motif = $("[name='motif']").val(); + this.dialogData.stress = $("[name='stress']").val(); + this.dialogData.immediat = $("[name='immediat']").prop("checked");; + } + + /* -------------------------------------------- */ + activateListeners(html) { + super.activateListeners(html); + html.find(".select-actor").change((event) => this.onSelectActor(event)); + } + + async onSelectActor(event) { + event.preventDefault(); + const options = event.currentTarget.options; + for (var i = 0; i < options.length; i++) { // looping over the options + const actorId = options[i].attributes["data-actor-id"].value; + const actor = this.dialogData.actors.find(it => it._id == actorId); + if (actor) { + actor.selected = options[i].selected; + } + }; + } + +} \ No newline at end of file diff --git a/module/misc.js b/module/misc.js index ea0d7aa1..25ceacd3 100644 --- a/module/misc.js +++ b/module/misc.js @@ -133,6 +133,16 @@ export class Misc { return game.user.id == Misc.connectedGMOrUser(); } + /* -------------------------------------------- */ + static findPlayer(name) { + return Misc.findFirstLike(name, game.users, it=>it.name,'joueurs'); + } + + /* -------------------------------------------- */ + static findActor(name, actors = game.actors, description= 'acteurs') { + return Misc.findFirstLike(name, actors, it=>it.name, description); + } + /* -------------------------------------------- */ static findFirstLike(value, elements, mapper = it=>it.name, description = 'valeurs') { value = Grammar.toLowerCaseNoAccent(value); diff --git a/module/rdd-commands.js b/module/rdd-commands.js index c6ff622f..ef2840b3 100644 --- a/module/rdd-commands.js +++ b/module/rdd-commands.js @@ -1,6 +1,7 @@ /* -------------------------------------------- */ import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; +import { DialogStress } from "./dialog-stress.js"; import { RdDItemCompetence } from "./item-competence.js"; import { Misc } from "./misc.js"; import { RdDCarac } from "./rdd-carac.js"; @@ -97,11 +98,12 @@ export class RdDCommands { }); rddCommands.registerCommand({ - path: ["/stress"], func: (content, msg, params) => RdDUtility.distribuerStress(params[0], params[1], params[2]), + path: ["/stress"], func: (content, msg, params) => rddCommands.distribuerStress(params), descr: `Distribue du stress aux personnages. Exemples: +
/stress : Ouvre une fenêtre pour donner du stress ou de l'expérience à un ensemble de personnages
/stress 6 : Distribue 6 points des Stress à tout les personnages joueurs, sans raison renseignée -
/stress 6 Tigre : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre Vert -
/stress 6 Glou Paulo : Distribue 6 points de Stres à l'acteur connecté au joueur Paulo, à cause d'un Glou` +
/stress 6 Tigre : Distribue 6 points des Stress à tout les personnages joueurs, à cause d'un Tigre (Vert) +
/stress 6 Glou Paulo : Distribue 6 points de Stress au personnage Paulon ou au personnage joueur Paulo, à cause d'un Glou` }); game.system.rdd.commands = rddCommands; @@ -289,7 +291,7 @@ export class RdDCommands { finalLevel: diff, showDice: true, diviseurSignificative: significative ? 2 : 1, - show: { title: "Table de résolution"} + show: { title: "Table de résolution" } }; await RdDResolutionTable.rollData(rollData); RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData)); @@ -297,7 +299,7 @@ export class RdDCommands { /* -------------------------------------------- */ async rollDeDraconique(msg) { - let ddr = await RdDDice.rollTotal("1dr + 7", { showDice:true }); + let ddr = await RdDDice.rollTotal("1dr + 7", { showDice: true }); RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr}`); } @@ -351,5 +353,41 @@ export class RdDCommands { }); return true; } + + async distribuerStress(params) { + if (!game.user.isGM) { + ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /stress"); + return false; + } + if (params.length == 0) { + DialogStress.distribuerStress(); + } + else { + let stress = params[0] + if (stress == undefined) { + ui.notifications.warn("Pas de valeur de stress à distribuer!"); + return; + } + + let motif = params[1]; + let name = params[2]; + if (name == undefined) { + for (let actor of game.actors) { + actor.distribuerStress('stress', stress, motif); + } + } else { + //console.log(stressValue, nomJoueur); + let actor = Misc.findActor(name, game.actors.filter(it => it.hasPlayerOwner)) ?? Misc.findPlayer(name)?.character + if (actor) { + actor.distribuerStress('stress', stress, motif); + } + else { + ui.notifications.warn(`Pas de personnage ou de joueur correspondant à ${name}!`); + } + } + + } + return true; + } } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 2fec2e3d..9dc188bb 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -887,32 +887,6 @@ export class RdDUtility { } } - /*-------------------------------------------- */ - static distribuerStress(stressValue, raison = 'Inconnu', nomJoueur = undefined) { - if (game.user.isGM) { - if (stressValue == undefined){ - ui.notifications.warn("Pas de valeur de stress à distribuer!"); - return; - } - if (nomJoueur == undefined) { - for (let actor of game.actors) { - if (actor.hasPlayerOwner && actor.isPersonnage() ) { - actor.addCompteurValue('stress', stressValue, raison); - ui.notifications.info(`${actor.name} a reçu ${stressValue} points de Stress (raison : ${raison})`); - } - } - } else { - //console.log(stressValue, nomJoueur); - let joueur = game.users.find(user => user.name.toLowerCase() == nomJoueur.toLowerCase()); - //console.log("Player", joueur, joueur.character ); - joueur.character.addCompteurValue('stress', stressValue, raison); - ui.notifications.info(`${joueur.character.name} a reçu ${stressValue} points de Stress (raison : ${raison})`); - } - } else { - ui.notifications.warn("Seul le MJ est autorisé à utiliser la commande /stress"); - } - } - /*-------------------------------------------- */ static async onRenderChatMessage(app, html, msg) { // TODO diff --git a/templates/dialog-stress.html b/templates/dialog-stress.html new file mode 100644 index 00000000..4273ab70 --- /dev/null +++ b/templates/dialog-stress.html @@ -0,0 +1,24 @@ +
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
\ No newline at end of file From 840c2f69a45f185076bbd11cb89f15388072d492 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 00:05:07 +0200 Subject: [PATCH 04/11] cleanup import --- module/misc.js | 1 - 1 file changed, 1 deletion(-) diff --git a/module/misc.js b/module/misc.js index 25ceacd3..ff06f533 100644 --- a/module/misc.js +++ b/module/misc.js @@ -1,5 +1,4 @@ import { Grammar } from "./grammar.js"; -import { RdDDice } from "./rdd-dice.js"; /** * This class is intended as a placeholder for utility methods unrelated From 8abe2145eed8869fd1553b8d4b9333dc39f5d623 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 00:21:26 +0200 Subject: [PATCH 05/11] =?UTF-8?q?Fix=20cat=C3=A9gorie=20d'arme=20des=20cr?= =?UTF-8?q?=C3=A9atures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Régression rendant la parade bouclier des armes naturelles impossible --- module/item-competencecreature.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/module/item-competencecreature.js b/module/item-competencecreature.js index d9aaf53b..30fcce60 100644 --- a/module/item-competencecreature.js +++ b/module/item-competencecreature.js @@ -17,23 +17,23 @@ export class RdDItemCompetenceCreature extends Item { } /* -------------------------------------------- */ - static toArme(itemData) { - if (RdDItemCompetenceCreature.isCompetenceAttaque(itemData)) { - itemData = Misc.data(itemData); - let arme = { name: itemData.name, data: duplicate(itemData) }; + static toArme(item) { + if (RdDItemCompetenceCreature.isCompetenceAttaque(item)) { + // si c'est un Item compétence: cloner pour ne pas modifier lma compétence + let arme = Misc.data( (item instanceof Item) ? item.clone(): item); mergeObject(arme.data, { - competence: itemData.name, + competence: arme.name, resistance: 100, equipe: true, - dommagesReels: itemData.data.dommages, + dommagesReels: arme.data.dommages, penetration: 0, force: 0, rapide: true }); return arme; } - console.error("RdDItemCompetenceCreature.toArme(", itemData, ") : impossible de transformer l'Item en arme"); + console.error("RdDItemCompetenceCreature.toArme(", item, ") : impossible de transformer l'Item en arme"); return undefined; } From 4db13e8b0f1c5a9d583aac0a9169adb18cce2891 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 00:23:04 +0200 Subject: [PATCH 06/11] =?UTF-8?q?Fix=20r=C3=A9gression=20en=20cas=20de=20j?= =?UTF-8?q?et=20de=20r=C3=A9sistance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suite à une charge, la règle "défenseur désarmé" référence la résistance qui n'était pas définie au bon niveau --- module/rdd-combat.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 3105ade7..24b55914 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -1165,11 +1165,11 @@ export class RdDCombat { const dmg = attackerRoll.dmg.dmgArme + attackerRoll.dmg.dmgActor; let arme = defenderRoll.arme; let msg = ""; + let resistance = Misc.toInt(arme.data.resistance); if (arme.data.magique) { defenderRoll.show.deteriorationArme = 'resiste'; // Par défaut if (arme.data.resistance_magique == undefined) arme.data.resistance_magique = 0; // Quick fix if (dmg > arme.data.resistance_magique) { // Jet uniquement si dommages supérieur à résistance magique (cf. 274) - let resistance = Misc.toInt(arme.data.resistance); // Jet de résistance de l'arme de parade (p.132) let resistRoll = await RdDResolutionTable.rollData({ caracValue: resistance, @@ -1185,7 +1185,6 @@ export class RdDCombat { } } } else { - let resistance = Misc.toInt(arme.data.resistance); // Jet de résistance de l'arme de parade (p.132) let resistRoll = await RdDResolutionTable.rollData({ caracValue: resistance, From 910d37eeb1aa8e90df5a2600453cb1ddf911371e Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 10:37:19 +0200 Subject: [PATCH 07/11] Fix: achat de plusieurs conteneurs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Les conteneurs n'ont pas de quantité, du coup, en créer plusieurs en cas d'achat multiples --- module/actor.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/module/actor.js b/module/actor.js index 57e34ce6..90a2a96d 100644 --- a/module/actor.js +++ b/module/actor.js @@ -3623,10 +3623,11 @@ export class RdDActor extends Actor { type: vente.item.type, img: vente.item.img, name: vente.item.name, - data: vente.item.data + data: vente.item.data, + quantite: "quantite" in vente.item ? achat.quantiteTotal : undefined } - achatData.data.quantite = achat.quantiteTotal; - let items = await acheteur.createEmbeddedDocuments("Item", [achatData]); + let listeAchat = ("quantite" in vente.item) ? [achatData] : Array.from({length: achat.quantiteTotal}, (_, i) => achatData) + let items = await acheteur.createEmbeddedDocuments("Item", listeAchat) if (achat.choix.consommer && vente.item.type == 'nourritureboisson') { achat.choix.doses = achat.choix.nombreLots; await acheteur.consommerNourritureboisson(items[0], achat.choix); From f28a58ebb8e63f212666a9771d4e52f19257623d Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 10:39:45 +0200 Subject: [PATCH 08/11] Fix: suppression des ventes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La suppression des derniers éléments ne marchait plus deleteEmbeddedDocuments prend un tableau d'ids --- module/actor.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/module/actor.js b/module/actor.js index 90a2a96d..0b0ed72f 100644 --- a/module/actor.js +++ b/module/actor.js @@ -3601,18 +3601,17 @@ export class RdDActor extends Actor { return; } } - const itemVendu = vendeur?.getObjet(itemId); + const itemVendu = Misc.data(vendeur?.getObjet(itemId)); if (itemVendu) { - let itemVenduData = Misc.data(itemVendu); - if ("quantite" in itemVenduData.data ? itemVenduData.data.quantite < achat.quantiteTotal : achat.choix.nombreLots != 1) { + if ("quantite" in itemVendu.data ? itemVendu.data.quantite < achat.quantiteTotal : achat.choix.nombreLots != 1) { await acheteur?.ajouterDeniers(coutDeniers); ChatUtility.notifyUser(achat.userId, 'warn', `Le vendeur n'a plus assez de ${vente.item.name} !`); return; } vendeur.ajouterDeniers(coutDeniers); - let resteQuantite = (itemVenduData.data.quantite ?? 1) - achat.quantiteTotal; + let resteQuantite = (itemVendu.data.quantite ?? 1) - achat.quantiteTotal; if (resteQuantite == 0) { - vendeur.deleteEmbeddedDocuments("Item", itemId); + vendeur.deleteEmbeddedDocuments("Item", [itemId]); } else { vendeur.updateEmbeddedDocuments("Item", [{ _id: itemId, 'data.quantite': resteQuantite }]); From 9a637be4e9d0d379de48276001f9543324d70cf9 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 22:02:13 +0200 Subject: [PATCH 09/11] Affichage des bonus requis MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'affichage est en option (ce n'est pas une règle officielle) --- module/rdd-resolution-table.js | 8 ++++++-- module/rdd-roll-resolution-table.js | 3 +-- module/regles-optionelles.js | 1 + styles/simple.css | 5 +++++ templates/chat-infojet.html | 4 +++- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js index bb0a37c9..269043bb 100644 --- a/module/rdd-resolution-table.js +++ b/module/rdd-resolution-table.js @@ -1,6 +1,7 @@ import { ChatUtility } from "./chat-utility.js"; import { Misc } from "./misc.js"; import { RdDDice } from "./rdd-dice.js"; +import { ReglesOptionelles } from "./regles-optionelles.js"; /** * difficultés au delà de -10 @@ -119,8 +120,11 @@ export class RdDResolutionTable { rolled.finalLevel = finalLevel; rolled.bonus = rollData.bonus; rolled.factorHtml = Misc.getFractionHtml(rollData.diviseurSignificative); - rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll ); - rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel; + + if (ReglesOptionelles.isUsing("afficher-colonnes-reussite")){ + rolled.niveauNecessaire = this.findNiveauNecessaire(caracValue, rolled.roll); + rolled.ajustementNecessaire = rolled.niveauNecessaire - finalLevel; + } return rolled; } diff --git a/module/rdd-roll-resolution-table.js b/module/rdd-roll-resolution-table.js index 271e6a05..91ba953b 100644 --- a/module/rdd-roll-resolution-table.js +++ b/module/rdd-roll-resolution-table.js @@ -51,8 +51,7 @@ export class RdDRollResolutionTable extends Dialog { content: html, buttons: { 'lancer-fermer': { label: 'Lancer les dés et fermer', callback: html => this.onLancerFermer() } - }, - default: 'lancer' + } }; super(conf, { classes: ["rdddialog"], width: 800, height: 800, 'z-index': 99999 }); diff --git a/module/regles-optionelles.js b/module/regles-optionelles.js index 6b2d1955..b09a8016 100644 --- a/module/regles-optionelles.js +++ b/module/regles-optionelles.js @@ -10,6 +10,7 @@ const listeReglesOptionelles = [ { name: 'astrologie', group: 'Règles de générales', descr: "Appliquer les ajustements astrologiques aux jets de chance et aux rituels", default: true }, { name: 'afficher-prix-joueurs', group: 'Règles de générales', descr: "Afficher le prix de l'équipement des joueurs", default: true }, { name: 'appliquer-fatigue', group: 'Règles de générales', descr: "Appliquer les règles de fatigue", default: true }, + { name: 'afficher-colonnes-reussite', group: 'Règles de générales', descr: "Afficher le nombre de colonnes de réussite ou d'échec", default: false }, ]; export class ReglesOptionelles extends FormApplication { diff --git a/styles/simple.css b/styles/simple.css index fa959565..3e134ea1 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -503,6 +503,11 @@ table {border: 1px solid #7a7971;} background:linear-gradient(30deg, rgba(61, 55, 93, 0.2), rgba(178, 179, 196, 0.1), rgba(59, 62, 63, 0.2), rgba(206, 204, 199, 0.1), rgba(61, 46, 49, 0.2)); } +.rdd-niveau-requis{ + font-size: 0.80rem; + text-align: right; +} + .table-resolution-carac { background-color: yellow; } diff --git a/templates/chat-infojet.html b/templates/chat-infojet.html index 9785ecfa..76227bb9 100644 --- a/templates/chat-infojet.html +++ b/templates/chat-infojet.html @@ -22,5 +22,7 @@
{{rolled.roll}} : {{rolled.quality}} - (Min.:{{numberFormat rolled.niveauNecessaire decimals=0 sign=true}}/{{numberFormat rolled.ajustementNecessaire decimals=0 sign=true}}) + {{#if rolled.ajustementNecessaire}} + (Réussite si {{numberFormat rolled.niveauNecessaire decimals=0 sign=true}} / avec niveau {{numberFormat rolled.ajustementNecessaire decimals=0 sign=true}}) + {{/if}}
\ No newline at end of file From bf2ec639c871afb126d43be3eacd31699c66f8a9 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 22:04:34 +0200 Subject: [PATCH 10/11] =?UTF-8?q?Am=C3=A9lioration=20des=20potions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - effet de base en cas de résistance à potion magique - un seul message de tchat - affichage du résultat du jet de résistance - utilisation des l'image de la potion - fabrication avec image de l'herbe --- module/actor.js | 69 +++++++------------ templates/chat-appliquer-potion-repos.html | 22 ------ templates/chat-appliquer-potion-soin.html | 21 ------ .../chat-consommer-potion-generique.html | 15 +++- templates/chat-consommer-potion-repos.html | 24 +++++-- templates/chat-consommer-potion-soin.html | 22 ++++-- templates/chat-fabriquer-potion-base.html | 4 +- 7 files changed, 76 insertions(+), 101 deletions(-) delete mode 100644 templates/chat-appliquer-potion-repos.html delete mode 100644 templates/chat-appliquer-potion-soin.html diff --git a/module/actor.js b/module/actor.js index 0b0ed72f..60f112d8 100644 --- a/module/actor.js +++ b/module/actor.js @@ -3841,32 +3841,21 @@ export class RdDActor extends Actor { potionData.supprimer = true; if (potionData.data.magique) { - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData) - }); // Gestion de la résistance: - let rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); - potionData.reveResultDice = rolled.roll; - potionData.scoreReve = rolled.score; - potionData.reussiteReve = false; - if (!rolled.isSuccess) { + potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); + if (potionData.rolled.isEchec) { await this.reveActuelIncDec(-1); potionData.guerisonData = await this.buildPotionGuerisonList(potionData.data.puissance); potionData.guerisonMinutes = potionData.guerisonData.pointsConsommes * 5; - potionData.reussiteReve = true; } - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-appliquer-potion-soin.html`, potionData) - }); - } else { - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-appliquer-potion-soin.html`, potionData) - }); + } + if (!potionData.data.magique || potionData.rolled.isSuccess) { this.bonusRecuperationPotion = potionData.data.herbeBonus; } + ChatMessage.create({ + whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), + content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-soin.html`, potionData) + }); } /* -------------------------------------------- */ @@ -3875,22 +3864,14 @@ export class RdDActor extends Actor { potionData.supprimer = true; if (potionData.data.magique) { - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData) - }); // Gestion de la résistance: - let rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); - potionData.reveResultDice = rolled.roll; - potionData.scoreReve = rolled.score; - potionData.reussiteReve = false; - if (!rolled.isSuccess) { + potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); + if (potionData.rolled.isEchec) { await this.reveActuelIncDec(-1); let fatigueActuelle = this.getFatigueActuelle(); potionData.caseFatigueReel = Math.min(fatigueActuelle, potionData.data.puissance); potionData.guerisonDureeUnite = (potionData.data.reposalchimique) ? "rounds" : "minutes"; potionData.guerisonDureeValue = (potionData.data.reposalchimique) ? potionData.caseFatigueReel : potionData.caseFatigueReel * 5; - potionData.reussiteReve = true; potionData.aphasiePermanente = false; if (potionData.data.reposalchimique) { let chanceAphasie = await RdDDice.rollTotal("1d100"); @@ -3900,17 +3881,14 @@ export class RdDActor extends Actor { } await this.santeIncDec("fatigue", -potionData.caseFatigueReel); } - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-appliquer-potion-repos.html`, potionData) - }); - } else { - ChatMessage.create({ - whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), - content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-appliquer-potion-repos.html`, potionData) - }); + } + if (!potionData.data.magique || potionData.rolled.isSuccess) { this.bonusRepos = potionData.data.herbeBonus; } + ChatMessage.create({ + whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), + content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-repos.html`, potionData) + }); } /* -------------------------------------------- */ dialogFabriquerPotion(herbe) { @@ -3938,10 +3916,9 @@ export class RdDActor extends Actor { let newQuantite = herbeData.data.quantite - herbeData.nbBrins; let messageData = { alias: this.name, - categorie: herbeData.data.categorie, - herbe: herbeData.name, - nbBrinsPotion: herbeData.nbBrins, - nbBrinsReste: newQuantite + nbBrinsReste: newQuantite, + potion: newPotion, + herbe: herbeData } this.diminuerQuantiteObjet(herbeData._id, herbeData.nbBrins); @@ -3949,7 +3926,6 @@ export class RdDActor extends Actor { whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-fabriquer-potion-base.html`, messageData) }); - } /* -------------------------------------------- */ @@ -3964,6 +3940,13 @@ export class RdDActor extends Actor { async consommerPotionGenerique(potionData) { potionData.alias = this.name; + if (potionData.data.magique) { + // Gestion de la résistance: + potionData.rolled = await RdDResolutionTable.roll(this.getReveActuel(), -8); + if (potionData.rolled.isEchec) { + await this.reveActuelIncDec(-1); + } + } ChatMessage.create({ whisper: ChatUtility.getWhisperRecipientsAndGMs(game.user.name), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-consommer-potion-generique.html`, potionData) diff --git a/templates/chat-appliquer-potion-repos.html b/templates/chat-appliquer-potion-repos.html deleted file mode 100644 index 23fdd89d..00000000 --- a/templates/chat-appliquer-potion-repos.html +++ /dev/null @@ -1,22 +0,0 @@ -potion de repos -

- {{#if reussiteReve}} - {{alias}} a bu la potion et a échoué son Jet de Résistance (Rêve actuel à -8 : {{reveResultDice}}/{{scoreReve}}) : la potion fait effet ! - {{else}} - {{alias}} a bu la potion et a réussi son Jet de Résistance (Rêve actuel à -8 : {{reveResultDice}}/{{scoreReve}}) : la potion ne fait pas effet ! - {{/if}} -

-
-
- {{#if reussiteReve}} - {{alias}} perd 1 point de rêve (déduit automatiquement) et s'endort pour {{guerisonDureeValue}} {{guerisonDureeUnite}} et - se repose de {{caseFatigueReel}} cases de fatigue.
- {{#if data.reposalchimique}} - De plus, étant donné que la potion était alchimique, {{alias}} est en aphasie pendant cette durée. - {{#if aphasiePermanente}} - Et malheureusement, l'aphasie est permanente tant que {{alias}} ne réussit pas un jet de VOLONTE à 0 à Chateau Dormant (le moral compte). - {{/if}} - {{/if}} - {{/if}} - La potion a également été supprimée de l'équipement. -
diff --git a/templates/chat-appliquer-potion-soin.html b/templates/chat-appliquer-potion-soin.html deleted file mode 100644 index 1c21fa5f..00000000 --- a/templates/chat-appliquer-potion-soin.html +++ /dev/null @@ -1,21 +0,0 @@ -potion de soin -

- {{#if reussiteReve}} - {{alias}} a bu la potion et a échoué son Jet de Résistance (Rêve actuel à -8 : {{reveResultDice}}/{{scoreReve}}) : la potion fait effet ! - {{else}} - {{alias}} a bu la potion et a réussi son Jet de Résistance (Rêve actuel à -8 : {{reveResultDice}}/{{scoreReve}}) : la potion ne fait pas effet ! - {{/if}} -

-
-
- {{#if reussiteReve}} - {{alias}} perd 1 point de rêve (déduit automatiquement) et s'endort pour {{guerisonMinutes}} minutes. A son réveil, les blessures suivantes seront guéries : -
    - {{#each guerisonData.list as |guerison key|}} -
  • {{guerison}}
  • - {{/each}} -
-
- {{/if}} - La potion a également été supprimée de l'équipement. -
diff --git a/templates/chat-consommer-potion-generique.html b/templates/chat-consommer-potion-generique.html index e3d514ca..9898a038 100644 --- a/templates/chat-consommer-potion-generique.html +++ b/templates/chat-consommer-potion-generique.html @@ -1,9 +1,18 @@ -potion de repos +potion de repos

- {{alias}} consomme sa Potion {{#if data.magique}}enchantée{{/if}} de {{name}}. + {{alias}} a bu une {{name}}{{#if data.magique}} enchantée{{/if}}


- Les effets de la potions sont à gérer manuellement, en fonction de sa nature{{#if data.magique}} et de son enchantement ({{data.pr}} Points de Rêve){{/if}}. + {{#if data.magique}} + Le Jet de Résistance est {{#if rolled.isSuccess}}réussi{{else}}échoué{{/if}}. + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} + {{/if}} +
Les effets de la potions sont à gérer manuellement, en fonction de sa nature + {{#if data.magique}} + {{#if rolled.isEchec}}et de son enchantement ({{data.pr}} Points de Rêve) + {{else}}son enchantement n'a pas d'effet + {{/if}} + {{/if}}.
La potion a été supprimée de l'équipement.
diff --git a/templates/chat-consommer-potion-repos.html b/templates/chat-consommer-potion-repos.html index 37cc9f99..873a78c8 100644 --- a/templates/chat-consommer-potion-repos.html +++ b/templates/chat-consommer-potion-repos.html @@ -1,13 +1,27 @@ -potion de repos +potion de repos

- {{alias}} consomme sa Potion de Repos {{#if data.magique}}enchantée{{/if}} de {{name}} ({{data.herbe}}, {{data.herbebrins}} brins). + {{alias}} a bu une {{name}}{{#if data.magique}} enchantée{{/if}}


{{#if data.magique}} - Elle permet de récupérer jusqu'à {{data.puissance}} cases de repos. + Le Jet de Résistance est {{#if rolled.isSuccess}}réussi{{else}}échoué{{/if}}. + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} + {{#if rolled.isEchec}} +
La potion fait effet ! + {{alias}} a perdu 1 point de rêve et s'endort pour {{guerisonDureeValue}} {{guerisonDureeUnite}} et + se récupère {{caseFatigueReel}} cases de fatigue.
+ {{#if data.reposalchimique}} + De plus, la potion étant alchimique, {{alias}} est en aphasie pendant cette durée. + {{#if aphasiePermanente}} + Malheureusement, l'aphasie est permanente tant que {{alias}} ne réussit pas un jet de VOLONTE à 0 à Chateau Dormant (le moral compte). + {{/if}} + {{/if}} + {{else}} +
La potion ne fait pas effet ! Elle vous octroie tout de même un bonus de {{data.herbebonus}} segments de fatigue récupérés en plus à la fin de Chateau Dormant (à gérer manuellement). + {{/if}} {{else}} - Une fois consommée vers fin Lyre, elle vous octroie un bonus de {{data.herbebonus}} segments de fatigue récupérés en plus à la fin de Chateau Dormant (à gérer manuellement). -
La potion a également été supprimée de l'équipement. + Une fois consommée (vers fin Lyre), elle vous octroie un bonus de {{data.herbebonus}} segments de fatigue récupérés en plus à la fin de Chateau Dormant (à gérer manuellement). {{/if}} +
La potion a été supprimée de l'équipement.
diff --git a/templates/chat-consommer-potion-soin.html b/templates/chat-consommer-potion-soin.html index 0d88518a..ae429fe6 100644 --- a/templates/chat-consommer-potion-soin.html +++ b/templates/chat-consommer-potion-soin.html @@ -1,13 +1,25 @@ -potion de soin +potion de soin

- {{alias}} consomme sa Potion de soins {{#if data.magique}}enchantée{{/if}} de {{name}} ({{data.herbe}}, {{data.herbebrins}} brins). + {{alias}} a bu une {{name}}{{#if data.magique}} enchantée{{/if}}


{{#if data.magique}} - Elle permet de guérir {{data.puissance}} Points de Guérison. + Le Jet de Résistance est {{#if rolled.isSuccess}}réussi{{else}}échoué{{/if}}. + {{> "systems/foundryvtt-reve-de-dragon/templates/chat-infojet.html"}} + {{#if rolled.isEchec}} +
La potion fait effet! + {{alias}} a perdu 1 point de rêve et s'endort pour {{guerisonMinutes}} minutes. A son réveil, les blessures suivantes seront guéries : +
    + {{#each guerisonData.list as |guerison key|}} +
  • {{guerison}}
  • + {{/each}} +
+ {{else}} +
La potion ne fait pas effet ! Lors de votre prochain jet de récupération à Chateau Dormant, vous bénéficierez d'un bonus de {{data.herbebonus}} (appliqué automatiquement). + {{/if}} {{else}} - Lors de votre prochain jet de récupération à Chateau Dormant, vous bénéficierez d'un bonus de {{data.herbebonus}} (appliqué automatiquement). -
La potion a également été supprimée de l'équipement. + Lors de votre prochain jet de récupération à Chateau Dormant, vous bénéficierez d'un bonus de {{data.herbebonus}} (appliqué automatiquement). {{/if}} +
La potion a été supprimée de l'équipement.
diff --git a/templates/chat-fabriquer-potion-base.html b/templates/chat-fabriquer-potion-base.html index f26d5212..e298d0b7 100644 --- a/templates/chat-fabriquer-potion-base.html +++ b/templates/chat-fabriquer-potion-base.html @@ -1,6 +1,6 @@ -fabrication +fabrication

- {{alias}} a fabriqué une potion de {{categorie}} de {{herbe}}, avec {{nbBrinsPotion}} brins. + {{alias}} a fabriqué une potion de {{herbe.data.categorie}} de {{herbe.name}}, avec {{herbe.nbBrins}} brins.


From 307b66adeefc98d6433bc3b8a7d8808b3aeaf58e Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 9 Oct 2021 22:06:00 +0200 Subject: [PATCH 11/11] =?UTF-8?q?Utiliser=20images=20webp=20plut=C3=B4t=20?= =?UTF-8?q?que=20png?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/chat-resultat-alchimie.html | 2 +- templates/chat-resultat-reve-de-dragon.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/chat-resultat-alchimie.html b/templates/chat-resultat-alchimie.html index e76696fe..6788ff35 100644 --- a/templates/chat-resultat-alchimie.html +++ b/templates/chat-resultat-alchimie.html @@ -1,4 +1,4 @@ -préparation alchimique +préparation alchimique

{{alias}} essaye de réaliser sa recette Alchimique : {{recette.name}}

diff --git a/templates/chat-resultat-reve-de-dragon.html b/templates/chat-resultat-reve-de-dragon.html index f0f84b0b..5f94d708 100644 --- a/templates/chat-resultat-reve-de-dragon.html +++ b/templates/chat-resultat-reve-de-dragon.html @@ -1,4 +1,4 @@ -Rêve de Dragon +Rêve de Dragon

{{alias}} tente de maîtriser un Rêve de Dragon!