diff --git a/module/rdd-commands.js b/module/rdd-commands.js
new file mode 100644
index 00000000..409ae4ee
--- /dev/null
+++ b/module/rdd-commands.js
@@ -0,0 +1,185 @@
+/* -------------------------------------------- */
+
+import { ChatUtility } from "./chat-utility.js";
+import { Misc } from "./misc.js";
+import { RdDResolutionTable } from "./rdd-resolution-table.js";
+import { RdDRollResolution } from "./rdd-roll-resolution.js";
+import { RdDRollTables } from "./rdd-rolltables.js";
+import { RdDUtility } from "./rdd-utility.js";
+import { TMRUtility } from "./tmr-utility.js";
+
+const rddRollNumeric = /(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
+
+/* -------------------------------------------- */
+export class RdDCommands {
+
+ static init() {
+ if (!game.system.rdd.commands) {
+ const rddCommands = new RdDCommands();
+ rddCommands.registerCommand({ path: ["/aide"], descr: "Affiche l'aide pour toutes les commandes", func: (content, msg, params) => rddCommands.help(msg) });
+ rddCommands.registerCommand({ path: ["/help"], descr: "Affiche l'aide pour toutes les commandes", func: (content, msg, params) => rddCommands.help(msg) });
+ rddCommands.registerCommand({ path: ["/table", "queues"], descr: "Tire une Queue de Dragon", func: (content, msg, params) => RdDRollTables.getQueue() });
+ rddCommands.registerCommand({ path: ["/table", "ombre"], descr: "Tire une Ombre de Dragon", func: (content, msg, params) => RdDRollTables.getOmbre() });
+ rddCommands.registerCommand({ path: ["/table", "tetehr"], descr: "Tire une Tête de Dragon pour Hauts Revants", func: (content, msg, params) => RdDRollTables.getTeteHR() });
+ rddCommands.registerCommand({ path: ["/table", "tete"], descr: "Tire une Tête de Dragon", func: (content, msg, params) => RdDRollTables.getTete() });
+ rddCommands.registerCommand({ path: ["/table", "souffle"], descr: " Tire un Souffle de Dragon", func: (content, msg, params) => RdDRollTables.getSouffle() });
+ rddCommands.registerCommand({ path: ["/table", "tarot"], descr: "Tire une carte du Tarot Draconique", func: (content, msg, params) => RdDRollTables.getTarot() });
+ rddCommands.registerCommand({ path: ["/table", "tmr"], descr: "Tire une case aléatoire des Terre médiane", func: (content, msg, params) => TMRUtility.getTMRAleatoire() });
+
+ rddCommands.registerCommand({ path: ["/tmra"], descr: "Tire une case aléatoire des Terre médiane", func: (content, msg, params) => TMRUtility.getTMRAleatoire() });
+ rddCommands.registerCommand({ path: ["/tmrr"], descr: "Syntaxe: /tmrr case jet
Détermine quelle est la rencontre dans la case pour le jet
Example: /tmrr forêt 50", func: (content, msg, params) => rddCommands.getRencontreTMR(params) });
+ rddCommands.registerCommand({
+ path: ["/rdd"], descr: `Effectue un jet de dés dans la table de résolution. Examples:
+
/rdd ouvre la table de résolution
+
/rdd 10 3 effectue un jet 10 à +3
+
/rdd 10 +2 effectue un jet 10 à +2
+
/rdd 15 -2 effectue un jet 15 à -2
+
/rdd 15 0 s effectue un jet 15 à 0, avec significative requise
+ `, func: (content, msg, params) => rddCommands.rollRdd(msg, params)
+ });
+
+ rddCommands.registerCommand({ path: ["/payer"], descr: `Permet de payer un montant. Exemples:
+
/payer 5s 10d permet d'envoyer un message pour payer 5 sols et 10 deniers
+
/payer 10d permet d'envoyer un message pour payer 10 deniers
+ `, func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1])});
+ game.system.rdd.commands = rddCommands;
+ }
+ }
+
+ constructor() {
+ this.commandsTable = {};
+ }
+
+ registerCommand(command) {
+ this._addCommand(this.commandsTable, command.path, command);
+ }
+
+ _addCommand(targetTable, path, command) {
+ if (!this._validateCommand(targetTable, path, command)) {
+ return;
+ }
+ const term = path[0];
+ if (path.length == 1) {
+ targetTable[term] = command;
+ }
+ else {
+ if (!targetTable[term]) {
+ targetTable[term] = { subTable: {} };
+ }
+ this._addCommand(targetTable[term].subTable, path.slice(1), command)
+ }
+ }
+
+ _validateCommand(targetTable, path, command) {
+ if (path.length > 0 && path[0] && command.descr && (path.length != 1 || targetTable[path[0]] == undefined)) {
+ return true;
+ }
+ console.warn("RdDCommands._validateCommand failed ", targetTable, path, command);
+ return false;
+ }
+
+
+ /* -------------------------------------------- */
+ /* Manage chat commands */
+ processChatCommand(commandLine, content, msg) {
+ // Setup new message's visibility
+ let rollMode = game.settings.get("core", "rollMode");
+ if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
+ if (rollMode === "blindroll") msg["blind"] = true;
+ msg["type"] = 0;
+
+ let command = commandLine[0];
+ let params = commandLine.slice(1);
+
+ return this.process(command, params, content, msg);
+ }
+
+ process(command, params, content, msg) {
+ return this._processCommand(this.commandsTable, command, params, content, msg);
+ }
+
+ _processCommand(commandsTable, name, params, content = '', msg = {}, path = "") {
+ let command = commandsTable[name];
+ path = path + name + " ";
+ if (command && command.subTable) {
+ if (params[0]) {
+ return this._processCommand(command.subTable, params[0], params.slice(1), content, msg, path)
+ }
+ else {
+ this.help(msg, command.subTable);
+ return true;
+ }
+ }
+ if (command && command.func) {
+ if (command.func(content, msg, params) === false) {
+ this._displayHelp(msg, `${path}: ${command.descr}`);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /* -------------------------------------------- */
+ help(msg, table = undefined) {
+ let list = []
+ this._buildSubTableHelp(list, '', table || this.commandsTable);
+ msg.whisper = [game.user._id];
+ msg.content = 'Commandes disponibles
- ' + list.reduce((a, b) => a + '
- ' + b) + '
';
+ ChatMessage.create(msg);
+ }
+
+ /* -------------------------------------------- */
+ _buildSubTableHelp(list, path, table) {
+ for (let [name, command] of Object.entries(table)) {
+ if (command) {
+ if (command.subTable) {
+ this._buildSubTableHelp(list, path + name + " ", command.subTable);
+ } else {
+ list.push(`${path}${name}: ${command.descr}`);
+ }
+ }
+ }
+ return list;
+ }
+
+
+ getRencontreTMR(params) {
+ if (params.length == 2) {
+ return TMRUtility.getRencontre(params[0], params[1])
+ }
+ else {
+ return false;
+ }
+ }
+
+ async rollRdd(msg, params) {
+ if (params.length == 0) {
+ RdDRollResolution.open();
+ }
+ else {
+ let flatParams = params.reduce((a, b) => `${a} ${b}`);
+ const numericParams = flatParams.match(rddRollNumeric);
+ if (numericParams) {
+ const carac = Misc.toInt(numericParams[1]);
+ const diff = Misc.toInt(numericParams[2] || 0);
+ const significative = numericParams[3] == 's'
+ await this.rollRdDNumeric(msg, carac, diff, significative);
+ return;
+ }
+ }
+ }
+
+ async rollRdDNumeric(msg, carac, diff, significative = false) {
+ let rollData = {
+ caracValue: carac,
+ finalLevel: diff,
+ showDice: true,
+ needSignificative: significative,
+ show: { title: "Table de résolution", points: true }
+ };
+ await RdDResolutionTable.rollData(rollData);
+ msg.content = await RdDResolutionTable.explainRollDataV2(rollData);
+ ChatUtility.chatWithRollMode(msg, game.user.name);
+ }
+}
+
diff --git a/module/rdd-main.js b/module/rdd-main.js
index a6be6ccb..8ef650e9 100644
--- a/module/rdd-main.js
+++ b/module/rdd-main.js
@@ -19,6 +19,7 @@ import { TMRUtility } from "./tmr-utility.js";
import { RdDCalendrier } from "./rdd-calendrier.js";
import { RdDResolutionTable } from "./rdd-resolution-table.js";
import { RdDTokenHud } from "./rdd-token-hud.js";
+import { RdDCommands } from "./rdd-commands.js";
/* -------------------------------------------- */
/* Foundry VTT Initialization */
@@ -212,14 +213,15 @@ Hooks.once("init", async function() {
/* -------------------------------------------- */
function messageDeBienvenue(){
game.messages
- .filter(it => it.user._id == game.user._id && it.data.content.match(/^Bienvenu(e)? dans le Rêve des Dragons/))
+ .filter(it => it.user._id == game.user._id && it.data.content.match(/^ " +
- "Vous trouverez quelques informations pour démarrer dans ce document : @Compendium[foundryvtt-reve-de-dragon.rappel-des-regles.7uGrUHGdPu0EmIu2]{Documentation MJ/Joueurs}" }
- );
+ content : `
Bienvenue dans le Rêve des Dragons !
+
Vous trouverez quelques informations pour démarrer dans ce document : @Compendium[foundryvtt-reve-de-dragon.rappel-des-regles.7uGrUHGdPu0EmIu2]{Documentation MJ/Joueurs}
+
La commande /aide
dans le chat permet de voir les commandes spécifiques à Rêve de Dragon.
+ ` });
}
/* -------------------------------------------- */
@@ -232,6 +234,8 @@ Hooks.once("renderApplication", () => {
/* -------------------------------------------- */
Hooks.once("ready", function() {
+ // préparation des lignes de commandes
+ RdDCommands.init();
/* -------------------------------------------- */
/* Affiche/Init le calendrier */
let calendrier = new RdDCalendrier();
@@ -271,11 +275,15 @@ Hooks.on("preCreateToken", (scene, tokenData, options) => {
/* Foundry VTT Initialization */
/* -------------------------------------------- */
Hooks.on("chatMessage", (html, content, msg) => {
- let regExp = /(\S+)/g;
- let commands = content.match(regExp);
-
- return RdDUtility.processChatCommand( commands, content, msg );
-} );
+ if (content[0] == '/') {
+ let regExp = /(\S+)/g;
+ let commands = content.toLowerCase().match(regExp);
+ if (game.system.rdd.commands.processChatCommand(commands, content, msg)){
+ return false;
+ }
+ }
+ return true;
+});
/* -------------------------------------------- */
Hooks.on("getCombatTrackerEntryContext", (html, options) => {
diff --git a/module/rdd-resolution-table.js b/module/rdd-resolution-table.js
index b65ad195..4fea285e 100644
--- a/module/rdd-resolution-table.js
+++ b/module/rdd-resolution-table.js
@@ -89,13 +89,22 @@ export class RdDResolutionTable {
}
static explainRollData(rollData) {
- let message = "
Difficultés
libre: " + rollData.diffLibre + " / conditions: " + Misc.toSignedString(rollData.diffConditions)
- + " / état: " + rollData.etat;
- message += RdDResolutionTable.explain(rollData.rolled)
- if (rollData.selectedCarac == rollData.carac.volonte) {
- message += " / moral: " + rollData.moral;
+ let parts = [];
+ if (rollData.diffLibre != undefined) {
+ parts.push(`
libre: ${rollData.diffLibre}`);
}
- return message;
+ if (rollData.diffConditions != undefined) {
+ parts.push(`conditions: ${Misc.toSignedString(rollData.diffConditions)}`);
+ }
+ if (rollData.etat != undefined) {
+ parts.push(`état: ${rollData.etat}`);
+ }
+ if (rollData.selectedCarac != undefined && rollData.moral != undefined && rollData.selectedCarac.label == 'Volonté') {
+ parts.push(`moral: ${rollData.moral}`);
+ }
+ let message = parts.length > 0 ? "
Difficulté " + parts.reduce((a, b) => a + ' / ' + b) : "";
+
+ return message+ RdDResolutionTable.explain(rollData.rolled)
}
/* -------------------------------------------- */
diff --git a/module/rdd-roll-resolution.js b/module/rdd-roll-resolution.js
index da37e502..3f22ef46 100644
--- a/module/rdd-roll-resolution.js
+++ b/module/rdd-roll-resolution.js
@@ -10,16 +10,17 @@ import { RdDResolutionTable } from "./rdd-resolution-table.js";
export class RdDRollResolution extends Dialog {
/* -------------------------------------------- */
- static async open() {
- let rollData = RdDRollResolution._prepareDefaultOptions();
+ static async open(rollData = {selectedCarac:10}) {
+ RdDRollResolution._setDefaultOptions(rollData);
let html = await renderTemplate('systems/foundryvtt-reve-de-dragon/templates/dialog-roll-resolution.html', rollData);
const dialog = new RdDRollResolution(rollData, html);
dialog.render(true);
}
/* -------------------------------------------- */
- static _prepareDefaultOptions() {
- let rollData = {
+ static _setDefaultOptions(rollData) {
+
+ let defRollData = {
ajustementsConditions: CONFIG.RDD.ajustementsConditions,
difficultesLibres: CONFIG.RDD.difficultesLibres,
etat: 0,
@@ -29,11 +30,14 @@ export class RdDRollResolution extends Dialog {
diffConditions: 0,
diffLibre: 0
}
+ mergeObject(rollData, defRollData, {overwrite: false});
for (let i = 1; i < 21; i++) {
rollData.carac[i] = { type: "number", value: i, label: i }
+ if (rollData.selectedCarac == i) {
+ rollData.selectedCarac = rollData.carac[i];
+ }
+
}
- rollData.selectedCarac = rollData.carac[10];
- return rollData;
}
/* -------------------------------------------- */
diff --git a/module/rdd-utility.js b/module/rdd-utility.js
index 46031101..bab53c0d 100644
--- a/module/rdd-utility.js
+++ b/module/rdd-utility.js
@@ -891,17 +891,6 @@ export class RdDUtility {
});
}
- /* -------------------------------------------- */
- /* Display help for /table */
- static displayHelpTable( msg )
- {
- msg.content = "";
- for (let [name, tableData] of Object.entries(table2func)) {
- msg.content += "
" + tableData.descr;
- }
- ChatMessage.create( msg );
- }
-
/* -------------------------------------------- */
static afficherDemandePayer(som1, som2) {
som1 = (som1) ? som1.toLowerCase() : "0d";
@@ -922,38 +911,4 @@ export class RdDUtility {
msgPayer += "
Payer"
ChatMessage.create( { content: msgPayer } );
}
-
- /* -------------------------------------------- */
- /* Manage chat commands */
- static processChatCommand( commands, content, msg ) {
- // Setup new message's visibility
- let rollMode = game.settings.get("core", "rollMode");
- if (["gmroll", "blindroll"].includes(rollMode)) msg["whisper"] = ChatMessage.getWhisperRecipients("GM");
- if (rollMode === "blindroll") msg["blind"] = true;
- msg["type"] = 0;
-
- let command = commands[0];
-
- // Roll on a table
- if (command === "/table") {
- if ( commands[1] ) {
- let tableName = commands[1].toLowerCase();
- table2func[tableName].func();
- } else {
- this.displayHelpTable( msg );
- }
- return false
- } else if (command === "/tmrr") {
- TMRUtility.getRencontre(commands[1], commands[2] )
- return false
- } else if (command === "/tmra") {
- TMRUtility.getTMRAleatoire( )
- return false
- } else if (command === "/payer") {
- RdDUtility.afficherDemandePayer( commands[1], commands[2] )
- return false
- }
-
- return true;
- }
}