289 lines
12 KiB
JavaScript
289 lines
12 KiB
JavaScript
import { RdDItem } from '../item.js';
|
|
import { HtmlUtility } from '../html-utility.js';
|
|
import { Misc } from "../misc.js";
|
|
import { CompendiumTableHelpers } from '../settings/system-compendiums.js';
|
|
import { RdDRaretes } from './raretes.js';
|
|
|
|
const FILTER_GROUPS = [
|
|
{ group: 'type', label: "Type d'objet" },
|
|
{ group: 'comestible', label: 'Alimentaire' },
|
|
{ group: 'categorie', label: 'Utilisation' },
|
|
{ group: 'milieu', label: 'Milieu' },
|
|
{ group: 'rarete', label: 'Rarete' },
|
|
{ group: 'qualite', label: 'Qualité' },
|
|
{ group: 'enc', label: 'Encombrement' },
|
|
{ group: 'prix', label: 'Prix' },
|
|
]
|
|
|
|
const FILTERS = [
|
|
{ group: 'comestible', code: 'comestible', label: 'Comestible', check: item => item.getUtilisation() == 'cuisine' },
|
|
{ group: 'comestible', code: 'pret', label: 'Préparé', check: item => item.getUtilisationCuisine() == 'pret' },
|
|
{ group: 'comestible', code: 'brut', label: 'A préparer', check: item => item.getUtilisationCuisine() == 'brut' },
|
|
{ group: 'comestible', code: 'boisson', label: 'Boisson', check: item => item.isBoisson() },
|
|
{ group: 'comestible', code: 'alcool', label: 'Alcool', check: item => item.isAlcool() },
|
|
{ group: 'comestible', code: 'immangeable', label: 'Immangeable', check: item => item.isInventaire() && item.getUtilisation() != 'cuisine' },
|
|
|
|
{ group: 'categorie', code: 'alchimie', label: 'Alchimique', check: item => item.isInventaire() && item.getUtilisation() == 'alchimie' },
|
|
{ group: 'categorie', code: 'soins', label: 'Médical', check: item => item.isInventaire() && item.getUtilisation() == 'soins' },
|
|
{ group: 'categorie', code: 'poison', label: 'Toxique', check: item => item.isInventaire() && item.getUtilisation() == 'poison' },
|
|
{ group: 'categorie', code: 'autres', label: 'Autres', check: item => !item.isInventaire() || item.getUtilisation() == '' },
|
|
|
|
{ group: "qualite", code: "mauvaise", label: "Mauvaise (négative)", check: item => item.isInventaire() && item.system.qualite < 0 },
|
|
{ group: "qualite", code: "quelconque", label: "Quelconque (0)", check: item => item.isInventaire() && item.system.qualite == 0 },
|
|
{ group: "qualite", code: "correcte", label: "Correcte (1-3)", check: item => item.isInventaire() && 1 <= item.system.qualite && item.system.qualite <= 3 },
|
|
{ group: "qualite", code: "bonne", label: "Bonne (4-6)", check: item => item.isInventaire() && 4 <= item.system.qualite && item.system.qualite <= 6 },
|
|
{ group: "qualite", code: "excellente", label: "Excellente (7-9)", check: item => item.isInventaire() && 7 <= item.system.qualite && item.system.qualite <= 9 },
|
|
{ group: "qualite", code: "mythique", label: "Mythique (10+)", check: item => item.isInventaire() && 10 <= item.system.qualite },
|
|
|
|
{ group: "enc", code: "negligeable", label: "Négligeable (jusqu'à 0.1)", check: item => item.isInventaire() && item.system.encombrement <= 0.1 },
|
|
{ group: "enc", code: "leger", label: "Léger (0.1 à 0.5)", check: item => item.isInventaire() && 0.1 < item.system.encombrement && item.system.encombrement <= 0.5 },
|
|
{ group: "enc", code: "moyen", label: "Moyen (0.5 à 1.5)", check: item => item.isInventaire() && 0.5 < item.system.encombrement && item.system.encombrement <= 1.5 },
|
|
{ group: "enc", code: "lourd", label: "Lourd (1.5 à 3)", check: item => item.isInventaire() && 1.5 < item.system.encombrement && item.system.encombrement <= 3 },
|
|
{ group: "enc", code: "massif", label: "Massif (3 à 10)", check: item => item.isInventaire() && 3 < item.system.encombrement && item.system.encombrement <= 10 },
|
|
{ group: "enc", code: "anemort", label: "Un âne mort (plus de 10)", check: item => item.isInventaire() && 10 < item.system.encombrement },
|
|
|
|
{ group: "prix", code: "gratuit", label: "Gratuit", check: item => item.isInventaire() && item.system.cout == 0 },
|
|
{ group: "prix", code: "deniers", label: "Deniers (étain)", check: item => item.isInventaire() && 0 < item.system.cout && item.system.cout < 0.1 },
|
|
{ group: "prix", code: "bronze", label: "Sous (bronze)", check: item => item.isInventaire() && 0.1 <= item.system.cout && item.system.cout < 1 },
|
|
{ group: "prix", code: "sols", label: "Sols (argent)", check: item => item.isInventaire() && 1 <= item.system.cout && item.system.cout < 10 },
|
|
{ group: "prix", code: "dragons", label: "Dragons (or)", check: item => item.isInventaire() && 10 <= item.system.cout },
|
|
]
|
|
|
|
|
|
function $typeToFilter(type) { return { group: 'type', code: type, label: Misc.typeName('Item', type), check: item => item.type == type }; }
|
|
|
|
function $filterMilieux(milieux) {
|
|
return milieux.map(m => { return { group: 'milieu', code: m, label: m, check: item => item.isPresentDansMilieux(m) } })
|
|
}
|
|
|
|
function $filterRarete() {
|
|
return RdDRaretes.raretes()
|
|
.filter(it => it.frequence > 0)
|
|
.map(r => { return { group: 'rarete', code: r.code, label: r.label, check: item => item.getRarete()?.code == r.code }; });
|
|
}
|
|
|
|
function $filterTypes() {
|
|
return RdDItem.getItemTypesInventaire().map(it => $typeToFilter(it));
|
|
}
|
|
|
|
function $getAllFilters(milieux) {
|
|
return FILTERS
|
|
.concat($filterTypes())
|
|
.concat($filterMilieux(milieux))
|
|
.concat($filterRarete());
|
|
}
|
|
|
|
function $addFilterToGroup(groups, filter) {
|
|
if (filter.group && filter.code && filter.label) {
|
|
let fg = groups.find(g => g.group == filter.group);
|
|
if (fg == undefined) {
|
|
groups.push({ group: filter.group, label: filter.group, filters: [filter] })
|
|
}
|
|
else if (fg.filters == undefined) {
|
|
fg.filters = [filter];
|
|
}
|
|
else {
|
|
fg.filters.push(filter);
|
|
}
|
|
}
|
|
else {
|
|
console.warn("Filtre incorrect, pas de groupe/code/label", filter);
|
|
}
|
|
}
|
|
|
|
function $loadFilters(parameters) {
|
|
$getAllFilters(parameters.milieux).forEach(f => $addFilterToGroup(parameters.filterGroups, f));
|
|
}
|
|
|
|
|
|
|
|
export class FenetreRechercheTirage extends Application {
|
|
static get defaultOptions() {
|
|
return mergeObject(super.defaultOptions, {
|
|
template: "systems/foundryvtt-reve-de-dragon/templates/tirage/fenetre-recherche-tirage.hbs",
|
|
title: `Recherches et tirages`,
|
|
width: 600,
|
|
height: 600,
|
|
popOut: true,
|
|
dragDrop: [{ dragSelector: "a.content-link" }],
|
|
resizable: true
|
|
});
|
|
}
|
|
|
|
static async create() {
|
|
const parameters = {
|
|
milieux: await game.system.rdd.environnement.milieux(),
|
|
filterGroups: duplicate(FILTER_GROUPS).filter(it => it.group),
|
|
}
|
|
const options = {}
|
|
$loadFilters(parameters);
|
|
|
|
new FenetreRechercheTirage(parameters, options).render(true);
|
|
}
|
|
|
|
constructor(parameters, options) {
|
|
super(options);
|
|
this.parameters = parameters;
|
|
}
|
|
|
|
async getData() {
|
|
let formData = super.getData();
|
|
mergeObject(formData, this.parameters)
|
|
return formData;
|
|
}
|
|
|
|
_canDragStart() {
|
|
return true;
|
|
}
|
|
_onDragStart(event) {
|
|
console.log('_onDragStart', event)
|
|
}
|
|
_getHeaderButtons() {
|
|
let buttons = super._getHeaderButtons();
|
|
if (game.user.isGM) {
|
|
buttons.unshift({
|
|
class: "configurer",
|
|
label: "Configurer",
|
|
icon: "fas fa-cogs",
|
|
onclick: ev => this.configurer()
|
|
});
|
|
}
|
|
return buttons
|
|
}
|
|
|
|
activateListeners(html) {
|
|
super.activateListeners(html);
|
|
this.html = html;
|
|
|
|
HtmlUtility.showControlWhen(this.html.find('div.group-filters'), false);
|
|
HtmlUtility.showControlWhen(this.html.find('i.filter-group-hide'), false);
|
|
HtmlUtility.showControlWhen(this.html.find('i.filter-group-show'), true);
|
|
|
|
this.html.find("a.filter-group-toggle").click(event => {
|
|
const groupDiv = this.html.find(event.currentTarget)?.parents('div.filter-group').first();
|
|
const visible = groupDiv.find('div.group-filters').first().is(":visible");
|
|
this.showFilterGroup(groupDiv, !visible)
|
|
});
|
|
|
|
this.html.find("input.activate-filter").change(event => this.changeListeFiltresActifs())
|
|
|
|
this.html.find("a.supprimer-filtres").click(async event => this.supprimerFiltres())
|
|
|
|
this.html.find("a.recherche-filtres").click(async event => await this.recherche())
|
|
|
|
this.html.find("a.tirage-filtres").click(async event => {
|
|
const table = await this.buildTable();
|
|
const row = await CompendiumTableHelpers.getRandom(table, 'Item')
|
|
await CompendiumTableHelpers.tableRowToChatMessage(row, 'Item');
|
|
})
|
|
}
|
|
|
|
supprimerFiltres() {
|
|
this.html.find('div.liste-resultats').html('');
|
|
return this.html.find('input.activate-filter:checked').prop("checked", false);
|
|
}
|
|
|
|
async recherche() {
|
|
const table = await this.buildTable();
|
|
const htmlResultats = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats.hbs`, { resultats: table });
|
|
this.html.find('div.liste-resultats').html(htmlResultats);
|
|
this._dragDrop.forEach(dragDropHandler => dragDropHandler.bind(this.element[0]))
|
|
}
|
|
|
|
async buildTable() {
|
|
return await game.system.rdd.environnement.buildTable(it => it.getFrequence(), this.buildCheckedItemsFilter())
|
|
}
|
|
|
|
buildCheckedItemsFilter() {
|
|
const byGroup = this.getCheckedFiltersByGroup();
|
|
const groupSummaries = Object.entries(byGroup).map(([key, list]) => {
|
|
const group = this.parameters.filterGroups.find(g => key == g.group);
|
|
const filters = list.map(it => it.code).map(code => group.filters.find(f => code == f.code))
|
|
return filters
|
|
.map(f => f.check)
|
|
.reduce((a, b) => { return it => a(it) || b(it) });;
|
|
});
|
|
if (groupSummaries.length == 0) {
|
|
return it => true;
|
|
}
|
|
return groupSummaries.reduce((a, b) => { return it => a(it) && b(it) })
|
|
}
|
|
|
|
showFilterGroup(groupDiv, show) {
|
|
if (groupDiv) {
|
|
HtmlUtility.showControlWhen(groupDiv.find('div.group-filters'), show);
|
|
HtmlUtility.showControlWhen(groupDiv.find('i.filter-group-hide'), show);
|
|
HtmlUtility.showControlWhen(groupDiv.find('i.filter-group-show'), !show);
|
|
}
|
|
}
|
|
|
|
changeListeFiltresActifs() {
|
|
const byGroup = this.getCheckedFiltersByGroup();
|
|
const groupSummaries = Object.entries(byGroup).map(([key, list]) => {
|
|
const group = this.parameters.filterGroups.find(g => key == g.group);
|
|
const filters = list.map(it => it.code).map(code => group.filters.find(f => code == f.code))
|
|
return group.label + ': ' + filters
|
|
.map(f => f.label)
|
|
.reduce(Misc.joining(', '));;
|
|
});
|
|
const fullText = groupSummaries.length == 0 ? "" : groupSummaries.reduce(Misc.joining(' - '));
|
|
this.html.find('span.liste-filtres-actifs').text(fullText);
|
|
}
|
|
|
|
getCheckedFiltersByGroup() {
|
|
const selectedFilters = jQuery.map(this.html.find('input.activate-filter:checked'), it => {
|
|
const element = this.html.find(it);
|
|
return { group: element.data('group'), code: element.data('code') };
|
|
});
|
|
return Misc.classify(selectedFilters, it => it.group);
|
|
}
|
|
|
|
async configurer() {
|
|
FenetreRechercheConfiguration.create();
|
|
}
|
|
}
|
|
|
|
class FenetreRechercheConfiguration extends Dialog {
|
|
static async create() {
|
|
const configuration = {
|
|
compendiums: game.packs.filter(it => it.metadata.type == 'Item').map(it => it.metadata)
|
|
.map(it => mergeObject({ selected: game.system.rdd.environnement.compendiums.includes(it.id) }, it))
|
|
}
|
|
const html = await renderTemplate("systems/foundryvtt-reve-de-dragon/templates/tirage/fenetre-recherche-configuration.hbs", configuration);
|
|
new FenetreRechercheConfiguration(html).render(true);
|
|
}
|
|
|
|
constructor(html) {
|
|
const options = {
|
|
classes: ["fenetre-recherche-configuration"],
|
|
width: 600,
|
|
height: 'fit-content',
|
|
'max-height': 600,
|
|
height: 'fit-content',
|
|
'z-index': 99999
|
|
};
|
|
const conf = {
|
|
title: 'Configuration de la recherche',
|
|
content: html,
|
|
buttons: {
|
|
"Sauvegarder": { label: "Sauvegarder", callback: async it => { await this.sauvegarder(); } }
|
|
}
|
|
};
|
|
super(conf, options)
|
|
}
|
|
|
|
activateListeners(html) {
|
|
this.html = html;
|
|
super.activateListeners(html);
|
|
this.html.find("button.configuration-save").click(event => this.sauvegarder())
|
|
}
|
|
|
|
async sauvegarder() {
|
|
const compendiumIds = jQuery.map(this.html.find("input.select-compendium:checked"), it => {
|
|
return this.html.find(it).data('id');
|
|
});
|
|
await game.system.rdd.environnement.saveCompendiums(compendiumIds);
|
|
this.close();
|
|
}
|
|
}
|