import { SYSTEM_RDD } from "./constants.js"; import { Grammar } from "./grammar.js"; import { Misc } from "./misc.js"; import { CompendiumTableHelpers, CompendiumTable } from "./settings/system-compendiums.js"; import { RdDRaretes } from "./tirage/raretes.js"; 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', 'plante', 'ingredient', 'faune' ] export class Environnement { static typesEnvironnement(){ return ITEM_ENVIRONNEMENT_TYPES } 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) } 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, filter) { if (!milieux){ milieux = await this.milieux() } const frequence = item => item.getRarete(milieux)?.frequence ?? 0; return await this.table.buildTable(frequence, it => frequence(it) > 0 && filter(it)); } async getElements(itemFrequence, filter) { return await this.table.getContent(itemFrequence, filter); } } export class EnvironmentSheetHelper { static defaultOptions(defaultOptions) { return mergeObject(defaultOptions, { tabs: [{ navSelector: ".sheet-tabs", contentSelector: ".sheet-body", initial: "informations" }] }); } 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) { return mergeObject(formData, { milieux: await game.system.rdd.environnement.autresMilieux(sheet.item) }); } static activateListeners(sheet) { if (!sheet.options.editable) return; sheet.html.find("input.input-selection-milieu").keypress(event => { if (event.keyCode == '13') { EnvironmentSheetHelper.onAddMilieu(sheet, event); } event.stopPropagation(); }) sheet.html.find("a.milieu-add").click(event => EnvironmentSheetHelper.onAddMilieu(sheet, event)); sheet.html.find("div.environnement-milieu a.milieu-delete").click(event => EnvironmentSheetHelper.onDeleteMilieu(sheet, event)); sheet.html.find("div.environnement-milieu select.environnement-rarete").change(event => EnvironmentSheetHelper.onChange(sheet, event, updated => EnvironmentSheetHelper.$changeRarete(sheet, event, updated))); sheet.html.find("div.environnement-milieu input[name='environnement-frequence']").change(event => EnvironmentSheetHelper.onChange(sheet, event, updated => EnvironmentSheetHelper.$changeFrequence(sheet, event, updated))); } static $changeFrequence(sheet, event, updated) { updated.frequence = Number(sheet.html.find(event.currentTarget).val()); } static $changeRarete(sheet, event, updated) { const name = sheet.html.find(event.currentTarget).val(); const rarete = RdDRaretes.getRarete(name); updated.rarete = rarete.code; updated.frequence = rarete.frequence; } static async onAddMilieu(sheet, event) { const milieu = sheet.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 = RdDRaretes.getRarete(); const newList = [...list, { milieu, rarete: rarete.code, 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(sheet, 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(sheet, 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(sheet, event) { return sheet.html.find(event.currentTarget)?.parents("div.environnement-milieu").data("milieu"); } }