304 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* -------------------------------------------- */
 | |
| 
 | |
| 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 { 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
 | |
|           <br><strong>/tmra forêt</strong> détermine une 'forêt' aléatoire
 | |
|           <br><strong>/tmra</strong> 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
 | |
|           <br><strong>/tmrr foret</strong> lance un d100 et détermine la rencontre correspondante en 'forêt'
 | |
|           <br><strong>/tmrr forêt 47</strong> 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:
 | |
|         <br>/xp comp -6 1: pour passer de -6 à +1
 | |
|         <br>/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:
 | |
|         <br>/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:
 | |
|           <br><strong>/rdd</strong> ouvre la table de résolution
 | |
|           <br><strong>/rdd 10 3</strong> effectue un jet 10 à +3
 | |
|           <br><strong>/rdd 15 -2</strong> effectue un jet 15 à -2
 | |
|           <br><strong>/rdd 15 0 s</strong> effectue un jet 15 à 0, avec significative requise
 | |
|           <br><strong>/rdd Vue Vigilance -2</strong> effectue un jet de Vue/Vigilance à -2 pour les tokens sélectionnés
 | |
|           <br><strong>/rdd vol déser +2</strong> effectue un jet de Volonté/Survie en désert à +2 pour les tokens sélectionnés
 | |
|           `
 | |
|       });
 | |
|       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:
 | |
|           <br><strong>/payer 5s 10d</strong> permet d'envoyer un message pour payer 5 sols et 10 deniers
 | |
|           <br><strong>/payer 10d</strong> 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:
 | |
|           <br><strong>/astro Lyre</strong>`
 | |
|       });
 | |
|       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 = `<strong>${fullPath}</strong>: ${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 + '</li><li class="list-item">' + b);
 | |
|     RdDCommands._chatAnswer(msg, `Commandes disponibles<ul class="alterne-list"><li class="list-item">${messageAide}</li></ul>`);
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   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;
 | |
|       }
 | |
| 
 | |
|       let actors = canvas.tokens.controlled.map(it => it.actor).filter(it => it);
 | |
|       if (actors && actors.length > 0){
 | |
|         let length = params.length;
 | |
|         let diff = Number(params[length-1]);
 | |
|         if (Number.isInteger(Number(diff))){
 | |
|           length --;
 | |
|         }
 | |
|         else {
 | |
|           diff = 0;
 | |
|         }
 | |
|         const caracName = params[0];
 | |
|         const compName = length>1 ? params.slice(1, length).reduce((a, b) => `${a} ${b}`): undefined;
 | |
|         for (let actor of actors) {
 | |
|           await actor.rollCaracCompetence(caracName, compName, diff);
 | |
|         }
 | |
|         return;
 | |
|       }
 | |
|       else{
 | |
|         ui.notifications.warn("Sélectionnez au moins un personnage pour lancer les dés")
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* -------------------------------------------- */
 | |
|   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;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 |