Compare commits

..

4 Commits

Author SHA1 Message Date
c63a1d0991 Utilisation du nom du Nom du token
suite (pour les encaissements)
2024-10-26 01:52:11 +02:00
5c78ecb64e Localisation des blessures en regle optionnelle 2024-10-26 01:33:20 +02:00
c150dee6de Amélioration message encaissement 2024-10-26 01:20:03 +02:00
c8afb6e98a Afficher le nom du token au lieu du nom d'Acteur
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é.
2024-10-26 00:10:47 +02:00
16 changed files with 187 additions and 127 deletions

View File

@ -1,6 +1,8 @@
# 12.0 # 12.0
## 12.0.16 - Le secret d'Astrobazzarh ## 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) - 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 ## 12.0.15 - Le messager d'Astrobazzarh
- Correction des faces de dés personalisés dice-so-nice - Correction des faces de dés personalisés dice-so-nice

View File

@ -220,18 +220,18 @@ export class RdDActorSheet extends RdDBaseActorSangSheet {
// Points de reve actuel // Points de reve actuel
this.html.find('.roll-reve-actuel').click(async event => this.actor.rollCarac('reve-actuel', true)) 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('.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 // Initiative pour l'arme
this.html.find('.arme-initiative a').click(async event => { 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) { if (combatant) {
let action = this._getEventArmeCombat(event); RdDCombatManager.rollInitiativeAction(combatant._id, this._getEventArmeCombat(event));
RdDCombatManager.rollInitiativeAction(combatant._id, action);
} else { } else {
ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat."); ui.notifications.info("Impossible de lancer l'initiative sans être dans un combat.");
} }
}); })
// Display TMR // Display TMR
this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal")) this.html.find('.button-tmr').click(async event => this.actor.displayTMR("normal"))

View File

@ -327,14 +327,15 @@ export class RdDBaseActorReve extends RdDBaseActor {
const competence = this.getCompetence(idOrName); const competence = this.getCompetence(idOrName);
let rollData = { carac: this.system.carac, competence: competence, arme: options.arme } let rollData = { carac: this.system.carac, competence: competence, arme: options.arme }
if (competence.type == ITEM_TYPES.competencecreature) { if (competence.type == ITEM_TYPES.competencecreature) {
const token = RdDUtility.getSelectedToken(this)
const arme = RdDItemCompetenceCreature.armeCreature(competence) const arme = RdDItemCompetenceCreature.armeCreature(competence)
if (arme && options.tryTarget && Targets.hasTargets()) { if (arme && options.tryTarget && Targets.hasTargets()) {
Targets.selectOneToken(target => { Targets.selectOneTargetToken(target => {
if (arme.action == "possession") { if (arme.action == "possession") {
RdDPossession.onAttaquePossession(target, this, competence) RdDPossession.onAttaquePossession(target, this, competence)
} }
else { else {
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme) RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme)
} }
}); });
return; return;
@ -364,7 +365,8 @@ export class RdDBaseActorReve extends RdDBaseActor {
* @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession * @param {*} categorieArme catégorie d'attaque à utiliser: competence (== melee), lancer, tir; naturelle, possession
* @returns * @returns
*/ */
rollArme(arme, categorieArme = "competence") { rollArme(arme, categorieArme, token) {
token = token ?? RdDUtility.getSelectedToken(this)
const compToUse = this.$getCompetenceArme(arme, categorieArme) const compToUse = this.$getCompetenceArme(arme, categorieArme)
if (!RdDItemArme.isArmeUtilisable(arme)) { if (!RdDItemArme.isArmeUtilisable(arme)) {
ui.notifications.warn(`Arme inutilisable: ${arme.name} a une résistance de 0 ou moins`) 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 return
} }
Targets.selectOneToken(target => { Targets.selectOneTargetToken(target => {
if (Targets.isTargetEntite(target)) { if (Targets.isTargetEntite(target)) {
ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`); ui.notifications.warn(`Vous ne pouvez pas attaquer une entité non incarnée avec votre ${arme.name}!!!!`);
return return
@ -395,7 +397,7 @@ export class RdDBaseActorReve extends RdDBaseActor {
if (competence.isCompetencePossession()) { if (competence.isCompetencePossession()) {
return RdDPossession.onAttaquePossession(target, this, competence); return RdDPossession.onAttaquePossession(target, this, competence);
} }
RdDCombat.rddCombatTarget(target, this).attaque(competence, arme); RdDCombat.rddCombatTarget(target, this, token).attaque(competence, arme);
}) })
} }
@ -413,48 +415,47 @@ export class RdDBaseActorReve extends RdDBaseActor {
/* -------------------------------------------- */ /* -------------------------------------------- */
async encaisser() { await RdDEncaisser.encaisser(this) } async encaisser() { await RdDEncaisser.encaisser(this) }
async encaisserDommages(rollData, attacker = undefined, show = undefined) { async encaisserDommages(rollData, attacker = undefined, show = undefined, attackerToken = undefined, defenderToken = undefined) {
if (attacker && !await attacker.accorder(this, 'avant-encaissement')) { if (attacker && !await attacker.accorder(this, 'avant-encaissement')) {
return; return;
} }
const armure = await this.computeArmure(rollData); const armure = await this.computeArmure(rollData);
if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) { if (ReglesOptionnelles.isUsing('validation-encaissement-gr')) {
await this.encaisserDommagesValidationGR(rollData, armure, attacker?.id, show); await this.encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken);
} }
else { else {
const jet = await RdDUtility.jetEncaissement(rollData, armure, { showDice: SHOW_DICE }); const jet = await RdDUtility.jetEncaissement(this, rollData, armure, { showDice: SHOW_DICE });
await this.$onEncaissement(jet, show, attacker); await this.$onEncaissement(jet, show, attackerToken, defenderToken)
} }
} }
async encaisserDommagesValidationGR(rollData, armure, attackerId, show) { async encaisserDommagesValidationGR(rollData, armure, show, attackerToken, defenderToken) {
if (!game.user.isGM) { if (!game.user.isGM) {
RdDBaseActor.remoteActorCall({ RdDBaseActor.remoteActorCall({
tokenId: this.token?.id, tokenId: this.token?.id,
actorId: this.id, actorId: this.id,
method: 'encaisserDommagesValidationGR', method: 'encaisserDommagesValidationGR',
args: [rollData, armure, attackerId, show] args: [rollData, armure, show, attackerToken, defenderToken]
}); })
} else { } else {
const attacker = game.actors.get(attackerId);
DialogValidationEncaissement.validerEncaissement(this, rollData, armure, DialogValidationEncaissement.validerEncaissement(this, rollData, armure,
jet => this.$onEncaissement(jet, show, attacker)); jet => this.$onEncaissement(jet, show, attackerToken, defenderToken));
} }
} }
async $onEncaissement(jet, show, attacker) { async $onEncaissement(jet, show, attackerToken, defenderToken) {
await this.onAppliquerJetEncaissement(jet, attacker); await this.onAppliquerJetEncaissement(jet, attackerToken);
await this.$afficherEncaissement(jet, show); await this.$afficherEncaissement(jet, show, defenderToken);
} }
async onAppliquerJetEncaissement(encaissement, attacker) { } async onAppliquerJetEncaissement(encaissement, attackerToken) { }
async $afficherEncaissement(encaissement, show) { async $afficherEncaissement(encaissement, show, defenderToken) {
foundry.utils.mergeObject(encaissement, { foundry.utils.mergeObject(encaissement, {
alias: this.name, alias: defenderToken?.name ?? this.name,
hasPlayerOwner: this.hasPlayerOwner, hasPlayerOwner: this.hasPlayerOwner,
show: show ?? {} show: show ?? {}
}); }, {overwrite: false});
await ChatUtility.createChatWithRollMode( await ChatUtility.createChatWithRollMode(
{ {

View File

@ -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 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 perteVie = await this.santeIncDec("vie", -encaissement.vie);
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance, blessure?.isCritique()); 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) return;
if (encaissement.gravite > 0) { if (encaissement.gravite > 0) {
while (this.countBlessures(it => it.system.gravite == encaissement.gravite) >= RdDItemBlessure.maxBlessures(encaissement.gravite) && encaissement.gravite <= 6) { 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 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()) { if (blessure.isCritique()) {
encaissement.endurance = endActuelle; encaissement.endurance = endActuelle;
} }

View File

@ -74,7 +74,7 @@ export class RdDEntite extends RdDBaseActorReve {
return [STATUSES.StatusComma].includes(effectId); return [STATUSES.StatusComma].includes(effectId);
} }
async onAppliquerJetEncaissement(encaissement, attacker) { async onAppliquerJetEncaissement(encaissement, attackerToken) {
const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance); const perteEndurance = await this.santeIncDec("endurance", -encaissement.endurance);
foundry.utils.mergeObject(encaissement, { foundry.utils.mergeObject(encaissement, {
resteEndurance: perteEndurance.newValue, resteEndurance: perteEndurance.newValue,

View File

@ -8,14 +8,13 @@ import { RdDUtility } from "./rdd-utility.js";
export class DialogValidationEncaissement extends Dialog { export class DialogValidationEncaissement extends Dialog {
static async validerEncaissement(actor, rollData, armure, onEncaisser) { 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', { const html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-validation-encaissement.html', {
actor: actor, actor: actor,
rollData: rollData, rollData: rollData,
encaissement: encaissement encaissement: encaissement
}); });
const dialog = new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser); new DialogValidationEncaissement(html, actor, rollData, armure, encaissement, onEncaisser).render(true);
dialog.render(true);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@ -56,14 +55,14 @@ export class DialogValidationEncaissement extends Dialog {
this.html = html; this.html = html;
this.html.find('input.encaissement-roll-result').keyup(async event => { this.html.find('input.encaissement-roll-result').keyup(async event => {
this.forceDiceResult.total = event.currentTarget.value; 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-total').text(this.encaissement.total);
this.html.find('label.encaissement-blessure').text(this.encaissement.blessures) this.html.find('label.encaissement-blessure').text(this.encaissement.blessures)
}); });
} }
async onValider() { 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) this.onEncaisser(this.encaissement)
} }
} }

View File

@ -457,7 +457,7 @@ export class RdDCombat {
if (Misc.isFirstConnectedGM()) { if (Misc.isFirstConnectedGM()) {
let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId); let turn = combat.turns.find(t => t.token?.id == combat.current.tokenId);
if (turn?.actor) { if (turn?.actor) {
RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token.id); RdDCombat.displayActorCombatStatus(combat, turn.actor, turn.token);
// TODO Playaudio for player?? // TODO Playaudio for player??
} }
} }
@ -469,52 +469,51 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static rddCombatTarget(target, attacker) { static rddCombatTarget(target, attacker, attackerToken) {
const defender = target?.actor; return new RdDCombat(attacker, attackerToken?.id, target?.actor, target?.id, target)
const defenderTokenId = target?.id;
return new RdDCombat(attacker, defender, defenderTokenId, target)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static rddCombatForAttackerAndDefender(attackerId, defenderTokenId) { static rddCombatForAttackerAndDefender(attackerId, attackerTokenId, defenderTokenId) {
const attacker = game.actors.get(attackerId); const attacker = game.actors.get(attackerId)
let defender = defenderTokenId ? canvas.tokens.get(defenderTokenId)?.actor : undefined; const defenderToken = defenderTokenId ? canvas.tokens.get(defenderTokenId) : undefined
let defender = defenderToken?.actor;
let target = undefined let target = undefined
if (!defenderTokenId || !defender) { if (!defenderTokenId || !defender) {
console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`); console.warn(`RdDCombat.rddCombatForAttackerAndDefender: appel avec defenderTokenId ${defenderTokenId} incorrect, ou pas de defender correspondant`);
target = Targets.getTarget() target = Targets.getTarget()
if (!target) { if (!target) {
return; return
} }
defenderTokenId = target.id; defenderTokenId = target.id;
defender = target.actor; defender = target.actor;
if (!defenderTokenId || !defender) { if (!defenderTokenId || !defender) {
return; return
} }
} }
return new RdDCombat(attacker, defender, defenderTokenId, target) return new RdDCombat(attacker, attackerTokenId, defender, defenderTokenId, target)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static onMsgEncaisser(msg) { static onMsgEncaisser(msg) {
let defender = canvas.tokens.get(msg.defenderTokenId).actor;
if (Misc.isOwnerPlayerOrUniqueConnectedGM()) { if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
let attackerRoll = msg.attackerRoll; let attackerRoll = msg.attackerRoll;
let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined; let attacker = msg.attackerId ? game.actors.get(msg.attackerId) : undefined;
let defender = canvas.tokens.get(msg.defenderToken.id).actor;
defender.encaisserDommages(attackerRoll, attacker); defender.encaisserDommages(attackerRoll, attacker, msg.attackerToken);
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id);
rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme); rddCombat?.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static onMsgDefense(msg) { static onMsgDefense(msg) {
let defenderToken = canvas.tokens.get(msg.defenderTokenId); let defenderToken = canvas.tokens.get(msg.defenderToken.id)
if (defenderToken && Misc.isFirstConnectedGM()) { if (defenderToken && Misc.isFirstConnectedGM()) {
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.defenderTokenId); const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(msg.attackerId, msg.attackerToken.id, msg.defenderToken.id)
rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme); rddCombat?.removeChatMessageActionsPasseArme(msg.defenderRoll.passeArme)
rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll); rddCombat?._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll)
} }
} }
@ -545,6 +544,7 @@ export class RdDCombat {
html.on("click", button, event => { html.on("click", button, event => {
const rddCombat = RdDCombat.rddCombatForAttackerAndDefender( const rddCombat = RdDCombat.rddCombatForAttackerAndDefender(
event.currentTarget.attributes['data-attackerId']?.value, event.currentTarget.attributes['data-attackerId']?.value,
event.currentTarget.attributes['data-attackerTokenId']?.value,
event.currentTarget.attributes['data-defenderTokenId']?.value); event.currentTarget.attributes['data-defenderTokenId']?.value);
if (rddCombat) { if (rddCombat) {
rddCombat.onEvent(button, event); rddCombat.onEvent(button, event);
@ -560,22 +560,38 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
constructor(attacker, defender, defenderTokenId, target) { constructor(attacker, attackerTokenId, defender, defenderTokenId, target) {
this.attacker = attacker this.attacker = attacker
this.defender = defender this.defender = defender
this.target = target this.target = target
this.attackerId = this.attacker.id this.attackerId = this.attacker.id
this.defenderId = this.defender.id this.defenderId = this.defender.id
this.attackerTokenId = attackerTokenId
this.defenderTokenId = defenderTokenId this.defenderTokenId = defenderTokenId
this.attackerToken = RdDCombat.$extractAttackerTokenData(attacker, attackerTokenId)
this.defenderToken = RdDCombat.$extractDefenderTokenData(defender, defenderTokenId, 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(defenderTokenId);
return token ? Targets.extractTokenData(token) : Targets.buildActorTokenData(defenderTokenId, defender)
}
/* -------------------------------------------- */ /* -------------------------------------------- */
async onEvent(button, event) { async onEvent(button, event) {
const chatMessage = ChatUtility.getChatMessage(event); const chatMessage = ChatUtility.getChatMessage(event);
const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll'); const defenderRoll = ChatUtility.getMessageData(chatMessage, 'defender-roll');
const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll'); const attackerRoll = defenderRoll?.attackerRoll ?? ChatUtility.getMessageData(chatMessage, 'attacker-roll');
console.log('RdDCombat', attackerRoll, defenderRoll); console.log('RdDCombat', attackerRoll, defenderRoll);
const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value; const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
const competence = event.currentTarget.attributes['data-competence']?.value; const competence = event.currentTarget.attributes['data-competence']?.value;
@ -585,7 +601,7 @@ export class RdDCombat {
case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value); case '#particuliere-attaque': return await this.choixParticuliere(attackerRoll, event.currentTarget.attributes['data-mode'].value);
case '#parer-button': return this.parade(attackerRoll, armeParadeId); case '#parer-button': return this.parade(attackerRoll, armeParadeId);
case '#esquiver-button': return this.esquive(attackerRoll, compId, competence); 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 '#echec-total-attaque': return this._onEchecTotal(attackerRoll);
case '#appel-chance-attaque': return this.attacker.rollAppelChance( case '#appel-chance-attaque': return this.attacker.rollAppelChance(
@ -702,7 +718,7 @@ export class RdDCombat {
}) })
} }
else { else {
const defenderToken = canvas.tokens.get(this.defenderTokenId); const defenderToken = canvas.tokens.get(this.defenderTokenId)
const dist = this.distance(_token, defenderToken) const dist = this.distance(_token, defenderToken)
const isVisible = this.isVisible(_token, defenderToken) const isVisible = this.isVisible(_token, defenderToken)
const portee = this._ajustementPortee(dist, rollData.arme) const portee = this._ajustementPortee(dist, rollData.arme)
@ -769,7 +785,7 @@ export class RdDCombat {
} }
RdDEmpoignade.checkEmpoignadeEnCours(this.attacker) RdDEmpoignade.checkEmpoignadeEnCours(this.attacker)
let rollData = this._prepareAttaque(competence, arme); let rollData = this._prepareAttaque(competence, arme)
console.log("RdDCombat.attaque >>>", rollData); console.log("RdDCombat.attaque >>>", rollData);
if (arme) { if (arme) {
this.attacker.verifierForceMin(arme); this.attacker.verifierForceMin(arme);
@ -795,18 +811,21 @@ export class RdDCombat {
dialog.render(true); dialog.render(true);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
_prepareAttaque(competence, arme) { _prepareAttaque(competence, arme) {
let rollData = { let rollData = {
alias: this.attackerToken.name,
passeArme: foundry.utils.randomID(16), passeArme: foundry.utils.randomID(16),
mortalite: arme?.system.mortalite, mortalite: arme?.system.mortalite,
competence: competence, competence: competence,
surprise: this.attacker.getSurprise(true), surprise: this.attacker.getSurprise(true),
surpriseDefenseur: this.defender.getSurprise(true), surpriseDefenseur: this.defender.getSurprise(true),
targetToken: Targets.extractTokenData(this.target), sourceToken: this.attackerToken,
targetToken: this.defenderToken,
essais: {} essais: {}
}; };
if (this.attacker.isCreatureEntite()) { if (this.attacker.isCreatureEntite()) {
RdDItemCompetenceCreature.setRollDataCreature(rollData); RdDItemCompetenceCreature.setRollDataCreature(rollData);
} }
@ -848,9 +867,10 @@ export class RdDCombat {
alias: this.attacker.name, alias: this.attacker.name,
whisper: ChatUtility.getOwners(this.attacker), whisper: ChatUtility.getOwners(this.attacker),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', { 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, attackerId: this.attackerId,
defenderTokenId: this.defenderTokenId, attackerToken: this.attackerToken,
defenderToken: this.defenderToken,
isForce: isForce, isForce: isForce,
isFinesse: isFinesse, isFinesse: isFinesse,
isRapide: isRapide, isRapide: isRapide,
@ -867,7 +887,7 @@ export class RdDCombat {
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite()); attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker, this.defender.isEntite());
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} } let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
attackerRoll.show = { attackerRoll.show = {
cible: this.target ? this.defender.name : 'la cible', cible: this.defenderToken?.name ?? 'la cible',
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge') isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
} }
await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html'); await RdDResolutionTable.displayRollData(attackerRoll, this.attacker, 'chat-resultat-attaque.html');
@ -908,7 +928,8 @@ export class RdDCombat {
attacker: this.attacker, attacker: this.attacker,
attackerId: this.attackerId, attackerId: this.attackerId,
esquives: esquives, esquives: esquives,
defenderTokenId: this.defenderTokenId, attackerToken: this.attackerToken,
defenderToken: this.defenderToken,
mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps, mainsNues: attackerRoll.dmg.mortalite != 'mortel' && corpsACorps,
armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme), armes: this._filterArmesParade(this.defender, attackerRoll.competence, attackerRoll.arme),
diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0, diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0,
@ -932,7 +953,7 @@ export class RdDCombat {
const choixDefense = await ChatMessage.create({ const choixDefense = await ChatMessage.create({
// message privé: du défenseur à lui même (et aux GMs) // message privé: du défenseur à lui même (et aux GMs)
speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)), speaker: ChatMessage.getSpeaker(this.defender, canvas.tokens.get(this.defenderTokenId)),
alias: this.attacker.name, alias: this.attackerToken.name,
whisper: ChatUtility.getOwners(this.defender), whisper: ChatUtility.getOwners(this.defender),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense), content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense),
}); });
@ -946,8 +967,9 @@ export class RdDCombat {
game.socket.emit(SYSTEM_SOCKET_ID, { game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_defense", data: { msg: "msg_defense", data: {
attackerId: this.attacker?.id, attackerId: this.attacker?.id,
attackerToken: this.attackerToken,
defenderId: this.defender?.id, defenderId: this.defender?.id,
defenderTokenId: this.defenderTokenId, defenderToken: this.defenderToken,
defenderRoll: defenderRoll, defenderRoll: defenderRoll,
paramChatDefense: paramChatDefense, paramChatDefense: paramChatDefense,
rollMode: true rollMode: true
@ -980,7 +1002,8 @@ export class RdDCombat {
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', { content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', {
attackerId: this.attackerId, attackerId: this.attackerId,
attacker: this.attacker, attacker: this.attacker,
defenderTokenId: this.defenderTokenId, attackerToken: this.attackerToken,
defenderToken: this.defenderToken,
essais: attackerRoll.essais essais: attackerRoll.essais
}) })
}); });
@ -1052,8 +1075,11 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
_prepareParade(attackerRoll, armeParade, competenceParade) { _prepareParade(attackerRoll, armeParade, competenceParade) {
let defenderRoll = { let defenderRoll = {
alias: this.defenderToken?.name,
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
diffLibre: attackerRoll.diffLibre, diffLibre: attackerRoll.diffLibre,
attackerToken: this.attackerToken,
defenderToken: this.defenderToken,
attackerRoll: attackerRoll, attackerRoll: attackerRoll,
competence: this.defender.getCompetence(competenceParade), competence: this.defender.getCompetence(competenceParade),
arme: armeParade, arme: armeParade,
@ -1133,8 +1159,11 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
_prepareEsquive(attackerRoll, competence) { _prepareEsquive(attackerRoll, competence) {
let rollData = { let rollData = {
alias: this.defenderToken?.name,
passeArme: attackerRoll.passeArme, passeArme: attackerRoll.passeArme,
diffLibre: attackerRoll.diffLibre, diffLibre: attackerRoll.diffLibre,
attackerToken: this.attackerToken,
defenderToken: this.defenderToken,
attackerRoll: attackerRoll, attackerRoll: attackerRoll,
competence: competence, competence: competence,
surprise: this.defender.getSurprise(true), surprise: this.defender.getSurprise(true),
@ -1276,9 +1305,8 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
async encaisser(attackerRoll, defenderRoll, defenderTokenId) { async encaisser(attackerRoll, defenderRoll) {
defenderTokenId = defenderTokenId || this.defenderTokenId; console.log("RdDCombat.encaisser >>>", attackerRoll, defenderRoll);
console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId);
if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) { if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) {
this._onEchecTotal(defenderRoll); this._onEchecTotal(defenderRoll);
@ -1286,18 +1314,19 @@ export class RdDCombat {
if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) { if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) {
attackerRoll.attackerId = this.attackerId; attackerRoll.attackerId = this.attackerId;
attackerRoll.defenderTokenId = defenderTokenId; attackerRoll.defenderTokenId = this.defenderToken.id;
await this.computeRecul(defenderRoll); await this.computeRecul(defenderRoll);
await this.defender.encaisserDommages(attackerRoll, this.attacker, 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 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, { game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_encaisser", msg: "msg_encaisser",
data: { data: {
attackerId: this.attackerId, attackerId: this.attackerId,
defenderTokenId: defenderTokenId, attackerRoll: attackerRoll,
attackerRoll: attackerRoll attackerToken: this.attackerToken,
defenderToken: this.defenderToken
} }
}); });
} }
@ -1305,28 +1334,28 @@ export class RdDCombat {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async displayActorCombatStatus(combat, actor, tokenId) { static async displayActorCombatStatus(combat, actor, token) {
let formData = { let formData = {
combatId: combat._id, combatId: combat._id,
alias: actor.name, alias: token.name ?? actor.name,
etatGeneral: actor.getEtatGeneral(), etatGeneral: actor.getEtatGeneral(),
isSonne: actor.getSonne(), isSonne: actor.getSonne(),
blessuresStatus: actor.computeResumeBlessure(), blessuresStatus: actor.computeResumeBlessure(),
SConst: actor.getSConst(), SConst: actor.getSConst(),
actorId: actor.id, actorId: actor.id,
actor: actor, actor: actor,
tokenId: tokenId, tokenId: token.id,
isGrave: actor.countBlessures(it => it.isGrave()) > 0, isGrave: actor.countBlessures(it => it.isGrave()) > 0,
isCritique: actor.countBlessures(it => it.isCritique()) > 0 isCritique: actor.countBlessures(it => it.isCritique()) > 0
} }
await ChatMessage.create({ await ChatMessage.create({
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-acteur.hbs`, formData), 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({ await ChatMessage.create({
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData), content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-actor-turn-sante.hbs`, formData),
whisper: ChatUtility.getOwners(actor), whisper: ChatUtility.getOwners(actor),
alias: actor.name alias: token.name ?? actor.name
}); });
} }
} }

View File

@ -72,6 +72,6 @@ export class RdDEncaisser extends Dialog {
encaisserSpecial: this.encaisserSpecial, encaisserSpecial: this.encaisserSpecial,
mortalite: mortalite mortalite: mortalite
} }
}); })
} }
} }

View File

@ -37,7 +37,7 @@ export class RdDTokenHud {
// initiative // initiative
await RdDTokenHud.addExtensionHudInit(html, combatant, actions); await RdDTokenHud.addExtensionHudInit(html, combatant, actions);
// combat // 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) { static async addExtensionHudCombat(html, combatant, token, actions) {
const hudData = { combatant, actions, commandes: [] }; const hudData = { combatant, token, actions, commandes: [] };
const controlIconTarget = html.find('.control-icon[data-action=target]'); const controlIconTarget = html.find('.control-icon[data-action=target]');
await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData, await RdDTokenHud._configureSubMenu(controlIconTarget, 'systems/foundryvtt-reve-de-dragon/templates/hud-actor-attaque.html', hudData,
(event) => { (event) => {
@ -80,7 +80,7 @@ export class RdDTokenHud {
combatant.actor.conjurerPossession(possession); combatant.actor.conjurerPossession(possession);
} }
else { else {
combatant.actor.rollArme(action); combatant.actor.rollArme(action, 'competence', token)
} }
}); });
} }

View File

@ -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); const diff = Math.abs(rollData.diffLibre);
let formula = RdDUtility.formuleEncaissement(diff, options) let formula = RdDUtility.formuleEncaissement(diff, options)
const roll = await RdDDice.roll(formula, options); const roll = await RdDDice.roll(formula, options);
RdDUtility.remplaceDeMinParDifficulte(roll, diff, 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) { 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 // 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 bonusDegatsDiffLibre = ReglesOptionnelles.isUsing('degat-ajout-malus-libre') ? Math.abs(rollData.diffLibre ?? 0) : 0
const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre const jetTotal = roll.total + rollData.dmg.total - armure + bonusDegatsDiffLibre
const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite); const encaissement = RdDUtility._selectEncaissement(jetTotal, rollData.dmg.mortalite);
const over20 = Math.max(jetTotal - 20, 0); const over20 = Math.max(jetTotal - 20, 0);
encaissement.dmg = rollData.dmg; encaissement.dmg = rollData.dmg
encaissement.dmg.loc = rollData.dmg.loc ?? await RdDUtility.getLocalisation(this.type); if (ReglesOptionnelles.isUsing('localisation-aleatoire')){
encaissement.dmg.loc.label = encaissement.dmg.loc.label ?? 'Corps;'; 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.dmg.bonusDegatsDiffLibre = bonusDegatsDiffLibre
encaissement.roll = roll; encaissement.roll = roll;
encaissement.armure = armure; encaissement.armure = armure;
@ -741,6 +746,15 @@ export class RdDUtility {
return undefined; 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) { static getSelectedActor(msgPlayer = undefined) {
if (canvas.tokens.controlled.length == 1) { if (canvas.tokens.controlled.length == 1) {
let token = canvas.tokens.controlled[0]; let token = canvas.tokens.controlled[0];

View File

@ -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é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: '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: '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" }, { group: 'Règles de combat', name: 'deteriorationArmure', descr: "Tenir compte de la détérioration des armures" },

View File

@ -13,18 +13,21 @@ export class Targets {
static extractTokenData(target) { static extractTokenData(target) {
return { id: target?.id, name: target?.document.name, img: target?.document.texture.src ?? target?.actor.img ?? 'icons/svg/mystery-man.svg' }; 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) { static isTargetEntite(target) {
return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE; return target?.actor.type == 'entite' && target?.actor.system.definition.typeentite == ENTITE_NONINCARNE;
} }
static async selectOneToken(onSelectTarget = target => { }) { static async selectOneTargetToken(onSelectTarget = target => { }) {
const targets = Targets.listTargets(); const targets = Targets.listTargets()
switch (targets.length) { switch (targets.length) {
case 0: return; case 0:
return
case 1: case 1:
onSelectTarget(targets[0]); onSelectTarget(targets[0])
return; return
default: default:
{ {
const selectData = { const selectData = {
@ -32,7 +35,7 @@ export class Targets {
label: "Choisir une seule des cibles", label: "Choisir une seule des cibles",
list: targets.map(it => Targets.extractTokenData(it)) list: targets.map(it => Targets.extractTokenData(it))
}; };
DialogSelect.select(selectData, onSelectTarget); DialogSelect.select(selectData, onSelectTarget)
} }
} }
} }

View File

@ -1561,6 +1561,11 @@ div.control-icon.token-hud-icon {
height: 100%; height: 100%;
object-fit: contain; object-fit: contain;
} }
.chat-inline-icon {
border: 0;
padding: 1px;
vertical-align: text-top;
}
#sidebar-tabs { #sidebar-tabs {
flex: 0 0 28px; flex: 0 0 28px;

View File

@ -3,20 +3,22 @@
<br> <br>
{{#if (eq attacker.type 'personnage')}} {{#if (eq attacker.type 'personnage')}}
{{#unless essais.attaqueChance}} {{#unless essais.attaqueChance}}
<a class='chat-card-button' id='appel-chance-attaque' data-attackerId='{{attackerId}}' <a class='chat-card-button' id='appel-chance-attaque'
data-defenderTokenId='{{defenderTokenId}}'>Faire appel à la chance</a> data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderToken.id}}' data-attackerTokenId='{{attackerToken.id}}'>
Faire appel à la chance</a>
</a> </a>
<br> <br>
{{/unless}} {{/unless}}
{{#if (gt attacker.system.compteurs.destinee.value 0)}} {{#if (gt attacker.system.compteurs.destinee.value 0)}}
<a class='chat-card-button' id='appel-destinee-attaque' data-attackerId='{{attackerId}}' <a class='chat-card-button' id='appel-destinee-attaque'
data-defenderTokenId='{{defenderTokenId}}'>Utiliser la destinée</a> data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderToken.id}}' data-attackerTokenId='{{attackerToken.id}}'>
Utiliser la destinée</a>
</a> </a>
<br> <br>
{{/if}} {{/if}}
{{/if}} {{/if}}
<a class='chat-card-button' id='echec-total-attaque' data-attackerId='{{attackerId}}' <a class='chat-card-button' id='echec-total-attaque'
data-defenderTokenId='{{defenderTokenId}}'> data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderToken.id}}' data-attackerTokenId='{{attackerToken.id}}'>
Tirer la maladresse ! Tirer la maladresse !
</a> </a>
</div> </div>

View File

@ -1,17 +1,17 @@
<div data-passearme="{{passeArme}}"> <div data-passearme="{{passeArme}}">
{{#if (eq surprise 'totale')}} {{#if (eq surprise 'totale')}}
<span><strong>{{defender.name}}</strong> est totalement surpris</span> <span><strong>{{defenderToken.name}}</strong> est totalement surpris</span>
{{else if essais.defense}} {{else if essais.defense}}
<span><strong>{{defender.name}}</strong> doit :</span> <span><strong>{{defenderToken.name}}</strong> doit :</span>
{{else}} {{else}}
<span><strong>{{defender.name}}</strong> doit se défendre <span><strong>{{defenderToken.name}}</strong> doit se défendre
{{~#if (eq surprise 'demi')}} avec une significative {{/if}} d'une attaque {{~#if (eq surprise 'demi')}} avec une significative {{/if}} d'une attaque
{{~#if attaqueParticuliere}} <strong>particulière en {{~#if attaqueParticuliere}} <strong>particulière en
{{~#if (eq attaqueParticuliere 'finesse')}} finesse {{~#if (eq attaqueParticuliere 'finesse')}} finesse
{{else if (eq attaqueParticuliere 'force')}} force {{else if (eq attaqueParticuliere 'force')}} force
{{else if (eq attaqueParticuliere 'rapidite')}} rapidité {{else if (eq attaqueParticuliere 'rapidite')}} rapidité
{{/if~}}</strong> {{/if~}}</strong>
{{/if}} de {{attacker.name}} ({{attaqueArme.name}}): {{/if}} de {{attackerToken.name}} ({{attaqueArme.name}}):
</span> </span>
{{/if}} {{/if}}
<span class='chat-card-button-area'> <span class='chat-card-button-area'>
@ -20,15 +20,17 @@
{{#if essais.defense}} {{#if essais.defense}}
{{#unless essais.defenseChance}} {{#unless essais.defenseChance}}
{{#if (eq defender.type 'personnage')}} {{#if (eq defender.type 'personnage')}}
<a class='chat-card-button' id='appel-chance-defense' data-attackerId='{{attackerId}}' <a class='chat-card-button' id='appel-chance-defense'
data-defenderTokenId='{{defenderTokenId}}'>Faire appel à la chance</a> data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderToken.id}}' data-attackerTokenId='{{attackerToken.id}}'>
Faire appel à la chance</a>
</a> </a>
<br> <br>
{{/if}} {{/if}}
{{#if (eq defender.type 'personnage')}} {{#if (eq defender.type 'personnage')}}
{{#if (gt defender.system.compteurs.destinee.value 0)}} {{#if (gt defender.system.compteurs.destinee.value 0)}}
<a class='chat-card-button' id='appel-destinee-defense' data-attackerId='{{attackerId}}' <a class='chat-card-button' id='appel-destinee-defense'
data-defenderTokenId='{{defenderTokenId}}'>Utiliser la destinée</a> data-attackerId='{{attackerId}}' data-attackerTokenId='{{attackerToken.id}}' data-defenderTokenId='{{defenderToken.id}}'>
Utiliser la destinée</a>
</a> </a>
<br> <br>
{{/if}} {{/if}}
@ -36,24 +38,26 @@
{{/unless}} {{/unless}}
{{else}} {{else}}
{{#each armes as |arme key|}} {{#each armes as |arme key|}}
<a class='chat-card-button' id='parer-button' data-attackerId='{{../attackerId}}' data-defenderTokenId='{{../defenderTokenId}}' <a class='chat-card-button' id='parer-button'
data-armeid='{{arme._id}}'> data-attackerId='{{../attackerId}}' data-defenderTokenId='{{../defenderToken.id}}' data-attackerTokenId='{{../attackerToken.id}}'
data-armeid='{{arme._id}}'>
Parer avec {{arme.name}} à {{../diffLibre }}{{#if arme.system.nbUsage}} (Utilisations : {{arme.system.nbUsage}}){{/if}} Parer avec {{arme.name}} à {{../diffLibre }}{{#if arme.system.nbUsage}} (Utilisations : {{arme.system.nbUsage}}){{/if}}
</a> </a>
<br> <br>
{{/each}} {{/each}}
{{#if mainsNues}} {{#if mainsNues}}
<a class='chat-card-button' id='parer-button' data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderTokenId}}' <a class='chat-card-button' id='parer-button'
data-armeid='{{arme._id}}' data-competence='{{arme.system.competence}}'> data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderToken.id}}' data-attackerTokenId='{{attackerToken.id}}'
data-armeid='{{arme._id}}' data-competence='{{arme.system.competence}}'>
Parer à mains nues à {{diffLibre}}{{#if arme.system.nbUsage}} (Utilisations : {{arme.system.nbUsage}}){{/if}} Parer à mains nues à {{diffLibre}}{{#if arme.system.nbUsage}} (Utilisations : {{arme.system.nbUsage}}){{/if}}
</a> </a>
<br> <br>
{{/if}} {{/if}}
{{#if (ne attaqueCategorie 'tir')}} {{#if (ne attaqueCategorie 'tir')}}
{{#each esquives as |esquive key|}} {{#each esquives as |esquive key|}}
<a class='chat-card-button' id='esquiver-button' data-attackerId='{{../attackerId}}' data-defenderTokenId='{{../defenderTokenId}}' <a class='chat-card-button' id='esquiver-button'
data-compid='{{esquive._id}}' data-competence='{{esquive.name}}'> data-attackerId='{{../attackerId}}' data-defenderTokenId='{{../defenderToken.id}}' data-attackerTokenId='{{../attackerToken.id}}'
{{log 'esquive' esquive}} data-compid='{{esquive._id}}' data-competence='{{esquive.name}}'>
{{esquive.name}} à {{../diffLibre}} {{#if esquive.system.nbUsage}} (Utilisations : {{esquive.system.nbUsage}}){{/if}} {{esquive.name}} à {{../diffLibre}} {{#if esquive.system.nbUsage}} (Utilisations : {{esquive.system.nbUsage}}){{/if}}
</a> </a>
<br> <br>
@ -61,8 +65,8 @@
{{/if}} {{/if}}
{{/if}} {{/if}}
{{/unless}} {{/unless}}
<a class='chat-card-button' id='encaisser-button' data-attackerId='{{attackerId}}' <a class='chat-card-button' id='encaisser-button'
data-defenderTokenId='{{defenderTokenId}}'> data-attackerId='{{attackerId}}' data-defenderTokenId='{{defenderToken.id}}' data-attackerTokenId='{{attackerToken.id}}'>
Encaisser à {{plusMoins dmg.total}} Encaisser à {{plusMoins dmg.total}}
{{#if (eq dmg.mortalite 'non-mortel')~}} {{#if (eq dmg.mortalite 'non-mortel')~}}
(non-mortel) ! (non-mortel) !

View File

@ -18,18 +18,18 @@
</h4> </h4>
<div> <div>
Jet d'encaissement de {{roll.total}} 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 (eq penetration 0)}} (pénétration de {{penetration}}){{/unless}}
{{~/unless}}, total: <span class="rdd-roll-echec">{{total}}</span> {{~/unless~}}, total: <span class="rdd-roll-echec">{{total}}</span>
<br> <br>
{{alias}} {{alias}}
{{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup {{#if (eq dmg.mortalite 'entiteincarnee')}}subit le coup
{{else if mort}}vient de mourir {{else if mort}}vient de mourir
{{else if blessure}} {{else if blessure}}
{{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.label}} {{#if (gt blessure.system.gravite 0)}}subit une blessure {{blessure.system.label}}
{{else}}subit une contusion {{~else~}}subit une contusion
{{~/if~}} {{~/if~}}
{{else}}s'en sort sans une égratignure {{~else~}}s'en sort sans une égratignure
{{~/if~}} {{~/if~}}
{{~#unless (eq dmg.mortalite 'entiteincarnee')}} {{~#unless (eq dmg.mortalite 'entiteincarnee')}}
@ -39,11 +39,11 @@
{{/unless~}} {{/unless~}}
{{~#if (gt endurance 0)}} {{~#if (gt endurance 0)}}
{{~#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance {{~#if hasPlayerOwner}}, a perdu {{endurance}} points d'endurance
{{#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if}} {{~#if (ne vie 0)}}, <span class="rdd-roll-echec">{{vie}} points de vie</span>{{/if~}}
{{/if}} {{/if}}
{{#if (ne dmg.mortalite 'entiteincarnee')}} {{#if (ne dmg.mortalite 'entiteincarnee')}}
{{#if (gt endurance 1)}}et {{#if (gt endurance 1)}}et
{{#if sonne}}est <strong>sonné</strong><img class="chat-icon" src="icons/svg/stoned.svg" data-tooltip="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}! {{#if sonne}}est <strong>sonné</strong><img class="chat-inline-icon" src="icons/svg/stoned.svg" data-tooltip="charge" height="16" width="16" /> jusqu'à la fin du prochain round{{else}}n'est pas sonné{{/if}}!
{{#if hasPlayerOwner}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}} {{#if hasPlayerOwner}}Jet d'endurance : {{jetEndurance}} / {{resteEndurance}}{{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}