Fréquences par milieu pour l'environnement

Les herbes et les ingrédients peuvent être cherchées/tirées
This commit is contained in:
Vincent Vandemeulebrouck
2022-11-28 11:31:19 +01:00
parent b7a8b0c08d
commit b7a0e5d034
23 changed files with 702 additions and 158 deletions

222
module/environnement.js Normal file
View File

@ -0,0 +1,222 @@
import { SYSTEM_RDD } from "./constants.js";
import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { CompendiumTableHelpers, SystemCompendiums, CompendiumTable } from "./settings/system-compendiums.js";
const RARETES = [
{ name: 'Commune', frequence: 54, min: 27, max: 108 },
{ name: 'Frequente', frequence: 18, min: 9, max: 36 },
{ name: 'Rare', frequence: 6, min: 3, max: 12 },
{ name: 'Rarissime', frequence: 2, min: 1, max: 4 }]
const SETTINGS_LISTE_MILIEUX = "liste-milieux";
const MILIEUX = [
"Collines",
"Déserts",
"Désolations",
"Forêts",
"Forêts Tropicales",
"Marais",
"Milieux Aquatiques",
"Milieux Maritimes",
"Montagnes",
"Plaines",
"Sous-Sols",
]
const ITEM_ENVIRONNEMENT_TYPES = [
'herbe', 'ingredient'
]
const COMPENDIUMS_ENVIRONNEMENT = [
{ type: 'Item', subType: 'herbe', compendium: 'botanique' },
{ type: 'Item', subType: 'ingredient', compendium: 'botanique' },
{ type: 'Item', subType: 'ingredient', compendium: 'equipement' },
]
export class Environnement {
static init() {
game.settings.register(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX, {
name: "Liste des milieux proposés",
hint: "Liste des noms de milieux proposés, séparés par des virgules",
scope: "world",
config: true,
default: MILIEUX.reduce(Misc.joining(',')),
type: String
});
game.system.rdd.environnement = new Environnement();
}
constructor() {
this.table = new CompendiumTable('faune-flore-mineraux', 'Item', ITEM_ENVIRONNEMENT_TYPES)
}
static getRarete(name = undefined) {
return RARETES.find(it => it.name == name) ?? RARETES[0];
}
static getFrequenceRarete(rarete, field = undefined) {
const selected = this.getRarete(rarete);
return selected[field];
}
async milieux() {
const milieux = new Set(this.getMilieuxSettings());
const elements = await this.getElements(it => 1, it => ITEM_ENVIRONNEMENT_TYPES.includes(it.type));
elements.forEach(it => it.system.environnement.forEach(env => milieux.add(env.milieu)))
return [...milieux];
}
getMilieuxSettings() {
return game.settings.get(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX).split(',');
}
async findEnvironnementsLike(search) {
return (await this.milieux()).filter(it => Grammar.includesLowerCaseNoAccent(it, search));
}
async searchToChatMessage(search) {
const table = await this.buildEnvironnementTable(search);
await CompendiumTableHelpers.tableToChatMessage(table, 'Item', 'herbe', 'Ressource naturelle');
return true
}
async getRandom(search) {
const table = await this.buildEnvironnementTable(search);
const row = await CompendiumTableHelpers.getRandom(table, 'Item', 'herbe', undefined, 'Ressource naturelle');
return row
}
async buildEnvironnementTable(search) {
const itemRareteEnMilieu = item => item.system?.environnement.find(env => Grammar.includesLowerCaseNoAccent(env.milieu, search));
const itemFrequenceEnMilieu = item => itemRareteEnMilieu(item)?.frequence ?? 0;
const isPresentEnMilieu = item => itemFrequenceEnMilieu(item) > 0;
let elements = await this.getElements(itemFrequenceEnMilieu, isPresentEnMilieu);
return CompendiumTableHelpers.buildTable(elements, itemFrequenceEnMilieu);
}
async getElements(itemFrequence, filter) {
let elements = [];
for (let c of COMPENDIUMS_ENVIRONNEMENT) {
const fromCompendium = await c.table.getContent(itemFrequence, filter);
elements = elements.concat(fromCompendium);
}
return elements;
}
}
export class EnvironmentSheetHelper {
static defaultOptions(defaultOptions, type) {
return mergeObject(defaultOptions, {
classes: ["rdd", "sheet", "item"],
template: `systems/foundryvtt-reve-de-dragon/templates/item-${type}-sheet.html`,
width: 500,
height: 600,
tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "informations" }]
});
}
/* -------------------------------------------- */
static getHeaderButtons(sheet, buttons) {
buttons.unshift({ class: "post", icon: "fas fa-comment", onclick: ev => sheet.item.postItem() });
return buttons;
}
static setPosition(sheet, superPosition) {
const position = superPosition;
const sheetHeader = sheet.element.find(".sheet-header");
const sheetBody = sheet.element.find(".sheet-body");
sheetBody.css("height", position.height - sheetHeader[0].clientHeight)
return position;
}
/* -------------------------------------------- */
static async getData(sheet) {
const formData = duplicate(sheet.item);
const milieux = await game.system.rdd.environnement.milieux();
const milieuxDisponibles = milieux.filter(it => !sheet.item.system.environnement.find(e => e.milieu == it));
mergeObject(formData, {
title: formData.name,
isGM: game.user.isGM,
owner: sheet.actor?.isOwner,
isOwned: sheet.actor ? true : false,
actorId: sheet.actor?.id,
editable: sheet.isEditable,
cssClass: sheet.isEditable ? "editable" : "locked",
milieux: milieuxDisponibles
});
return formData;
}
static activateListeners(sheet, html) {
if (!sheet.options.editable) return;
html.find("a.milieu-add").click(event => EnvironmentSheetHelper.onAddMilieu(sheet, event));
html.find("div.environnement-milieu a.milieu-delete").click(event => EnvironmentSheetHelper.onDeleteMilieu(sheet, event));
html.find("div.environnement-milieu select.environnement-rarete").change(event => EnvironmentSheetHelper.onChange(sheet, event,
(updated) => {
const name = $(event.currentTarget).val();
const rarete = Environnement.getRarete(name);
updated.rarete = rarete.name;
updated.frequence = Math.min(
Math.max(rarete.min, updated.frequence ?? rarete.frequence),
rarete.max);
}));
html.find("div.environnement-milieu input[name='environnement-frequence']").change(event => EnvironmentSheetHelper.onChange(sheet, event,
(updated) => {
updated.frequence = Number($(event.currentTarget).val())
}));
}
static async onAddMilieu(sheet, event) {
const milieu = $("input.input-selection-milieu").val();
if (!milieu) {
ui.notifications.warn(`Choisissez le milieu dans lequel se trouve le/la ${sheet.item.name}`);
return
}
const list = sheet.item.system.environnement;
const exists = list.find(it => it.milieu == milieu);
if (exists) {
ui.notifications.warn(`${sheet.item.name} a déjà une rareté ${exists.rarete} en ${milieu} (fréquence: ${exists.frequence})`);
return
}
const rarete = Environnement.getRarete();
const newList = [...list, { milieu, rarete: rarete.name, frequence: rarete.frequence }].sort(Misc.ascending(it => it.milieu))
await sheet.item.update({ 'system.environnement': newList })
}
static async onDeleteMilieu(sheet, event) {
const milieu = EnvironmentSheetHelper.$getEventMilieu(event);
if (milieu) {
const newList = sheet.item.system.environnement.filter(it => it.milieu != milieu)
.sort(Misc.ascending(it => it.milieu));
await sheet.item.update({ 'system.environnement': newList });
}
}
static async onChange(sheet, event, doMutation) {
const list = sheet.item.system.environnement;
const milieu = EnvironmentSheetHelper.$getEventMilieu(event);
const updated = list.find(it => it.milieu == milieu);
if (updated) {
doMutation(updated);
const newList = [...list.filter(it => it.milieu != milieu), updated]
.sort(Misc.ascending(it => it.milieu));
await sheet.item.update({ 'system.environnement': newList });
}
}
static $getEventMilieu(event) {
return $(event.currentTarget)?.parents("div.environnement-milieu").data("milieu");
}
static template(itemType) {
/* -------------------------------------------- */
return `systems/foundryvtt-reve-de-dragon/templates/item-${itemType}-sheet.html`;
}
static title(item) {
return Misc.typeName('Item', item.type) + ': ' + item.name;
}
}

View File

@ -0,0 +1,45 @@
import { SYSTEM_RDD } from "./constants.js";
import { EnvironmentSheetHelper as EnvironmentItemSheet } from "./environnement.js";
import { Misc } from "./misc.js";
const ITEM_TYPE = 'herbe';
export class RdDHerbeItemSheet extends ItemSheet {
static register() {
Items.registerSheet(SYSTEM_RDD, RdDHerbeItemSheet, {
label: Misc.typeName('Item', ITEM_TYPE),
types: [ITEM_TYPE],
makeDefault: true
});
}
static get defaultOptions() {
return EnvironmentItemSheet.defaultOptions(super.defaultOptions, ITEM_TYPE);
}
_getHeaderButtons() {
return EnvironmentItemSheet.getHeaderButtons(this, super._getHeaderButtons());
}
setPosition(options = {}) {
return EnvironmentItemSheet.setPosition(this, super.setPosition(options));
}
async getData() {
return await EnvironmentItemSheet.getData(this);
}
activateListeners(html) {
super.activateListeners(html);
EnvironmentItemSheet.activateListeners(this, html);
}
get template() {
return EnvironmentItemSheet.template(this.item.type);
}
get title() {
return EnvironmentItemSheet.title(this.item);
}
}

View File

@ -0,0 +1,44 @@
import { SYSTEM_RDD } from "./constants.js";
import { EnvironmentSheetHelper } from "./environnement.js";
import { Misc } from "./misc.js";
const ITEM_TYPE = 'ingredient';
export class RdDIngredientItemSheet extends ItemSheet {
static register() {
Items.registerSheet(SYSTEM_RDD, RdDIngredientItemSheet, {
label: Misc.typeName('Item', ITEM_TYPE),
types: [ITEM_TYPE],
makeDefault: true
});
}
static get defaultOptions() {
return EnvironmentSheetHelper.defaultOptions(super.defaultOptions, ITEM_TYPE);
}
_getHeaderButtons() {
return EnvironmentSheetHelper.getHeaderButtons(this, super._getHeaderButtons());
}
setPosition(options = {}) {
return EnvironmentSheetHelper.setPosition(this, super.setPosition(options));
}
async getData() {
return await EnvironmentSheetHelper.getData(this);
}
activateListeners(html) {
super.activateListeners(html);
EnvironmentSheetHelper.activateListeners(this, html);
}
get template() {
return EnvironmentSheetHelper.template(this.item.type);
}
get title() {
return EnvironmentSheetHelper.title(this.item);
}
}

View File

@ -1,6 +1,6 @@
import { LOG_HEAD, SYSTEM_RDD } from "./constants.js";
import { Environnement } from "./environnement.js";
import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
class Migration {
get code() { return "sample"; }
@ -179,6 +179,7 @@ class _10_2_5_ArmesTirLancer extends Migration {
return Grammar.toLowerCaseNoAccent(it.system.competence);
}
}
class _10_2_10_DesirLancinant_IdeeFixe extends Migration {
get code() { return "desir-lancinat-idee-fixe"; }
get version() { return "10.2.10"; }
@ -240,6 +241,24 @@ class _10_3_0_Inventaire extends Migration {
}
}
class _10_3_0_FrequenceEnvironnement extends Migration {
get code() { return "migration-frequence-resources"; }
get version() { return "10.3.0"; }
async migrate() {
await this.applyItemsUpdates(items => items.filter(it => ['herbe', 'ingredient'].includes(it.type))
.map(it => this._updatesFrequences(it)));
}
_updatesFrequences(it) {
return {
_id: it.id,
'system.rarete': undefined,
'system.environnement': [{ milieu: it.system.milieu, rarete: it.system.rarete, frequence: Environnement.getFrequenceRarete(it.system.rarete, 'frequence') }]
}
}
}
export class Migrations {
static getMigrations() {
return [
@ -249,7 +268,8 @@ export class Migrations {
new _10_0_33_MigrationNomsDraconic(),
new _10_2_5_ArmesTirLancer(),
new _10_2_10_DesirLancinant_IdeeFixe(),
new _10_3_0_Inventaire()
new _10_3_0_Inventaire(),
new _10_3_0_FrequenceEnvironnement()
];
}
@ -264,11 +284,9 @@ export class Migrations {
}
migrate() {
const currentVersion = game.settings.get(
SYSTEM_RDD,
"systemMigrationVersion"
);
if (isNewerVersion(game.system.version, currentVersion)) {
const currentVersion = game.settings.get(SYSTEM_RDD,"systemMigrationVersion");
//if (isNewerVersion(game.system.version, currentVersion)) {
if (true) { /* comment previous and uncomment here to test before upgrade */
const migrations = Migrations.getMigrations().filter(m => isNewerVersion(m.version, currentVersion));
if (migrations.length > 0) {
migrations.sort((a, b) =>

View File

@ -13,6 +13,7 @@ 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 { CompendiumTableHelpers } from "./settings/system-compendiums.js";
import { TMRUtility } from "./tmr-utility.js";
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
@ -49,7 +50,9 @@ export class RdDCommands {
<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`
});
this.registerCommand({ path: ["/table", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params,'liste'), descr: "Affiche la table des trouvailles dans un milieu donné" });
this.registerCommand({ path: ["/tirer", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params, 'chat'), descr: "Affiche la table des trouvailles dans un milieu donné" });
this.registerCommand({ path: ["/tirer", "comp"], func: (content, msg, params) => RdDRollTables.getCompetence('chat'), descr: "Tire une compétence au hasard" });
this.registerCommand({ path: ["/tirer", "queue"], func: (content, msg, params) => RdDRollTables.getQueue('chat'), descr: "Tire une Queue de Dragon" });
this.registerCommand({ path: ["/tirer", "ombre"], func: (content, msg, params) => RdDRollTables.getOmbre('chat'), descr: "Tire une Ombre de Thanatos" });
@ -363,6 +366,7 @@ export class RdDCommands {
}
return false;
}
async tableRencontres(msg, params) {
if (params && params.length > 0) {
const search = Misc.join(params, ' ');
@ -370,11 +374,29 @@ export class RdDCommands {
if (solvedTerrain == undefined) {
return RdDCommands._chatAnswer(msg, 'Aucune TMR correspondant à ' + search);
}
return game.system.rdd.rencontresTMR.chatTable(solvedTerrain);
return await game.system.rdd.rencontresTMR.chatTable(solvedTerrain);
}
return false;
}
async tableMilieu(msg, params, toChat) {
if (params && params.length > 0) {
const search = Misc.join(params, ' ');
const searches = game.system.rdd.environnement.findEnvironnementsLike(search);
if (searches.length == 0) {
return RdDCommands._chatAnswer(msg, 'Aucun milieu correspondant à ' + search);
}
if (toChat == 'liste') {
return await game.system.rdd.environnement.searchToChatMessage(search);
}
else {
const row = await game.system.rdd.environnement.getRandom(search);
await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item');
return true;
}
}
return false;
}
/* -------------------------------------------- */
getCoutXpComp(msg, params) {
if (params && (params.length == 1 || params.length == 2)) {

View File

@ -39,6 +39,9 @@ import { DialogChronologie } from "./dialog-chronologie.js";
import { SystemCompendiums } from "./settings/system-compendiums.js";
import { RdDRencontreItemSheet } from "./item-rencontre-sheet.js";
import { TMRRencontres } from "./tmr-rencontres.js";
import { RdDHerbeItemSheet } from "./item-herbe-sheet.js";
import { Environnement } from "./environnement.js";
import { RdDIngredientItemSheet } from "./item-ingredient-sheet.js";
/* -------------------------------------------- */
/* Foundry VTT Initialization */
@ -194,11 +197,13 @@ Hooks.once("init", async function () {
types: ["rencontre"],
makeDefault: true
});
RdDHerbeItemSheet.register();
RdDIngredientItemSheet.register();
Items.registerSheet(SYSTEM_RDD, RdDItemSheet, {
types: [
"competence", "competencecreature",
"recettealchimique", "musique", "chant", "danse", "jeu", "recettecuisine", "oeuvre",
"objet", "arme", "armure", "conteneur", "herbe", "ingredient", "livre", "potion", "munition",
"objet", "arme", "armure", "conteneur", "livre", "potion", "munition",
"monnaie", "nourritureboisson", "gemme",
"meditation", "queue", "ombre", "souffle", "tete", "casetmr", "sort", "sortreserve",
"nombreastral", "tache", "maladie", "poison", "possession",
@ -224,6 +229,7 @@ Hooks.once("init", async function () {
RdDHotbar.initDropbar();
RdDPossession.init();
TMRRencontres.init();
Environnement.init();
});
/* -------------------------------------------- */

View File

@ -1,5 +1,5 @@
import { Grammar } from "./grammar.js";
import { SystemCompendiums } from "./settings/system-compendiums.js";
import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } from "./settings/system-compendiums.js";
export class RdDRollTables {
@ -37,7 +37,7 @@ export class RdDRollTables {
/* -------------------------------------------- */
static async getCompetence(toChat = false) {
if (toChat == 'liste') {
return await SystemCompendiums.chatTableItems('competences', 'Item', 'competence', it => 1);
return await RdDRollTables.listOrRoll('competences', 'Item', 'competence', toChat, it => 1);
}
else {
return await RdDRollTables.drawItemFromRollTable("Détermination aléatoire de compétence", toChat);
@ -55,13 +55,15 @@ export class RdDRollTables {
}
static async getDesirLancinant(toChat = false) {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat, it => it.system.frequence,
it => it.system.categorie == 'lancinant' );
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat,
it => it.system.frequence,
it => it.system.categorie == 'lancinant');
}
static async getIdeeFixe(toChat = false) {
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat, it => it.system.frequence,
it => it.system.categorie == 'ideefixe' );
return await RdDRollTables.listOrRoll('queues-de-dragon', 'Item', 'queue', toChat,
it => it.system.frequence,
it => it.system.categorie == 'ideefixe');
}
/* -------------------------------------------- */
@ -86,10 +88,15 @@ export class RdDRollTables {
/* -------------------------------------------- */
static async listOrRoll(compendium, type, subType, toChat, itemFrequence = it => it.system.frequence, filter = it => true) {
const table = new CompendiumTable(compendium, type, subType);
if (toChat == 'liste') {
return await SystemCompendiums.chatTableItems(compendium, type, subType, itemFrequence, filter);
return await table.toChatMessage(itemFrequence, filter);
}
return await SystemCompendiums.getRandom(compendium, type, subType, toChat, itemFrequence, filter);
const row = await table.getRandom(itemFrequence, filter);
if (row) {
await CompendiumTableHelpers.tableRowToChatMessage(row, type);
}
return row;
}
/* -------------------------------------------- */

View File

@ -15,6 +15,7 @@ import { RdDNameGen } from "./rdd-namegen.js";
import { RdDConfirm } from "./rdd-confirm.js";
import { RdDCalendrier } from "./rdd-calendrier.js";
import { RdDCarac } from "./rdd-carac.js";
import { Environnement } from "./environnement.js";
/* -------------------------------------------- */
// This table starts at 0 -> niveau -10
@ -169,7 +170,11 @@ export class RdDUtility {
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-suivants.html',
'systems/foundryvtt-reve-de-dragon/templates/actor/liens-vehicules.html',
//Items
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete-script.hbs',
'systems/foundryvtt-reve-de-dragon/templates/scripts/autocomplete.hbs',
'systems/foundryvtt-reve-de-dragon/templates/item/partial-inventaire.html',
'systems/foundryvtt-reve-de-dragon/templates/item/partial-environnement.html',
'systems/foundryvtt-reve-de-dragon/templates/item/partial-tab-environnement.html',
'systems/foundryvtt-reve-de-dragon/templates/header-item.html',
'systems/foundryvtt-reve-de-dragon/templates/item-competence-sheet.html',
'systems/foundryvtt-reve-de-dragon/templates/item-competencecreature-sheet.html',
@ -326,7 +331,8 @@ export class RdDUtility {
Handlebars.registerHelper('linkCompendium', (compendium, id, name) => `@Compendium[${compendium}.${id}]{${name}}`);
Handlebars.registerHelper('uniteQuantite', (type) => RdDItem.getUniteQuantite(type));
Handlebars.registerHelper('isEquipementFieldEditable', (type, field) => RdDItem.isEquipementFieldEditable(type, field));
Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field));
Handlebars.registerHelper('either', (a, b) => a ?? b);
return loadTemplates(templatePaths);
}

View File

@ -16,8 +16,13 @@ const CONFIGURABLE_COMPENDIUMS = {
'rencontres': { label: "Rencontres dans les TMR", type: "Item" },
'tetes-de-dragon-pour-haut-revants': { label: "Têtes de dragons (haut-rêvant)", type: "Item" },
'tetes-de-dragon-pour-tous-personnages': { label: "Têtes de dragons (tous)", type: "Item" },
'botanique': { label: "Herbes & plantes", type: "Item" },
'equipement': { label: "Equipements", type: "Item" },
}
/**
* ======= Gestion des accès aux compendiums systèmes (ou surchargés) =======
*/
export class SystemCompendiums extends FormApplication {
static init() {
Object.keys(CONFIGURABLE_COMPENDIUMS).forEach(compendium => {
@ -50,7 +55,7 @@ export class SystemCompendiums extends FormApplication {
return game.packs.get(SystemCompendiums.getCompendium(compendium));
}
static async getContent(compendium, docType) {
static async getPackContent(compendium, docType) {
const pack = SystemCompendiums.getPack(compendium);
if (pack.metadata.type == docType) {
return await pack.getDocuments();
@ -83,35 +88,17 @@ export class SystemCompendiums extends FormApplication {
}
static async getItems(compendium, itemType = undefined) {
const items = await SystemCompendiums.getContent(compendium, 'Item');
const items = await SystemCompendiums.getPackContent(compendium, 'Item');
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)
static async getContent(compendium, type, filter, itemFrequence, sorting) {
let elements = await SystemCompendiums.getPackContent(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);
return elements;
}
static async getDefaultItems(compendium) {
@ -180,48 +167,69 @@ export class SystemCompendiums extends FormApplication {
}
}
export class SystemCompendiumTable {
/**
* ======= Gestion de jets dans une table correspondant à un compendium =======
*/
export class CompendiumTable {
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
this.sorting = sorting ?? Misc.ascending(it => it.name);
}
typeName() {
return Misc.typeName(this.type, this.subType);
}
applyType(filter) {
return it => it.type == this.subType && filter(it);
async getContent(itemFrequence = it => it.system.frequence, filter = it => true) {
return await SystemCompendiums.getContent(this.compendium,
this.type,
it => this.subType == it.type && filter(it),
itemFrequence,
this.sorting);
}
async getRandom(toChat = true, itemFrequence = it => it.system.frequence, filter = it => true, forcedRoll = undefined) {
const table = await this.$buildTable(itemFrequence, filter);
async buildTable(itemFrequence = it => it.system.frequence, filter = it => true) {
const elements = await this.getContent(filter, itemFrequence);
return CompendiumTableHelpers.buildTable(elements, itemFrequence);
}
async getRandom(itemFrequence = it => it.system.frequence, filter = it => true, forcedRoll = undefined) {
const table = await this.buildTable(itemFrequence, filter);
return await CompendiumTableHelpers.getRandom(table, this.type, this.subType, forcedRoll, SystemCompendiums.getCompendium(compendium));
}
async toChatMessage(itemFrequence = it => it.system.frequence, filter = it => true, typeName = undefined) {
const table = await this.buildTable(itemFrequence, filter);
await CompendiumTableHelpers.tableToChatMessage(table, this.type, this.subType, typeName);
return true;
}
}
/**
* ======= Gestion de tables correspondant à un compendium =======
*/
export class CompendiumTableHelpers {
static buildTable(elements, itemFrequence) {
let max = 0;
const total = elements.map(it => itemFrequence(it)).reduce(Misc.sum(), 0);
return elements.map(it => {
const frequence = itemFrequence(it);
let row = { document: it, frequence: frequence, min: max + 1, max: max + frequence, total: total };
max += frequence;
return row;
});
}
static async getRandom(table, type, subType, forcedRoll = undefined, localisation = undefined) {
if (table.length == 0) {
ui.notifications.warn(`Aucun ${this.typeName()} dans ${this.sourceCompendium}`);
ui.notifications.warn(`Aucun ${Misc.typeName(type, subType)} trouvé dans ${localisation ?? ' les compendiums'}`);
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);
return await CompendiumTableHelpers.selectRow(table, forcedRoll);
}
/* -------------------------------------------- */
async $selectRow(table, forcedRoll = undefined) {
static async selectRow(table, forcedRoll = undefined) {
if (table.length == 0) {
return undefined
}
@ -238,14 +246,16 @@ export class SystemCompendiumTable {
}
/* -------------------------------------------- */
async $chatRolledResult(row) {
static async tableRowToChatMessage(row, type = 'Item') {
if (!row) {
return;
}
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,
document: row.document,
percentages,
typeName: this.typeName(),
sourceCompendium: this.sourceCompendium,
typeName: Misc.typeName(type, row.document.type),
isGM: game.user.isGM,
});
const messageData = {
@ -260,11 +270,10 @@ export class SystemCompendiumTable {
}
/* -------------------------------------------- */
async $chatSystemCompendiumTable(table, typeName) {
static async tableToChatMessage(table, type, subType, typeName = undefined) {
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,
img: RdDItem.getDefaultImg(subType),
typeName: typeName ?? Misc.typeName(type, subType),
table,
isGM: game.user.isGM,
});
@ -275,5 +284,4 @@ export class SystemCompendiumTable {
}, { rollMode: "gmroll" });
}
}
}

View File

@ -1,7 +1,7 @@
import { Grammar } from "./grammar.js";
import { Misc } from "./misc.js";
import { RdDDice } from "./rdd-dice.js";
import { SystemCompendiums, SystemCompendiumTable } from "./settings/system-compendiums.js";
import { SystemCompendiums, CompendiumTable, CompendiumTableHelpers } from "./settings/system-compendiums.js";
import { TMRUtility } from "./tmr-utility.js";
@ -15,7 +15,7 @@ export class TMRRencontres {
}
constructor(){
this.table = new SystemCompendiumTable('rencontres', 'Item', 'rencontre', Misc.ascending(it => it.system.ordreTri));
this.table = new CompendiumTable('rencontres', 'Item', 'rencontre', Misc.ascending(it => it.system.ordreTri));
}
/* -------------------------------------------- */
@ -36,9 +36,12 @@ export class TMRRencontres {
const codeTerrain = Grammar.toLowerCaseNoAccent(terrain)
const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
const frequence = it => it.system.frequence[codeTerrain];
const random = await this.table.getRandom(true, frequence, filtreMauvaise, forcedRoll);
const row = await this.table.getRandom(frequence, filtreMauvaise, forcedRoll);
if (row) {
await CompendiumTableHelpers.tableRowToChatMessage(row);
}
return random?.document;
return row?.document;
}
async chatTable(terrain) {
@ -47,9 +50,9 @@ export class TMRRencontres {
const filtreMauvaise = isMauvaise ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
const frequence = it => it.system.frequence[codeTerrain];
const typeName = isMauvaise ? 'Mauvaises rencontres' : `Rencontres en ${Misc.upperFirst(terrain)}`;
await this.table.chatTable(frequence, filtreMauvaise, typeName);
return true
return await this.table.toChatMessage(frequence, filtreMauvaise, typeName);
}
/* -------------------------------------------- */
async createRencontre(rencontre, tmr = undefined) {
return rencontre.clone({
@ -95,7 +98,7 @@ export class TMRRencontres {
const filtreMauvaise = codeTerrain == 'mauvaise' ? it => it.system.mauvaiseRencontre : it => !it.system.mauvaiseRencontre;
const frequence = it => it.system.frequence[codeTerrain];
const row = await this.table.getRandom(false, frequence, filtreMauvaise);
const row = await this.table.getRandom(frequence, filtreMauvaise);
if (row) {
row.document = this.createRencontre(row.document, tmr);
await this.$chatRolledRencontre(row, tmr);