Fix échange de messages de combat
Les actions des joueurs n'étaient pas toujours possibles à cause de tests multijoueurs insuffisants
This commit is contained in:
parent
9ee1b0250d
commit
7a668eb1cf
@ -28,9 +28,9 @@ export class RdDCombat {
|
||||
static onSocketMessage(sockmsg) {
|
||||
switch (sockmsg.msg) {
|
||||
case "msg_encaisser":
|
||||
return RdDCombat.terminerPasseArmes(data);
|
||||
return RdDCombat.onMsgEncaisser(sockmsg.data);
|
||||
case "msg_defense":
|
||||
return RdDCombat.handleMsgDefense(sockmsg.data);
|
||||
return RdDCombat.onMsgDefense(sockmsg.data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,6 +99,36 @@ export class RdDCombat {
|
||||
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) {
|
||||
return new RdDCombat(attacker, defender, defenderTokenId, target)
|
||||
@ -121,59 +151,36 @@ export class RdDCombat {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static handleMsgDefense(data) {
|
||||
let defenderToken = canvas.tokens.get(data.defenderTokenId);
|
||||
static onMsgEncaisser(data) {
|
||||
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 (!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.");
|
||||
return;
|
||||
}
|
||||
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);
|
||||
game.system.rdd.combatStore.attaques[data.attackerId] = duplicate(data.rollData);
|
||||
data.whisper = [game.user];
|
||||
data.blind = true;
|
||||
data.rollMode = "blindroll";
|
||||
ChatMessage.create(data);
|
||||
const defenderRoll = msgData.defenderRoll;
|
||||
RdDCombat._storeAttaque(msgData.attackerId, defenderRoll.attackerRoll);
|
||||
RdDCombat._storeDefense(defenderRoll);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
let actorId = event.currentTarget.attributes['data-actorId'].value;
|
||||
@ -218,11 +225,12 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async onEvent(button, event) {
|
||||
let attackerRoll = game.system.rdd.combatStore.attaques[this.attackerId];
|
||||
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 defenderTokenId = event.currentTarget.attributes['data-defenderTokenId']?.value;
|
||||
|
||||
const armeParadeId = event.currentTarget.attributes['data-armeid']?.value;
|
||||
@ -238,8 +246,8 @@ export class RdDCombat {
|
||||
() => this.attaqueChanceuse(attackerRoll),
|
||||
() => this._onEchecTotal(attackerRoll));
|
||||
case '#appel-chance-defense': return this.defender.rollAppelChance(
|
||||
() => this.defenseChanceuse(attackerRoll),
|
||||
() => this.afficherOptionsDefense(attackerRoll, { defenseChance: true }));
|
||||
() => this.defenseChanceuse(attackerRoll, defenderRoll),
|
||||
() => this.afficherOptionsDefense(attackerRoll, defenderRoll, { defenseChance: true }));
|
||||
case '#appel-destinee-attaque': return this.attacker.appelDestinee(
|
||||
() => 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) {
|
||||
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")
|
||||
attackerRoll.essais.defenseChance = true;
|
||||
attackerRoll.essais.defense = false;
|
||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||
this._sendMessageDefense(attackerRoll);
|
||||
this._sendMessageDefense(attackerRoll, defenderRoll, attackerRoll.essais);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
defenseDestinee(attackerRoll) {
|
||||
let defenderRoll = this._getDefense(attackerRoll.passeArme);
|
||||
let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
|
||||
if (defenderRoll) {
|
||||
ui.notifications.info('Défense significative grâce à la destinée')
|
||||
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");
|
||||
this._sendMessageDefense(attackerRoll, essais);
|
||||
this._sendMessageDefense(attackerRoll, defenderRoll, essais);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -410,13 +401,15 @@ export class RdDCombat {
|
||||
|
||||
/* -------------------------------------------- */
|
||||
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
|
||||
const isMeleeDiffNegative = rollData.selectedCarac.label == "Mêlée" && rollData.diffLibre < 0;
|
||||
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', {
|
||||
alias: this.attacker.name,
|
||||
attackerId: this.attackerId,
|
||||
defenderTokenId: this.defenderTokenId,
|
||||
isFinesse: isMeleeDiffNegative,
|
||||
@ -432,7 +425,7 @@ export class RdDCombat {
|
||||
attackerRoll.dmg = RdDBonus.dmg(attackerRoll, this.attacker.getBonusDegat(), this.defender.isEntiteCauchemar());
|
||||
|
||||
// Save rollData for defender
|
||||
game.system.rdd.combatStore.attaques[this.attackerId] = duplicate(attackerRoll);
|
||||
RdDCombat._storeAttaque(this.attackerId, attackerRoll);
|
||||
|
||||
attackerRoll.show = {
|
||||
cible: this.target ? this.defender.data.name : 'la cible',
|
||||
@ -450,11 +443,13 @@ export class RdDCombat {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async _sendMessageDefense(attackerRoll, essais = {}) {
|
||||
console.log("RdDCombat._sendMessageDefense", attackerRoll, essais, " / ", this.attacker, this.target, this.attackerId, attackerRoll.competence.data.categorie);
|
||||
async _sendMessageDefense(attackerRoll, defenderRoll = undefined, essaisPrecedents = undefined) {
|
||||
console.log("RdDCombat._sendMessageDefense", attackerRoll, defenderRoll, essaisPrecedents, " / ", this.attacker, this.target, this.attackerId, attackerRoll.competence.data.categorie);
|
||||
|
||||
this.removeChatMessageActionsPasseArme(attackerRoll.passeArme);
|
||||
mergeObject(attackerRoll.essais, essais, { overwrite: true });
|
||||
if (essaisPrecedents) {
|
||||
mergeObject(attackerRoll.essais, essaisPrecedents, { overwrite: true });
|
||||
}
|
||||
const paramDemandeDefense = {
|
||||
passeArme: attackerRoll.passeArme,
|
||||
essais: attackerRoll.essais,
|
||||
@ -467,11 +462,33 @@ export class RdDCombat {
|
||||
attaqueParticuliere: attackerRoll.particuliere,
|
||||
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) {
|
||||
items = items.filter(item => (item.type == 'arme' && item.data.equipe) || (item.type == 'competencecreature' && item.data.isparade));
|
||||
@ -491,7 +508,7 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
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
|
||||
ChatMessage.create({
|
||||
@ -615,11 +632,11 @@ export class RdDCombat {
|
||||
async _onParadeNormale(defenderRoll) {
|
||||
console.log("RdDCombat._onParadeNormale >>>", defenderRoll);
|
||||
|
||||
this._consumeDefense(defenderRoll.passeArme);
|
||||
await this.computeRecul(defenderRoll);
|
||||
await this.computeDeteriorationArme(defenderRoll);
|
||||
|
||||
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
|
||||
|
||||
RdDCombat._deleteDefense(defenderRoll.passeArme);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -629,7 +646,7 @@ export class RdDCombat {
|
||||
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-parade.html');
|
||||
|
||||
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
||||
this._sendMessageDefense(defenderRoll.attackerRoll, { defense: true });
|
||||
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true });
|
||||
this._storeDefense(defenderRoll);
|
||||
}
|
||||
|
||||
@ -690,8 +707,8 @@ export class RdDCombat {
|
||||
/* -------------------------------------------- */
|
||||
async _onEsquiveNormale(defenderRoll) {
|
||||
console.log("RdDCombat._onEsquiveNormal >>>", defenderRoll);
|
||||
this._consumeDefense(defenderRoll.passeArme);
|
||||
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
|
||||
RdDCombat._deleteDefense(defenderRoll.passeArme);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
@ -701,7 +718,7 @@ export class RdDCombat {
|
||||
await RdDResolutionTable.displayRollData(defenderRoll, this.defender, 'chat-resultat-esquive.html');
|
||||
|
||||
this.removeChatMessageActionsPasseArme(defenderRoll.passeArme);
|
||||
this._sendMessageDefense(defenderRoll.attackerRoll, { defense: true })
|
||||
this._sendMessageDefense(defenderRoll.attackerRoll, defenderRoll, { defense: true })
|
||||
this._storeDefense(defenderRoll);
|
||||
}
|
||||
|
||||
@ -791,15 +808,8 @@ export class RdDCombat {
|
||||
defenderTokenId = defenderTokenId || this.defenderTokenId;
|
||||
console.log("RdDCombat.encaisser >>>", attackerRoll, defenderTokenId);
|
||||
|
||||
let defenderRoll = this._consumeDefense(attackerRoll.passeArme);
|
||||
if (!defenderRoll) {
|
||||
defenderRoll = {
|
||||
attackerRoll: attackerRoll,
|
||||
show: {}
|
||||
};
|
||||
}
|
||||
else if (RdDCombat.isEchecTotal(defenderRoll)) {
|
||||
// TODO: echec total!!!
|
||||
let defenderRoll = RdDCombat._getDefense(attackerRoll.passeArme);
|
||||
if (defenderRoll?.rolled && RdDCombat.isEchecTotal(defenderRoll)) {
|
||||
this._onEchecTotal(defenderRoll);
|
||||
}
|
||||
|
||||
@ -809,12 +819,18 @@ export class RdDCombat {
|
||||
|
||||
await this.computeRecul(defenderRoll);
|
||||
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", {
|
||||
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);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
@ -635,8 +635,6 @@ export class RdDUtility {
|
||||
static onSocketMesssage(sockmsg) {
|
||||
console.log(">>>>> MSG RECV", sockmsg);
|
||||
switch (sockmsg.msg) {
|
||||
case "msg_encaisser":
|
||||
return RdDUtility._handleMsgEncaisser(sockmsg.data);
|
||||
case "msg_gm_chat_message":
|
||||
return ChatUtility.handleGMChatMessage(sockmsg.data);
|
||||
case "msg_sync_time":
|
||||
@ -749,15 +747,6 @@ export class RdDUtility {
|
||||
});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static _handleMsgEncaisser(data) {
|
||||
if (game.user.isGM) { // Seul le GM effectue l'encaissement sur la fiche
|
||||
let defender = canvas.tokens.get(data.defenderTokenId).actor;
|
||||
let attacker = data.attackerId ? game.actors.get(data.attackerId) : null;
|
||||
defender.encaisserDommages(attackerRoll, attacker);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
static async chatListeners(html) {
|
||||
RdDCombat.registerChatCallbacks(html);
|
||||
|
Loading…
Reference in New Issue
Block a user