`)
- /*
- * TODO: support de plusieurs combats parallèles
- * il faudrait avoir un id de combat en plus de celui de passe d'armes
- */
- for (const key in game.system.rdd.combatStore.attaques) {
- const attackerRoll = game.system.rdd.combatStore.attaques[key];
- ChatUtility.removeChatMessageContaining(`
`);
- }
- for (const key in game.system.rdd.combatStore.defenses) {
- const defenderRoll = game.system.rdd.combatStore.defenses[key];
- ChatUtility.removeChatMessageContaining(`
`);
- }
- RdDCombat.initStorePasseArmes();
+ game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
+ .forEach(it => it.delete());
}
}
@@ -471,61 +449,6 @@ export class RdDCombat {
return undefined;
}
- /* -------------------------------------------- */
- static messagePasseArme(data) {
- // TODO: store required info for combat in the chat message presenting choices?
- game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_combat_passearme", data: data });
- RdDCombat.onMsgPasseArme(data);
- }
-
- /* -------------------------------------------- */
- static onMsgPasseArme(data) {
- switch (data.actionPasseArme) {
- case "store-attaque":
- game.system.rdd.combatStore.attaques[data.id] = data.rollData;
- break;
- case "store-defense":
- game.system.rdd.combatStore.defenses[data.id] = data.rollData;
- break;
- case "delete-attaque":
- delete game.system.rdd.combatStore.attaques[data.id];
- break;
- case "delete-defense":
- delete game.system.rdd.combatStore.defenses[data.id];
- break;
- }
- }
-
- /* -------------------------------------------- */
- static _storeAttaque(attackerId, attackerRoll) {
- RdDCombat.messagePasseArme({ actionPasseArme: "store-attaque", id: attackerId, rollData: attackerRoll });
- }
-
- /* -------------------------------------------- */
- static _getAttaque(attackerId) {
- return game.system.rdd.combatStore.attaques[attackerId];
- }
-
- /* -------------------------------------------- */
- static _deleteAttaque(attackerId) {
- RdDCombat.messagePasseArme({ actionPasseArme: "delete-attaque", id: attackerId });
- }
-
- /* -------------------------------------------- */
- static _storeDefense(passeArme, defenderRoll) {
- RdDCombat.messagePasseArme({ actionPasseArme: "store-defense", id: passeArme, rollData: defenderRoll });
- }
-
- /* -------------------------------------------- */
- static _getDefense(passeArme) {
- return game.system.rdd.combatStore.defenses[passeArme];
- }
-
- /* -------------------------------------------- */
- static _deleteDefense(passeArme) {
- RdDCombat.messagePasseArme({ actionPasseArme: "delete-defense", id: passeArme });
- }
-
/* -------------------------------------------- */
static create(attacker, defender, defenderTokenId, target = undefined) {
return new RdDCombat(attacker, defender, defenderTokenId, target)
@@ -547,7 +470,7 @@ export class RdDCombat {
static onMsgEncaisser(data) {
let defender = canvas.tokens.get(data.defenderTokenId).actor;
if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
- let attackerRoll = RdDCombat._getAttaque(data.attackerId); // Retrieve the rolldata from the store
+ let attackerRoll = data.attackerRoll;
let attacker = data.attackerId ? game.actors.get(data.attackerId) : null;
defender.encaisserDommages(attackerRoll, attacker);
@@ -563,10 +486,8 @@ export class RdDCombat {
const rddCombat = RdDCombat.createForAttackerAndDefender(msg.attackerId, msg.defenderTokenId);
if (rddCombat) {
const defenderRoll = msg.defenderRoll;
- RdDCombat._storeAttaque(msg.attackerId, defenderRoll.attackerRoll);
- RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
rddCombat.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
- rddCombat._chatMessageDefense(msg.paramChatDefense);
+ rddCombat._chatMessageDefense(msg.paramChatDefense, msg.defenderRoll);
}
}
}
@@ -621,12 +542,10 @@ export class RdDCombat {
/* -------------------------------------------- */
async onEvent(button, event) {
- const attackerRoll = RdDCombat._getAttaque(this.attackerId);
- if (!attackerRoll) {
- ui.notifications.warn("Action automatisée impossible, le jet de l'attaquant a été perdu (suite à un raffraichissement?)")
- return;
- }
- const defenderRoll = game.system.rdd.combatStore.defenses[attackerRoll.passeArme];
+ const chatMessage = ChatUtility.getChatMessage(event);
+ 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;
@@ -637,7 +556,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, defenderTokenId);
+ case '#encaisser-button': return this.encaisser(attackerRoll, defenderRoll, defenderTokenId);
case '#echec-total-attaque': return this._onEchecTotal(attackerRoll);
case '#appel-chance-attaque': return this.attacker.rollAppelChance(
@@ -650,7 +569,7 @@ export class RdDCombat {
() => this.attaqueSignificative(attackerRoll),
() => { });
case '#appel-destinee-defense': return this.defender.appelDestinee(
- () => this.defenseDestinee(attackerRoll),
+ () => this.defenseDestinee(defenderRoll),
() => { });
}
}
@@ -680,8 +599,7 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- defenseDestinee(attackerRoll) {
- let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
+ defenseDestinee(defenderRoll) {
if (defenderRoll) {
ui.notifications.info('Défense significative grâce à la destinée')
RdDResolutionTable.significativeRequise(defenderRoll.rolled);
@@ -819,8 +737,7 @@ export class RdDCombat {
/* -------------------------------------------- */
async _onAttaqueParticuliere(rollData) {
- RdDCombat._storeAttaque(this.attackerId, rollData);
-
+
const isMeleeDiffNegative = (rollData.competence.type == 'competencecreature' || rollData.selectedCarac.label == "Mêlée") && rollData.diffLibre < 0;
// force toujours, sauf empoignade
// finesse seulement en mélée, pour l'empoignade, ou si la difficulté libre est de -1 minimum
@@ -838,8 +755,8 @@ export class RdDCombat {
else if (!isForce && !isFinesse && isRapide) {
return await this.choixParticuliere(rollData, "rapidite");
}
-
- ChatMessage.create({
+
+ const choixParticuliere = await ChatMessage.create({
alias: this.attacker.name,
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-particuliere.html', {
@@ -852,6 +769,7 @@ export class RdDCombat {
passeArme: rollData.passeArme
})
});
+ ChatUtility.setMessageData(choixParticuliere, 'attacker-roll', rollData);
}
/* -------------------------------------------- */
@@ -860,10 +778,6 @@ export class RdDCombat {
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
let defenderRoll = { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} }
- // Save rollData for defender
- RdDCombat._storeAttaque(this.attackerId, attackerRoll);
- RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
-
attackerRoll.show = {
cible: this.target ? this.defender.data.name : 'la cible',
isRecul: (attackerRoll.particuliere == 'force' || attackerRoll.tactique == 'charge')
@@ -918,7 +832,7 @@ export class RdDCombat {
};
if (Misc.isUniqueConnectedGM()) {
- await this._chatMessageDefense(paramChatDefense);
+ await this._chatMessageDefense(paramChatDefense, defenderRoll);
}
else {
this._socketSendMessageDefense(paramChatDefense, defenderRoll);
@@ -926,14 +840,16 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- async _chatMessageDefense(paramDemandeDefense) {
- ChatMessage.create({
+ async _chatMessageDefense(paramDemandeDefense, defenderRoll) {
+ 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,
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.defender.name),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense),
});
+ // flag pour garder les jets d'attaque/defense
+ ChatUtility.setMessageData(choixDefense, 'defender-roll', defenderRoll);
}
/* -------------------------------------------- */
@@ -974,10 +890,7 @@ export class RdDCombat {
/* -------------------------------------------- */
async _onAttaqueEchecTotal(attackerRoll) {
-
- RdDCombat._storeAttaque(this.attackerId, attackerRoll);
-
- ChatMessage.create({
+ const choixEchecTotal = await ChatMessage.create({
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-attaque-etotal.html', {
attackerId: this.attackerId,
@@ -986,6 +899,7 @@ export class RdDCombat {
essais: attackerRoll.essais
})
});
+ ChatUtility.setMessageData(choixEchecTotal, 'attacker-roll', attackerRoll);
}
/* -------------------------------------------- */
@@ -1105,7 +1019,6 @@ export class RdDCombat {
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true });
- RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
}
/* -------------------------------------------- */
@@ -1177,7 +1090,6 @@ export class RdDCombat {
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true })
- RdDCombat._storeDefense(defenderRoll.passeArme, defenderRoll);
}
/* -------------------------------------------- */
@@ -1282,15 +1194,10 @@ export class RdDCombat {
}
/* -------------------------------------------- */
- async encaisser(attackerRoll, defenderTokenId) {
+ async encaisser(attackerRoll, defenderRoll, defenderTokenId) {
defenderTokenId = defenderTokenId || this.defenderTokenId;
console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId);
- let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
- if (!defenderRoll) {
- ui.notifications.warn("Cette passe d'arme est déjà terminée!")
- return;
- }
if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) {
this._onEchecTotal(defenderRoll);
}