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) !