foundryvtt-reve-de-dragon/module/tmr-rencontres.js
2022-11-10 00:42:01 +01:00

143 lines
5.7 KiB
JavaScript

import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js";
import { SystemCompendiums } from "./settings/system-compendiums.js";
import { TMRUtility } from "./tmr-utility.js";
/* -------------------------------------------- */
export class TMRRencontres {
/* -------------------------------------------- */
/**
* Retourne une recontre en fonction de la case et du tirage
* @param {*} terrain
* @param {*} forcedRoll
*/
static async rollRencontre(terrain, forcedRoll) {
// TODO: recherche parmi les types de terrains + mauvaise, rejet si plusieurs choix
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain);
if (!terrain) {
ChatMessage.create({
user: game.user.id,
whisper: [game.user.id],
content: "Un type de case doit être indiqué (par exemple sanctuaire, desert ou cité)"
});
return false;
}
if (forcedRoll && (forcedRoll <= 0 || forcedRoll > 100)) {
forcedRoll = undefined;
}
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');
const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
const rencontres = items.filter(it => it.type == 'rencontre')
.filter(filtreMauvaise)
.filter(it => it.system.frequence[codeTerrain] > 0)
.sort(Misc.ascending(it => it.system.ordreTri))
.map(it => {
const frequence = it.system.frequence[codeTerrain];
max += frequence;
return { rencontre: it, min: max - frequence + 1, max: max,frequence: frequence };
});
return rencontres;
}
/* -------------------------------------------- */
static async $selectRencontre(terrain, table, roll = undefined) {
const total = table.map(it => it.frequence).reduce(Misc.sum(), 0);
if (total == 0){
ui.notifications.warn(`Pas de rencontres définies pour ${terrain}`);
return undefined;
}
if (roll != undefined && (roll > total || roll <= 0)) {
ui.notifications.warn(`Jet de rencontre ${roll} en dehors de la table [1..${total}], le jet est relancé`);
roll = undefined;
}
if (!roll) {
roll = await RdDDice.rollTotal(`1d${total}`);
}
return [table.find(it => it.min <= roll && roll <= it.max), roll];
}
/* -------------------------------------------- */
static async createRencontre(rencontre, tmr = undefined) {
return rencontre.clone({
'system.force': await RdDDice.rollTotal(rencontre.system.formule),
'system.coord': tmr?.coord,
'system.date': game.system.rdd.calendrier.getDateFromIndex(),
'system.heure': game.system.rdd.calendrier.getCurrentHeure()
}, {save: false});
}
static async calculRencontre(rencontre, tmr = undefined) {
if (rencontre.system.coord == ""){
rencontre.system.coord = tmr?.coord;
}
if (rencontre.system.force == 0){
rencontre.system.force = await RdDDice.rollTotal(rencontre.system.formule);
}
if (rencontre.system.date == "" ) {
rencontre.system.date = game.system.rdd.calendrier.getDateFromIndex();
}
if (rencontre.system.heure == "") {
rencontre.system.heure = game.system.rdd.calendrier.getCurrentHeure();
}
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() {
const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
return rencontres.filter(it => !it.system.mauvaiseRencontre && it.system.presentCite).map(it =>
it.clone({ 'system.formule': "2d6" }, {save: false}));
}
static async getReveDeDragon(force) {
const rencontres = await SystemCompendiums.getDefaultItems('rencontres');
const reveDeDragon = rencontres.find(it => Grammar.equalsInsensitive(it.name, 'Rêve de Dragon'));
return reveDeDragon?.clone({ 'system.force': force }, {save: false});
}
/* -------------------------------------------- */
static async getRencontreAleatoire(tmr, mauvaise) {
const codeTerrain = mauvaise ? 'mauvaise' : tmr.type;
const table = await TMRRencontres.$buildTableRencontre(codeTerrain);
const [selected, roll] = await TMRRencontres.$selectRencontre(codeTerrain, table);
const rencontre = await TMRRencontres.createRencontre(selected.rencontre, tmr);
TMRRencontres.$chatRolledRencontre(rencontre, TMRUtility.getTMRType(tmr.coord), table, roll);
return rencontre;
}
}