diff --git a/module/actor.js b/module/actor.js
index 0e076007..717152c0 100644
--- a/module/actor.js
+++ b/module/actor.js
@@ -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');
}
/* -------------------------------------------- */
diff --git a/module/chat-utility.js b/module/chat-utility.js
index 65e0c557..976e1b0c 100644
--- a/module/chat-utility.js
+++ b/module/chat-utility.js
@@ -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 + "
" + 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);
+ }
+
}
diff --git a/module/constants.js b/module/constants.js
index be1d1c86..865a0559 100644
--- a/module/constants.js
+++ b/module/constants.js
@@ -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';
diff --git a/module/misc.js b/module/misc.js
index 3f8fa2a9..59fc080c 100644
--- a/module/misc.js
+++ b/module/misc.js
@@ -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
*/
diff --git a/module/rdd-astrologie-joueur.js b/module/rdd-astrologie-joueur.js
index bf0c3692..7497a97a 100644
--- a/module/rdd-astrologie-joueur.js
+++ b/module/rdd-astrologie-joueur.js
@@ -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
});
diff --git a/module/rdd-calendrier.js b/module/rdd-calendrier.js
index 7cc351c5..73a97003 100644
--- a/module/rdd-calendrier.js
+++ b/module/rdd-calendrier.js
@@ -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)
});
diff --git a/module/rdd-combat.js b/module/rdd-combat.js
index 0c354d1a..e341ed42 100644
--- a/module/rdd-combat.js
+++ b/module/rdd-combat.js
@@ -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(`