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 DEFAULT_RARETE = 1; const SETTINGS_LISTE_MILIEUX = "liste-milieux"; const MILIEUX = [ "Collines", "Déserts", "Forêts", "Marais", "Cours d'eau", "Maritimes", "Montagnes", "Plaines", "Sous-Sols", ] const ITEM_ENVIRONNEMENT_TYPES = [ 'herbe', 'ingredient' ] export class Environnement { static init() { game.settings.register(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX, { name: "Liste des milieux proposés", hint: "Liste des milieux proposés pour la faune&flore, 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[DEFAULT_RARETE]; } 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].filter(env => env); } getMilieuxSettings() { return game.settings.get(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX).split(','); } async findEnvironnementsLike(search) { const milieux = (await this.milieux()).filter(it => Grammar.includesLowerCaseNoAccent(it, search)); if (milieux.length > 1) { const milieuExact = milieux.find(it => Grammar.equalsInsensitive(it, search)); if (milieuExact) { return [milieuExact]; } } return milieux; } async searchToChatMessage(milieux, typeName) { const table = await this.buildEnvironnementTable(milieux); await CompendiumTableHelpers.tableToChatMessage(table, 'Item', ITEM_ENVIRONNEMENT_TYPES, typeName); return true } async getRandom(milieux, typeName) { const table = await this.buildEnvironnementTable(milieux); return await CompendiumTableHelpers.getRandom(table, 'Item', ITEM_ENVIRONNEMENT_TYPES, undefined, typeName); } async buildEnvironnementTable(milieux) { const filterMilieux = item => item.system?.environnement.filter(env => milieux.includes(env.milieu)); const itemRareteEnMilieu = item => { const raretes = filterMilieux(item); const frequenceMax = Math.max(raretes.map(env => env.frequence)); return raretes.find(env => env.frequence == frequenceMax); } const itemFrequenceEnMilieu = item => itemRareteEnMilieu(item)?.frequence ?? 0; const isPresentEnMilieu = item => itemFrequenceEnMilieu(item) > 0; return await this.table.buildTable(itemFrequenceEnMilieu, isPresentEnMilieu); } async getElements(itemFrequence, filter) { return await this.table.getContent(itemFrequence, filter); } } 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(html, 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(html, sheet, event) { const milieu = html.find('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; } }