/* -------------------------------------------- */ import { DeDraconique } from "./de-draconique.js"; import { RdDItemCompetence } from "./item-competence.js"; import { Misc } from "./misc.js"; import { RdDCarac } from "./rdd-carac.js"; import { RdDDice } from "./rdd-dice.js"; import { RdDNameGen } from "./rdd-namegen.js"; import { RdDResolutionTable } from "./rdd-resolution-table.js"; import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js"; import { RdDRollTables } from "./rdd-rolltables.js"; import { RdDUtility } from "./rdd-utility.js"; import { TMRRencontres } from "./tmr-rencontres.js"; import { TMRType, 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"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" }); rddCommands.registerCommand({ path: ["/help"], func: (content, msg, params) => rddCommands.help(msg), descr: "Affiche l'aide pour toutes les commandes" }); rddCommands.registerCommand({ path: ["/table", "queues"], func: (content, msg, params) => RdDRollTables.getQueue(true), descr: "Tire une Queue de Dragon" }); rddCommands.registerCommand({ path: ["/table", "ideefixe"], func: (content, msg, params) => RdDRollTables.getIdeeFixe(true), descr: "Tire une Idée fixe" }); rddCommands.registerCommand({ path: ["/table", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant(true), descr: "Tire un Désir Lancinant" }); rddCommands.registerCommand({ path: ["/table", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre(true), descr: "Tire une Ombre de Dragon" }); rddCommands.registerCommand({ path: ["/table", "tetehr"], func: (content, msg, params) => RdDRollTables.getTeteHR(true), descr: "Tire une Tête de Dragon pour Hauts Revants" }); rddCommands.registerCommand({ path: ["/table", "tete"], func: (content, msg, params) => RdDRollTables.getTete(true), descr: "Tire une Tête de Dragon" }); rddCommands.registerCommand({ path: ["/table", "souffle"], func: (content, msg, params) => RdDRollTables.getSouffle(true), descr: " Tire un Souffle de Dragon" }); rddCommands.registerCommand({ path: ["/table", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence(true), descr: "Tire une compétence au hasard" }); rddCommands.registerCommand({ path: ["/table", "tarot"], func: (content, msg, params) => RdDRollTables.getTarot(true), descr: "Tire une carte du Tarot Draconique" }); rddCommands.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" }); rddCommands.registerCommand({ path: ["/tmra"], func: (content, msg, params) => rddCommands.getTMRAleatoire(msg, params), descr: `Tire une case aléatoire des Terres médianes
/tmra forêt détermine une 'forêt' aléatoire
/tmra détermine une case aléatoire dans toutes les TMR` }); rddCommands.registerCommand({ path: ["/tmrr"], func: (content, msg, params) => rddCommands.getRencontreTMR(params), descr: `Détermine une rencontre dans un type de case
/tmrr foret lance un d100 et détermine la rencontre correspondante en 'forêt'
/tmrr forêt 47 détermine la rencontre en 'forêt' pour un jet de dé de 47` }); rddCommands.registerCommand({ path: ["/xp", "comp"], func: (content, msg, params) => rddCommands.getCoutXpComp(msg, params), descr: `Détermine le coût d'expérience pour augmenter une compétence. Exemples:
/xp comp -6 1: pour passer de -6 à +1
/xp comp +4: pour atteindre le niveau 4 (depuis +3)` }); rddCommands.registerCommand({ path: ["/xp", "carac"], func: (content, msg, params) => rddCommands.getCoutXpCarac(msg, params), descr: `Détermine le coût d'expérience pour augmenter une caractéristique. Exemples:
/xp carac 15: coût pour atteindre 15 (depuis 14)` }); rddCommands.registerCommand({ path: ["/rdd"], func: (content, msg, params) => rddCommands.rollRdd(msg, params), descr: `Effectue un jet de dés dans la table de résolution. Exemples:
/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` }); rddCommands.registerCommand({ path: ["/ddr"], func: (content, msg, params) => rddCommands.rollDeDraconique(msg), descr: "Lance un Dé Draconique" }); rddCommands.registerCommand({ path: ["/payer"], func: (content, msg, params) => RdDUtility.afficherDemandePayer(params[0], params[1]), 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` }); rddCommands.registerCommand({ path: ["/astro"], func: (content, msg, params) => RdDUtility.afficherHeuresChanceMalchance(params[0]), descr: `Affiche les heures de chance et de malchance selon l'heure de naissance donnée en argument. Exemples:
/astro Lyre` }); game.system.rdd.commands = rddCommands; } } constructor() { this.commandsTable = {}; } /* -------------------------------------------- */ registerCommand(command) { this._addCommand(this.commandsTable, command.path, '', command); } /* -------------------------------------------- */ _addCommand(targetTable, path, fullPath, command) { if (!this._validateCommand(targetTable, path, command)) { return; } const term = path[0]; fullPath = fullPath + term + ' ' if (path.length == 1) { command.descr = `${fullPath}: ${command.descr}`; targetTable[term] = command; } else { if (!targetTable[term]) { targetTable[term] = { subTable: {} }; } this._addCommand(targetTable[term].subTable, path.slice(1), fullPath, 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) { const result = command.func(content, msg, params); if (result == false) { RdDCommands._chatAnswer(msg, command.descr); } return true; } return false; } /* -------------------------------------------- */ help(msg, table = undefined) { let list = [] this._buildSubTableHelp(list, table || this.commandsTable); const messageAide = list.reduce((a, b) => a + '
  • ' + b); RdDCommands._chatAnswer(msg, `Commandes disponibles`); } /* -------------------------------------------- */ static _chatAnswer(msg, content) { msg.whisper = [game.user._id]; msg.content = content; ChatMessage.create(msg); } /* -------------------------------------------- */ _buildSubTableHelp(list, table) { for (let [name, command] of Object.entries(table)) { if (command) { if (command.subTable) { this._buildSubTableHelp(list, command.subTable); } else { list.push(command.descr); } } } return list.sort(); } /* -------------------------------------------- */ async getRencontreTMR(params) { if (params.length == 1 || params.length == 2) { return TMRRencontres.rollRencontre(params[0], params[1]) } else { return false; } } /* -------------------------------------------- */ async rollRdd(msg, params) { if (params.length == 0) { RdDRollResolutionTable.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, diviseurSignificative: significative ? 2 : 1, show: { title: "Table de résolution" } }; await RdDResolutionTable.rollData(rollData); RdDCommands._chatAnswer(msg, await RdDResolutionTable.buildRollDataHtml(rollData)); } /* -------------------------------------------- */ async rollDeDraconique(msg) { let ddr = new DeDraconique().evaluate(); ddr.showDice = true; await RdDDice.showDiceSoNice(ddr); RdDCommands._chatAnswer(msg, `Lancer d'un Dé draconique: ${ddr.total}`); } getTMRAleatoire(msg, params) { if (params.length < 2) { let type = params[0]; const tmr = TMRUtility.getTMRAleatoire(type ? (it => it.type == type) : (it => true)); RdDCommands._chatAnswer(msg, `Case aléatoire: ${tmr.coord} - ${tmr.label}`); } else { return false; } } /* -------------------------------------------- */ getCoutXpComp(msg, params) { if (params && (params.length == 1 || params.length == 2)) { let to = params.length == 1 ? Number(params[0]) : Number(params[1]); let from = params.length == 1 ? to - 1 : Number(params[0]); RdDCommands._chatAnswer(msg, `Coût pour passer une compétence de ${from} à ${to}: ${RdDItemCompetence.getDeltaXp(from, to)}`); } else { return false; } } /* -------------------------------------------- */ getCoutXpCarac(msg, params) { if (params && params.length == 1) { let to = Number(params[0]); RdDCommands._chatAnswer(msg, `Coût pour passer une caractéristique de ${to - 1} à ${to}: ${RdDCarac.getCaracXp(to)}`); } else { return false; } } }