Visibilité des tirages dans le compendium

Les tirages de queues, têtes, ... ne concernent plus tout le monde,
mais le joueur et le MJ
This commit is contained in:
2026-04-26 22:37:48 +02:00
parent ef30e76449
commit 76fb385c69
9 changed files with 79 additions and 75 deletions
+1
View File
@@ -4,6 +4,7 @@
- Correction du recul contre une entité de cauchemar (qui utilise le rêve comme force) - Correction du recul contre une entité de cauchemar (qui utilise le rêve comme force)
- Correction erreur lors de la suppression d'un objet d'un conteneur - Correction erreur lors de la suppression d'un objet d'un conteneur
- Meilleure gestion des messages publics/GM, en particulier pour les tirage dans les compendiums
## 13.0.34 - La saumuche d'Illysis ## 13.0.34 - La saumuche d'Illysis
+6 -6
View File
@@ -665,12 +665,12 @@ export class RdDBaseActorReve extends RdDBaseActor {
show: show ?? {} show: show ?? {}
}, { overwrite: false }); }, { overwrite: false });
await ChatUtility.createChatWithRollMode({ await ChatMessage.create(ChatUtility.adaptVisibility(
roll: encaissement.roll, {
content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement) roll: encaissement.roll,
}, content: await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-resultat-encaissement.hbs', encaissement)
this },
) { actor: this }))
if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) { if (!encaissement.hasPlayerOwner && encaissement.endurance != 0) {
encaissement = foundry.utils.duplicate(encaissement) encaissement = foundry.utils.duplicate(encaissement)
+12 -10
View File
@@ -92,27 +92,28 @@ export class ChatUtility {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async createChatWithRollMode(messageData, actor = undefined, rollMode = game.settings.get("core", "rollMode")) { static adaptVisibility( messageData, options = { actor: undefined, rollMode: undefined }) {
switch (rollMode) { foundry.utils.mergeObject(options, { rollMode: game.settings.get("core", "rollMode") }, { overwrite: false });
switch (options.rollMode) {
case "blindroll": // GM only case "blindroll": // GM only
if (!game.user.isGM) { if (!game.user.isGM) {
ChatUtility.blindMessageToGM(messageData) ChatUtility.blindMessageToGM(messageData)
messageData.whisper = [game.user]; messageData.whisper = [game.user]
messageData.content = "Message envoyé en aveugle au Gardien" messageData.content = "Message envoyé en aveugle au Gardien";
} }
else { else {
messageData.whisper = ChatUtility.getGMs() messageData.whisper = ChatUtility.getGMs()
} }
break break;
case "gmroll": case "gmroll":
messageData.whisper = actor ? ChatUtility.getOwners(actor) : ChatUtility.getUserAndGMs() messageData.whisper = options.actor ? ChatUtility.getOwners(options.actor) : ChatUtility.getUserAndGMs()
break break;
case "selfroll": case "selfroll":
messageData.whisper = [game.user] messageData.whisper = [game.user]
break break
} }
messageData.alias = messageData.alias ?? actor?.name ?? game.user.name messageData.alias = messageData.alias ?? options.actor?.name ?? game.user.name
return await ChatMessage.create(messageData) return messageData
} }
static tellToUser(message) { static tellToUser(message) {
@@ -134,6 +135,7 @@ export class ChatUtility {
whisper: ChatUtility.getUserAndGMs() whisper: ChatUtility.getUserAndGMs()
}) })
} }
static getOwners(document) { static getOwners(document) {
return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user] return document ? game.users.filter(it => document.getUserLevel(it) == CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) : [game.user]
} }
@@ -216,7 +218,7 @@ export class ChatUtility {
static async onRenderChatMessage(chatMessage, html, data) { static async onRenderChatMessage(chatMessage, html, data) {
const rddTimestamp = chatMessage.getFlag(SYSTEM_RDD, 'rdd-timestamp') const rddTimestamp = chatMessage.getFlag(SYSTEM_RDD, 'rdd-timestamp')
const heureRdD = $(html).find('header.message-header .heure-rdd') const heureRdD = $(html).find('header.message-header .heure-rdd')
if (rddTimestamp && heureRdD.length==0) { if (rddTimestamp && heureRdD.length == 0) {
const messageTimestamp = $(html).find('header.message-header .message-timestamp'); const messageTimestamp = $(html).find('header.message-header .message-timestamp');
const timestamp = new RdDTimestamp(rddTimestamp); const timestamp = new RdDTimestamp(rddTimestamp);
const timestampData = timestamp.toCalendrier(); const timestampData = timestamp.toCalendrier();
+8 -8
View File
@@ -996,9 +996,9 @@ export class RdDCombat {
const arme = rollData.arme; const arme = rollData.arme;
const avecArme = !['', 'sans-armes', 'armes-naturelles'].includes(arme?.system.categorie_parade ?? ''); const avecArme = !['', 'sans-armes', 'armes-naturelles'].includes(arme?.system.categorie_parade ?? '');
const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque"); const action = (rollData.attackerRoll ? (arme ? "la parade" : "l'esquive") : "l'attaque");
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: `<strong>Maladresse à ${action}!</strong> ` + await RdDRollTables.getMaladresse({ arme: avecArme }) }, { content: `<strong>Maladresse à ${action}!</strong> ` + await RdDRollTables.getMaladresse({ arme: avecArme }) },
this.defender) { actor: this.defender }))
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1122,9 +1122,9 @@ export class RdDCombat {
async infoAttaquantDesarme(rollData) { async infoAttaquantDesarme(rollData) {
if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) { if (/*TODO: parade?*/!rollData.attackerRoll?.particuliere) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132 // TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
this.defender) { actor: this.defender }))
} }
} }
@@ -1156,9 +1156,9 @@ export class RdDCombat {
console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll); console.log("RdDCombat._onParadeParticuliere >>>", defenderRoll);
if (!defenderRoll.attackerRoll.isPart) { if (!defenderRoll.attackerRoll.isPart) {
// TODO: attaquant doit jouer résistance et peut être désarmé p132 // TODO: attaquant doit jouer résistance et peut être désarmé p132
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` }, { content: `(à gérer) L'attaquant doit jouer résistance et peut être désarmé (p132)` },
this.defender) { actor: this.defender }))
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -1243,9 +1243,9 @@ export class RdDCombat {
/* -------------------------------------------- */ /* -------------------------------------------- */
async _onEsquiveParticuliere(defenderRoll) { async _onEsquiveParticuliere(defenderRoll) {
console.log("RdDCombat._onEsquiveParticuliere >>>", defenderRoll); console.log("RdDCombat._onEsquiveParticuliere >>>", defenderRoll);
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" }, { content: "<strong>Vous pouvez esquiver une deuxième fois!</strong>" },
this.defender); { actor: this.defender }))
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
+4 -6
View File
@@ -224,12 +224,10 @@ export class RdDEmpoignade {
const isNouvelle = empoignade == undefined; const isNouvelle = empoignade == undefined;
empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender)) empoignade = empoignade ?? (await RdDEmpoignade.createEmpoignade(attacker, defender))
if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) { if ((isNouvelle || empoignade.system.pointsemp == 0) && defender.hasArmeeMeleeEquipee()) {
ChatUtility.createChatWithRollMode( await ChatMessage.create(ChatUtility.adaptVisibility(
{ { content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.hbs`, { attacker: attacker, defender: defender }) },
content: await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/chat-empoignade-valider.hbs`, { attacker: attacker, defender: defender }) { actor: attacker }
}, ))
attacker
)
} else { } else {
await this.onAttaqueEmpoignadeValidee(attacker, defender) await this.onAttaqueEmpoignadeValidee(attacker, defender)
} }
+3 -5
View File
@@ -4,12 +4,10 @@ import { renderTemplate } from "./constants.js";
export class RdDRollResult { export class RdDRollResult {
static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') { static async displayRollData(rollData, actor = undefined, template = 'chat-resultat-general.hbs') {
const chatMessage = await ChatUtility.createChatWithRollMode( return await ChatMessage.create(ChatUtility.adaptVisibility(
{ content: await RdDRollResult.buildRollDataHtml(rollData, template) }, { content: await RdDRollResult.buildRollDataHtml(rollData, template) },
actor, { actor: actor, rollMode: rollData.current?.rollmode?.key }
rollData.current?.rollmode?.key ))
)
return chatMessage
} }
static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') { static async buildRollDataHtml(rollData, template = 'chat-resultat-general.hbs') {
+22 -20
View File
@@ -34,9 +34,9 @@ export class RdDRollTables {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getCompetence(toChat = false) { static async getCompetence(toChat = false, rollMode = "gmroll") {
if (toChat == 'liste') { if (toChat == 'liste') {
return await RdDRollTables.listOrRoll('competences', 'Item', ['competence'], toChat, it => 1); return await RdDRollTables.listOrRoll('competences', 'Item', ['competence'], toChat, rollMode, it => 1);
} }
else { else {
return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat); return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
@@ -44,56 +44,58 @@ export class RdDRollTables {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getSouffle(toChat = false) { static async getSouffle(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', ['souffle'], toChat); return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', ['souffle'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getQueue(toChat = false) { static async getQueue(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat); return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, rollMode);
} }
static async getDesirLancinant(toChat = false) { static async getDesirLancinant(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, rollMode,
it => it.system.frequence, it => it.system.frequence,
it => it.system.categorie == 'lancinant'); it => it.system.categorie == 'lancinant');
} }
static async getIdeeFixe(toChat = false) { static async getIdeeFixe(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', ['queue'], toChat, rollMode,
it => it.system.frequence, it => it.system.frequence,
it => it.system.categorie == 'ideefixe'); it => it.system.categorie == 'ideefixe');
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTeteHR(toChat = false) { static async getTeteHR(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', ['tete'], toChat); return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', ['tete'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTete(toChat = false) { static async getTete(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', ['tete'], toChat); return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', ['tete'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getOmbre(toChat = false) { static async getOmbre(toChat = false, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', ['ombre'], toChat); return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', ['ombre'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getTarot(toChat = true) { static async getTarot(toChat = true, rollMode = "gmroll") {
return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', ['tarot'], toChat); return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', ['tarot'], toChat, rollMode);
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async listOrRoll(compendium, type, subTypes, toChat, itemFrequence = it => it.system.frequence, filter = it => true) { static async listOrRoll(compendium, type, subTypes, toChat, rollMode,
itemFrequence = it => it.system.frequence,
filter = it => true) {
const table = new CompendiumTable(compendium, type, subTypes); const table = new CompendiumTable(compendium, type, subTypes);
if (toChat == 'liste') { if (toChat == 'liste') {
return await table.toChatMessage(itemFrequence, filter); return await table.toChatMessage(itemFrequence, filter);
} }
const row = await table.getRandom(itemFrequence, filter); const row = await table.getRandom(itemFrequence, filter);
if (row) { if (row) {
await CompendiumTableHelpers.tableRowToChatMessage(row, type); await CompendiumTableHelpers.tableRowToChatMessage(row, type, { rollMode: rollMode });
return row.document; return row.document;
} }
return undefined; return undefined;
+2 -2
View File
@@ -43,13 +43,13 @@ export default class ChatRollResult {
async display(roll, impacts) { async display(roll, impacts) {
this.prepareDisplay(roll) this.prepareDisplay(roll)
const chatMessage = await ChatUtility.createChatWithRollMode( const chatMessage = await ChatMessage.create(ChatUtility.adaptVisibility(
{ {
content: await this.buildRollHtml(roll) content: await this.buildRollHtml(roll)
}, },
roll.active.actor, roll.active.actor,
roll.current?.rollmode?.key roll.current?.rollmode?.key
) ))
await this.saveChatMessageRoll(chatMessage, roll, impacts) await this.saveChatMessageRoll(chatMessage, roll, impacts)
return chatMessage return chatMessage
+21 -18
View File
@@ -289,24 +289,26 @@ export class CompendiumTableHelpers {
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async tableRowToChatMessage(row, type, options = { showSource: true }) { static async tableRowToChatMessage(row, type, options = {}) {
foundry.utils.mergeObject(options, { showSource: true, rollMode: undefined }, { overwrite: false })
if (!row) { if (!row) {
return; return
} }
const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.hbs', { const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.hbs', {
roll: row.roll, roll: row.roll,
document: row.document, document: row.document,
typeName: Misc.typeName(type, row.document?.type ?? 'objet'), typeName: Misc.typeName(type, row.document?.type ?? 'objet'),
isGM: game.user.isGM, isGM: game.user.isGM,
options options: { showSource: options.showSource }
}); })
const messageData = { await ChatMessage.create(ChatUtility.adaptVisibility(
user: game.user.id, {
rolls: [row.roll], user: game.user.id,
sound: CONFIG.sounds.dice, rolls: [row.roll],
content: flavorContent sound: CONFIG.sounds.dice,
}; content: flavorContent
await ChatUtility.createChatWithRollMode(messageData) },
{ rollMode: options.rollMode }))
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
@@ -316,13 +318,14 @@ export class CompendiumTableHelpers {
typeName: typeName ?? Misc.typeName(type, subTypes[0]), typeName: typeName ?? Misc.typeName(type, subTypes[0]),
table, table,
isGM: game.user.isGM, isGM: game.user.isGM,
}); })
const messageData = { await ChatMessage.create(ChatUtility.adaptVisibility(
user: game.user.id, {
whisper: [game.user], user: game.user.id,
content: flavorContent whisper: [game.user],
}; content: flavorContent
await ChatUtility.createChatWithRollMode(messageData) }
))
} }
} }