This commit is contained in:
sladecraven 2022-01-30 16:11:24 +01:00
commit 20d57bf10c
12 changed files with 134 additions and 192 deletions

View File

@ -33,7 +33,7 @@ import { RollDataAjustements } from "./rolldata-ajustements.js";
import { DialogItemAchat } from "./dialog-item-achat.js";
import { RdDItem } from "./item.js";
import { RdDPossession } from "./rdd-possession.js";
import { SYSTEM_RDD } from "./constants.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
/* -------------------------------------------- */
/**
@ -62,26 +62,23 @@ export class RdDActor extends Actor {
}
}
static remoteActorCall(data) {
if (Misc.isUniqueConnectedGM()) {
static remoteActorCall(data, canExecuteLocally = () => Misc.isUniqueConnectedGM()) {
if (canExecuteLocally()) {
RdDActor.onRemoteActorCall(data);
return false;
}
else {
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_remote_actor_call", data: data });
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_remote_actor_call", data: data });
return true;
}
}
static onRemoteActorCall(data) {
if (Misc.isUniqueConnectedGM()) { // Seul le joueur choisi effectue l'appel
const actor = game.actors.get(data?.actorId);
if (!actor) {
console.info("RdDActor.onRemoteActorCall: Pas d'Actor disponible ", data);
}
else {
const args = data.args;
console.info(`RdDActor.onRemoteActorCall: pour l'Actor ${data.actorId}, appel de RdDActor.${data.method}(`, ...args, ')');
actor[data.method](...args);
}
const actor = game.actors.get(data?.actorId);
if (Misc.isOwnerPlayerOrUniqueConnectedGM(actor)) { // Seul le joueur choisi effectue l'appel: le joueur courant si propriétaire de l'actor, ou le MJ sinon
const args = data.args;
console.info(`RdDActor.onRemoteActorCall: pour l'Actor ${data.actorId}, appel de RdDActor.${data.method}(`, ...args, ')');
actor[data.method](...args);
}
}
@ -497,11 +494,11 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async _recupereChance() {
// On ne récupère un point de chance que si aucun appel à la chance dans la journée
if (this.getChanceActuel() < this.getChance() && !this.getFlag('foundryvtt-reve-de-dragon', 'utilisationChance')) {
if (this.getChanceActuel() < this.getChance() && !this.getFlag(SYSTEM_RDD, 'utilisationChance')) {
await this.chanceActuelleIncDec(1);
}
// Nouveau jour, suppression du flag
await this.unsetFlag('foundryvtt-reve-de-dragon', 'utilisationChance');
await this.unsetFlag(SYSTEM_RDD, 'utilisationChance');
}
async _jetDeMoralChateauDormant(message) {
@ -1472,7 +1469,7 @@ export class RdDActor extends Actor {
async cacheTMRetMessage() {
await this.reinsertionAleatoire("Action MJ");
await this.cacheTMR();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_tmr_move", data: {
actorId: this.data._id,
tmrPos: this.data.data.reve.tmrpos
@ -1483,7 +1480,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async afficheTMRetMessage() {
await this.montreTMR();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_tmr_move", data: {
actorId: this.data._id,
tmrPos: this.data.data.reve.tmrpos
@ -2461,7 +2458,7 @@ export class RdDActor extends Actor {
this.currentTMR.close(); // Close TMR !
}
// Final chat message
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html');
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-sort.html');
if (reveActuel == 0) { // 0 points de reve
ChatMessage.create({ content: this.name + " est réduit à 0 Points de Rêve, et tombe endormi !" });
@ -2491,7 +2488,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async _onRollCaracResult(rollData) {
// Final chat message
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-general.html');
}
async rollCaracCompetence(caracName, compName, diff, options = { title: "", apprecier: false }) {
@ -2519,7 +2516,7 @@ export class RdDActor extends Actor {
RollDataAjustements.calcul(rollData, this);
await RdDResolutionTable.rollData(rollData);
this._appliquerExperienceRollData(rollData);
RdDResolutionTable.displayRollData(rollData, this)
await RdDResolutionTable.displayRollData(rollData, this)
return rollData.rolled;
}
@ -2565,7 +2562,7 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async _competenceResult(rollData) {
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-competence.html')
}
/* -------------------------------------------- */
@ -2644,7 +2641,7 @@ export class RdDActor extends Actor {
this.updateEmbeddedDocuments('Item', [rollData.tache]);
this.santeIncDec("fatigue", rollData.tache.data.fatigue);
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html');
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-tache.html');
}
/* -------------------------------------------- */
@ -2691,7 +2688,7 @@ export class RdDActor extends Actor {
const baseQualite = (artData.rolled.isSuccess ? artData.oeuvre.data.niveau : artData.competence.data.niveau);
artData.qualiteFinale = Math.min(baseQualite, artData.oeuvre.data.niveau) + artData.rolled.ptQualite;
RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`);
await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`);
}
/* -------------------------------------------- */
@ -2769,7 +2766,7 @@ export class RdDActor extends Actor {
ui.notifications.info(`${platCuisine.data.quantite} rations de ${platCuisine.name} ont été ajoutés à votre équipement`);
}
artData.platCuisine = platCuisine;
RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`);
await RdDResolutionTable.displayRollData(artData, this.name, `chat-resultat-${artData.art}.html`);
}
/* -------------------------------------------- */
@ -2837,7 +2834,7 @@ export class RdDActor extends Actor {
await this.createEmbeddedDocuments("Item", [signeData]);
}
RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html');
await RdDResolutionTable.displayRollData(meditationData, this.name, 'chat-resultat-meditation.html');
}
/* -------------------------------------------- */
@ -2917,7 +2914,7 @@ export class RdDActor extends Actor {
await this.updateExperienceLog("XP Sort", rollData.xpSort, "Signe draconique en " + rollData.competence.name);
}
await this.deleteEmbeddedDocuments("Item", [rollData.signe._id]);
RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html');
await RdDResolutionTable.displayRollData(rollData, this.name, 'chat-resultat-lecture-signedraconique.html');
this.currentTMR.close();
}
@ -2943,7 +2940,7 @@ export class RdDActor extends Actor {
async _appelChanceResult(rollData, onSuccess = () => { }, onEchec = () => { }) {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-appelchance.html')
if (rollData.rolled.isSuccess) {
await this.setFlag('foundryvtt-reve-de-dragon', 'utilisationChance', true);
await this.setFlag(SYSTEM_RDD, 'utilisationChance', true);
await this.chanceActuelleIncDec(-1);
onSuccess();
}
@ -3342,7 +3339,7 @@ export class RdDActor extends Actor {
show: defenderRoll?.show ?? {}
});
ChatUtility.createChatWithRollMode(this.name, {
await ChatUtility.createChatWithRollMode(this.name, {
roll: encaissement.roll,
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.html', encaissement)
});
@ -3496,21 +3493,21 @@ export class RdDActor extends Actor {
/* -------------------------------------------- */
async resetItemUse() {
await this.unsetFlag('foundryvtt-reve-de-dragon', 'itemUse');
await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', {});
await this.unsetFlag(SYSTEM_RDD, 'itemUse');
await this.setFlag(SYSTEM_RDD, 'itemUse', {});
}
/* -------------------------------------------- */
async incDecItemUse(itemId, inc = 1) {
let itemUse = duplicate(this.getFlag('foundryvtt-reve-de-dragon', 'itemUse') ?? {});
let itemUse = duplicate(this.getFlag(SYSTEM_RDD, 'itemUse') ?? {});
itemUse[itemId] = (itemUse[itemId] ?? 0) + inc;
await this.setFlag('foundryvtt-reve-de-dragon', 'itemUse', itemUse);
await this.setFlag(SYSTEM_RDD, 'itemUse', itemUse);
console.log("ITEM USE INC", inc, itemUse);
}
/* -------------------------------------------- */
getItemUse(itemId) {
let itemUse = this.getFlag('foundryvtt-reve-de-dragon', 'itemUse') ?? {};
let itemUse = this.getFlag(SYSTEM_RDD, 'itemUse') ?? {};
console.log("ITEM USE GET", itemUse);
return itemUse[itemId] ?? 0;
}
@ -3668,7 +3665,10 @@ export class RdDActor extends Actor {
return;
}
if (fromActorId && !game.user.isGM) {
RdDActor.remoteActorCall({ userId: Misc.connectedGMOrUser(), actorId: this.id, method: 'ajouterDeniers', args: [gain, fromActorId] });
RdDActor.remoteActorCall({
userId: Misc.connectedGMOrUser(),
actorId: this.id,
method: 'ajouterDeniers', args: [gain, fromActorId] });
}
else {
const fromActor = game.actors.get(fromActorId)
@ -3700,7 +3700,11 @@ export class RdDActor extends Actor {
return;
}
if (!Misc.isUniqueConnectedGM()) {
RdDActor.remoteActorCall({ actorId: achat.vendeurId ?? achat.acheteurId, method: 'achatVente', args: [achat] });
RdDActor.remoteActorCall({
actorId: achat.vendeurId ?? achat.acheteurId,
method: 'achatVente',
args: [achat] },
);
return;
}
@ -3817,7 +3821,7 @@ export class RdDActor extends Actor {
callbacks: [
this.createCallbackExperience(),
this.createCallbackAppelAuMoral(),
{ action: r => this._alchimieResult(r, false) }
{ action: async r => await this._alchimieResult(r, false) }
]
}
);
@ -3830,8 +3834,8 @@ export class RdDActor extends Actor {
}
/* -------------------------------------------- */
_alchimieResult(rollData) {
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-alchimie.html');
async _alchimieResult(rollData) {
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-alchimie.html');
}
/* -------------------------------------------- */

View File

@ -1,4 +1,7 @@
import { Misc } from "./misc.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
export const MESSAGE_DATA = 'message-data';
/**
* Class providing helper methods to get the list of users, and
@ -23,7 +26,7 @@ export class ChatUtility {
ChatUtility.onNotifyUser(data);
}
else {
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_user_ui_notifications", data: data
});
}
@ -66,11 +69,11 @@ export class ChatUtility {
/* -------------------------------------------- */
static removeMessages(data) {
if (Misc.isUniqueConnectedGM()){
if (Misc.isUniqueConnectedGM()) {
ChatUtility.onRemoveMessages(data);
}
else {
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_delete_chat_message", data: data });
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_delete_chat_message", data: data });
}
}
@ -86,12 +89,12 @@ export class ChatUtility {
}
/* -------------------------------------------- */
static createChatWithRollMode(name, chatOptions) {
ChatUtility.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions);
static async createChatWithRollMode(name, chatOptions) {
return await ChatUtility.createChatMessage(name, game.settings.get("core", "rollMode"), chatOptions);
}
/* -------------------------------------------- */
static createChatMessage(name, rollMode, chatOptions) {
static async createChatMessage(name, rollMode, chatOptions) {
switch (rollMode) {
case "blindroll": // GM only
if (!game.user.isGM) {
@ -109,7 +112,7 @@ export class ChatUtility {
break;
}
chatOptions.alias = chatOptions.alias || name;
ChatMessage.create(chatOptions);
return await ChatMessage.create(chatOptions);
}
/* -------------------------------------------- */
@ -147,7 +150,7 @@ export class ChatUtility {
chatGM.whisper = ChatUtility.getUsers(user => user.isGM);
chatGM.content = "Message aveugle de " + game.user.name + "<br>" + chatOptions.content;
console.log("blindMessageToGM", chatGM);
game.socket.emit("system.foundryvtt-reve-de-dragon", { msg: "msg_gm_chat_message", data: chatGM });
game.socket.emit(SYSTEM_SOCKET_ID, { msg: "msg_gm_chat_message", data: chatGM });
}
/* -------------------------------------------- */
@ -159,4 +162,20 @@ export class ChatUtility {
}
}
static async setMessageData(chatMessage, key, data) {
if (data) {
await chatMessage.setFlag(SYSTEM_RDD, key, JSON.stringify(data));
}
}
static getMessageData(chatMessage, key) {
const json = chatMessage.getFlag(SYSTEM_RDD, key);
return json ? JSON.parse(json) : undefined;
}
static getChatMessage(event) {
const chatMessageId = $(event.currentTarget).closest('.chat-message').attr('data-message-id');
return game.messages.get(chatMessageId);
}
}

View File

@ -1,4 +1,5 @@
export const SYSTEM_RDD = "foundryvtt-reve-de-dragon";
export const SYSTEM_RDD = 'foundryvtt-reve-de-dragon';
export const SYSTEM_SOCKET_ID = 'system.foundryvtt-reve-de-dragon';
export const HIDE_DICE = 'hide';
export const SHOW_DICE = 'show';

View File

@ -147,6 +147,14 @@ export class Misc {
}
static isOwnerPlayer(actor, user=undefined) {
return actor.testUserPermission(user ?? game.user, CONST.DOCUMENT_PERMISSION_LEVELS.OWNER)
}
static isOwnerPlayerOrUniqueConnectedGM(actor, user =undefined){
return Misc.isOwnerPlayer(actor, user) ?? Misc.isUniqueConnectedGM();
}
/**
* @returns true pour un seul utilisateur: le premier GM connecté par ordre d'id
*/

View File

@ -1,5 +1,6 @@
import { RdDItemCompetence } from "./item-competence.js";
import { Misc } from "./misc.js";
import { SYSTEM_SOCKET_ID } from "./constants.js";
/**
@ -74,7 +75,7 @@ export class RdDAstrologieJoueur extends Dialog {
if (Misc.isUniqueConnectedGM()) {
game.system.rdd.calendrier.requestNombreAstral(data);
} else {
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_request_nombre_astral",
data: data
});

View File

@ -7,7 +7,7 @@ import { RdDUtility } from "./rdd-utility.js";
import { Grammar } from "./grammar.js";
import { RdDDice } from "./rdd-dice.js";
import { Misc } from "./misc.js";
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD } from "./constants.js";
import { HIDE_DICE, SHOW_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
/* -------------------------------------------- */
const dossierIconesHeures = 'systems/foundryvtt-reve-de-dragon/icons/heures/'
@ -172,7 +172,7 @@ export class RdDCalendrier extends Application {
this.listeNombreAstral = [];
game.settings.set(SYSTEM_RDD, "liste-nombre-astral", this.listeNombreAstral);
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_reset_nombre_astral",
data: {}
});
@ -254,8 +254,8 @@ export class RdDCalendrier extends Application {
this.checkMaladie("jour");
}
game.settings.set(SYSTEM_RDD, "calendrier", duplicate(this.calendrier));
// Notification aux joueurs
game.socket.emit("system.foundryvtt-reve-de-dragon", {
// Notification aux joueurs // TODO: replace with Hook on game settings update
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_sync_time",
data: duplicate(this.calendrier)
});
@ -343,7 +343,7 @@ export class RdDCalendrier extends Application {
if (Misc.getActiveUser(request.userId)?.isGM) {
RdDUtility.responseNombreAstral(request);
} else {
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_response_nombre_astral",
data: request
});
@ -474,7 +474,7 @@ export class RdDCalendrier extends Application {
await this.rebuildListeNombreAstral();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_sync_time",
data: duplicate(this.calendrier)
});

View File

@ -1,5 +1,5 @@
import { ChatUtility } from "./chat-utility.js";
import { HIDE_DICE, SYSTEM_RDD } from "./constants.js";
import { HIDE_DICE, SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { RdDItemArme } from "./item-arme.js";
import { RdDItemCompetence } from "./item-competence.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
@ -371,19 +371,10 @@ export class RdDCombatManager extends Combat {
export class RdDCombat {
static init() {
this.initStorePasseArmes();
Hooks.on("updateCombat", (combat, change, options, userId) => { RdDCombat.onUpdateCombat(combat, change, options, userId) });
Hooks.on("preDeleteCombat", (combat, options, userId) => { RdDCombat.onPreDeleteCombat(combat, options, userId); });
}
/* -------------------------------------------- */
static initStorePasseArmes() {
game.system.rdd.combatStore = {
attaques: {},
defenses: {}
};
}
/* -------------------------------------------- */
static onSocketMessage(sockmsg) {
switch (sockmsg.msg) {
@ -391,8 +382,6 @@ export class RdDCombat {
return RdDCombat.onMsgEncaisser(sockmsg.data);
case "msg_defense":
return RdDCombat.onMsgDefense(sockmsg.data);
case "msg_combat_passearme":
return RdDCombat.onMsgPasseArme(sockmsg.data);
}
}
@ -405,22 +394,11 @@ export class RdDCombat {
/* -------------------------------------------- */
static onPreDeleteCombat(combat, options, userId) {
if (game.user.isGM) {
if (Misc.isUniqueConnectedGM()) {
combat.cleanItemUse();
ChatUtility.removeChatMessageContaining(`<div data-combatid="${combat.id}" data-combatmessage="actor-turn-summary">`)
/*
* 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(`<div data-passearme="${attackerRoll.passeArme}">`);
}
for (const key in game.system.rdd.combatStore.defenses) {
const defenderRoll = game.system.rdd.combatStore.defenses[key];
ChatUtility.removeChatMessageContaining(`<div data-passearme="${defenderRoll.passeArme}">`);
}
RdDCombat.initStorePasseArmes();
game.messages.filter(m => ChatUtility.getMessageData(m, 'attacker-roll') != undefined && ChatUtility.getMessageData(m, 'defender-roll') != undefined)
.forEach(it => it.delete());
}
}
@ -471,60 +449,6 @@ export class RdDCombat {
return undefined;
}
/* -------------------------------------------- */
static messagePasseArme(data) {
game.socket.emit("system.foundryvtt-reve-de-dragon", { 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)
@ -544,16 +468,15 @@ export class RdDCombat {
/* -------------------------------------------- */
static onMsgEncaisser(data) {
if (Misc.isUniqueConnectedGM()) {
let attackerRoll = RdDCombat._getAttaque(data.attackerId); // Retrieve the rolldata from the store
let defender = canvas.tokens.get(data.defenderTokenId).actor;
if (Misc.isOwnerPlayerOrUniqueConnectedGM()) {
let attackerRoll = data.attackerRoll;
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);
}
}
/* -------------------------------------------- */
@ -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')
@ -917,29 +831,31 @@ export class RdDCombat {
dmg: attackerRoll.dmg,
};
if (!Misc.isUniqueConnectedGM()) {
this._socketSendMessageDefense(paramChatDefense, defenderRoll);
if (Misc.isUniqueConnectedGM()) {
await this._chatMessageDefense(paramChatDefense, defenderRoll);
}
else {
await this._chatMessageDefense(paramChatDefense);
this._socketSendMessageDefense(paramChatDefense, defenderRoll);
}
}
/* -------------------------------------------- */
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);
}
/* -------------------------------------------- */
_socketSendMessageDefense(paramChatDefense, defenderRoll) {
// envoyer le message au destinataire
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_defense", data: {
attackerId: this.attacker?.data._id,
defenderId: this.defender?.data._id,
@ -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,20 +1194,15 @@ 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);
}
if (Misc.isUniqueConnectedGM()) {
if (Misc.isOwnerPlayerOrUniqueConnectedGM(this.defender)) {
attackerRoll.attackerId = this.attackerId;
attackerRoll.defenderTokenId = defenderTokenId;
@ -1303,7 +1210,7 @@ export class RdDCombat {
this.defender.encaisserDommages(attackerRoll, this.attacker, defenderRoll);
}
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_SOCKET_ID, {
msg: "msg_encaisser",
data: {
attackerId: this.attackerId,

View File

@ -1,3 +1,4 @@
import { SYSTEM_RDD } from "./constants.js";
import { Misc } from "./misc.js";
export class RddCompendiumOrganiser {
@ -8,7 +9,7 @@ export class RddCompendiumOrganiser {
static async onRenderCompendium(compendium, html, data) {
console.log('onRenderCompendium', compendium, html, data);
const pack = compendium.collection
if (pack.metadata.system === 'foundryvtt-reve-de-dragon') {
if (pack.metadata.system === SYSTEM_RDD) {
html.find('.directory-item').each((i, element) => {
RddCompendiumOrganiser.setEntityTypeName(pack, element);
});

View File

@ -8,7 +8,7 @@
/* -------------------------------------------- */
// Import Modules
import { SYSTEM_RDD } from "./constants.js";
import { SYSTEM_RDD, SYSTEM_SOCKET_ID } from "./constants.js";
import { RdDActor } from "./actor.js";
import { RdDItemSheet } from "./item-sheet.js";
import { RdDActorSheet } from "./actor-sheet.js";
@ -147,7 +147,7 @@ Hooks.once("init", async function () {
};
/* -------------------------------------------- */
game.socket.on("system.foundryvtt-reve-de-dragon", sockmsg => {
game.socket.on(SYSTEM_SOCKET_ID, sockmsg => {
console.log(">>>>> MSG RECV", sockmsg);
RdDUtility.onSocketMessage(sockmsg);

View File

@ -50,13 +50,13 @@ export class RdDPossession {
}
/* -------------------------------------------- */
static resultConjuration( rollData) {
static async resultConjuration( rollData) {
console.log("RollData!!!", rollData);
if ( !rollData.rolled.isSuccess ) {
rollData.possession.data.compteur++;
}
this.updateEtatPossession(rollData.possession);
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
}
/* -------------------------------------------- */
@ -86,7 +86,7 @@ export class RdDPossession {
name: 'conjurer',
label: 'Conjurer une Possession',
callbacks: [
{ action: async r => this.resultConjuration(r) }
{ action: async r => await this.resultConjuration(r) }
]
}
);
@ -94,11 +94,11 @@ export class RdDPossession {
}
/* -------------------------------------------- */
static _onRollPossession( rollData, isSuccess ) {
static async _onRollPossession( rollData, isSuccess ) {
let possession = rollData.possession;
possession.isSuccess = isSuccess;
this.updateEtatPossession( possession);
RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
await RdDResolutionTable.displayRollData(rollData, this, 'chat-resultat-possession.html');
}
/* -------------------------------------------- */
@ -141,8 +141,8 @@ export class RdDPossession {
name: 'jet-possession',
label: 'Possession: ',
callbacks: [
{ condition: r => (r.rolled.isSuccess), action: r => this._onRollPossession(r, true) },
{ condition: r => (r.rolled.isEchec), action: r => this._onRollPossession(r, false) },
{ condition: r => (r.rolled.isSuccess), action: async r => await this._onRollPossession(r, true) },
{ condition: r => (r.rolled.isEchec), action: async r => await this._onRollPossession(r, false) },
]
});
dialog.render(true);

View File

@ -64,7 +64,7 @@ export class RdDResolutionTable {
/* -------------------------------------------- */
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.html') {
ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
return await ChatUtility.createChatWithRollMode(actor?.userName ?? game.user.name, {
content: await RdDResolutionTable.buildRollDataHtml(rollData, actor, template)
});
}

View File

@ -1,3 +1,4 @@
import { SYSTEM_SOCKET_ID } from "./constants.js";
import { RollDataAjustements } from "./rolldata-ajustements.js";
import { RdDUtility } from "./rdd-utility.js";
import { TMRUtility } from "./tmr-utility.js";
@ -947,7 +948,7 @@ export class RdDTMRDialog extends Dialog {
this.cumulFatigue += this.fatigueParCase;
}
this.updateValuesDisplay();
game.socket.emit("system.foundryvtt-reve-de-dragon", {
game.socket.emit(SYSTEM_SOCKET_ID, {
msg: "msg_tmr_move", data: {
actorId: this.actor.data._id,
tmrPos: Misc.data(this.actor).data.reve.tmrpos