From 4eabb58a89861f1701c5bf58d8a409dafa8d95d7 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Wed, 23 Oct 2024 23:42:38 +0200 Subject: [PATCH 1/9] Fix: Message uniquement MJ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit L'utilisation de firstConnectedGM renvoie le GM, pas true si un GM est connecté. --- changelog.md | 3 +++ module/actor.js | 8 ++++---- module/actor/base-actor.js | 4 ++-- module/chat-utility.js | 6 +++--- module/misc.js | 8 ++++---- module/rdd-combat.js | 10 +++++----- module/rdd-main.js | 2 +- module/sommeil/app-astrologie.js | 2 +- module/time/rdd-calendrier.js | 6 +++--- 9 files changed, 26 insertions(+), 23 deletions(-) diff --git a/changelog.md b/changelog.md index ad50c309..583aa09a 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # 12.0 +## 12.0.16 - Le secret d'Astrobazzarh +- Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) + ## 12.0.15 - Le messager d'Astrobazzarh - Correction des faces de dés personalisés dice-so-nice - Les messages de maladies ne sont plus publics diff --git a/module/actor.js b/module/actor.js index 73c21990..b8e6cd10 100644 --- a/module/actor.js +++ b/module/actor.js @@ -1548,7 +1548,7 @@ export class RdDActor extends RdDBaseActorSang { /* -------------------------------------------- */ async appliquerAjoutExperience(rollData, hideChatMessage = 'show') { - if (!Misc.firstConnectedGM()){ + if (!Misc.isFirstConnectedGM()){ return } hideChatMessage = hideChatMessage == 'hide' || (Misc.isRollModeHiddenToPlayer() && !game.user.isGM) @@ -3011,7 +3011,7 @@ export class RdDActor extends RdDBaseActorSang { /* -------------------------------------------- */ async onCreateOwnedDraconique(item, options, id) { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { let draconique = Draconique.all().find(it => it.match(item)); if (draconique) { await draconique.onActorCreateOwned(this, item) @@ -3023,7 +3023,7 @@ export class RdDActor extends RdDBaseActorSang { /* -------------------------------------------- */ async onDeleteOwnedDraconique(item, options, id) { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { let draconique = Draconique.all().find(it => it.match(item)); if (draconique) { await draconique.onActorDeleteOwned(this, item) @@ -3033,7 +3033,7 @@ export class RdDActor extends RdDBaseActorSang { /* -------------------------------------------- */ async onDeleteOwnedCaseTmr(item, options, id) { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { let draconique = Draconique.all().find(it => it.isCase(item)); if (draconique) { await draconique.onActorDeleteCaseTmr(this, item) diff --git a/module/actor/base-actor.js b/module/actor/base-actor.js index 57fbcb07..c92b8318 100644 --- a/module/actor/base-actor.js +++ b/module/actor/base-actor.js @@ -218,7 +218,7 @@ export class RdDBaseActor extends Actor { } async creerObjetParMJ(object) { - if (!Misc.isUniqueConnectedGM()) { + if (!Misc.isFirstConnectedGM()) { RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, @@ -335,7 +335,7 @@ export class RdDBaseActor extends Actor { ui.notifications.info("Inutile de se vendre à soi-même"); return; } - if (!Misc.isUniqueConnectedGM()) { + if (!Misc.isFirstConnectedGM()) { RdDBaseActor.remoteActorCall({ actorId: achat.vendeurId ?? achat.acheteurId, method: 'achatVente', diff --git a/module/chat-utility.js b/module/chat-utility.js index 76792c86..5f515ce8 100644 --- a/module/chat-utility.js +++ b/module/chat-utility.js @@ -49,7 +49,7 @@ export class ChatUtility { /* -------------------------------------------- */ static onRemoveMessages(socketData) { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { if (socketData.part) { const toDelete = game.messages.filter(it => it.content.includes(socketData.part)); toDelete.forEach(it => it.delete()); @@ -63,7 +63,7 @@ export class ChatUtility { /* -------------------------------------------- */ static removeMessages(socketData) { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { ChatUtility.onRemoveMessages(socketData); } else { @@ -161,7 +161,7 @@ export class ChatUtility { /* -------------------------------------------- */ static handleGMChatMessage(socketData) { console.log("blindMessageToGM", socketData); - if (Misc.firstConnectedGM()) { + if (Misc.isFirstConnectedGM()) { ChatMessage.create({ user: game.user.id, whisper: ChatUtility.getGMs(), diff --git a/module/misc.js b/module/misc.js index c22fe21e..a3f5f43d 100644 --- a/module/misc.js +++ b/module/misc.js @@ -195,7 +195,7 @@ export class Misc { return document } } - else if (Misc.isUniqueConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) { + else if (Misc.isFirstConnectedGM() || (Misc.connectedGMs().length == 0 && Misc.isOwnerPlayer(document))) { return document } return undefined @@ -206,14 +206,14 @@ export class Misc { } static isOwnerPlayerOrUniqueConnectedGM(actor) { - return Misc.isOwnerPlayer(actor) ?? Misc.isUniqueConnectedGM(); + return Misc.isOwnerPlayer(actor) ?? Misc.isFirstConnectedGM(); } /** * @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id */ - static isUniqueConnectedGM() { - return game.user.id == Misc.firstConnectedGMId(); + static isFirstConnectedGM() { + return game.user == Misc.firstConnectedGM(); } static firstConnectedGMId() { diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 68947438..f31f3554 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -53,7 +53,7 @@ export class RdDCombatManager extends Combat { /* -------------------------------------------- */ async onPreDeleteCombat() { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { await this.finDeRound({ terminer: true }) ChatUtility.removeChatMessageContaining(`
`) game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined) @@ -291,7 +291,7 @@ export class RdDCombatManager extends Combat { /* -------------------------------------------- */ static processPremierRoundInit() { // Check if we have the whole init ! - if (Misc.isUniqueConnectedGM() && game.combat.current.round == 1) { + if (Misc.isFirstConnectedGM() && game.combat.current.round == 1) { let initMissing = game.combat.combatants.find(it => !it.initiative); if (!initMissing) { // Premier round ! for (let combatant of game.combat.combatants) { @@ -454,7 +454,7 @@ export class RdDCombat { /* -------------------------------------------- */ static combatNouveauTour(combat) { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); if (turn?.actor) { RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id); @@ -511,7 +511,7 @@ export class RdDCombat { /* -------------------------------------------- */ static onMsgDefense(msg) { let defenderToken = canvas.tokens.get(msg.defenderTokenId); - if (defenderToken && Misc.isUniqueConnectedGM()) { + if (defenderToken && Misc.isFirstConnectedGM()) { const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme); rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll); @@ -919,7 +919,7 @@ export class RdDCombat { dmg: attackerRoll.dmg, }; - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { await this._chatMessageDefense(paramChatDefense, defenderRoll); } else { diff --git a/module/rdd-main.js b/module/rdd-main.js index 18778107..e4c58875 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -278,7 +278,7 @@ export class SystemReveDeDragon { /* Foundry VTT Initialization */ /* -------------------------------------------- */ game.system.rdd.calendrier = new RdDCalendrier() - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { new Migrations().migrate() this.messageDeBienvenue() import("https://www.uberwald.me/fvtt_appcount/count-class-ready.js").then(moduleCounter => { diff --git a/module/sommeil/app-astrologie.js b/module/sommeil/app-astrologie.js index 0e33a748..e8727294 100644 --- a/module/sommeil/app-astrologie.js +++ b/module/sommeil/app-astrologie.js @@ -186,7 +186,7 @@ export class AppAstrologie extends Application { date: this.html.find('[name="joursAstrologie"]').val(), userId: game.user.id } - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { game.system.rdd.calendrier.requestNombreAstral(socketData); } else { game.socket.emit(SYSTEM_SOCKET_ID, { diff --git a/module/time/rdd-calendrier.js b/module/time/rdd-calendrier.js index b2a4129d..727599c2 100644 --- a/module/time/rdd-calendrier.js +++ b/module/time/rdd-calendrier.js @@ -48,7 +48,7 @@ export class RdDCalendrier extends Application { constructor() { super(); this.timestamp = RdDTimestamp.getWorldTime(); - if (Misc.isUniqueConnectedGM()) { // Uniquement si GM + if (Misc.isFirstConnectedGM()) { // Uniquement si GM RdDTimestamp.setWorldTime(this.timestamp); this.rebuildNombresAstraux(); // Ensure always up-to-date } @@ -258,7 +258,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async rebuildNombresAstraux() { - if (Misc.isUniqueConnectedGM()) { + if (Misc.isFirstConnectedGM()) { const nombresAstraux = this.getNombresAstraux() let newNombresAstraux = []; for (let i = 0; i < MAX_NOMBRE_ASTRAL; i++) { @@ -337,7 +337,7 @@ export class RdDCalendrier extends Application { /* -------------------------------------------- */ async requestNombreAstral(request) { const actor = game.actors.get(request.id); - if (Misc.isUniqueConnectedGM()) { // Only once + if (Misc.isFirstConnectedGM()) { // Only once console.log(request); let jourDiff = this.getLectureAstrologieDifficulte(request.date); let niveau = Number(request.astrologie.system.niveau) + Number(request.conditions) + Number(jourDiff) + Number(request.etat); -- 2.35.3 From 2429f5b20a4fd39ec965543c9586938bbcef9b28 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Wed, 23 Oct 2024 23:51:19 +0200 Subject: [PATCH 2/9] Version 12.0.16 --- system.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system.json b/system.json index a92ba9db..580788f4 100644 --- a/system.json +++ b/system.json @@ -1,8 +1,8 @@ { "id": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", - "version": "12.0.15", - "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.15.zip", + "version": "12.0.16", + "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.16.zip", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md", "compatibility": { -- 2.35.3 From c8afb6e98aac310c484c09444b03f800c3869590 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 25 Oct 2024 23:28:09 +0200 Subject: [PATCH 3/9] Afficher le nom du token au lieu du nom d'Acteur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dans les messages d'automatisation de combat, le nom des tokens est utilisé au lieu d'utiliser le nom de l'acteur. Ceci permet de ne pas dévoiler un nom générique (Villageois) si le token a un nom personnalisé. --- changelog.md | 1 + module/actor-sheet.js | 10 +-- module/actor/base-actor-reve.js | 12 ++-- module/rdd-combat.js | 79 +++++++++++++++------- module/rdd-token-hud.js | 8 +-- module/rdd-utility.js | 9 +++ module/targets.js | 17 +++-- templates/chat-demande-attaque-etotal.html | 14 ++-- templates/chat-demande-defense.html | 38 ++++++----- 9 files changed, 121 insertions(+), 67 deletions(-) diff --git a/changelog.md b/changelog.md index 583aa09a..c5ac1466 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,7 @@ # 12.0 ## 12.0.16 - Le secret d'Astrobazzarh - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) +- Les noms affichés dans les automatisations de combat sont maintenant ceux des tokens plutôt que ceux des acteurs ## 12.0.15 - Le messager d'Astrobazzarh - Correction des faces de dés personalisés dice-so-nice diff --git a/module/actor-sheet.js b/module/actor-sheet.js index 5e2ff8b6..8e5ab07c 100644 --- a/module/actor-sheet.js +++ b/module/actor-sheet.js @@ -220,18 +220,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet { // Points de reve actuel this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true)) this.html.find('.empoignade-label a').click(async event => RdDEmpoignade.onAttaqueEmpoignadeFromItem(RdDSheetUtility.getItem(event, this.actor))) - this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)))) + + this.html.find('.roll-arme').click(async event => this.actor.rollArme(foundry.utils.duplicate(this._getEventArmeCombat(event)), 'competence')) // Initiative pour l'arme this.html.find('.arme-initiative a').click(async event => { - let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id); + let combatant = game.combat.combatants.find(c => c.actor.id == this.actor.id) if (combatant) { - let action = this._getEventArmeCombat(event); - RdDCombatManager.rollInitiativeAction(combatant._id, action); + RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event)); } else { ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); } - }); + }) // Display TMR this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal")) diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 06b560f5..4610fe82 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -327,14 +327,15 @@ export class RdDBaseActorReve extends RdDBaseActor { const competence = this.getCompetence(idOrName); let rollData = { carac: this.system.carac, competence: competence, arme: options.arme } if (competence.type == ITEM_TYPES.competencecreature) { + const token = RdDUtility.getSelectedToken(this) const arme = RdDItemCompetenceCreature.armeCreature(competence) if (arme && options.tryTarget && Targets.hasTargets()) { - Targets.selectOneToken(target => { + Targets.selectOneTargetToken(target => { if (arme.action == "possession") { RdDPossession.onAttaquePossession(target, this, competence) } else { - RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) + RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme) } }); return; @@ -364,7 +365,8 @@ export class RdDBaseActorReve extends RdDBaseActor { * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession * @returns */ - rollArme(arme, categorieArme = "competence") { + rollArme(arme, categorieArme, token) { + token = token ?? RdDUtility.getSelectedToken(this) const compToUse = this.$getCompetenceArme(arme, categorieArme) if (!RdDItemArme.isArmeUtilisable(arme)) { ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) @@ -385,7 +387,7 @@ export class RdDBaseActorReve extends RdDBaseActor { return } - Targets.selectOneToken(target => { + Targets.selectOneTargetToken(target => { if (Targets.isTargetEntite(target)) { ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`); return @@ -395,7 +397,7 @@ export class RdDBaseActorReve extends RdDBaseActor { if (competence.isCompetencePossession()) { return RdDPossession.onAttaquePossession(target, this, competence); } - RdDCombat.rddCombatTarget(target, this).attaque(competence, arme); + RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme); }) } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index f31f3554..e3e404c0 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -457,7 +457,7 @@ export class RdDCombat { if (Misc.isFirstConnectedGM()) { let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); if (turn?.actor) { - RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id); + RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token); // TODO Playaudio for player?? } } @@ -469,30 +469,29 @@ export class RdDCombat { } /* -------------------------------------------- */ - static rddCombatTarget(target, attacker) { - const defender = target?.actor; - const defenderTokenId = target?.id; - return new RdDCombat(attacker, defender, defenderTokenId, target) + static rddCombatTarget(target, attacker, attackerToken) { + return new RdDCombat(attacker, attackerToken?.id, target?.actor, target?.id, target) } /* -------------------------------------------- */ - static rddCombatForAttackerAndDefender(attackerId, defenderTokenId) { - const attacker = game.actors.get(attackerId); - let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined; + static rddCombatForAttackerAndDefender(attackerId, attackerTokenId, defenderTokenId) { + const attacker = game.actors.get(attackerId) + const defenderToken = defenderTokenId ? canvas.tokens.get(defenderTokenId) : undefined + let defender = defenderToken?.actor; let target = undefined if (!defenderTokenId || !defender) { console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`); target = Targets.getTarget() if (!target) { - return; + return } defenderTokenId = target.id; defender = target.actor; if (!defenderTokenId || !defender) { - return; + return } } - return new RdDCombat(attacker, defender, defenderTokenId, target) + return new RdDCombat(attacker, attackerTokenId, defender, defenderTokenId, target) } /* -------------------------------------------- */ @@ -503,7 +502,7 @@ export class RdDCombat { let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; defender.encaisserDommages(attackerRoll, attacker); - const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); + const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerTokenId, msg.defenderTokenId); rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); } } @@ -512,7 +511,7 @@ export class RdDCombat { static onMsgDefense(msg) { let defenderToken = canvas.tokens.get(msg.defenderTokenId); if (defenderToken && Misc.isFirstConnectedGM()) { - const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); + const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerTokenId, msg.defenderTokenId); rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme); rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll); } @@ -545,6 +544,7 @@ export class RdDCombat { html.on("click", button, event => { const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( event.currentTarget.attributes['data-attackerId']?.value, + event.currentTarget.attributes['data-attackerTokenId']?.value, event.currentTarget.attributes['data-defenderTokenId']?.value); if (rddCombat) { rddCombat.onEvent(button, event); @@ -560,15 +560,30 @@ export class RdDCombat { } /* -------------------------------------------- */ - constructor(attacker, defender, defenderTokenId, target) { + constructor(attacker, attackerTokenId, defender, defenderTokenId, target) { this.attacker = attacker this.defender = defender this.target = target this.attackerId = this.attacker.id this.defenderId = this.defender.id + this.attackerTokenId = attackerTokenId this.defenderTokenId = defenderTokenId } + _extractDefenderTokenData() { + if (this.target) { + return Targets.extractTokenData(this.target) + } + const token = canvas.tokens.get(this.defenderTokenId); + return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(this.defenderTokenId, this.defender) + } + + _extractAttackerTokenData(){ + const token = canvas.tokens.get(this.attackerTokenId); + return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(this.attackerTokenId, this.attacker) + } + + /* -------------------------------------------- */ async onEvent(button, event) { const chatMessage = ChatUtility.getChatMessage(event); @@ -769,7 +784,7 @@ export class RdDCombat { } RdDEmpoignade.checkEmpoignadeEnCours(this.attacker) - let rollData = this._prepareAttaque(competence, arme); + let rollData = this._prepareAttaque(competence, arme) console.log("RdDCombat.attaque >>>", rollData); if (arme) { this.attacker.verifierForceMin(arme); @@ -795,18 +810,22 @@ export class RdDCombat { dialog.render(true); } + /* -------------------------------------------- */ _prepareAttaque(competence, arme) { + const sourceToken = this._extractAttackerTokenData(); let rollData = { + alias: sourceToken.name, passeArme: foundry.utils.randomID(16), mortalite: arme?.system.mortalite, competence: competence, surprise: this.attacker.getSurprise(true), surpriseDefenseur: this.defender.getSurprise(true), - targetToken: Targets.extractTokenData(this.target), + sourceToken: sourceToken, + targetToken: this._extractDefenderTokenData(), essais: {} }; - + if (this.attacker.isCreatureEntite()) { RdDItemCompetenceCreature.setRollDataCreature(rollData); } @@ -850,7 +869,8 @@ export class RdDCombat { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { alias: this.attacker.name, attackerId: this.attackerId, - defenderTokenId: this.defenderTokenId, + attackerToken: this._extractAttackerTokenData(), + defenderToken: this._extractDefenderTokenData(), isForce: isForce, isFinesse: isFinesse, isRapide: isRapide, @@ -900,6 +920,7 @@ export class RdDCombat { const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive()) esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); + const paramChatDefense = { passeArme: attackerRoll.passeArme, essais: attackerRoll.essais, @@ -908,7 +929,8 @@ export class RdDCombat { attacker: this.attacker, attackerId: this.attackerId, esquives: esquives, - defenderTokenId: this.defenderTokenId, + attackerToken: this._extractAttackerTokenData(), + defenderToken: this._extractDefenderTokenData(), mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps, armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme), diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0, @@ -946,6 +968,7 @@ export class RdDCombat { game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_defense", data: { attackerId: this.attacker?.id, + attackerTokenId: this.attackerTokenId, defenderId: this.defender?.id, defenderTokenId: this.defenderTokenId, defenderRoll: defenderRoll, @@ -980,7 +1003,8 @@ export class RdDCombat { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { attackerId: this.attackerId, attacker: this.attacker, - defenderTokenId: this.defenderTokenId, + attackerToken: this._extractAttackerTokenData(), + defenderToken: this._extractDefenderTokenData(), essais: attackerRoll.essais }) }); @@ -1051,9 +1075,13 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareParade(attackerRoll, armeParade, competenceParade) { + const defenderToken = this._extractDefenderTokenData() let defenderRoll = { + alias: defenderToken?.name, passeArme: attackerRoll.passeArme, diffLibre: attackerRoll.diffLibre, + attackerToken: this._extractAttackerTokenData(), + defenderToken: defenderToken, attackerRoll: attackerRoll, competence: this.defender.getCompetence(competenceParade), arme: armeParade, @@ -1132,9 +1160,13 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareEsquive(attackerRoll, competence) { + const defenderToken= this._extractDefenderTokenData() let rollData = { + alias: defenderToken?.name, passeArme: attackerRoll.passeArme, diffLibre: attackerRoll.diffLibre, + attackerToken: this._extractAttackerTokenData(), + defenderToken: defenderToken, attackerRoll: attackerRoll, competence: competence, surprise: this.defender.getSurprise(true), @@ -1296,6 +1328,7 @@ export class RdDCombat { msg: "msg_encaisser", data: { attackerId: this.attackerId, + attackerTokenId: this.attackerTokenId, defenderTokenId: defenderTokenId, attackerRoll: attackerRoll } @@ -1305,17 +1338,17 @@ export class RdDCombat { } /* -------------------------------------------- */ - static async displayActorCombatStatus(combat, actor, tokenId) { + static async displayActorCombatStatus(combat, actor, token) { let formData = { combatId: combat._id, - alias: actor.name, + alias: token.name ?? actor.name, etatGeneral: actor.getEtatGeneral(), isSonne: actor.getSonne(), blessuresStatus: actor.computeResumeBlessure(), SConst: actor.getSConst(), actorId: actor.id, actor: actor, - tokenId: tokenId, + tokenId: token.id, isGrave: actor.countBlessures(it => it.isGrave()) > 0, isCritique: actor.countBlessures(it => it.isCritique()) > 0 } diff --git a/module/rdd-token-hud.js b/module/rdd-token-hud.js index 0cdf7adf..a230f8ee 100644 --- a/module/rdd-token-hud.js +++ b/module/rdd-token-hud.js @@ -37,7 +37,7 @@ export class RdDTokenHud { // initiative await RdDTokenHud.addExtensionHudInit(html, combatant, actions); // combat - await RdDTokenHud.addExtensionHudCombat(html, combatant, actions); + await RdDTokenHud.addExtensionHudCombat(html, combatant, token, actions); } @@ -68,8 +68,8 @@ export class RdDTokenHud { }); } - static async addExtensionHudCombat(html, combatant, actions) { - const hudData = { combatant, actions, commandes: [] }; + static async addExtensionHudCombat(html, combatant, token, actions) { + const hudData = { combatant, token, actions, commandes: [] }; const controlIconTarget = html.find('.control-icon[data-action=target]'); await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData, (event) => { @@ -80,7 +80,7 @@ export class RdDTokenHud { combatant.actor.conjurerPossession(possession); } else { - combatant.actor.rollArme(action); + combatant.actor.rollArme(action, 'competence', token) } }); } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 20b10526..2153bfa7 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -741,6 +741,15 @@ export class RdDUtility { return undefined; } + static getSelectedToken(actor) { + if (canvas.tokens.controlled.length > 0) { + const tokens = canvas.tokens.controlled + .filter(it => it.actor.id == actor.id) + return tokens[0] + } + return undefined + } + static getSelectedActor(msgPlayer = undefined) { if (canvas.tokens.controlled.length == 1) { let token = canvas.tokens.controlled[0]; diff --git a/module/targets.js b/module/targets.js index 09d83e5d..98f76f2a 100644 --- a/module/targets.js +++ b/module/targets.js @@ -13,18 +13,21 @@ export class Targets { static extractTokenData(target) { return { id: target?.id, name: target?.document.name, img: target?.document.texture.src ?? target?.actor.img ?? 'icons/svg/mystery-man.svg' }; } - + static buildActorTokenData(tokenId, actor) { + return { id: tokenId, name: actor.name, img: actor.img ?? 'icons/svg/mystery-man.svg' }; + } static isTargetEntite(target) { return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE; } - static async selectOneToken(onSelectTarget = target => { }) { - const targets = Targets.listTargets(); + static async selectOneTargetToken(onSelectTarget = target => { }) { + const targets = Targets.listTargets() switch (targets.length) { - case 0: return; + case 0: + return case 1: - onSelectTarget(targets[0]); - return; + onSelectTarget(targets[0]) + return default: { const selectData = { @@ -32,7 +35,7 @@ export class Targets { label: "Choisir une seule des cibles", list: targets.map(it => Targets.extractTokenData(it)) }; - DialogSelect.select(selectData, onSelectTarget); + DialogSelect.select(selectData, onSelectTarget) } } } diff --git a/templates/chat-demande-attaque-etotal.html b/templates/chat-demande-attaque-etotal.html index 6c88fc0f..c72007d7 100644 --- a/templates/chat-demande-attaque-etotal.html +++ b/templates/chat-demande-attaque-etotal.html @@ -3,20 +3,22 @@
{{#if (eq attacker.type 'personnage')}} {{#unless essais.attaqueChance}} - Faire appel à la chance + + Faire appel à la chance
{{/unless}} {{#if (gt attacker.system.compteurs.destinee.value 0)}} - Utiliser la destinée + + Utiliser la destinée
{{/if}} {{/if}} - + Tirer la maladresse !
\ No newline at end of file diff --git a/templates/chat-demande-defense.html b/templates/chat-demande-defense.html index 5d58505b..1260e009 100644 --- a/templates/chat-demande-defense.html +++ b/templates/chat-demande-defense.html @@ -1,17 +1,17 @@
{{#if (eq surprise 'totale')}} - {{defender.name}} est totalement surpris + {{defenderToken.name}} est totalement surpris {{else if essais.defense}} - {{defender.name}} doit : + {{defenderToken.name}} doit : {{else}} - {{defender.name}} doit se défendre + {{defenderToken.name}} doit se défendre {{~#if (eq surprise 'demi')}} avec une significative {{/if}} d'une attaque {{~#if attaqueParticuliere}} particulière en {{~#if (eq attaqueParticuliere 'finesse')}} finesse {{else if (eq attaqueParticuliere 'force')}} force {{else if (eq attaqueParticuliere 'rapidite')}} rapidité {{/if~}} - {{/if}} de {{attacker.name}} ({{attaqueArme.name}}): + {{/if}} de {{attackerToken.name}} ({{attaqueArme.name}}): {{/if}} @@ -20,15 +20,17 @@ {{#if essais.defense}} {{#unless essais.defenseChance}} {{#if (eq defender.type 'personnage')}} - Faire appel à la chance + + Faire appel à la chance
{{/if}} {{#if (eq defender.type 'personnage')}} {{#if (gt defender.system.compteurs.destinee.value 0)}} - Utiliser la destinée + + Utiliser la destinée
{{/if}} @@ -36,24 +38,26 @@ {{/unless}} {{else}} {{#each armes as |arme key|}} - + Parer avec {{arme.name}} à {{../diffLibre }}{{#if arme.system.nbUsage}} (Utilisations : {{arme.system.nbUsage}}){{/if}}
{{/each}} {{#if mainsNues}} - + Parer à mains nues à {{diffLibre}}{{#if arme.system.nbUsage}} (Utilisations : {{arme.system.nbUsage}}){{/if}}
{{/if}} {{#if (ne attaqueCategorie 'tir')}} {{#each esquives as |esquive key|}} - - {{log 'esquive' esquive}} + {{esquive.name}} à {{../diffLibre}} {{#if esquive.system.nbUsage}} (Utilisations : {{esquive.system.nbUsage}}){{/if}}
@@ -61,8 +65,8 @@ {{/if}} {{/if}} {{/unless}} - + Encaisser à {{plusMoins dmg.total}} {{#if (eq dmg.mortalite 'non-mortel')~}} (non-mortel) ! -- 2.35.3 From c150dee6dee096ee0b0fccee98a6b6a1f28ba79c Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 26 Oct 2024 01:20:03 +0200 Subject: [PATCH 4/9] =?UTF-8?q?Am=C3=A9lioration=20message=20encaissement?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- styles/simple.css | 5 +++++ templates/chat-resultat-encaissement.html | 12 ++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/styles/simple.css b/styles/simple.css index 491e0f7b..f9eb048f 100644 --- a/styles/simple.css +++ b/styles/simple.css @@ -1561,6 +1561,11 @@ div.control-icon.token-hud-icon { height: 100%; object-fit: contain; } +.chat-inline-icon { + border: 0; + padding: 1px; + vertical-align: text-top; +} #sidebar-tabs { flex: 0 0 28px; diff --git a/templates/chat-resultat-encaissement.html b/templates/chat-resultat-encaissement.html index 737eef53..d2c7ce22 100644 --- a/templates/chat-resultat-encaissement.html +++ b/templates/chat-resultat-encaissement.html @@ -18,18 +18,18 @@
Jet d'encaissement de {{roll.total}} - {{#unless (eq armure 0)}}, l'armure a protègé de {{armure}} + {{~#unless (eq armure 0)}}, l'armure a protègé de {{armure}} {{~#unless (eq penetration 0)}} (pénétration de {{penetration}}){{/unless}} - {{~/unless}}, total: {{total}} + {{~/unless~}}, total: {{total}}
{{alias}} {{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup {{else if mort}}vient de mourir {{else if blessure}} {{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.label}} - {{else}}subit une contusion + {{~else~}}subit une contusion {{~/if~}} - {{else}}s'en sort sans une égratignure + {{~else~}}s'en sort sans une égratignure {{~/if~}} {{~#unless (eq dmg.mortalite 'entiteincarnee')}} @@ -39,11 +39,11 @@ {{/unless~}} {{~#if (gt endurance 0)}} {{~#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance - {{#if (ne vie 0)}}, {{vie}} points de vie{{/if}} + {{~#if (ne vie 0)}}, {{vie}} points de vie{{/if~}} {{/if}} {{#if (ne dmg.mortalite 'entiteincarnee')}} {{#if (gt endurance 1)}}et - {{#if sonne}}est sonné jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}! + {{#if sonne}}est sonné jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}! {{#if hasPlayerOwner}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}} {{/if}} {{/if}} -- 2.35.3 From 5c78ecb64e3597c1b31e38cb39bccc76de3ab7a3 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 26 Oct 2024 01:33:20 +0200 Subject: [PATCH 5/9] Localisation des blessures en regle optionnelle --- changelog.md | 1 + module/actor/base-actor-reve.js | 23 +++-- module/actor/base-actor-sang.js | 8 +- module/actor/entite.js | 2 +- module/dialog-validation-encaissement.js | 9 +- module/rdd-combat.js | 102 +++++++++++------------ module/rdd-roll-encaisser.js | 2 +- module/rdd-utility.js | 17 ++-- module/settings/regles-optionnelles.js | 1 + 9 files changed, 83 insertions(+), 82 deletions(-) diff --git a/changelog.md b/changelog.md index c5ac1466..baf5946a 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,7 @@ ## 12.0.16 - Le secret d'Astrobazzarh - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) - Les noms affichés dans les automatisations de combat sont maintenant ceux des tokens plutôt que ceux des acteurs +- Ajout d'une option pour la localisation des blessures ## 12.0.15 - Le messager d'Astrobazzarh - Correction des faces de dés personalisés dice-so-nice diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 4610fe82..02e549d5 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -415,41 +415,40 @@ export class RdDBaseActorReve extends RdDBaseActor { /* -------------------------------------------- */ async encaisser() { await RdDEncaisser.encaisser(this) } - async encaisserDommages(rollData, attacker = undefined, show = undefined) { + async encaisserDommages(rollData, attacker = undefined, attackerToken = undefined, show = undefined) { if (attacker && !await attacker.accorder(this, 'avant-encaissement')) { return; } const armure = await this.computeArmure(rollData); if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) { - await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show); + await this.encaisserDommagesValidationGR(rollData, armure, attackerToken, show); } else { - const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE }); - await this.$onEncaissement(jet, show, attacker); + const jet = await RdDUtility.jetEncaissement(this, rollData, armure, { showDice: SHOW_DICE }); + await this.$onEncaissement(jet, show, attackerToken) } } - async encaisserDommagesValidationGR(rollData, armure, attackerId, show) { + async encaisserDommagesValidationGR(rollData, armure, attackerToken, show) { if (!game.user.isGM) { RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, method: 'encaisserDommagesValidationGR', - args: [rollData, armure, attackerId, show] - }); + args: [rollData, armure, attackerToken, show] + }) } else { - const attacker = game.actors.get(attackerId); DialogValidationEncaissement.validerEncaissement(this, rollData, armure, - jet => this.$onEncaissement(jet, show, attacker)); + jet => this.$onEncaissement(jet, show, attackerToken)); } } - async $onEncaissement(jet, show, attacker) { - await this.onAppliquerJetEncaissement(jet, attacker); + async $onEncaissement(jet, show, attackerToken) { + await this.onAppliquerJetEncaissement(jet, attackerToken); await this.$afficherEncaissement(jet, show); } - async onAppliquerJetEncaissement(encaissement, attacker) { } + async onAppliquerJetEncaissement(encaissement, attackerToken) { } async $afficherEncaissement(encaissement, show) { foundry.utils.mergeObject(encaissement, { diff --git a/module/actor/base-actor-sang.js b/module/actor/base-actor-sang.js index 978c27c2..48e5299a 100644 --- a/module/actor/base-actor-sang.js +++ b/module/actor/base-actor-sang.js @@ -89,9 +89,9 @@ export class RdDBaseActorSang extends RdDBaseActorReve { /* -------------------------------------------- */ - async onAppliquerJetEncaissement(encaissement, attacker) { + async onAppliquerJetEncaissement(encaissement, attackerToken) { const santeOrig = foundry.utils.duplicate(this.system.sante); - const blessure = await this.ajouterBlessure(encaissement, attacker); // Will update the result table + const blessure = await this.ajouterBlessure(encaissement, attackerToken); // Will update the result table const perteVie = await this.santeIncDec("vie", -encaissement.vie); const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique()); @@ -169,7 +169,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { /* -------------------------------------------- */ - async ajouterBlessure(encaissement, attacker = undefined) { + async ajouterBlessure(encaissement, attackerToken = undefined) { if (encaissement.gravite < 0) return; if (encaissement.gravite > 0) { while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) { @@ -181,7 +181,7 @@ export class RdDBaseActorSang extends RdDBaseActorReve { } } const endActuelle = this.getEnduranceActuelle(); - const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attacker); + const blessure = await RdDItemBlessure.createBlessure(this, encaissement.gravite, encaissement.dmg?.loc.label ?? '', attackerToken); if (blessure.isCritique()) { encaissement.endurance = endActuelle; } diff --git a/module/actor/entite.js b/module/actor/entite.js index 70bc0577..ff0ad06a 100644 --- a/module/actor/entite.js +++ b/module/actor/entite.js @@ -74,7 +74,7 @@ export class RdDEntite extends RdDBaseActorReve { return [STATUSES.StatusComma].includes(effectId); } - async onAppliquerJetEncaissement(encaissement, attacker) { + async onAppliquerJetEncaissement(encaissement, attackerToken) { const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); foundry.utils.mergeObject(encaissement, { resteEndurance: perteEndurance.newValue, diff --git a/module/dialog-validation-encaissement.js b/module/dialog-validation-encaissement.js index d4c41f61..c0a74d85 100644 --- a/module/dialog-validation-encaissement.js +++ b/module/dialog-validation-encaissement.js @@ -8,14 +8,13 @@ import { RdDUtility } from "./rdd-utility.js"; export class DialogValidationEncaissement extends Dialog { static async validerEncaissement(actor, rollData, armure, onEncaisser) { - let encaissement = await RdDUtility.jetEncaissement(rollData, armure, { showDice: HIDE_DICE }); + const encaissement = await RdDUtility.jetEncaissement(actor, rollData, armure, { showDice: HIDE_DICE }); const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', { actor: actor, rollData: rollData, encaissement: encaissement }); - const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser); - dialog.render(true); + new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser).render(true); } /* -------------------------------------------- */ @@ -56,14 +55,14 @@ export class DialogValidationEncaissement extends Dialog { this.html = html; this.html.find('input.encaissement-roll-result').keyup(async event => { this.forceDiceResult.total = event.currentTarget.value; - this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult}); + this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.rollData, this.armure, { showDice: HIDE_DICE, forceDiceResult: this.forceDiceResult}); this.html.find('label.encaissement-total').text(this.encaissement.total); this.html.find('label.encaissement-blessure').text(this.encaissement.blessures) }); } async onValider() { - this.encaissement = await RdDUtility.jetEncaissement(this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult}); + this.encaissement = await RdDUtility.jetEncaissement(this.actor, this.rollData, this.armure, { showDice: SHOW_DICE, forceDiceResult: this.forceDiceResult}); this.onEncaisser(this.encaissement) } } diff --git a/module/rdd-combat.js b/module/rdd-combat.js index e3e404c0..4de3fb5b 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -496,24 +496,24 @@ export class RdDCombat { /* -------------------------------------------- */ static onMsgEncaisser(msg) { - let defender = canvas.tokens.get(msg.defenderTokenId).actor; if (Misc.isOwnerPlayerOrUniqueConnectedGM()) { let attackerRoll = msg.attackerRoll; let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; + let defender = canvas.tokens.get(msg.defenderToken.id).actor; - defender.encaisserDommages(attackerRoll, attacker); - const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerTokenId, msg.defenderTokenId); + defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken); + const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id); rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); } } /* -------------------------------------------- */ static onMsgDefense(msg) { - let defenderToken = canvas.tokens.get(msg.defenderTokenId); + let defenderToken = canvas.tokens.get(msg.defenderToken.id) if (defenderToken && Misc.isFirstConnectedGM()) { - const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerTokenId, msg.defenderTokenId); - rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme); - rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll); + const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id) + rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme) + rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll) } } @@ -568,19 +568,21 @@ export class RdDCombat { this.defenderId = this.defender.id this.attackerTokenId = attackerTokenId this.defenderTokenId = defenderTokenId + this.attackerToken = RdDCombat.$extractAttackerTokenData(attacker, attackerTokenId) + this.defenderToken = RdDCombat.$extractDefenderTokenData(defender, defenderTokenId, target) } - _extractDefenderTokenData() { - if (this.target) { - return Targets.extractTokenData(this.target) + static $extractAttackerTokenData(attacker, attackerTokenId) { + const token = canvas.tokens.get(attackerTokenId); + return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(attackerTokenId, attacker) + } + + static $extractDefenderTokenData(defender, defenderTokenId, target) { + if (target) { + return Targets.extractTokenData(target) } - const token = canvas.tokens.get(this.defenderTokenId); - return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(this.defenderTokenId, this.defender) - } - - _extractAttackerTokenData(){ - const token = canvas.tokens.get(this.attackerTokenId); - return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(this.attackerTokenId, this.attacker) + const token = canvas.tokens.get(defenderTokenId); + return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(defenderTokenId, defender) } @@ -590,7 +592,6 @@ export class RdDCombat { const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll'); const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll'); console.log('RdDCombat', attackerRoll, defenderRoll); - const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value; const armeParadeId = event.currentTarget.attributes['data-armeid']?.value; const competence = event.currentTarget.attributes['data-competence']?.value; @@ -600,7 +601,7 @@ export class RdDCombat { case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); case '#parer-button': return this.parade(attackerRoll, armeParadeId); case '#esquiver-button': return this.esquive(attackerRoll, compId, competence); - case '#encaisser-button': return this.encaisser(attackerRoll, defenderRoll, defenderTokenId); + case '#encaisser-button': return this.encaisser(attackerRoll, defenderRoll); case '#echec-total-attaque': return this._onEchecTotal(attackerRoll); case '#appel-chance-attaque': return this.attacker.rollAppelChance( @@ -717,7 +718,7 @@ export class RdDCombat { }) } else { - const defenderToken = canvas.tokens.get(this.defenderTokenId); + 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) @@ -813,16 +814,15 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareAttaque(competence, arme) { - const sourceToken = this._extractAttackerTokenData(); let rollData = { - alias: sourceToken.name, + alias: this.attackerToken.name, passeArme: foundry.utils.randomID(16), mortalite: arme?.system.mortalite, competence: competence, surprise: this.attacker.getSurprise(true), surpriseDefenseur: this.defender.getSurprise(true), - sourceToken: sourceToken, - targetToken: this._extractDefenderTokenData(), + sourceToken: this.attackerToken, + targetToken: this.defenderToken, essais: {} }; @@ -867,10 +867,10 @@ export class RdDCombat { alias: this.attacker.name, whisper: ChatUtility.getOwners(this.attacker), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { - alias: this.attacker.name, + alias: this.attackerToken.name, attackerId: this.attackerId, - attackerToken: this._extractAttackerTokenData(), - defenderToken: this._extractDefenderTokenData(), + attackerToken: this.attackerToken, + defenderToken: this.defenderToken, isForce: isForce, isFinesse: isFinesse, isRapide: isRapide, @@ -920,7 +920,6 @@ export class RdDCombat { const esquives = foundry.utils.duplicate(this.defender.getCompetencesEsquive()) esquives.forEach(e => e.system.nbUsage = e?._id ? this.defender.getItemUse(e._id) : 0); - const paramChatDefense = { passeArme: attackerRoll.passeArme, essais: attackerRoll.essais, @@ -929,8 +928,8 @@ export class RdDCombat { attacker: this.attacker, attackerId: this.attackerId, esquives: esquives, - attackerToken: this._extractAttackerTokenData(), - defenderToken: this._extractDefenderTokenData(), + attackerToken: this.attackerToken, + defenderToken: this.defenderToken, mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps, armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme), diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0, @@ -954,7 +953,7 @@ export class RdDCombat { const choixDefense = await ChatMessage.create({ // message privé: du défenseur à lui même (et aux GMs) speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), - alias: this.attacker.name, + alias: this.attackerToken.name, whisper: ChatUtility.getOwners(this.defender), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), }); @@ -968,9 +967,9 @@ export class RdDCombat { game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_defense", data: { attackerId: this.attacker?.id, - attackerTokenId: this.attackerTokenId, + attackerToken: this.attackerToken, defenderId: this.defender?.id, - defenderTokenId: this.defenderTokenId, + defenderToken: this.defenderToken, defenderRoll: defenderRoll, paramChatDefense: paramChatDefense, rollMode: true @@ -1003,8 +1002,8 @@ export class RdDCombat { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { attackerId: this.attackerId, attacker: this.attacker, - attackerToken: this._extractAttackerTokenData(), - defenderToken: this._extractDefenderTokenData(), + attackerToken: this.attackerToken, + defenderToken: this.defenderToken, essais: attackerRoll.essais }) }); @@ -1075,13 +1074,12 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareParade(attackerRoll, armeParade, competenceParade) { - const defenderToken = this._extractDefenderTokenData() let defenderRoll = { - alias: defenderToken?.name, + alias: this.defenderToken?.name, passeArme: attackerRoll.passeArme, diffLibre: attackerRoll.diffLibre, - attackerToken: this._extractAttackerTokenData(), - defenderToken: defenderToken, + attackerToken: this.attackerToken, + defenderToken: this.defenderToken, attackerRoll: attackerRoll, competence: this.defender.getCompetence(competenceParade), arme: armeParade, @@ -1160,13 +1158,12 @@ export class RdDCombat { /* -------------------------------------------- */ _prepareEsquive(attackerRoll, competence) { - const defenderToken= this._extractDefenderTokenData() let rollData = { - alias: defenderToken?.name, + alias: this.defenderToken?.name, passeArme: attackerRoll.passeArme, diffLibre: attackerRoll.diffLibre, - attackerToken: this._extractAttackerTokenData(), - defenderToken: defenderToken, + attackerToken: this.attackerToken, + defenderToken: this.defenderToken, attackerRoll: attackerRoll, competence: competence, surprise: this.defender.getSurprise(true), @@ -1308,9 +1305,8 @@ export class RdDCombat { } /* -------------------------------------------- */ - async encaisser(attackerRoll, defenderRoll, defenderTokenId) { - defenderTokenId = defenderTokenId || this.defenderTokenId; - console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId); + async encaisser(attackerRoll, defenderRoll) { + console.log("RdDCombat.encaisser >>>", attackerRoll, defenderRoll); if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) { this._onEchecTotal(defenderRoll); @@ -1318,19 +1314,19 @@ export class RdDCombat { if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) { attackerRoll.attackerId = this.attackerId; - attackerRoll.defenderTokenId = defenderTokenId; + attackerRoll.defenderTokenId = this.defenderToken.id; await this.computeRecul(defenderRoll); - await this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show); + await this.defender.encaisserDommages(attackerRoll, this.attacker, this.attackerToken, defenderRoll?.show); } else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_encaisser", data: { attackerId: this.attackerId, - attackerTokenId: this.attackerTokenId, - defenderTokenId: defenderTokenId, - attackerRoll: attackerRoll + attackerRoll: attackerRoll, + attackerToken: this.attackerToken, + defenderToken: this.defenderToken } }); } @@ -1354,12 +1350,12 @@ export class RdDCombat { } await ChatMessage.create({ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), - alias: actor.name + alias: token.name ?? actor.name }) await ChatMessage.create({ content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), whisper: ChatUtility.getOwners(actor), - alias: actor.name + alias: token.name ?? actor.name }); } } \ No newline at end of file diff --git a/module/rdd-roll-encaisser.js b/module/rdd-roll-encaisser.js index a9fc2d84..14748a6e 100644 --- a/module/rdd-roll-encaisser.js +++ b/module/rdd-roll-encaisser.js @@ -72,6 +72,6 @@ export class RdDEncaisser extends Dialog { encaisserSpecial: this.encaisserSpecial, mortalite: mortalite } - }); + }) } } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 2153bfa7..70950c74 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -563,14 +563,14 @@ export class RdDUtility { } /* -------------------------------------------- */ - static async jetEncaissement(rollData, armure, options = { showDice: HIDE_DICE }) { + static async jetEncaissement(actor, rollData, armure, options = { showDice: HIDE_DICE }) { const diff = Math.abs(rollData.diffLibre); let formula = RdDUtility.formuleEncaissement(diff, options) const roll = await RdDDice.roll(formula, options); RdDUtility.remplaceDeMinParDifficulte(roll, diff, options); - return await RdDUtility.prepareEncaissement(rollData, roll, armure); + return await RdDUtility.prepareEncaissement(actor, rollData, roll, armure); } static remplaceDeMinParDifficulte(roll, diff, options) { @@ -602,15 +602,20 @@ export class RdDUtility { } /* -------------------------------------------- */ - static async prepareEncaissement(rollData, roll, armure) { + static async prepareEncaissement(actor, rollData, roll, armure) { // La difficulté d'ataque s'ajoute aux dégâts const bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0 const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite); const over20 = Math.max(jetTotal - 20, 0); - encaissement.dmg = rollData.dmg; - encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type); - encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'; + encaissement.dmg = rollData.dmg + if (ReglesOptionnelles.isUsing('localisation-aleatoire')){ + encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(actor.type) + encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;' + } + else{ + encaissement.dmg.loc = {label:''} + } encaissement.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre encaissement.roll = roll; encaissement.armure = armure; diff --git a/module/settings/regles-optionnelles.js b/module/settings/regles-optionnelles.js index 3eac1e2d..02c2cd60 100644 --- a/module/settings/regles-optionnelles.js +++ b/module/settings/regles-optionnelles.js @@ -11,6 +11,7 @@ const listeReglesOptionnelles = [ { group: 'Récupération', name: 'recuperation-moral', descr: "Le moral revient vers 0 durant Château Dormant"}, + { group: 'Règles de combat', name: 'localisation-aleatoire', descr: "Proposer une localisation aléatoire des blessures" }, { group: 'Règles de combat', name: 'recul', descr: "Appliquer le recul en cas de particulière en force ou de charge" }, { group: 'Règles de combat', name: 'resistanceArmeParade', descr: "Faire le jet de résistance des armes lors de parades pouvant les endommager" }, { group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" }, -- 2.35.3 From a7e7eec26120b8848e6a2a5b43d1e639c94271b4 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 26 Oct 2024 01:38:36 +0200 Subject: [PATCH 6/9] Utilisation du nom du Nom du token suite (pour les encaissements) --- module/actor/base-actor-reve.js | 22 +++++++++++----------- module/rdd-combat.js | 4 ++-- templates/chat-resultat-encaissement.html | 1 - 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/module/actor/base-actor-reve.js b/module/actor/base-actor-reve.js index 02e549d5..21d2e608 100644 --- a/module/actor/base-actor-reve.js +++ b/module/actor/base-actor-reve.js @@ -415,47 +415,47 @@ export class RdDBaseActorReve extends RdDBaseActor { /* -------------------------------------------- */ async encaisser() { await RdDEncaisser.encaisser(this) } - async encaisserDommages(rollData, attacker = undefined, attackerToken = undefined, show = undefined) { + async encaisserDommages(rollData, attacker = undefined, show = undefined, attackerToken = undefined, defenderToken = undefined) { if (attacker && !await attacker.accorder(this, 'avant-encaissement')) { return; } const armure = await this.computeArmure(rollData); if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) { - await this.encaisserDommagesValidationGR(rollData, armure, attackerToken, show); + await this.encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken); } else { const jet = await RdDUtility.jetEncaissement(this, rollData, armure, { showDice: SHOW_DICE }); - await this.$onEncaissement(jet, show, attackerToken) + await this.$onEncaissement(jet, show, attackerToken, defenderToken) } } - async encaisserDommagesValidationGR(rollData, armure, attackerToken, show) { + async encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken) { if (!game.user.isGM) { RdDBaseActor.remoteActorCall({ tokenId: this.token?.id, actorId: this.id, method: 'encaisserDommagesValidationGR', - args: [rollData, armure, attackerToken, show] + args: [rollData, armure, show, attackerToken, defenderToken] }) } else { DialogValidationEncaissement.validerEncaissement(this, rollData, armure, - jet => this.$onEncaissement(jet, show, attackerToken)); + jet => this.$onEncaissement(jet, show, attackerToken, defenderToken)); } } - async $onEncaissement(jet, show, attackerToken) { + async $onEncaissement(jet, show, attackerToken, defenderToken) { await this.onAppliquerJetEncaissement(jet, attackerToken); - await this.$afficherEncaissement(jet, show); + await this.$afficherEncaissement(jet, show, defenderToken); } async onAppliquerJetEncaissement(encaissement, attackerToken) { } - async $afficherEncaissement(encaissement, show) { + async $afficherEncaissement(encaissement, show, defenderToken) { foundry.utils.mergeObject(encaissement, { - alias: this.name, + alias: defenderToken?.name ?? this.name, hasPlayerOwner: this.hasPlayerOwner, show: show ?? {} - }); + }, {overwrite: false}); await ChatUtility.createChatWithRollMode( { diff --git a/module/rdd-combat.js b/module/rdd-combat.js index 4de3fb5b..22cca49a 100644 --- a/module/rdd-combat.js +++ b/module/rdd-combat.js @@ -887,7 +887,7 @@ export class RdDCombat { attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } attackerRoll.show = { - cible: this.target ? this.defender.name : 'la cible', + cible: this.defenderToken?.name ?? 'la cible', isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') } await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); @@ -1317,7 +1317,7 @@ export class RdDCombat { attackerRoll.defenderTokenId = this.defenderToken.id; await this.computeRecul(defenderRoll); - await this.defender.encaisserDommages(attackerRoll, this.attacker, this.attackerToken, defenderRoll?.show); + await this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll?.show, this.attackerToken, this.defenderToken); } else { // envoi à un GM: les joueurs n'ont pas le droit de modifier les personnages qu'ils ne possèdent pas game.socket.emit(SYSTEM_SOCKET_ID, { diff --git a/templates/chat-resultat-encaissement.html b/templates/chat-resultat-encaissement.html index d2c7ce22..f10b9ee5 100644 --- a/templates/chat-resultat-encaissement.html +++ b/templates/chat-resultat-encaissement.html @@ -1,5 +1,4 @@ {{#if isGM}} -{{log this}} {{#if (gt endurance 0)}} De plus, {{alias}} a perdu {{endurance}} points d'endurance -- 2.35.3 From 3de6179e9b402940b3003e4b259ed9f3d42402a1 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnien Date: Sat, 26 Oct 2024 10:56:52 +0200 Subject: [PATCH 7/9] Move to v12.0.17 --- system.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system.json b/system.json index 580788f4..c2c2c221 100644 --- a/system.json +++ b/system.json @@ -1,8 +1,8 @@ { "id": "foundryvtt-reve-de-dragon", "title": "Rêve de Dragon", - "version": "12.0.16", - "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.16.zip", + "version": "12.0.17", + "download": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/archive/foundryvtt-reve-de-dragon-12.0.17.zip", "manifest": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/v11/system.json", "changelog": "https://www.uberwald.me/gitea/public/foundryvtt-reve-de-dragon/raw/branch/v11/changelog.md", "compatibility": { -- 2.35.3 From e05753fc0bcdf246fc80c9ac48f7da7784e7f22f Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 26 Oct 2024 21:37:47 +0200 Subject: [PATCH 8/9] =?UTF-8?q?Fix:=20niveau=20de=20comp=C3=A9tence=20non?= =?UTF-8?q?=20d=C3=A9fini?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - quand le niveau de compétence n'était pas défini, la feuille de personnage simplifiée et l'export scriptarium ne marchaient pas - on pouvait saisitr une compétence avec un niveau non défini --- module/actor/export-scriptarium/mapping.js | 3 ++- module/item-competence.js | 2 +- module/item-sheet.js | 13 ++++++++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/module/actor/export-scriptarium/mapping.js b/module/actor/export-scriptarium/mapping.js index ffb2b788..6aaee07e 100644 --- a/module/actor/export-scriptarium/mapping.js +++ b/module/actor/export-scriptarium/mapping.js @@ -327,7 +327,8 @@ export class Mapping { const txtByCategories = Object.values(byCategories) .map(it => it.competencesParNiveau) .map(byNiveau => { - const niveaux = Object.keys(byNiveau).map(it => Number(it)).sort(Misc.ascending()) + const niveaux = Object.keys(byNiveau) + .map(it => Number(it)).sort(Misc.ascending()) if (niveaux.length == 0) { return '' } diff --git a/module/item-competence.js b/module/item-competence.js index 25c6659d..f09ca6a8 100644 --- a/module/item-competence.js +++ b/module/item-competence.js @@ -190,7 +190,7 @@ export class RdDItemCompetence extends Item { /* -------------------------------------------- */ static isNiveauBase(item) { - return Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie, item.type); + return item.system.niveau == undefined || Number(item.system.niveau) == RdDItemCompetence.getNiveauBase(item.system.categorie, item.type); } /* -------------------------------------------- */ diff --git a/module/item-sheet.js b/module/item-sheet.js index 93e3a6c5..dd58ab6f 100644 --- a/module/item-sheet.js +++ b/module/item-sheet.js @@ -267,10 +267,17 @@ export class RdDItemSheet extends ItemSheet { /* -------------------------------------------- */ /** @override */ _updateObject(event, formData) { - if (this.item.type == 'sort') { - // Données de bonus de cases ? - formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue); + switch (this.item.type) { + case ITEM_TYPES.sort: + // Données de bonus de cases ? + formData['system.bonuscase'] = RdDItemSort.buildBonuscaseFromArrays(formData.bonusValue, formData.caseValue) + break + case ITEM_TYPES.competence: + if (formData['system.niveau'] == undefined) { + formData['system.niveau'] = formData['system.base'] + } } + return this.item.update(formData); } -- 2.35.3 From d1b1b2a3414253bc9e0fa1bb28098e5dbdbdd47a Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 26 Oct 2024 22:43:58 +0200 Subject: [PATCH 9/9] =?UTF-8?q?Portrait=20dans=20les=20feuilles=20simplifi?= =?UTF-8?q?=C3=A9es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- changelog.md | 3 +++ .../export-scriptarium/actor-encart-sheet.hbs | 22 ++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/changelog.md b/changelog.md index baf5946a..7cb22398 100644 --- a/changelog.md +++ b/changelog.md @@ -1,4 +1,7 @@ # 12.0 +## 12.0.18 - A la barbe d'Astrobazzarh +- Ajout du portrait sur les feuilles simplifiées + ## 12.0.16 - Le secret d'Astrobazzarh - Fix: les jets envoyés messages uniquement au MJ ne sont plus envoyés à tous les autres joueurs (et dupliqués) - Les noms affichés dans les automatisations de combat sont maintenant ceux des tokens plutôt que ceux des acteurs diff --git a/templates/actor/export-scriptarium/actor-encart-sheet.hbs b/templates/actor/export-scriptarium/actor-encart-sheet.hbs index 91d943e6..1368d560 100644 --- a/templates/actor/export-scriptarium/actor-encart-sheet.hbs +++ b/templates/actor/export-scriptarium/actor-encart-sheet.hbs @@ -1,11 +1,17 @@
-
-
-
-

{{name}} -

+
+
+ +
+
+
+

{{name}}

-
+
+ + + + {{#if system.attributs.hautrevant.value}} @@ -17,10 +23,6 @@ {{/if}} - - - - {{#if @root.options.isGM}} {{/if}} -- 2.35.3