From 0dacbefd6b0278408618d415a9e1441d5ebe7898 Mon Sep 17 00:00:00 2001 From: Vincent Vandemeulebrouck Date: Sat, 26 Nov 2022 03:13:45 +0100 Subject: [PATCH] =?UTF-8?q?Tirer=20dans=20les=20compendiums=20selon=20les?= =?UTF-8?q?=20fr=C3=A9quences?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/actor.js | 3 +- module/item.js | 12 +- module/rdd-commands.js | 63 +++++--- module/rdd-main.js | 2 + module/rdd-rolltables.js | 52 ++++--- module/rdd-tmr-dialog.js | 4 +- module/rdd-utility.js | 7 +- module/rolldata-ajustements.js | 6 +- module/settings/system-compendiums.js | 146 +++++++++++++++++- module/tmr-rencontres.js | 144 ++++++++--------- module/tmr/present-cites.js | 3 +- packs/ombres-de-thanatos.db | 50 +++--- .../chat-compendium-table-roll-rencontre.html | 14 ++ templates/chat-compendium-table-roll.html | 13 ++ templates/chat-compendium-table.html | 16 ++ 15 files changed, 370 insertions(+), 165 deletions(-) create mode 100644 templates/chat-compendium-table-roll-rencontre.html create mode 100644 templates/chat-compendium-table-roll.html create mode 100644 templates/chat-compendium-table.html diff --git a/module/actor.js b/module/actor.js index 65017792..fa844883 100644 --- a/module/actor.js +++ b/module/actor.js @@ -21,7 +21,6 @@ import { STATUSES, StatusEffects } from "./settings/status-effects.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { RdDItemSigneDraconique } from "./item-signedraconique.js"; import { ReglesOptionelles } from "./settings/regles-optionelles.js"; -import { TMRRencontres } from "./tmr-rencontres.js"; import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; import { Draconique } from "./tmr/draconique.js"; import { RdDCarac } from "./rdd-carac.js"; @@ -771,7 +770,7 @@ export class RdDActor extends Actor { actor: this, competence: duplicate(this.getDraconicOuPossession()), canClose: false, - rencontre: await TMRRencontres.getReveDeDragon(force), + rencontre: await game.system.rencontresTMR.getReveDeDragon(force), tmr: true, use: { libre: false, conditions: false }, forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } } diff --git a/module/item.js b/module/item.js index c18aec5e..29fb3281 100644 --- a/module/item.js +++ b/module/item.js @@ -59,17 +59,23 @@ export const defaultItemImg = { possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.webp", + tarot: "systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp", } /* -------------------------------------------- */ export class RdDItem extends Item { + static getDefaultImg(itemType) { + return defaultItemImg[itemType]; + } + + constructor(itemData, context) { if (!itemData.img) { - itemData.img = defaultItemImg[itemData.type]; - } + itemData.img = RdDItem.getDefaultImg(itemData.type); + } super(itemData, context); - } + } static getTypesObjetsEquipement() { return typesObjetsEquipement diff --git a/module/rdd-commands.js b/module/rdd-commands.js index c9d8959d..9f4b4bbb 100644 --- a/module/rdd-commands.js +++ b/module/rdd-commands.js @@ -3,7 +3,6 @@ import { DialogChronologie } from "./dialog-chronologie.js"; import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; import { DialogStress } from "./dialog-stress.js"; -import { Grammar } from "./grammar.js"; import { RdDItemCompetence } from "./item-competence.js"; import { Misc } from "./misc.js"; import { RdDCarac } from "./rdd-carac.js"; @@ -14,7 +13,6 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js"; import { RdDRollTables } from "./rdd-rolltables.js"; import { RdDUtility } from "./rdd-utility.js"; -import { TMRRencontres } from "./tmr-rencontres.js"; import { TMRUtility } from "./tmr-utility.js"; const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/; @@ -27,15 +25,34 @@ export class RdDCommands { const rddCommands = new RdDCommands(); rddCommands.registerCommand({ path: ["/aide"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" }); rddCommands.registerCommand({ path: ["/help"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" }); - rddCommands.registerCommand({ path: ["/table", "queues"], func: (content, msg, params) => RdDRollTables.getQueue(true), descr: "Tire une Queue de Dragon" }); - rddCommands.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe(true), descr: "Tire une Idée fixe" }); - rddCommands.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant(true), descr: "Tire un Désir Lancinant" }); - rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre(true), descr: "Tire une Ombre de Dragon" }); - rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR(true), descr: "Tire une Tête de Dragon pour Hauts Revants" }); - rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(true), descr: "Tire une Tête de Dragon" }); - rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(true), descr: " Tire un Souffle de Dragon" }); - rddCommands.registerCommand({ path: ["/table", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence(true), descr: "Tire une compétence au hasard" }); - rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot(true), descr: "Tire une carte du Tarot Draconique" }); + + rddCommands.registerCommand({ path: ["/liste", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('liste'), descr: "Affiche la liste des compétences" }); + + rddCommands.registerCommand({ path: ["/table", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('liste'), descr: "Affiche la table des Queues de Dragon" }); + rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('liste'), descr: "Affiche la table des Ombres de Thanatos" }); + rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR('liste'), descr: "Affiche la table des Têtes de Dragon pour Hauts Revants" }); + rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete('liste'), descr: "Affiche la table des Tête de Dragon pour tous" }); + rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle('liste'), descr: "Affiche la table des Souffles de Dragon" }); + rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot('liste'), descr: "Affiche la table les cartes du Tarot Draconique" }); + rddCommands.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe('liste'), descr: "Affiche la table des Idées fixes" }); + rddCommands.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('liste'), descr: "Affiche la table des Désirs Lancinants" }); + rddCommands.registerCommand({ + path: ["/table", "rencontre"], func: (content, msg, params) => rddCommands.tableRencontres(msg, params), + descr: `Affiche la table des Rencontres +
/table rencontre deso affiche la table des rencontres en Désolation +
/table rencontre mauvaise affiche la table des mauvaises rencontres` }); + + rddCommands.registerCommand({ path: ["/tirer", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('chat'), descr: "Tire une compétence au hasard" }); + rddCommands.registerCommand({ path: ["/tirer", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('chat'), descr: "Tire une Queue de Dragon" }); + rddCommands.registerCommand({ path: ["/tirer", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('chat'), descr: "Tire une Ombre de Thanatos" }); + rddCommands.registerCommand({ path: ["/tirer", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR('chat'), descr: "Tire une Tête de Dragon pour Hauts Revants" }); + rddCommands.registerCommand({ path: ["/tirer", "tete"], func: (content, msg, params) => RdDRollTables.getTete('chat'), descr: "Tire une Tête de Dragon" }); + rddCommands.registerCommand({ path: ["/tirer", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle('chat'), descr: "Tire un Souffle de Dragon" }); + rddCommands.registerCommand({ path: ["/tirer", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot('chat'), descr: "Tire une carte du Tarot Draconique" }); + rddCommands.registerCommand({ path: ["/tirer", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe('chat'), descr: "Tire une Idée fixe" }); + rddCommands.registerCommand({ path: ["/tirer", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('chat'), descr: "Tire un Désir Lancinant" }); + rddCommands.registerCommand({ path: ["/tirer", "rencontre"], func: (content, msg, params) => rddCommands.getRencontreTMR(params), descr: `Détermine une rencontre dans les TMR (synonyme de "/tmrr")` }); + rddCommands.registerCommand({ path: ["/meteo"], func: (content, msg, params) => rddCommands.getMeteo(msg, params), descr: "Propose une météo marine" }); rddCommands.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" }); @@ -51,11 +68,10 @@ export class RdDCommands {
/tmra détermine une case aléatoire dans toutes les TMR` }); rddCommands.registerCommand({ path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params), - descr: `Détermine une rencontre dans un type de case + descr: `Détermine une rencontre dans les TMR
/tmrr forêt détermine une rencontre aléatoire en 'forêt'
/tmrr mauvaise détermine une mauvaise rencontre aléatoire -
/tmrr for 47 détermine la rencontre en 'forêt' pour un jet de dé de 47` - }); +
/tmrr for 47 détermine la rencontre en 'forêt' pour un jet de dé de 47` }); rddCommands.registerCommand({ path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params), @@ -208,10 +224,10 @@ export class RdDCommands { this.help(msg, undefined); } async help(msg, table) { - let list = [] - this._buildSubTableHelp(list, table || this.commandsTable); + let commands = [] + this._buildSubTableHelp(commands, table || this.commandsTable); - let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: list }); + let html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/settings/dialog-aide-commands.html", { commands: commands }); let d = new Dialog( { title: "Commandes disponibles dans le tchat", @@ -249,7 +265,7 @@ export class RdDCommands { /* -------------------------------------------- */ async getRencontreTMR(params) { if (params.length == 1 || params.length == 2) { - return TMRRencontres.rollRencontre(params[0], params[1]) + return game.system.rencontresTMR.rollRencontre(params[0], params[1]) } return false; } @@ -335,6 +351,17 @@ export class RdDCommands { } return false; } + async tableRencontres(msg, params) { + if (params && params.length > 0) { + const search = Misc.join(params, ' '); + const solvedTerrain = TMRUtility.findTMRLike(search); + if (solvedTerrain == undefined) { + return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search); + } + return game.system.rencontresTMR.chatTable(solvedTerrain); + } + return false; + } /* -------------------------------------------- */ getCoutXpComp(msg, params) { diff --git a/module/rdd-main.js b/module/rdd-main.js index 527a874a..af0b0fb3 100644 --- a/module/rdd-main.js +++ b/module/rdd-main.js @@ -39,6 +39,7 @@ import { Migrations } from './migrations.js'; import { DialogChronologie } from "./dialog-chronologie.js"; import { SystemCompendiums } from "./settings/system-compendiums.js"; import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js"; +import { TMRRencontres } from "./tmr-rencontres.js"; /* -------------------------------------------- */ /* Foundry VTT Initialization */ @@ -223,6 +224,7 @@ Hooks.once("init", async function () { TMRUtility.init(); RdDHotbar.initDropbar(); RdDPossession.init(); + TMRRencontres.init(); }); /* -------------------------------------------- */ diff --git a/module/rdd-rolltables.js b/module/rdd-rolltables.js index 8db91cf5..1d4fa456 100644 --- a/module/rdd-rolltables.js +++ b/module/rdd-rolltables.js @@ -1,3 +1,4 @@ +import { Grammar } from "./grammar.js"; import { SystemCompendiums } from "./settings/system-compendiums.js"; export class RdDRollTables { @@ -5,10 +6,8 @@ export class RdDRollTables { /* -------------------------------------------- */ static async genericGetTableResult(tableName, toChat) { let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName)); - const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"}); - //console.log("RdDRollTables", tableName, toChat, ":", draw); + const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll" }); return draw.results.length > 0 ? draw.results[0] : undefined; - } static getWorldTable(tableName) { @@ -28,7 +27,7 @@ export class RdDRollTables { const pack = game.packs.get(drawResult.documentCollection) return await pack.getDocument(drawResult.documentId) } - + /* -------------------------------------------- */ static async drawTextFromRollTable(tableName, toChat) { const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat); @@ -37,58 +36,67 @@ export class RdDRollTables { /* -------------------------------------------- */ static async getCompetence(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat); + if (toChat == 'liste') { + return await SystemCompendiums.chatTableItems('competences', 'Item', 'competence', it => 1); + } + else { + return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat); + } } /* -------------------------------------------- */ static async getSouffle(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Souffles de Dragon", toChat); + return await RdDRollTables.listOrRoll('souffles-de-dragon', 'Item', 'souffle', toChat); } /* -------------------------------------------- */ static async getQueue(toChat = false) { - let queue = await RdDRollTables.drawItemFromRollTable("Queues de dragon", toChat); - if (queue.name.toLowerCase().includes('lancinant') ) { - return await RdDRollTables.getDesirLancinant(toChat); - } - if (queue.name.toLowerCase().includes('fixe') ) { - return await RdDRollTables.getIdeeFixe(toChat); - } - return queue; + return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat); } static async getDesirLancinant(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Désirs lancinants", toChat); + return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat, it => it.system.frequence, + it => Grammar.toLowerCaseNoAccent(it.name).includes('desir lancinant') /* it.system.lancinant */); } - + static async getIdeeFixe(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Idées fixes", toChat); + return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat, it => it.system.frequence, + it => Grammar.toLowerCaseNoAccent(it.name).includes('idee fixe') /* it.system.ideefixe */); } /* -------------------------------------------- */ static async getTeteHR(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour haut-rêvants", toChat); + return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-haut-revants', 'Item', 'tete', toChat); } /* -------------------------------------------- */ static async getTete(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Têtes de Dragon pour tous personnages", toChat); + return await RdDRollTables.listOrRoll('tetes-de-dragon-pour-tous-personnages', 'Item', 'tete', toChat); } /* -------------------------------------------- */ static async getOmbre(toChat = false) { - return await RdDRollTables.drawItemFromRollTable("Ombre de Thanatos", toChat); + return await RdDRollTables.listOrRoll('ombres-de-thanatos', 'Item', 'ombre', toChat); } /* -------------------------------------------- */ static async getTarot(toChat = true) { - return await RdDRollTables.drawItemFromRollTable("Tarot Draconique", toChat); + return await RdDRollTables.listOrRoll('tarot-draconique', 'Item', 'tarot', toChat); } /* -------------------------------------------- */ - static async getMaladresse(options = {toChat: false, arme: false}) { + static async listOrRoll(compendium, type, subType, toChat, itemFrequence = it => it.system.frequence, filter = it => true) { + if (toChat == 'liste') { + return await SystemCompendiums.chatTableItems(compendium, type, subType, itemFrequence, filter); + } + return await SystemCompendiums.getRandom(compendium, type, subType, toChat, itemFrequence, filter); + } + + /* -------------------------------------------- */ + static async getMaladresse(options = { toChat: false, arme: false }) { return await RdDRollTables.drawTextFromRollTable( options.arme ? "Maladresse armé" : "Maladresses non armé", options.toChat); } + } diff --git a/module/rdd-tmr-dialog.js b/module/rdd-tmr-dialog.js index 6d3acf29..0c5e0439 100644 --- a/module/rdd-tmr-dialog.js +++ b/module/rdd-tmr-dialog.js @@ -575,7 +575,7 @@ export class RdDTMRDialog extends Dialog { async _jetDeRencontre(tmr) { let rencontre = this.lookupRencontreExistente(tmr); if (rencontre) { - return TMRRencontres.calculRencontre(rencontre, tmr); + return game.system.rencontresTMR.calculRencontre(rencontre, tmr); } let locTMR = (this.isDemiReveCache() ? TMRUtility.getTMRType(tmr.coord) + " ??" @@ -584,7 +584,7 @@ export class RdDTMRDialog extends Dialog { let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE }); if (myRoll == 7) { this._tellToUser(myRoll + ": Rencontre en " + locTMR); - return await TMRRencontres.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre()) + return await game.system.rencontresTMR.getRencontreAleatoire(tmr, this.actor.isMauvaiseRencontre()) } else { this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR); } diff --git a/module/rdd-utility.js b/module/rdd-utility.js index 4d80d747..10b4705d 100644 --- a/module/rdd-utility.js +++ b/module/rdd-utility.js @@ -283,14 +283,14 @@ export class RdDUtility { Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); }); Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord)); Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(coord)); - Handlebars.registerHelper('typeTmr-name', coord => TMRUtility.typeTmrName(coord)); + Handlebars.registerHelper('typeTmr-name', type => TMRUtility.typeTmrName(type)); Handlebars.registerHelper('effetRencontre-name', coord => TMRUtility.typeTmrName(coord)); Handlebars.registerHelper('signeHeure', (key, heure) => RdDCalendrier.getSigneAs(key, heure)); Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option)); Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name))); Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible) - .sort((a, b) => { + .sort((a, b) => { if (a.name.startsWith("Survie") && b.name.startsWith("Survie")) { if (a.name.includes("Cité")) return -1; if (b.name.includes("Cité")) return 1; @@ -320,7 +320,8 @@ export class RdDUtility { } return a.name.localeCompare(b.name); }) - ); + ); + Handlebars.registerHelper('linkCompendium', (compendium, id, name) => `@Compendium[${compendium}.${id}]{${name}}`); return loadTemplates(templatePaths); } diff --git a/module/rolldata-ajustements.js b/module/rolldata-ajustements.js index 08b2654d..690705a2 100644 --- a/module/rolldata-ajustements.js +++ b/module/rolldata-ajustements.js @@ -69,13 +69,13 @@ export const referenceAjustements = { }, surenc: { isVisible: (rollData, actor) => actor.isSurenc(), - isUsed: (rollData, actor) => rollData.use.surenc, + isUsed: (rollData, actor) => rollData.use?.surenc, getLabel: (rollData, actor) => 'Sur-encombrement', getValue: (rollData, actor) => actor.computeMalusSurEncombrement() }, moral: { - isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.use.moral, - isUsed: (rollData, actor) => rollData.use.moral, + isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.use?.moral, + isUsed: (rollData, actor) => rollData.use?.moral, getLabel: (rollData, actor) => 'Appel au moral', getValue: (rollData, actor) => 1 }, diff --git a/module/settings/system-compendiums.js b/module/settings/system-compendiums.js index 43e3af97..31ebb69d 100644 --- a/module/settings/system-compendiums.js +++ b/module/settings/system-compendiums.js @@ -1,4 +1,7 @@ -import { SYSTEM_RDD } from "../constants.js"; +import { HIDE_DICE, SYSTEM_RDD } from "../constants.js"; +import { RdDItem } from "../item.js"; +import { Misc } from "../misc.js"; +import { RdDDice } from "../rdd-dice.js"; const COMPENDIUM_SETTING_PREFIX = 'compendium-'; @@ -63,6 +66,7 @@ export class SystemCompendiums extends FormApplication { case 'vehicule': return []; } } + /* -------------------------------------------- */ static async getWorldOrCompendiumItems(itemType, compendium) { let items = game.items.filter(it => it.type == itemType); @@ -80,7 +84,34 @@ export class SystemCompendiums extends FormApplication { static async getItems(compendium, itemType = undefined) { const items = await SystemCompendiums.getContent(compendium, 'Item'); - return itemType ? items.filter(it => it.type == itemType) : items; + return (itemType ? items.filter(it => it.type == itemType) : items); + } + + static async buildTable(compendium, itemFrequence, filter, type = 'Item', sorting = undefined) { + let elements = await SystemCompendiums.getContent(compendium, type); + elements = elements.filter(filter).filter(it => itemFrequence(it) > 0) + if (sorting) { + elements = elements.sort(sorting); + } + let max = 0; + const table = elements + .map(it => { + const frequence = itemFrequence(it) + let row = { document: it, frequence: frequence, min: max + 1, max: max + frequence } + max += frequence; + return row; + }); + table.forEach(it => it.total = max); + return table; + } + + static async getRandom(compendium, type, subType, toChat = true, itemFrequence = it => it.system.frequence, filter = it => true) { + const table = new SystemCompendiumTable(compendium, type, subType); + return await table.getRandom(toChat, itemFrequence, filter); + } + static async chatTableItems(compendium, type, subType, itemFrequence = it => it.system.frequence, filter = it => true) { + const table = new SystemCompendiumTable(compendium, type, subType, itemFrequence); + await table.chatTable(itemFrequence, filter); } static async getDefaultItems(compendium) { @@ -125,11 +156,13 @@ export class SystemCompendiums extends FormApplication { getData() { const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS) .map(it => mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) })); - const availableCompendiums = game.packs.map(pack => { return { - name: pack.collection, - path: pack.collection.replace('.', " / "), - type: pack.metadata.type - } }); + const availableCompendiums = game.packs.map(pack => { + return { + name: pack.collection, + path: pack.collection.replace('.', " / "), + type: pack.metadata.type + } + }); return mergeObject(super.getData(), { systemCompendiums: systemCompendiums, availableCompendiums: availableCompendiums @@ -145,5 +178,102 @@ export class SystemCompendiums extends FormApplication { game.settings.set(SYSTEM_RDD, systemCompendium.setting, value); }); } +} -} \ No newline at end of file +export class SystemCompendiumTable { + + constructor(compendium, type, subType, sorting = undefined) { + this.compendium = compendium; + this.type = type; + this.subType = subType; + this.compendium = compendium; + this.sourceCompendium = SystemCompendiums.getCompendium(compendium); + this.sorting = sorting + } + + typeName() { + return game.i18n.localize(`${this.type.toUpperCase()}.Type${Misc.upperFirst(this.subType)}`); + } + applyType(filter) { + return it => it.type == this.subType && filter(it); + } + + async getRandom(toChat = true, itemFrequence = it => it.system.frequence, filter = it => true, forcedRoll = undefined) { + const table = await this.$buildTable(itemFrequence, filter); + if (table.length == 0) { + ui.notifications.warn(`Aucun ${this.typeName()} dans ${this.sourceCompendium}`); + return undefined; + } + const row = await this.$selectRow(table, forcedRoll); + if (row && toChat) { + await this.$chatRolledResult(row); + } + return row; + } + + async chatTable(itemFrequence = it => it.system.frequence, filter = it => true, typeName = undefined) { + const table = await this.$buildTable(itemFrequence, filter); + await this.$chatSystemCompendiumTable(table, typeName); + } + + async $buildTable(itemFrequence, filter) { + return await SystemCompendiums.buildTable(this.compendium, itemFrequence, this.applyType(filter), this.type, this.sorting); + } + + /* -------------------------------------------- */ + async $selectRow(table, forcedRoll = undefined) { + if (table.length == 0) { + return undefined + } + const total = table[0].total; + const formula = `1d${total}`; + if (forcedRoll == undefined && (forcedRoll > total || forcedRoll <= 0)) { + ui.notifications.warn(`Jet de rencontre ${forcedRoll} en dehors de la table [1..${total}], le jet est relancé`); + forcedRoll = undefined; + } + const roll = forcedRoll ? { total: forcedRoll, formula } : await RdDDice.roll(formula, { showDice: HIDE_DICE }); + const row = table.find(it => it.min <= roll.total && roll.total <= it.max); + row.roll = roll; + return row; + } + + /* -------------------------------------------- */ + async $chatRolledResult(row) { + const percentages = (row.total == 100) ? '%' : '' + const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll.html', { + roll: row.roll, + document: row?.document, + percentages, + typeName: this.typeName(), + sourceCompendium: this.sourceCompendium, + isGM: game.user.isGM, + }); + const messageData = { + // flavor: flavorContent, + user: game.user.id, + type: CONST.CHAT_MESSAGE_TYPES.ROLL, + roll: row.roll, + sound: CONFIG.sounds.dice, + content: flavorContent + }; + ChatMessage.create(messageData, { rollMode: "gmroll" }); + } + + /* -------------------------------------------- */ + async $chatSystemCompendiumTable(table, typeName) { + const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table.html', { + img: RdDItem.getDefaultImg(this.subType), + typeName: typeName ?? this.typeName(), + sourceCompendium: this.sourceCompendium, + table, + isGM: game.user.isGM, + }); + ChatMessage.create({ + user: game.user.id, + whisper: game.user.id, + content: flavorContent + }, { rollMode: "gmroll" }); + } + + +} diff --git a/module/tmr-rencontres.js b/module/tmr-rencontres.js index 5c2f069f..8defba46 100644 --- a/module/tmr-rencontres.js +++ b/module/tmr-rencontres.js @@ -1,88 +1,73 @@ import { Grammar } from "./grammar.js"; import { Misc } from "./misc.js"; import { RdDDice } from "./rdd-dice.js"; -import { SystemCompendiums } from "./settings/system-compendiums.js"; +import { SystemCompendiums, SystemCompendiumTable } from "./settings/system-compendiums.js"; import { TMRUtility } from "./tmr-utility.js"; /* -------------------------------------------- */ export class TMRRencontres { + static init() { + const tmrRencontre = new TMRRencontres(); + game.system.rencontresTMR = tmrRencontre; + + } + + constructor(){ + this.table = new SystemCompendiumTable('rencontres', 'Item', 'rencontre', Misc.ascending(it => it.system.ordreTri)); + } + /* -------------------------------------------- */ /** * Retourne une recontre en fonction de la case et du tirage * @param {*} terrain * @param {*} forcedRoll */ - static async rollRencontre(terrain, forcedRoll) { + async rollRencontre(terrain, forcedRoll) { terrain = TMRUtility.findTMRLike(terrain); if (terrain == undefined) { return undefined; } - + if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) { forcedRoll = undefined; } const codeTerrain = Grammar.toLowerCaseNoAccent(terrain) - const table = await TMRRencontres.$buildTableRencontre(codeTerrain); - const [selected, roll] = await TMRRencontres.$selectRencontre(codeTerrain, table, forcedRoll); - const rencontre = await TMRRencontres.createRencontre(selected.rencontre); - TMRRencontres.$chatRolledRencontre(rencontre, terrain, table, roll, true); - return false; - } - - /* -------------------------------------------- */ - static async $buildTableRencontre(codeTerrain) { - let max = 0; - const items = await SystemCompendiums.getItems('rencontres', 'rencontre'); const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre; - const rencontres = items.filter(it => it.type == 'rencontre') - .filter(filtreMauvaise) - .filter(it => it.system.frequence[codeTerrain] > 0) - .sort(Misc.ascending(it => it.system.ordreTri)) - .map(it => { - const frequence = it.system.frequence[codeTerrain]; - max += frequence; - return { rencontre: it, min: max - frequence + 1, max: max,frequence: frequence }; - }); - return rencontres; + const frequence = it => it.system.frequence[codeTerrain]; + const random = await this.table.getRandom(true, frequence, filtreMauvaise, forcedRoll); + + return random?.document; } - - /* -------------------------------------------- */ - static async $selectRencontre(terrain, table, roll = undefined) { - const total = table.map(it => it.frequence).reduce(Misc.sum(), 0); - if (total == 0){ - ui.notifications.warn(`Pas de rencontres définies pour ${terrain}`); - return undefined; - } - if (roll != undefined && (roll > total || roll <= 0)) { - ui.notifications.warn(`Jet de rencontre ${roll} en dehors de la table [1..${total}], le jet est relancé`); - roll = undefined; - } - if (!roll) { - roll = await RdDDice.rollTotal(`1d${total}`); - } - return [table.find(it => it.min <= roll && roll <= it.max), roll]; + + async chatTable(terrain) { + const codeTerrain = Grammar.toLowerCaseNoAccent(terrain) + const isMauvaise = codeTerrain == 'mauvaise'; + const filtreMauvaise = isMauvaise ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre; + const frequence = it => it.system.frequence[codeTerrain]; + const typeName = isMauvaise ? 'Mauvaises rencontres' : `Rencontres en ${Misc.upperFirst(terrain)}`; + await this.table.chatTable(frequence, filtreMauvaise, typeName); + return true } - /* -------------------------------------------- */ - static async createRencontre(rencontre, tmr = undefined) { + async createRencontre(rencontre, tmr = undefined) { return rencontre.clone({ 'system.force': await RdDDice.rollTotal(rencontre.system.formule), 'system.coord': tmr?.coord, 'system.date': game.system.rdd.calendrier.getDateFromIndex(), 'system.heure': game.system.rdd.calendrier.getCurrentHeure() - }, {save: false}); + }, { save: false }); } - static async calculRencontre(rencontre, tmr = undefined) { - if (rencontre.system.coord == ""){ + async calculRencontre(rencontre, tmr = undefined) { + if (rencontre.system.coord == "") { rencontre.system.coord = tmr?.coord; } - if (rencontre.system.force == 0){ + if (rencontre.system.force == 0) { rencontre.system.force = await RdDDice.rollTotal(rencontre.system.formule); } - if (rencontre.system.date == "" ) { + if (rencontre.system.date == "") { rencontre.system.date = game.system.rdd.calendrier.getDateFromIndex(); } if (rencontre.system.heure == "") { @@ -91,46 +76,51 @@ export class TMRRencontres { return rencontre; } - /* -------------------------------------------- */ - static $chatRolledRencontre(rencontre, terrain, table, roll = 0, displayTable=false){ - const total = table.map(it => it.frequence).reduce(Misc.sum(), 0); - const namesPercent = displayTable ? - table.map(it => `
${it.rencontre.name} : ${it.frequence}${total == 100 ? '%' : ''} (${it.min} - ${it.max})`).reduce((a, b) => a + b, '
') - : ''; - const chances = game.user.isGM - ? (roll ? `Jet: ${roll} / ${total}` : `Valeurs: [1..${total}]`) - : (roll ? `Jet: ${Math.ceil(roll*100/total)} / 100` : ''); - ChatMessage.create({ - user: game.user.id, - whisper: [game.user.id], - content: `Compendium: ${SystemCompendiums.getCompendium('rencontres')} -
Rencontre en ${terrain}: - ${namesPercent}
-
${chances} -
Rencontre: ${rencontre.name} ${rencontre.system.force} (${rencontre.system.formule})` - }); - } - static async getPresentsCite() { + async getPresentsCite() { const rencontres = await SystemCompendiums.getDefaultItems('rencontres'); - return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it => - it.clone({ 'system.formule': "2d6" }, {save: false})); + return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it => + it.clone({ 'system.formule': "2d6" }, { save: false })); } - static async getReveDeDragon(force) { + async getReveDeDragon(force) { const rencontres = await SystemCompendiums.getDefaultItems('rencontres'); const reveDeDragon = rencontres.find(it => Grammar.equalsInsensitive(it.name, 'Rêve de Dragon')); - return reveDeDragon?.clone({ 'system.force': force }, {save: false}); + return reveDeDragon?.clone({ 'system.force': force }, { save: false }); } /* -------------------------------------------- */ - static async getRencontreAleatoire(tmr, mauvaise) { + async getRencontreAleatoire(tmr, mauvaise) { const codeTerrain = mauvaise ? 'mauvaise' : tmr.type; - const table = await TMRRencontres.$buildTableRencontre(codeTerrain); - const [selected, roll] = await TMRRencontres.$selectRencontre(codeTerrain, table); - const rencontre = await TMRRencontres.createRencontre(selected.rencontre, tmr); - TMRRencontres.$chatRolledRencontre(rencontre, TMRUtility.getTMRType(tmr.coord), table, roll); - return rencontre; + const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre; + const frequence = it => it.system.frequence[codeTerrain]; + + const row = await this.table.getRandom(false, frequence, filtreMauvaise); + if (row) { + row.document = this.createRencontre(row.document, tmr); + await this.$chatRolledRencontre(row, tmr); + } + return row?.document; } + + /* -------------------------------------------- */ + async $chatRolledRencontre(row, tmr) { + const flavorContent = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/chat-compendium-table-roll-rencontre.html', + { + roll: row.roll, + rencontre: row?.document, + percentages: (row.total == 100) ? '%' : '', + tmr, + isGM: game.user.isGM, + }); + const messageData = { + user: game.user.id, + type: CONST.CHAT_MESSAGE_TYPES.ROLL, + roll: row.roll, + sound: CONFIG.sounds.dice, + content: flavorContent + }; + ChatMessage.create(messageData, { rollMode: "gmroll" }); + } } diff --git a/module/tmr/present-cites.js b/module/tmr/present-cites.js index 4cb83afa..2ad65244 100644 --- a/module/tmr/present-cites.js +++ b/module/tmr/present-cites.js @@ -3,7 +3,6 @@ import { Grammar } from "../grammar.js"; import { TMRUtility } from "../tmr-utility.js"; import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js"; import { Draconique } from "./draconique.js"; -import { TMRRencontres } from "../tmr-rencontres.js"; export class PresentCites extends Draconique { @@ -47,7 +46,7 @@ export class PresentCites extends Draconique { } async choisirUnPresent(casetmr, onChoixPresent) { - const presents = await TMRRencontres.getPresentsCite() + const presents = await game.system.rencontresTMR.getPresentsCite() const buttons = {}; presents.forEach(r => buttons['present'+r.id] = { icon: '', label: r.name, callback: async () => onChoixPresent(r) }); let d = new Dialog({ diff --git a/packs/ombres-de-thanatos.db b/packs/ombres-de-thanatos.db index 3f152c03..1d991723 100644 --- a/packs/ombres-de-thanatos.db +++ b/packs/ombres-de-thanatos.db @@ -1,25 +1,25 @@ -{"_id":"2KM1yiEOE0ZdT2oL","name":"Désir d'escalade difficile","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Hauteur à grimper : 4d6 m, difficulté de l’escalade : 1d4-4.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245686781,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"2KbzOC2aj98CiQbW","name":"Désir de blesser un enfant","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Causer au minimum une blessure légère.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245669381,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"3dnmi4Fyh5eUQcyP","name":"Urgence draconique","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Le haut-rêvant est pris du besoin irrésistible de déclencher immédiatement son plus proche sort en réserve. À équidistance, prendre dans le sens des aiguilles d’une montre en commençant par le haut. En cas de rencontre dans les TMR, se dérober équivaut à refouler la queue de Dragon. Si aucun sort n’est en réserve, ou si il y a impossibilité de pratiquer la magie à cause d’une autre queue ou d’un souffle, tirer à la place une idée fixe.

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245423625,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"6MUcjYfxfi45STvo","name":"Insomnie","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Impossibilité totale de dormir, et donc de rêver, pendant un jour.

","descriptionmj":"","frequence":12,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245903215,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"DnhuuGUEbOF95JlN","name":"Désir de boire du sang chaud","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Il s’agit de sang encore chaud de la chaleur naturelle de la victime.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245767229,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"N9j8K6x89BdS7ZKN","name":"Conquête","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Avant de pouvoir à nouveau faire usage du haut-rêve, y compris déclencher volontairement un sort mis en réserve, le haut-rêvant doit se rendre dans une certaine case des TMR déterminée aléatoirement et la maîtriser, difficulté -7. Ce peut être n’importe quelle case, sauf une case humide. En cas d’échec, la concentration est rompue ; il n’y a pas de souffle de Dragon en cas d’échec total.

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245838677,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"PMz7SaB6sRxhwrWw","name":"Coup de barre","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Prise immédiate de 3d6 points de fatigue.

","descriptionmj":"","frequence":12,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245807121,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"PmEjVox3Q6SPF730","name":"Inertie draconique","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Pendant un jour, la fatigue en TMR est doublée. Chaque case ou round coûte 2 points au lieu d’un.

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245891846,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"RrPMV2HW2Rg8POK1","name":"Souvenir morbide de l'archétype","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Les prochains points d’expérience dus au stress doivent être mis en Thanatos.

","descriptionmj":"","frequence":20,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245945292,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"S7se7qPnL6WDg5U5","name":"Mauvaise rencontre en perspective","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Tirer la prochaine rencontre dans les TMR sur la @Compendium[foundryvtt-reve-de-dragon.tables-diverses.66ye0OOxBO9LEjdd]{Table spéciale de rencontres}

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669246265627,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"UmvGxA4cFSoRE82Z","name":"Dépouillement","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Faire don de toute la monnaie actuellement possédée à la première personne inconnue rencontrée. En attendant, se garder d’aucune dépense.

","descriptionmj":"","frequence":12,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245718726,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"aZWuRmi8lplZQcdM","name":"Amnésie sélective","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Pendant un jour, perte totale d’une compétence, à l’exclusion du Draconic. Déterminer aléatoirement la compétence visée qui, pratiquement, retourne au niveau de base. Si elle est déjà au niveau de base, en choisir une autre.

","descriptionmj":"","frequence":12,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245862349,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"cUkRSRz5DJYb3WM8","name":"Couardise irraisonnée","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

la prochaine occasion de combat, obligation de fuir, de se cacher ou de se rendre. Impossibilité d’utiliser aucune magie, ni sur l’ennemi, ni sur soi-même.

","descriptionmj":"","frequence":12,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245818435,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"dFf8jaC0RvidC1ZC","name":"Haine fatale","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

On devient immédiatement haineux et jaloux envers la première personne inconnue de même sexe et de même espèce rencontrée. Traiter comme le Coup de foudre fatal. La satisfaction s’obtient en blessant gravement ou en infligeant une cuisante humiliation publique.

","descriptionmj":"","frequence":40,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245610242,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"e67rXcuO236ioYAr","name":"Infarctus","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Perte immédiate de 4 points de vie (et 8 points d’endurance). Ces points pourront commencer à être regagnés au bout d’un jour complet.

","descriptionmj":"","frequence":20,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245539318,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"fO1jjVlOb6faLv3T","name":"Désir de dormir dans un cercueil","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245761559,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"fUKNZ0uEG2y2PkOk","name":"Injurier la première personne inconnue rencontrée","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir d'injurier la première personne inconnue rencontrée

","descriptionmj":"","frequence":12,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245531134,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"gT0PQAxlYrtITyut","name":"Désir de blesser une femme","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Causer au minimum une blessure légère.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245656931,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"lz3ghhJzkPRWJ2jz","name":"Désir de parler à un crâne (humain)","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. La \"conversation\" doit durer un minimum de 15 minutes.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245746673,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"spYuiInqbCoDsKvd","name":"Héroïsme forcené","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

À la prochaine occasion de combat, obligation de foncer en tête en corps à corps ou avec une arme de mêlée. Impossibilité d’utiliser aucune magie, ni sur l’ennemi, ni sur soi-même.

","descriptionmj":"","frequence":36,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245588346,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"twUoR8ALYiabkfoE","name":"Désir d'entendre hurler de terreur","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Il doit s’agir d’un hurlement humain.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245698110,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"uQ4PwcwplvZarfn1","name":"Montée laborieuse","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Pendant un jour, monter en TMR coûte 2 points de rêve au lieu d’un, et 3 points en déplacement accéléré.

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245960190,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"wqWkQQsAPVlFw4ft","name":"Désir d'assister à une pendaison","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire.

","descriptionmj":"","frequence":16,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245712946,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"yEHdCabJYx0qvoL5","name":"Réinsertion aléatoire","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Comme après une sortie de la carte, le gardien des rêves réintroduit secrètement le demi-rêve du haut-rêvant dans les TMR.

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245952797,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} -{"_id":"zIXgRwfB83DMaNX8","name":"Pèlerinage","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Avant de pouvoir à nouveau faire usage du haut-rêve, y compris déclencher volontairement un sort mis en réserve, le haut-rêvant doit se rendre dans une certaine case des TMR déterminée aléatoirement. Un Passeur peut l’y téléporter, mais un Messager ne peut s’y rendre à sa place. Dès que la case est atteinte, le pèlerinage est accompli.

","descriptionmj":"","frequence":12,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.9","coreVersion":"10.290","createdTime":null,"modifiedTime":1669245955917,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"2KM1yiEOE0ZdT2oL","name":"Désir d'escalade difficile","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Hauteur à grimper : 4d6 m, difficulté de l’escalade : 1d4-4.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427837818,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"2KbzOC2aj98CiQbW","name":"Désir de blesser un enfant","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Causer au minimum une blessure légère.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427834434,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"3dnmi4Fyh5eUQcyP","name":"Urgence draconique","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Le haut-rêvant est pris du besoin irrésistible de déclencher immédiatement son plus proche sort en réserve. À équidistance, prendre dans le sens des aiguilles d’une montre en commençant par le haut. En cas de rencontre dans les TMR, se dérober équivaut à refouler la queue de Dragon. Si aucun sort n’est en réserve, ou si il y a impossibilité de pratiquer la magie à cause d’une autre queue ou d’un souffle, tirer à la place une idée fixe.

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427785086,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"6MUcjYfxfi45STvo","name":"Insomnie","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Impossibilité totale de dormir, et donc de rêver, pendant un jour.

","descriptionmj":"","frequence":3,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427803087,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"DnhuuGUEbOF95JlN","name":"Désir de boire du sang chaud","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Il s’agit de sang encore chaud de la chaleur naturelle de la victime.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427827866,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"N9j8K6x89BdS7ZKN","name":"Conquête","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Avant de pouvoir à nouveau faire usage du haut-rêve, y compris déclencher volontairement un sort mis en réserve, le haut-rêvant doit se rendre dans une certaine case des TMR déterminée aléatoirement et la maîtriser, difficulté -7. Ce peut être n’importe quelle case, sauf une case humide. En cas d’échec, la concentration est rompue ; il n’y a pas de souffle de Dragon en cas d’échec total.

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427859261,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"PMz7SaB6sRxhwrWw","name":"Coup de barre","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Prise immédiate de 3d6 points de fatigue.

","descriptionmj":"","frequence":3,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427852060,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"PmEjVox3Q6SPF730","name":"Inertie draconique","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Pendant un jour, la fatigue en TMR est doublée. Chaque case ou round coûte 2 points au lieu d’un.

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427811264,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"RrPMV2HW2Rg8POK1","name":"Souvenir morbide de l'archétype","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Les prochains points d’expérience dus au stress doivent être mis en Thanatos.

","descriptionmj":"","frequence":5,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427788837,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"S7se7qPnL6WDg5U5","name":"Mauvaise rencontre en perspective","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Tirer la prochaine rencontre dans les TMR sur la @Compendium[foundryvtt-reve-de-dragon.tables-diverses.66ye0OOxBO9LEjdd]{Table spéciale de rencontres}

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427799694,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"UmvGxA4cFSoRE82Z","name":"Dépouillement","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Faire don de toute la monnaie actuellement possédée à la première personne inconnue rencontrée. En attendant, se garder d’aucune dépense.

","descriptionmj":"","frequence":3,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427848516,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"aZWuRmi8lplZQcdM","name":"Amnésie sélective","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Pendant un jour, perte totale d’une compétence, à l’exclusion du Draconic. Déterminer aléatoirement la compétence visée qui, pratiquement, retourne au niveau de base. Si elle est déjà au niveau de base, en choisir une autre.

","descriptionmj":"","frequence":3,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427861397,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"cUkRSRz5DJYb3WM8","name":"Couardise irraisonnée","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

la prochaine occasion de combat, obligation de fuir, de se cacher ou de se rendre. Impossibilité d’utiliser aucune magie, ni sur l’ennemi, ni sur soi-même.

","descriptionmj":"","frequence":3,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427854380,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"dFf8jaC0RvidC1ZC","name":"Haine fatale","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

On devient immédiatement haineux et jaloux envers la première personne inconnue de même sexe et de même espèce rencontrée. Traiter comme le Coup de foudre fatal. La satisfaction s’obtient en blessant gravement ou en infligeant une cuisante humiliation publique.

","descriptionmj":"","frequence":10,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427820353,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"e67rXcuO236ioYAr","name":"Infarctus","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Perte immédiate de 4 points de vie (et 8 points d’endurance). Ces points pourront commencer à être regagnés au bout d’un jour complet.

","descriptionmj":"","frequence":5,"hautrevant":false,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427808560,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"fO1jjVlOb6faLv3T","name":"Désir de dormir dans un cercueil","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427825802,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"fUKNZ0uEG2y2PkOk","name":"Injurier le premier inconnu rencontré","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir d'injurier la première personne inconnue rencontrée

","descriptionmj":"","frequence":3,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427911390,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"gT0PQAxlYrtITyut","name":"Désir de blesser une femme","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Causer au minimum une blessure légère.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427830337,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"lz3ghhJzkPRWJ2jz","name":"Désir de parler à un crâne (humain)","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. La \"conversation\" doit durer un minimum de 15 minutes.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427823529,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"spYuiInqbCoDsKvd","name":"Héroïsme forcené","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

À la prochaine occasion de combat, obligation de foncer en tête en corps à corps ou avec une arme de mêlée. Impossibilité d’utiliser aucune magie, ni sur l’ennemi, ni sur soi-même.

","descriptionmj":"","frequence":9,"hautrevant":false,"refoulement":4,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427816736,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"twUoR8ALYiabkfoE","name":"Désir d'entendre hurler de terreur","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire. Il doit s’agir d’un hurlement humain.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427840771,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"uQ4PwcwplvZarfn1","name":"Montée laborieuse","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Pendant un jour, monter en TMR coûte 2 points de rêve au lieu d’un, et 3 points en déplacement accéléré.

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427796790,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"wqWkQQsAPVlFw4ft","name":"Désir d'assister à une pendaison","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Désir thanataire.

","descriptionmj":"","frequence":4,"hautrevant":false,"refoulement":2,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427845355,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"yEHdCabJYx0qvoL5","name":"Réinsertion aléatoire","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Comme après une sortie de la carte, le gardien des rêves réintroduit secrètement le demi-rêve du haut-rêvant dans les TMR.

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"jOzRscDxoXZWpGS6":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427791990,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} +{"_id":"zIXgRwfB83DMaNX8","name":"Pèlerinage","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"

Avant de pouvoir à nouveau faire usage du haut-rêve, y compris déclencher volontairement un sort mis en réserve, le haut-rêvant doit se rendre dans une certaine case des TMR déterminée aléatoirement. Un Passeur peut l’y téléporter, mais un Messager ne peut s’y rendre à sa place. Dès que la case est atteinte, le pèlerinage est accompli.

","descriptionmj":"","frequence":3,"hautrevant":true,"refoulement":0,"duree":"","restant":0},"ownership":{"default":0,"Q2G6GTdrotKzYGUC":3},"folder":null,"sort":0,"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.2.8","coreVersion":"10.290","createdTime":null,"modifiedTime":1669427794038,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"}} diff --git a/templates/chat-compendium-table-roll-rencontre.html b/templates/chat-compendium-table-roll-rencontre.html new file mode 100644 index 00000000..bb951c88 --- /dev/null +++ b/templates/chat-compendium-table-roll-rencontre.html @@ -0,0 +1,14 @@ +{{rencontre.name}} +

{{#if mauvaise}}Mauvaise rencontre{{else}}Rencontre{{/if}} en {{typeTmr-name tmr.type}}

+
{{sourceCompendium}}
+
Jet: {{roll.formula}} : {{roll.total}}{{percentages}}
+
+
+

{{rencontre.name}} {{rencontre.system.force}} ({{rencontre.system.formule}})

+

{{linkCompendium sourceCompendium rencontre.id rencontre.name}}

+ {{#if rencontre.system.description}} +
+ {{{rencontre.system.description}}} +
+ {{/if}} +
\ No newline at end of file diff --git a/templates/chat-compendium-table-roll.html b/templates/chat-compendium-table-roll.html new file mode 100644 index 00000000..c131780d --- /dev/null +++ b/templates/chat-compendium-table-roll.html @@ -0,0 +1,13 @@ +

Tirage aléatoire: {{typeName}}

+
{{sourceCompendium}}
+
Jet {{roll.formula}} : {{roll.total}}{{percentages}}
+
+
+ {{document.name}} +

{{linkCompendium @root.sourceCompendium document.id document.name}}

+ {{#if document.system.description}} +
+ {{{document.system.description}}} +
+ {{/if}} +
\ No newline at end of file diff --git a/templates/chat-compendium-table.html b/templates/chat-compendium-table.html new file mode 100644 index 00000000..caef27d8 --- /dev/null +++ b/templates/chat-compendium-table.html @@ -0,0 +1,16 @@ +
+ {{typeName}} +

Table aléatoire: {{typeName}}

+
{{sourceCompendium}}
+
+
+
+ +