import { SYSTEM_RDD } from "./constants.js"; import { Grammar } from "./grammar.js"; import { Misc } from "./misc.js"; import { CompendiumTableHelpers, 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", "Cours d'eau", "Déserts", "Forêts", "Marais", "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() { return Object.values(await this.mapMilieux()); } async mapMilieux() { const compendiumItems = await this.getElements(it => 1, it => ITEM_ENVIRONNEMENT_TYPES.includes(it.type)); return Misc.indexLowercase(this.getMilieuxSettings().concat(Environnement.listMilieux(compendiumItems))); } static listMilieux(items) { return Misc.concat(items.map(it => Environnement.$itemToMilieux(it).filter(m => m))); } async autresMilieux(item) { const mapMilieux = await this.mapMilieux(); const milieuxExistants = Environnement.$itemToMilieux(item).map(it => Grammar.toLowerCaseNoAccent(it)); return Object.keys(mapMilieux) .filter(it => !milieuxExistants.includes(it)) .map(it => mapMilieux[it]); } static $itemToMilieux(item) { return item.system.environnement.map(env => env.milieu); } getMilieuxSettings() { return game.settings.get(SYSTEM_RDD, SETTINGS_LISTE_MILIEUX).split(',').map(it => it.trim()).filter(it => it != ''); } async findEnvironnementsLike(search) { const milieux = await this.mapMilieux(); const searchLower = Grammar.toLowerCaseNoAccent(search); const keys = Object.keys(milieux).filter(it => it.includes(searchLower)); if (keys.length > 1) { const milieuExact = milieux[searchLower]; if (milieuExact) { return [milieuExact]; } } return keys.map(k => milieux[k]); } 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, formData) { const autresMilieux = await game.system.rdd.environnement.autresMilieux(sheet.item); 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: autresMilieux }); return formData; } static activateListeners(sheet, html) { if (!sheet.options.editable) return; html.find("input.input-selection-milieu").keypress(event => { if (event.keyCode == '13') { EnvironmentSheetHelper.onAddMilieu(html, sheet, event); } event.stopPropagation(); }) 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 => EnvironmentSheetHelper.$changeRarete(event, updated))); html.find("div.environnement-milieu input[name='environnement-frequence']").change(event => EnvironmentSheetHelper.onChange(sheet, event, updated => EnvironmentSheetHelper.$changeFrequence(updated, event))); } static $changeFrequence(updated, event) { updated.frequence = Number($(event.currentTarget).val()); } static $changeRarete(event, updated) { const name = $(event.currentTarget).val(); const rarete = Environnement.getRarete(name); updated.rarete = rarete.name; updated.frequence = rarete.frequence; // updated.frequence = Math.min( // Math.max(rarete.min, updated.frequence ?? rarete.frequence), // rarete.max); } 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 != undefined) { 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; } }