From c8afb6e98aac310c484c09444b03f800c3869590 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Fri, 25 Oct 2024 23:28:09 +0200 Subject: [PATCH] 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) !