Tirer dans les compendiums selon les fréquences

This commit is contained in:
Vincent Vandemeulebrouck 2022-11-26 03:13:45 +01:00
parent 970be67537
commit 0dacbefd6b
15 changed files with 370 additions and 165 deletions

View File

@ -21,7 +21,6 @@ import { STATUSES, StatusEffects } from "./settings/status-effects.js";
import { RdDItemCompetenceCreature } from "./item-competencecreature.js"; import { RdDItemCompetenceCreature } from "./item-competencecreature.js";
import { RdDItemSigneDraconique } from "./item-signedraconique.js"; import { RdDItemSigneDraconique } from "./item-signedraconique.js";
import { ReglesOptionelles } from "./settings/regles-optionelles.js"; import { ReglesOptionelles } from "./settings/regles-optionelles.js";
import { TMRRencontres } from "./tmr-rencontres.js";
import { EffetsDraconiques } from "./tmr/effets-draconiques.js"; import { EffetsDraconiques } from "./tmr/effets-draconiques.js";
import { Draconique } from "./tmr/draconique.js"; import { Draconique } from "./tmr/draconique.js";
import { RdDCarac } from "./rdd-carac.js"; import { RdDCarac } from "./rdd-carac.js";
@ -771,7 +770,7 @@ export class RdDActor extends Actor {
actor: this, actor: this,
competence: duplicate(this.getDraconicOuPossession()), competence: duplicate(this.getDraconicOuPossession()),
canClose: false, canClose: false,
rencontre: await TMRRencontres.getReveDeDragon(force), rencontre: await game.system.rencontresTMR.getReveDeDragon(force),
tmr: true, tmr: true,
use: { libre: false, conditions: false }, use: { libre: false, conditions: false },
forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } } forceCarac: { 'reve-actuel': { label: "Rêve Actuel", value: this.getReveActuel() } }

View File

@ -59,17 +59,23 @@ export const defaultItemImg = {
possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp", possession: "systems/foundryvtt-reve-de-dragon/icons/entites/possession2.webp",
sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp", sortreserve: "systems/foundryvtt-reve-de-dragon/icons/competence_oniros.webp",
extraitpoetique: "systems/foundryvtt-reve-de-dragon/icons/competence_ecriture.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 { export class RdDItem extends Item {
static getDefaultImg(itemType) {
return defaultItemImg[itemType];
}
constructor(itemData, context) { constructor(itemData, context) {
if (!itemData.img) { if (!itemData.img) {
itemData.img = defaultItemImg[itemData.type]; itemData.img = RdDItem.getDefaultImg(itemData.type);
} }
super(itemData, context); super(itemData, context);
} }
static getTypesObjetsEquipement() { static getTypesObjetsEquipement() {
return typesObjetsEquipement return typesObjetsEquipement

View File

@ -3,7 +3,6 @@
import { DialogChronologie } from "./dialog-chronologie.js"; import { DialogChronologie } from "./dialog-chronologie.js";
import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js"; import { DialogCreateSigneDraconique } from "./dialog-create-signedraconique.js";
import { DialogStress } from "./dialog-stress.js"; import { DialogStress } from "./dialog-stress.js";
import { Grammar } from "./grammar.js";
import { RdDItemCompetence } from "./item-competence.js"; import { RdDItemCompetence } from "./item-competence.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDCarac } from "./rdd-carac.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 { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
import { RdDRollTables } from "./rdd-rolltables.js"; import { RdDRollTables } from "./rdd-rolltables.js";
import { RdDUtility } from "./rdd-utility.js"; import { RdDUtility } from "./rdd-utility.js";
import { TMRRencontres } from "./tmr-rencontres.js";
import { TMRUtility } from "./tmr-utility.js"; import { TMRUtility } from "./tmr-utility.js";
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/; const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
@ -27,15 +25,34 @@ export class RdDCommands {
const rddCommands = new 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: ["/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: ["/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: ["/liste", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('liste'), descr: "Affiche la liste des compétences" });
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", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('liste'), descr: "Affiche la table des Queues 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", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('liste'), descr: "Affiche la table des Ombres de Thanatos" });
rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(true), descr: "Tire une Tête de Dragon" }); 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", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(true), descr: " Tire un Souffle de Dragon" }); 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", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence(true), descr: "Tire une compétence au hasard" }); 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(true), descr: "Tire une carte du Tarot Draconique" }); 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
<br><strong>/table rencontre deso</strong> affiche la table des rencontres en Désolation
<br><strong>/table rencontre mauvaise</strong> 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: ["/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" }); 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 {
<br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR` }); <br><strong>/tmra</strong> détermine une case aléatoire dans toutes les TMR` });
rddCommands.registerCommand({ rddCommands.registerCommand({
path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params), 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
<br><strong>/tmrr forêt</strong> détermine une rencontre aléatoire en 'forêt' <br><strong>/tmrr forêt</strong> détermine une rencontre aléatoire en 'forêt'
<br><strong>/tmrr mauvaise</strong> détermine une mauvaise rencontre aléatoire <br><strong>/tmrr mauvaise</strong> détermine une mauvaise rencontre aléatoire
<br><strong>/tmrr for 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47` <br><strong>/tmrr for 47</strong> détermine la rencontre en 'forêt' pour un jet de dé de 47` });
});
rddCommands.registerCommand({ rddCommands.registerCommand({
path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params), path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params),
@ -208,10 +224,10 @@ export class RdDCommands {
this.help(msg, undefined); this.help(msg, undefined);
} }
async help(msg, table) { async help(msg, table) {
let list = [] let commands = []
this._buildSubTableHelp(list, table || this.commandsTable); 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( let d = new Dialog(
{ {
title: "Commandes disponibles dans le tchat", title: "Commandes disponibles dans le tchat",
@ -249,7 +265,7 @@ export class RdDCommands {
/* -------------------------------------------- */ /* -------------------------------------------- */
async getRencontreTMR(params) { async getRencontreTMR(params) {
if (params.length == 1 || params.length == 2) { 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; return false;
} }
@ -335,6 +351,17 @@ export class RdDCommands {
} }
return false; 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) { getCoutXpComp(msg, params) {

View File

@ -39,6 +39,7 @@ import { Migrations } from './migrations.js';
import { DialogChronologie } from "./dialog-chronologie.js"; import { DialogChronologie } from "./dialog-chronologie.js";
import { SystemCompendiums } from "./settings/system-compendiums.js"; import { SystemCompendiums } from "./settings/system-compendiums.js";
import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js"; import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js";
import { TMRRencontres } from "./tmr-rencontres.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
/* Foundry VTT Initialization */ /* Foundry VTT Initialization */
@ -223,6 +224,7 @@ Hooks.once("init", async function () {
TMRUtility.init(); TMRUtility.init();
RdDHotbar.initDropbar(); RdDHotbar.initDropbar();
RdDPossession.init(); RdDPossession.init();
TMRRencontres.init();
}); });
/* -------------------------------------------- */ /* -------------------------------------------- */

View File

@ -1,3 +1,4 @@
import { Grammar } from "./grammar.js";
import { SystemCompendiums } from "./settings/system-compendiums.js"; import { SystemCompendiums } from "./settings/system-compendiums.js";
export class RdDRollTables { export class RdDRollTables {
@ -5,10 +6,8 @@ export class RdDRollTables {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async genericGetTableResult(tableName, toChat) { static async genericGetTableResult(tableName, toChat) {
let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName)); let table = RdDRollTables.getWorldTable(tableName) ?? (await RdDRollTables.getSystemTable(tableName));
const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll"}); const draw = await table.draw({ displayChat: toChat, rollMode: "gmroll" });
//console.log("RdDRollTables", tableName, toChat, ":", draw);
return draw.results.length > 0 ? draw.results[0] : undefined; return draw.results.length > 0 ? draw.results[0] : undefined;
} }
static getWorldTable(tableName) { static getWorldTable(tableName) {
@ -28,7 +27,7 @@ export class RdDRollTables {
const pack = game.packs.get(drawResult.documentCollection) const pack = game.packs.get(drawResult.documentCollection)
return await pack.getDocument(drawResult.documentId) return await pack.getDocument(drawResult.documentId)
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async drawTextFromRollTable(tableName, toChat) { static async drawTextFromRollTable(tableName, toChat) {
const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat); const drawResult = await RdDRollTables.genericGetTableResult(tableName, toChat);
@ -37,58 +36,67 @@ export class RdDRollTables {
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getCompetence(toChat = false) { 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) { 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) { static async getQueue(toChat = false) {
let queue = await RdDRollTables.drawItemFromRollTable("Queues de dragon", toChat); return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', 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;
} }
static async getDesirLancinant(toChat = false) { 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) { 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) { 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) { 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) { 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) { 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( return await RdDRollTables.drawTextFromRollTable(
options.arme ? "Maladresse armé" : "Maladresses non armé", options.arme ? "Maladresse armé" : "Maladresses non armé",
options.toChat); options.toChat);
} }
} }

View File

@ -575,7 +575,7 @@ export class RdDTMRDialog extends Dialog {
async _jetDeRencontre(tmr) { async _jetDeRencontre(tmr) {
let rencontre = this.lookupRencontreExistente(tmr); let rencontre = this.lookupRencontreExistente(tmr);
if (rencontre) { if (rencontre) {
return TMRRencontres.calculRencontre(rencontre, tmr); return game.system.rencontresTMR.calculRencontre(rencontre, tmr);
} }
let locTMR = (this.isDemiReveCache() let locTMR = (this.isDemiReveCache()
? TMRUtility.getTMRType(tmr.coord) + " ??" ? TMRUtility.getTMRType(tmr.coord) + " ??"
@ -584,7 +584,7 @@ export class RdDTMRDialog extends Dialog {
let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE }); let myRoll = await RdDDice.rollTotal("1dt", { showDice: SHOW_DICE });
if (myRoll == 7) { if (myRoll == 7) {
this._tellToUser(myRoll + ": Rencontre en " + locTMR); 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 { } else {
this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR); this._tellToUser(myRoll + ": Pas de rencontre en " + locTMR);
} }

View File

@ -283,14 +283,14 @@ export class RdDUtility {
Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); }); Handlebars.registerHelper('buildContenu', (objet) => { return new Handlebars.SafeString(RdDUtility.buildContenu(objet, 1, true)); });
Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord)); Handlebars.registerHelper('caseTmr-label', coord => TMRUtility.getTMRLabel(coord));
Handlebars.registerHelper('caseTmr-type', coord => TMRUtility.getTMRType(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('effetRencontre-name', coord => TMRUtility.typeTmrName(coord));
Handlebars.registerHelper('signeHeure', (key, heure) => RdDCalendrier.getSigneAs(key, heure)); Handlebars.registerHelper('signeHeure', (key, heure) => RdDCalendrier.getSigneAs(key, heure));
Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1))); Handlebars.registerHelper('min', (...args) => Math.min(...args.slice(0, -1)));
Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option)); Handlebars.registerHelper('regle-optionnelle', (option) => ReglesOptionelles.isUsing(option));
Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name))); Handlebars.registerHelper('trier', list => list.sort((a, b) => a.name.localeCompare(b.name)));
Handlebars.registerHelper('filtreTriCompetences', competences => competences.filter(it => it.system.isVisible) 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.startsWith("Survie") && b.name.startsWith("Survie")) {
if (a.name.includes("Cité")) return -1; if (a.name.includes("Cité")) return -1;
if (b.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); return a.name.localeCompare(b.name);
}) })
); );
Handlebars.registerHelper('linkCompendium', (compendium, id, name) => `@Compendium[${compendium}.${id}]{${name}}`);
return loadTemplates(templatePaths); return loadTemplates(templatePaths);
} }

View File

@ -69,13 +69,13 @@ export const referenceAjustements = {
}, },
surenc: { surenc: {
isVisible: (rollData, actor) => actor.isSurenc(), isVisible: (rollData, actor) => actor.isSurenc(),
isUsed: (rollData, actor) => rollData.use.surenc, isUsed: (rollData, actor) => rollData.use?.surenc,
getLabel: (rollData, actor) => 'Sur-encombrement', getLabel: (rollData, actor) => 'Sur-encombrement',
getValue: (rollData, actor) => actor.computeMalusSurEncombrement() getValue: (rollData, actor) => actor.computeMalusSurEncombrement()
}, },
moral: { moral: {
isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.use.moral, isVisible: (rollData, actor) => actor.isPersonnage() && RdDCarac.isActionPhysique(rollData.selectedCarac) && rollData.use?.moral,
isUsed: (rollData, actor) => rollData.use.moral, isUsed: (rollData, actor) => rollData.use?.moral,
getLabel: (rollData, actor) => 'Appel au moral', getLabel: (rollData, actor) => 'Appel au moral',
getValue: (rollData, actor) => 1 getValue: (rollData, actor) => 1
}, },

View File

@ -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-'; const COMPENDIUM_SETTING_PREFIX = 'compendium-';
@ -63,6 +66,7 @@ export class SystemCompendiums extends FormApplication {
case 'vehicule': return []; case 'vehicule': return [];
} }
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async getWorldOrCompendiumItems(itemType, compendium) { static async getWorldOrCompendiumItems(itemType, compendium) {
let items = game.items.filter(it => it.type == itemType); let items = game.items.filter(it => it.type == itemType);
@ -80,7 +84,34 @@ export class SystemCompendiums extends FormApplication {
static async getItems(compendium, itemType = undefined) { static async getItems(compendium, itemType = undefined) {
const items = await SystemCompendiums.getContent(compendium, 'Item'); 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) { static async getDefaultItems(compendium) {
@ -125,11 +156,13 @@ export class SystemCompendiums extends FormApplication {
getData() { getData() {
const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS) const systemCompendiums = Object.values(CONFIGURABLE_COMPENDIUMS)
.map(it => mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) })); .map(it => mergeObject(it, { value: SystemCompendiums.getCompendium(it.compendium) }));
const availableCompendiums = game.packs.map(pack => { return { const availableCompendiums = game.packs.map(pack => {
name: pack.collection, return {
path: pack.collection.replace('.', " / "), name: pack.collection,
type: pack.metadata.type path: pack.collection.replace('.', " / "),
} }); type: pack.metadata.type
}
});
return mergeObject(super.getData(), { return mergeObject(super.getData(), {
systemCompendiums: systemCompendiums, systemCompendiums: systemCompendiums,
availableCompendiums: availableCompendiums availableCompendiums: availableCompendiums
@ -145,5 +178,102 @@ export class SystemCompendiums extends FormApplication {
game.settings.set(SYSTEM_RDD, systemCompendium.setting, value); game.settings.set(SYSTEM_RDD, systemCompendium.setting, value);
}); });
} }
}
} 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" });
}
}

View File

@ -1,88 +1,73 @@
import { Grammar } from "./grammar.js"; import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js"; import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.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"; import { TMRUtility } from "./tmr-utility.js";
/* -------------------------------------------- */ /* -------------------------------------------- */
export class TMRRencontres { 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 * Retourne une recontre en fonction de la case et du tirage
* @param {*} terrain * @param {*} terrain
* @param {*} forcedRoll * @param {*} forcedRoll
*/ */
static async rollRencontre(terrain, forcedRoll) { async rollRencontre(terrain, forcedRoll) {
terrain = TMRUtility.findTMRLike(terrain); terrain = TMRUtility.findTMRLike(terrain);
if (terrain == undefined) { if (terrain == undefined) {
return undefined; return undefined;
} }
if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) { if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) {
forcedRoll = undefined; forcedRoll = undefined;
} }
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain) 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 filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
const rencontres = items.filter(it => it.type == 'rencontre') const frequence = it => it.system.frequence[codeTerrain];
.filter(filtreMauvaise) const random = await this.table.getRandom(true, frequence, filtreMauvaise, forcedRoll);
.filter(it => it.system.frequence[codeTerrain] > 0)
.sort(Misc.ascending(it => it.system.ordreTri)) return random?.document;
.map(it => {
const frequence = it.system.frequence[codeTerrain];
max += frequence;
return { rencontre: it, min: max - frequence + 1, max: max,frequence: frequence };
});
return rencontres;
} }
/* -------------------------------------------- */ async chatTable(terrain) {
static async $selectRencontre(terrain, table, roll = undefined) { const codeTerrain = Grammar.toLowerCaseNoAccent(terrain)
const total = table.map(it => it.frequence).reduce(Misc.sum(), 0); const isMauvaise = codeTerrain == 'mauvaise';
if (total == 0){ const filtreMauvaise = isMauvaise ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
ui.notifications.warn(`Pas de rencontres définies pour ${terrain}`); const frequence = it => it.system.frequence[codeTerrain];
return undefined; const typeName = isMauvaise ? 'Mauvaises rencontres' : `Rencontres en ${Misc.upperFirst(terrain)}`;
} await this.table.chatTable(frequence, filtreMauvaise, typeName);
if (roll != undefined && (roll > total || roll <= 0)) { return true
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];
} }
/* -------------------------------------------- */ /* -------------------------------------------- */
static async createRencontre(rencontre, tmr = undefined) { async createRencontre(rencontre, tmr = undefined) {
return rencontre.clone({ return rencontre.clone({
'system.force': await RdDDice.rollTotal(rencontre.system.formule), 'system.force': await RdDDice.rollTotal(rencontre.system.formule),
'system.coord': tmr?.coord, 'system.coord': tmr?.coord,
'system.date': game.system.rdd.calendrier.getDateFromIndex(), 'system.date': game.system.rdd.calendrier.getDateFromIndex(),
'system.heure': game.system.rdd.calendrier.getCurrentHeure() 'system.heure': game.system.rdd.calendrier.getCurrentHeure()
}, {save: false}); }, { save: false });
} }
static async calculRencontre(rencontre, tmr = undefined) { async calculRencontre(rencontre, tmr = undefined) {
if (rencontre.system.coord == ""){ if (rencontre.system.coord == "") {
rencontre.system.coord = tmr?.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); 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(); rencontre.system.date = game.system.rdd.calendrier.getDateFromIndex();
} }
if (rencontre.system.heure == "") { if (rencontre.system.heure == "") {
@ -91,46 +76,51 @@ export class TMRRencontres {
return rencontre; 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 => `<br>${it.rencontre.name} : ${it.frequence}${total == 100 ? '%' : ''} (${it.min} - ${it.max})`).reduce((a, b) => a + b, '<hr>')
: '';
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')}
<br>Rencontre en ${terrain}:
${namesPercent}<hr>
<br>${chances}
<br>Rencontre: ${rencontre.name} ${rencontre.system.force} (${rencontre.system.formule})`
});
}
static async getPresentsCite() { async getPresentsCite() {
const rencontres = await SystemCompendiums.getDefaultItems('rencontres'); const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it => return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it =>
it.clone({ 'system.formule': "2d6" }, {save: false})); it.clone({ 'system.formule': "2d6" }, { save: false }));
} }
static async getReveDeDragon(force) { async getReveDeDragon(force) {
const rencontres = await SystemCompendiums.getDefaultItems('rencontres'); const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
const reveDeDragon = rencontres.find(it => Grammar.equalsInsensitive(it.name, 'Rêve de Dragon')); 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 codeTerrain = mauvaise ? 'mauvaise' : tmr.type;
const table = await TMRRencontres.$buildTableRencontre(codeTerrain); const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
const [selected, roll] = await TMRRencontres.$selectRencontre(codeTerrain, table); const frequence = it => it.system.frequence[codeTerrain];
const rencontre = await TMRRencontres.createRencontre(selected.rencontre, tmr);
TMRRencontres.$chatRolledRencontre(rencontre, TMRUtility.getTMRType(tmr.coord), table, roll); const row = await this.table.getRandom(false, frequence, filtreMauvaise);
return rencontre; 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" });
}
} }

View File

@ -3,7 +3,6 @@ import { Grammar } from "../grammar.js";
import { TMRUtility } from "../tmr-utility.js"; import { TMRUtility } from "../tmr-utility.js";
import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js"; import { tmrConstants, tmrTokenZIndex } from "../tmr-constants.js";
import { Draconique } from "./draconique.js"; import { Draconique } from "./draconique.js";
import { TMRRencontres } from "../tmr-rencontres.js";
export class PresentCites extends Draconique { export class PresentCites extends Draconique {
@ -47,7 +46,7 @@ export class PresentCites extends Draconique {
} }
async choisirUnPresent(casetmr, onChoixPresent) { async choisirUnPresent(casetmr, onChoixPresent) {
const presents = await TMRRencontres.getPresentsCite() const presents = await game.system.rencontresTMR.getPresentsCite()
const buttons = {}; const buttons = {};
presents.forEach(r => buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) }); presents.forEach(r => buttons['present'+r.id] = { icon: '<i class="fas fa-check"></i>', label: r.name, callback: async () => onChoixPresent(r) });
let d = new Dialog({ let d = new Dialog({

View File

@ -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":"<p>Désir thanataire. Hauteur à grimper : 4d6 m, difficulté de lescalade : 1d4-4.</p>","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":"2KM1yiEOE0ZdT2oL","name":"Désir d'escalade difficile","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Désir thanataire. Hauteur à grimper : 4d6 m, difficulté de lescalade : 1d4-4.</p>","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":"<p>Désir thanataire. Causer au minimum une blessure légère.</p>","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":"2KbzOC2aj98CiQbW","name":"Désir de blesser un enfant","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Désir thanataire. Causer au minimum une blessure légère.</p>","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":"<p>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 dune 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 nest en réserve, ou si il y a impossibilité de pratiquer la magie à cause dune autre queue ou dun souffle, tirer à la place une idée fixe.</p>","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":"3dnmi4Fyh5eUQcyP","name":"Urgence draconique","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>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 dune 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 nest en réserve, ou si il y a impossibilité de pratiquer la magie à cause dune autre queue ou dun souffle, tirer à la place une idée fixe.</p>","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":"<p>Impossibilité totale de dormir, et donc de rêver, pendant un jour.</p>","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":"6MUcjYfxfi45STvo","name":"Insomnie","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Impossibilité totale de dormir, et donc de rêver, pendant un jour.</p>","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":"<p>Désir thanataire. Il sagit de sang encore chaud de la chaleur naturelle de la victime.</p>","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":"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":"<p>Désir thanataire. Il sagit de sang encore chaud de la chaleur naturelle de la victime.</p>","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":"<p>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&nbsp;<em>maîtriser</em>, difficulté -7. Ce peut être nimporte quelle case, sauf une case humide. En cas déchec, la concentration est rompue ; il ny a pas de souffle de Dragon en cas déchec total.</p>","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":"N9j8K6x89BdS7ZKN","name":"Conquête","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>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&nbsp;<em>maîtriser</em>, difficulté -7. Ce peut être nimporte quelle case, sauf une case humide. En cas déchec, la concentration est rompue ; il ny a pas de souffle de Dragon en cas déchec total.</p>","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":"<p>Prise immédiate de 3d6 points de fatigue.</p>","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":"PMz7SaB6sRxhwrWw","name":"Coup de barre","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Prise immédiate de 3d6 points de fatigue.</p>","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":"<p>Pendant un jour, la fatigue en TMR est doublée. Chaque case ou round coûte 2 points au lieu dun.</p>","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":"PmEjVox3Q6SPF730","name":"Inertie draconique","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Pendant un jour, la fatigue en TMR est doublée. Chaque case ou round coûte 2 points au lieu dun.</p>","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":"<p>Les prochains points dexpérience dus au stress doivent être mis en Thanatos.</p>","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":"RrPMV2HW2Rg8POK1","name":"Souvenir morbide de l'archétype","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Les prochains points dexpérience dus au stress doivent être mis en Thanatos.</p>","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":"<p>Tirer la prochaine rencontre dans les TMR sur la @Compendium[foundryvtt-reve-de-dragon.tables-diverses.66ye0OOxBO9LEjdd]{Table sp&eacute;ciale de rencontres}</p>","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":"S7se7qPnL6WDg5U5","name":"Mauvaise rencontre en perspective","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Tirer la prochaine rencontre dans les TMR sur la @Compendium[foundryvtt-reve-de-dragon.tables-diverses.66ye0OOxBO9LEjdd]{Table sp&eacute;ciale de rencontres}</p>","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":"<p>Faire don de toute la monnaie actuellement possédée à la première personne inconnue rencontrée. En attendant, se garder daucune dépense.</p>","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":"UmvGxA4cFSoRE82Z","name":"Dépouillement","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Faire don de toute la monnaie actuellement possédée à la première personne inconnue rencontrée. En attendant, se garder daucune dépense.</p>","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":"<p>Pendant un jour, perte totale dune compétence, à lexclusion 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.</p>","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":"aZWuRmi8lplZQcdM","name":"Amnésie sélective","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Pendant un jour, perte totale dune compétence, à lexclusion 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.</p>","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":"<p>la prochaine occasion de combat, obligation de fuir, de se cacher ou de se rendre. Impossibilité dutiliser aucune magie, ni sur lennemi, ni sur soi-même.</p>","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":"cUkRSRz5DJYb3WM8","name":"Couardise irraisonnée","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>la prochaine occasion de combat, obligation de fuir, de se cacher ou de se rendre. Impossibilité dutiliser aucune magie, ni sur lennemi, ni sur soi-même.</p>","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":"<p>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 sobtient en blessant gravement ou en infligeant une cuisante humiliation publique.</p>","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":"dFf8jaC0RvidC1ZC","name":"Haine fatale","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>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 sobtient en blessant gravement ou en infligeant une cuisante humiliation publique.</p>","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":"<p>Perte immédiate de 4 points de vie (et 8 points dendurance). Ces points pourront commencer à être regagnés au bout dun jour complet.</p>","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":"e67rXcuO236ioYAr","name":"Infarctus","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Perte immédiate de 4 points de vie (et 8 points dendurance). Ces points pourront commencer à être regagnés au bout dun jour complet.</p>","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":"<p>Désir thanataire.</p>","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":"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":"<p>Désir thanataire.</p>","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 la première personne inconnue rencontrée","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Désir d'injurier la première personne inconnue rencontrée</p>","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":"fUKNZ0uEG2y2PkOk","name":"Injurier le premier inconnu rencontré","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Désir d'injurier la première personne inconnue rencontrée</p>","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":"<p>Désir thanataire. Causer au minimum une blessure légère.</p>","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":"gT0PQAxlYrtITyut","name":"Désir de blesser une femme","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Désir thanataire. Causer au minimum une blessure légère.</p>","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":"<p>Désir thanataire. La \"conversation\" doit durer un minimum de 15 minutes.</p>","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":"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":"<p>Désir thanataire. La \"conversation\" doit durer un minimum de 15 minutes.</p>","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":"<p>À la prochaine occasion de combat, obligation de foncer en tête en corps à corps ou avec une arme de mêlée. Impossibilité dutiliser aucune magie, ni sur lennemi, ni sur soi-même.</p>","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":"spYuiInqbCoDsKvd","name":"Héroïsme forcené","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>À la prochaine occasion de combat, obligation de foncer en tête en corps à corps ou avec une arme de mêlée. Impossibilité dutiliser aucune magie, ni sur lennemi, ni sur soi-même.</p>","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":"<p>Désir thanataire. Il doit sagir dun hurlement humain.</p>","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":"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":"<p>Désir thanataire. Il doit sagir dun hurlement humain.</p>","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":"<p>Pendant un jour, monter en TMR coûte 2 points de rêve au lieu dun, et 3 points en déplacement accéléré.</p>","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":"uQ4PwcwplvZarfn1","name":"Montée laborieuse","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Pendant un jour, monter en TMR coûte 2 points de rêve au lieu dun, et 3 points en déplacement accéléré.</p>","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":"<p>Désir thanataire.</p>","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":"wqWkQQsAPVlFw4ft","name":"Désir d'assister à une pendaison","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>Désir thanataire.</p>","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":"<p>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.</p>","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":"yEHdCabJYx0qvoL5","name":"Réinsertion aléatoire","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>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.</p>","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":"<p>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 ly téléporter, mais un Messager ne peut sy rendre à sa place. Dès que la case est atteinte, le pèlerinage est accompli.</p>","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":"zIXgRwfB83DMaNX8","name":"Pèlerinage","type":"ombre","flags":{},"img":"systems/foundryvtt-reve-de-dragon/icons/queue_dragon.webp","effects":[],"system":{"description":"<p>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 ly téléporter, mais un Messager ne peut sy rendre à sa place. Dès que la case est atteinte, le pèlerinage est accompli.</p>","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"}}

View File

@ -0,0 +1,14 @@
<img class="chat-icon" src="{{rencontre.img}}" alt="{{rencontre.name}}" />
<h4>{{#if mauvaise}}Mauvaise rencontre{{else}}Rencontre{{/if}} en {{typeTmr-name tmr.type}}</h4>
<div>{{sourceCompendium}}</div>
<div>Jet: {{roll.formula}} : {{roll.total}}{{percentages}}</div>
<hr>
<div>
<p>{{rencontre.name}} {{rencontre.system.force}} ({{rencontre.system.formule}})</p>
<p>{{linkCompendium sourceCompendium rencontre.id rencontre.name}}</p>
{{#if rencontre.system.description}}
<div class="poesie-extrait">
{{{rencontre.system.description}}}
</div>
{{/if}}
</div>

View File

@ -0,0 +1,13 @@
<h4>Tirage aléatoire: {{typeName}}</h4>
<div>{{sourceCompendium}}</div>
<div>Jet {{roll.formula}} : {{roll.total}}{{percentages}}</div>
<hr>
<div>
<img class="chat-icon" src="{{document.img}}" alt="{{document.name}}" />
<p>{{linkCompendium @root.sourceCompendium document.id document.name}}</p>
{{#if document.system.description}}
<div class="poesie-extrait">
{{{document.system.description}}}
</div>
{{/if}}
</div>

View File

@ -0,0 +1,16 @@
<div>
<img class="chat-icon" src="{{img}}" alt="{{typeName}}" />
<h4>Table aléatoire: {{typeName}}</h4>
<div>{{sourceCompendium}}</div>
<br>
</div>
<div>
<ul class="flexcol item-list alterne-list">
{{#each table as |row|}}
<li class="select-target item list-item" >
<span>{{row.min}}{{#unless (eq row.min row.max)}}-{{row.max}}{{/unless}} : &nbsp;</span>
<span>{{linkCompendium @root.sourceCompendium row.document.id row.document.name}}</span>
</li>
{{/each}}
</ul>
</div>