|
|
@ -28,9 +28,9 @@ export class RdDCombat {
|
|
|
|
static onSocketMessage(sockmsg) {
|
|
|
|
static onSocketMessage(sockmsg) {
|
|
|
|
switch (sockmsg.msg) {
|
|
|
|
switch (sockmsg.msg) {
|
|
|
|
case "msg_encaisser":
|
|
|
|
case "msg_encaisser":
|
|
|
|
return RdDCombat.terminerPasseArmes(data);
|
|
|
|
return RdDCombat.onMsgEncaisser(sockmsg.data);
|
|
|
|
case "msg_defense":
|
|
|
|
case "msg_defense":
|
|
|
|
return RdDCombat.handleMsgDefense(sockmsg.data);
|
|
|
|
return RdDCombat.onMsgDefense(sockmsg.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -99,6 +99,36 @@ export class RdDCombat {
|
|
|
|
return undefined;
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _storeAttaque(attackerId, attackerRoll) {
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.attaques[attackerId] = duplicate(attackerRoll);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _getAttaque(attackerId) {
|
|
|
|
|
|
|
|
return game.system.rdd.combatStore.attaques[attackerId];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _deleteAttaque(attackerId) {
|
|
|
|
|
|
|
|
delete game.system.rdd.combatStore.attaques[attackerId];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _storeDefense(defenderRoll) {
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.defenses[defenderRoll.passeArme] = duplicate(defenderRoll);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _getDefense(passeArme) {
|
|
|
|
|
|
|
|
return game.system.rdd.combatStore.defenses[passeArme];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _deleteDefense(passeArme) {
|
|
|
|
|
|
|
|
delete game.system.rdd.combatStore.defenses;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static create(attacker, defender, defenderTokenId, target = undefined) {
|
|
|
|
static create(attacker, defender, defenderTokenId, target = undefined) {
|
|
|
|
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
|
|
|
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
|
|
@ -121,59 +151,36 @@ export class RdDCombat {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static handleMsgDefense(data) {
|
|
|
|
static onMsgEncaisser(data) {
|
|
|
|
let defenderToken = canvas.tokens.get(data.defenderTokenId);
|
|
|
|
let attackerRoll = RdDCombat._getAttaque(data.attackerId); // Retrieve the rolldata from the store
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (game.user.id === data.gmId) { // Seul le GM effectue l'encaissement sur la fiche
|
|
|
|
|
|
|
|
let attacker = data.attackerId ? game.actors.get(data.attackerId) : null;
|
|
|
|
|
|
|
|
let defender = canvas.tokens.get(data.defenderTokenId).actor;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
defender.encaisserDommages(attackerRoll, attacker);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RdDCombat._deleteDefense(attackerRoll.passeArme);
|
|
|
|
|
|
|
|
RdDCombat._deleteAttaque(data.attackerId);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static onMsgDefense(msgData) {
|
|
|
|
|
|
|
|
let defenderToken = canvas.tokens.get(msgData.defenderTokenId);
|
|
|
|
if (defenderToken) {
|
|
|
|
if (defenderToken) {
|
|
|
|
if (!game.user.isGM && game.user.character == undefined) { // vérification / sanity check
|
|
|
|
if (!game.user.isGM && !game.user.character) { // vérification / sanity check
|
|
|
|
ui.notifications.error("Le joueur " + game.user.name + " n'est connecté à aucun personnage. Impossible de continuer.");
|
|
|
|
ui.notifications.error("Le joueur " + game.user.name + " n'est connecté à aucun personnage. Impossible de continuer.");
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((game.user.isGM && !defenderToken.actor.hasPlayerOwner) || (defenderToken.actor.hasPlayerOwner && (game.user.character.id == defenderToken.actor.data._id))) {
|
|
|
|
if ((game.user.isGM && !defenderToken.actor.hasPlayerOwner) || (defenderToken.actor.hasPlayerOwner && (game.user.character.id == defenderToken.actor.data._id))) {
|
|
|
|
//console.log("User is pushing message...", game.user.name);
|
|
|
|
const defenderRoll = msgData.defenderRoll;
|
|
|
|
game.system.rdd.combatStore.attaques[data.attackerId] = duplicate(data.rollData);
|
|
|
|
RdDCombat._storeAttaque(msgData.attackerId, defenderRoll.attackerRoll);
|
|
|
|
data.whisper = [game.user];
|
|
|
|
RdDCombat._storeDefense(defenderRoll);
|
|
|
|
data.blind = true;
|
|
|
|
|
|
|
|
data.rollMode = "blindroll";
|
|
|
|
|
|
|
|
ChatMessage.create(data);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static terminerPasseArmes(data) {
|
|
|
|
|
|
|
|
if (game.user.isGM) { // Seul le GM nettoie le stockage des données de combat
|
|
|
|
|
|
|
|
let attackerRoll = game.system.rdd.combatStore.attaques[data.attackerId]; // Retrieve the rolldata from the store
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.attaques[data.attackerId] = undefined;
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.defenses[attackerRoll.passeArme] = undefined;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _sendRollMessage(sender, recipient, defenderTokenId, topic, message, rollData) {
|
|
|
|
|
|
|
|
let chatMessage = {
|
|
|
|
|
|
|
|
content: message,
|
|
|
|
|
|
|
|
whisper: ChatUtility.getWhisperRecipients("blindroll", recipient.name),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// envoyer le message au destinataire
|
|
|
|
|
|
|
|
if (!game.user.isGM || recipient.hasPlayerOwner) {
|
|
|
|
|
|
|
|
let data = {
|
|
|
|
|
|
|
|
attackerId: sender?.data._id,
|
|
|
|
|
|
|
|
defenderId: recipient?.data._id,
|
|
|
|
|
|
|
|
defenderTokenId: defenderTokenId,
|
|
|
|
|
|
|
|
rollData: duplicate(rollData),
|
|
|
|
|
|
|
|
rollMode: true
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
mergeObject(data, chatMessage);
|
|
|
|
|
|
|
|
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: topic, data: data });
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
chatMessage.whisper = [game.user];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (game.user.isGM) { // Always push the message to the MJ
|
|
|
|
|
|
|
|
ChatMessage.create(chatMessage);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
static _callJetDeVie(event) {
|
|
|
|
static _callJetDeVie(event) {
|
|
|
|
let actorId = event.currentTarget.attributes['data-actorId'].value;
|
|
|
|
let actorId = event.currentTarget.attributes['data-actorId'].value;
|
|
|
@ -218,11 +225,12 @@ export class RdDCombat {
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
async onEvent(button, event) {
|
|
|
|
async onEvent(button, event) {
|
|
|
|
let attackerRoll = game.system.rdd.combatStore.attaques[this.attackerId];
|
|
|
|
const attackerRoll = RdDCombat._getAttaque(this.attackerId);
|
|
|
|
if (!attackerRoll) {
|
|
|
|
if (!attackerRoll) {
|
|
|
|
ui.notifications.warn("Action automatisée impossible, le jet de l'attaquant a été perdu (suite à un raffraichissement?)")
|
|
|
|
ui.notifications.warn("Action automatisée impossible, le jet de l'attaquant a été perdu (suite à un raffraichissement?)")
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const defenderRoll = game.system.rdd.combatStore.defenses[attackerRoll.passeArme];
|
|
|
|
const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
|
|
|
|
const defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
|
|
|
|
|
|
|
|
|
|
|
|
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
|
|
|
|
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
|
|
|
@ -238,8 +246,8 @@ export class RdDCombat {
|
|
|
|
() => this.attaqueChanceuse(attackerRoll),
|
|
|
|
() => this.attaqueChanceuse(attackerRoll),
|
|
|
|
() => this._onEchecTotal(attackerRoll));
|
|
|
|
() => this._onEchecTotal(attackerRoll));
|
|
|
|
case '#appel-chance-defense': return this.defender.rollAppelChance(
|
|
|
|
case '#appel-chance-defense': return this.defender.rollAppelChance(
|
|
|
|
() => this.defenseChanceuse(attackerRoll),
|
|
|
|
() => this.defenseChanceuse(attackerRoll, defenderRoll),
|
|
|
|
() => this.afficherOptionsDefense(attackerRoll, { defenseChance: true }));
|
|
|
|
() => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true }));
|
|
|
|
case '#appel-destinee-attaque': return this.attacker.appelDestinee(
|
|
|
|
case '#appel-destinee-attaque': return this.attacker.appelDestinee(
|
|
|
|
() => this.attaqueSignificative(attackerRoll),
|
|
|
|
() => this.attaqueSignificative(attackerRoll),
|
|
|
|
() => { });
|
|
|
|
() => { });
|
|
|
@ -249,23 +257,6 @@ export class RdDCombat {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
_consumeDefense(passeArme) {
|
|
|
|
|
|
|
|
let defenderRoll = this._getDefense(passeArme);
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.defenses[passeArme] = undefined;
|
|
|
|
|
|
|
|
return defenderRoll;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
_getDefense(passeArme) {
|
|
|
|
|
|
|
|
return game.system.rdd.combatStore.defenses[passeArme];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
_storeDefense(defenderRoll) {
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.defenses[defenderRoll.passeArme] = defenderRoll;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
attaqueChanceuse(attackerRoll) {
|
|
|
|
attaqueChanceuse(attackerRoll) {
|
|
|
|
ui.notifications.info("L'attaque est rejouée grâce à la chance")
|
|
|
|
ui.notifications.info("L'attaque est rejouée grâce à la chance")
|
|
|
@ -282,17 +273,17 @@ export class RdDCombat {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
defenseChanceuse(attackerRoll) {
|
|
|
|
defenseChanceuse(attackerRoll, defenderRoll) {
|
|
|
|
ui.notifications.info("La défense est rejouée grâce à la chance")
|
|
|
|
ui.notifications.info("La défense est rejouée grâce à la chance")
|
|
|
|
attackerRoll.essais.defenseChance = true;
|
|
|
|
attackerRoll.essais.defenseChance = true;
|
|
|
|
attackerRoll.essais.defense = false;
|
|
|
|
attackerRoll.essais.defense = false;
|
|
|
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
|
|
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
|
|
|
this._sendMessageDefense(attackerRoll);
|
|
|
|
this._sendMessageDefense(attackerRoll, defenderRoll, attackerRoll.essais);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
defenseDestinee(attackerRoll) {
|
|
|
|
defenseDestinee(attackerRoll) {
|
|
|
|
let defenderRoll = this._getDefense(attackerRoll.passeArme);
|
|
|
|
let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
|
|
|
|
if (defenderRoll) {
|
|
|
|
if (defenderRoll) {
|
|
|
|
ui.notifications.info('Défense significative grâce à la destinée')
|
|
|
|
ui.notifications.info('Défense significative grâce à la destinée')
|
|
|
|
RdDResolutionTable.forceSignificative(defenderRoll.rolled);
|
|
|
|
RdDResolutionTable.forceSignificative(defenderRoll.rolled);
|
|
|
@ -310,9 +301,9 @@ export class RdDCombat {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
afficherOptionsDefense(attackerRoll, essais) {
|
|
|
|
afficherOptionsDefense(attackerRoll, defenderRoll, essais) {
|
|
|
|
ui.notifications.info("La chance n'est pas avec vous");
|
|
|
|
ui.notifications.info("La chance n'est pas avec vous");
|
|
|
|
this._sendMessageDefense(attackerRoll, essais);
|
|
|
|
this._sendMessageDefense(attackerRoll, defenderRoll, essais);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
@ -410,13 +401,15 @@ export class RdDCombat {
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
async _onAttaqueParticuliere(rollData) {
|
|
|
|
async _onAttaqueParticuliere(rollData) {
|
|
|
|
game.system.rdd.combatStore.attaques[this.attackerId] = duplicate(rollData);
|
|
|
|
RdDCombat._storeAttaque(this.attackerId, rollData);
|
|
|
|
|
|
|
|
|
|
|
|
// Finesse et Rapidité seulement en mêlée et si la difficulté libre est de -1 minimum
|
|
|
|
// Finesse et Rapidité seulement en mêlée et si la difficulté libre est de -1 minimum
|
|
|
|
const isMeleeDiffNegative = rollData.selectedCarac.label == "Mêlée" && rollData.diffLibre < 0;
|
|
|
|
const isMeleeDiffNegative = rollData.selectedCarac.label == "Mêlée" && rollData.diffLibre < 0;
|
|
|
|
ChatMessage.create({
|
|
|
|
ChatMessage.create({
|
|
|
|
whisper: ChatMessage.getWhisperRecipients(this.attacker.name),
|
|
|
|
alias: this.attacker.name,
|
|
|
|
|
|
|
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.attacker.name),
|
|
|
|
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,
|
|
|
|
attackerId: this.attackerId,
|
|
|
|
attackerId: this.attackerId,
|
|
|
|
defenderTokenId: this.defenderTokenId,
|
|
|
|
defenderTokenId: this.defenderTokenId,
|
|
|
|
isFinesse: isMeleeDiffNegative,
|
|
|
|
isFinesse: isMeleeDiffNegative,
|
|
|
@ -432,7 +425,7 @@ export class RdDCombat {
|
|
|
|
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
|
|
|
|
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
|
|
|
|
|
|
|
|
|
|
|
|
// Save rollData for defender
|
|
|
|
// Save rollData for defender
|
|
|
|
game.system.rdd.combatStore.attaques[this.attackerId] = duplicate(attackerRoll);
|
|
|
|
RdDCombat._storeAttaque(this.attackerId, attackerRoll);
|
|
|
|
|
|
|
|
|
|
|
|
attackerRoll.show = {
|
|
|
|
attackerRoll.show = {
|
|
|
|
cible: this.target ? this.defender.data.name : 'la cible',
|
|
|
|
cible: this.target ? this.defender.data.name : 'la cible',
|
|
|
@ -450,29 +443,52 @@ export class RdDCombat {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
async _sendMessageDefense(attackerRoll, essais = {}) {
|
|
|
|
async _sendMessageDefense(attackerRoll, defenderRoll = undefined, essaisPrecedents = undefined) {
|
|
|
|
console.log("RdDCombat._sendMessageDefense", attackerRoll, essais, " / ", this.attacker, this.target, this.attackerId, attackerRoll.competence.data.categorie);
|
|
|
|
console.log("RdDCombat._sendMessageDefense", attackerRoll, defenderRoll, essaisPrecedents, " / ", this.attacker, this.target, this.attackerId, attackerRoll.competence.data.categorie);
|
|
|
|
|
|
|
|
|
|
|
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
|
|
|
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
|
|
|
mergeObject(attackerRoll.essais, essais, { overwrite: true });
|
|
|
|
if (essaisPrecedents) {
|
|
|
|
|
|
|
|
mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
|
|
|
|
|
|
|
|
}
|
|
|
|
const paramDemandeDefense = {
|
|
|
|
const paramDemandeDefense = {
|
|
|
|
passeArme: attackerRoll.passeArme,
|
|
|
|
passeArme: attackerRoll.passeArme,
|
|
|
|
essais: attackerRoll.essais,
|
|
|
|
essais: attackerRoll.essais,
|
|
|
|
// surprise: this.defender.getSurprise(true),
|
|
|
|
|
|
|
|
// surprise: attackerRoll.ajustements.attaqueDefenseurSurpris.used,
|
|
|
|
|
|
|
|
defender: this.defender,
|
|
|
|
defender: this.defender,
|
|
|
|
attackerId: this.attackerId,
|
|
|
|
attackerId: this.attackerId,
|
|
|
|
defenderTokenId: this.defenderTokenId,
|
|
|
|
defenderTokenId: this.defenderTokenId,
|
|
|
|
mainsNues: attackerRoll.dmg.mortalite != 'mortel' && this.defender.getCompetence("Corps à corps"),
|
|
|
|
mainsNues: attackerRoll.dmg.mortalite != 'mortel' && this.defender.getCompetence("Corps à corps"),
|
|
|
|
armes: this._filterArmesParade(this.defender.data.items, attackerRoll.competence, attackerRoll.arme),
|
|
|
|
armes: this._filterArmesParade(this.defender.data.items, attackerRoll.competence, attackerRoll.arme),
|
|
|
|
diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0,
|
|
|
|
diffLibre: attackerRoll.ajustements?.diffLibre?.value ?? 0,
|
|
|
|
|
|
|
|
attaqueParticuliere: attackerRoll.particuliere,
|
|
|
|
dmg: attackerRoll.dmg
|
|
|
|
dmg: attackerRoll.dmg
|
|
|
|
};
|
|
|
|
};
|
|
|
|
let message = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RdDCombat._sendRollMessage(this.attacker, this.defender, this.defenderTokenId, "msg_defense", message, attackerRoll);
|
|
|
|
RdDCombat._sendRollMessage(this.attacker, this.defender, this.defenderTokenId,
|
|
|
|
|
|
|
|
defenderRoll ?? { attackerRoll: attackerRoll, passeArme: attackerRoll.passeArme, show: {} },
|
|
|
|
|
|
|
|
essaisPrecedents != undefined);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let chatMessage = {
|
|
|
|
|
|
|
|
alias: this.attacker.name,
|
|
|
|
|
|
|
|
whisper: ChatUtility.getWhisperRecipientsAndGMs(this.defender.name),
|
|
|
|
|
|
|
|
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-demande-defense.html', paramDemandeDefense),
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
ChatMessage.create(chatMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
|
|
|
|
static _sendRollMessage(sender, recipient, defenderTokenId, defenderRoll, selfMessage) {
|
|
|
|
|
|
|
|
// envoyer le message au destinataire
|
|
|
|
|
|
|
|
if (!selfMessage || !game.user.isGM || recipient.hasPlayerOwner) {
|
|
|
|
|
|
|
|
let data = {
|
|
|
|
|
|
|
|
attackerId: sender?.data._id,
|
|
|
|
|
|
|
|
defenderId: recipient?.data._id,
|
|
|
|
|
|
|
|
defenderTokenId: defenderTokenId,
|
|
|
|
|
|
|
|
defenderRoll: duplicate(defenderRoll),
|
|
|
|
|
|
|
|
rollMode: true
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_defense", data: data });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
_filterArmesParade(items, competence) {
|
|
|
|
_filterArmesParade(items, competence) {
|
|
|
|
items = items.filter(item => (item.type == 'arme' && item.data.equipe) || (item.type == 'competencecreature' && item.data.isparade));
|
|
|
|
items = items.filter(item => (item.type == 'arme' && item.data.equipe) || (item.type == 'competencecreature' && item.data.isparade));
|
|
|
@ -492,7 +508,7 @@ export class RdDCombat {
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
async _onAttaqueEchecTotal(attackerRoll) {
|
|
|
|
async _onAttaqueEchecTotal(attackerRoll) {
|
|
|
|
|
|
|
|
|
|
|
|
game.system.rdd.combatStore.attaques[this.attackerId] = duplicate(attackerRoll);
|
|
|
|
RdDCombat._storeAttaque(this.attackerId, attackerRoll);
|
|
|
|
|
|
|
|
|
|
|
|
// Finesse et Rapidité seulement en mêlée et si la difficulté libre est de -1 minimum
|
|
|
|
// Finesse et Rapidité seulement en mêlée et si la difficulté libre est de -1 minimum
|
|
|
|
ChatMessage.create({
|
|
|
|
ChatMessage.create({
|
|
|
@ -616,11 +632,11 @@ export class RdDCombat {
|
|
|
|
async _onParadeNormale(defenderRoll) {
|
|
|
|
async _onParadeNormale(defenderRoll) {
|
|
|
|
console.log("RdDCombat._onParadeNormale >>>", defenderRoll);
|
|
|
|
console.log("RdDCombat._onParadeNormale >>>", defenderRoll);
|
|
|
|
|
|
|
|
|
|
|
|
this._consumeDefense(defenderRoll.passeArme);
|
|
|
|
|
|
|
|
await this.computeRecul(defenderRoll);
|
|
|
|
await this.computeRecul(defenderRoll);
|
|
|
|
await this.computeDeteriorationArme(defenderRoll);
|
|
|
|
await this.computeDeteriorationArme(defenderRoll);
|
|
|
|
|
|
|
|
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RdDCombat._deleteDefense(defenderRoll.passeArme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
@ -630,7 +646,7 @@ export class RdDCombat {
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
|
|
|
|
|
|
|
|
|
|
|
|
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
|
|
|
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
|
|
|
this._sendMessageDefense(defenderRoll.attackerRoll, { defense: true });
|
|
|
|
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true });
|
|
|
|
this._storeDefense(defenderRoll);
|
|
|
|
this._storeDefense(defenderRoll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -691,8 +707,8 @@ export class RdDCombat {
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
async _onEsquiveNormale(defenderRoll) {
|
|
|
|
async _onEsquiveNormale(defenderRoll) {
|
|
|
|
console.log("RdDCombat._onEsquiveNormal >>>", defenderRoll);
|
|
|
|
console.log("RdDCombat._onEsquiveNormal >>>", defenderRoll);
|
|
|
|
this._consumeDefense(defenderRoll.passeArme);
|
|
|
|
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
|
|
|
|
|
|
|
|
RdDCombat._deleteDefense(defenderRoll.passeArme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
@ -702,7 +718,7 @@ export class RdDCombat {
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
|
|
|
|
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
|
|
|
|
|
|
|
|
|
|
|
|
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
|
|
|
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
|
|
|
this._sendMessageDefense(defenderRoll.attackerRoll, { defense: true })
|
|
|
|
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true })
|
|
|
|
this._storeDefense(defenderRoll);
|
|
|
|
this._storeDefense(defenderRoll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -792,15 +808,8 @@ export class RdDCombat {
|
|
|
|
defenderTokenId = defenderTokenId || this.defenderTokenId;
|
|
|
|
defenderTokenId = defenderTokenId || this.defenderTokenId;
|
|
|
|
console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId);
|
|
|
|
console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId);
|
|
|
|
|
|
|
|
|
|
|
|
let defenderRoll = this._consumeDefense(attackerRoll.passeArme);
|
|
|
|
let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
|
|
|
|
if (!defenderRoll) {
|
|
|
|
if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) {
|
|
|
|
defenderRoll = {
|
|
|
|
|
|
|
|
attackerRoll: attackerRoll,
|
|
|
|
|
|
|
|
show: {}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (RdDCombat.isEchecTotal(defenderRoll)) {
|
|
|
|
|
|
|
|
// TODO: echec total!!!
|
|
|
|
|
|
|
|
this._onEchecTotal(defenderRoll);
|
|
|
|
this._onEchecTotal(defenderRoll);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -810,12 +819,18 @@ export class RdDCombat {
|
|
|
|
|
|
|
|
|
|
|
|
await this.computeRecul(defenderRoll);
|
|
|
|
await this.computeRecul(defenderRoll);
|
|
|
|
this.defender.encaisserDommages(attackerRoll, this.attacker);
|
|
|
|
this.defender.encaisserDommages(attackerRoll, this.attacker);
|
|
|
|
} else { // Emit message for GM
|
|
|
|
} 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.foundryvtt-reve-de-dragon", {
|
|
|
|
game.socket.emit("system.foundryvtt-reve-de-dragon", {
|
|
|
|
msg: "msg_encaisser",
|
|
|
|
msg: "msg_encaisser",
|
|
|
|
data: { attackerId: this.attackerId, defenderTokenId: defenderTokenId }
|
|
|
|
data: {
|
|
|
|
|
|
|
|
attackerId: this.attackerId,
|
|
|
|
|
|
|
|
defenderTokenId: defenderTokenId,
|
|
|
|
|
|
|
|
attackerRoll: attackerRoll,
|
|
|
|
|
|
|
|
gmId: game.users.entities.find(u => u.isGM)?.id,
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
RdDCombat._deleteDefense(attackerRoll.passeArme);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* -------------------------------------------- */
|
|
|
|
/* -------------------------------------------- */
|
|
|
|