Vincent Vandemeulebrouck
86f69566a6
Dans la fenêtre de recherche, possibilité de chercher sur le nom des objets en plus des autres critères
360 lines
15 KiB
JavaScript
360 lines
15 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 '../item/raretes.js';
|
|
import { Grammar } from '../grammar.js';
|
|
|
|
const FILTER_GROUPS = [
|
|
{ group: 'type', label: "Type d'objet" },
|
|
{ group: 'comestible', label: 'Alimentaire' },
|
|
{ group: 'utilisation', label: 'Utilisation' },
|
|
{ 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, milieux) => item.getUtilisation() == 'cuisine' },
|
|
{ group: 'comestible', code: 'pret', label: 'Préparé', check: (item, milieux) => item.getUtilisationCuisine() == 'pret' },
|
|
{ group: 'comestible', code: 'brut', label: 'A préparer', check: (item, milieux) => item.getUtilisationCuisine() == 'brut' },
|
|
{ group: 'comestible', code: 'boisson', label: 'Boisson', check: (item, milieux) => item.isBoisson() },
|
|
{ group: 'comestible', code: 'alcool', label: 'Alcool', check: (item, milieux) => item.isAlcool() },
|
|
{ group: 'comestible', code: 'immangeable', label: 'Immangeable', check: (item, milieux) => item.isInventaire() && item.getUtilisation() != 'cuisine' },
|
|
|
|
{ group: 'utilisation', code: 'alchimie', label: 'Alchimique', check: (item, milieux) => item.isInventaire() && item.getUtilisation() == 'alchimie' },
|
|
{ group: 'utilisation', code: 'soins', label: 'Médical', check: (item, milieux) => item.isInventaire() && item.getUtilisation() == 'soins' },
|
|
{ group: 'utilisation', code: 'poison', label: 'Toxique', check: (item, milieux) => item.isInventaire() && item.getUtilisation() == 'poison' },
|
|
{ group: 'utilisation', code: 'cuisine', label: 'Cuisine', check: (item, milieux) => item.isInventaire() && item.getUtilisation() == 'cuisine' },
|
|
{ group: 'utilisation', code: 'autres', label: 'Autres/inconnu', check: (item, milieux) => !item.isInventaire() || item.getUtilisation() == '' },
|
|
|
|
{ group: "qualite", code: "mauvaise", label: "Mauvaise (négative)", check: (item, milieux) => item.isInventaire() && item.system.qualite < 0 },
|
|
{ group: "qualite", code: "quelconque", label: "Quelconque (0)", check: (item, milieux) => item.isInventaire() && item.system.qualite == 0 },
|
|
{ group: "qualite", code: "correcte", label: "Correcte (1-3)", check: (item, milieux) => item.isInventaire() && 1 <= item.system.qualite && item.system.qualite <= 3 },
|
|
{ group: "qualite", code: "bonne", label: "Bonne (4-6)", check: (item, milieux) => item.isInventaire() && 4 <= item.system.qualite && item.system.qualite <= 6 },
|
|
{ group: "qualite", code: "excellente", label: "Excellente (7-9)", check: (item, milieux) => item.isInventaire() && 7 <= item.system.qualite && item.system.qualite <= 9 },
|
|
{ group: "qualite", code: "mythique", label: "Mythique (10+)", check: (item, milieux) => item.isInventaire() && 10 <= item.system.qualite },
|
|
|
|
{ group: "enc", code: "negligeable", label: "Négligeable (jusqu'à 0.1)", check: (item, milieux) => item.isInventaire() && item.system.encombrement <= 0.1 },
|
|
{ group: "enc", code: "leger", label: "Léger (0.1 à 0.5)", check: (item, milieux) => item.isInventaire() && 0.1 < item.system.encombrement && item.system.encombrement <= 0.5 },
|
|
{ group: "enc", code: "moyen", label: "Moyen (0.5 à 1.5)", check: (item, milieux) => item.isInventaire() && 0.5 < item.system.encombrement && item.system.encombrement <= 1.5 },
|
|
{ group: "enc", code: "lourd", label: "Lourd (1.5 à 3)", check: (item, milieux) => item.isInventaire() && 1.5 < item.system.encombrement && item.system.encombrement <= 3 },
|
|
{ group: "enc", code: "massif", label: "Massif (3 à 10)", check: (item, milieux) => item.isInventaire() && 3 < item.system.encombrement && item.system.encombrement <= 10 },
|
|
{ group: "enc", code: "anemort", label: "Un âne mort (plus de 10)", check: (item, milieux) => item.isInventaire() && 10 < item.system.encombrement },
|
|
|
|
{ group: "prix", code: "gratuit", label: "Gratuit", check: (item, milieux) => item.isInventaire() && item.system.cout == 0 },
|
|
{ group: "prix", code: "deniers", label: "Deniers (étain)", check: (item, milieux) => item.isInventaire() && 0 < item.system.cout && item.system.cout < 0.1 },
|
|
{ group: "prix", code: "bronze", label: "Sous (bronze)", check: (item, milieux) => item.isInventaire() && 0.1 <= item.system.cout && item.system.cout < 1 },
|
|
{ group: "prix", code: "sols", label: "Sols (argent)", check: (item, milieux) => item.isInventaire() && 1 <= item.system.cout && item.system.cout < 10 },
|
|
{ group: "prix", code: "dragons", label: "Dragons (or)", check: (item, milieux) => item.isInventaire() && 10 <= item.system.cout },
|
|
]
|
|
|
|
|
|
function $filterMilieux(milieux) {
|
|
return milieux.map(m => {
|
|
return {
|
|
code: m,
|
|
label: m,
|
|
check: (item, milieux) => 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, milieux) => item.getRaretes(milieux).map(it => it.code).includes(r.code)
|
|
}
|
|
});
|
|
}
|
|
|
|
function $filterTypes() {
|
|
return RdDItem.getItemTypesInventaire().map(type => {
|
|
return {
|
|
group: 'type',
|
|
code: type,
|
|
label: Misc.typeName('Item', type),
|
|
check: (item, milieux) => item.type == type
|
|
};
|
|
});
|
|
}
|
|
|
|
function $getAllFilters() {
|
|
return FILTERS
|
|
.concat($filterTypes())
|
|
.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 milieux = await game.system.rdd.environnement.milieux();
|
|
const parameters = {
|
|
milieux: milieux,
|
|
filterMilieux: $filterMilieux(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() {
|
|
return mergeObject(await super.getData(), this.parameters)
|
|
}
|
|
|
|
_canDragStart() { return true; }
|
|
_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;
|
|
|
|
this.showFilterGroup(this.html, false);
|
|
|
|
this.html.find("a.section-filters-toggle").click(event => {
|
|
const groupDiv = this.html.find(event.currentTarget)?.parents('div.section-filters-root').first();
|
|
const visible = groupDiv.find('div.section-filters-content').first().is(":visible");
|
|
this.showFilterGroup(groupDiv, !visible)
|
|
});
|
|
|
|
this.html.find("input:is(.activate-filter-group,.activate-filter-milieu)").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');
|
|
})
|
|
|
|
// this.html.find('.recherche')
|
|
// .each((index, field) => {
|
|
// if (this.options.recherche) {
|
|
// field.focus();
|
|
// field.setSelectionRange(this.options.recherche.start, this.options.recherche.end);
|
|
// }
|
|
// })
|
|
// .keyup(async event => {
|
|
// const nouvelleRecherche = this._optionRecherche(event.currentTarget);
|
|
// if (this.options.recherche?.text != nouvelleRecherche?.text) {
|
|
// this.options.recherche = nouvelleRecherche;
|
|
// if (this.timerRecherche) {
|
|
// clearTimeout(this.timerRecherche);
|
|
// }
|
|
// this.timerRecherche = setTimeout(() => {
|
|
// this.timerRecherche = undefined;
|
|
// this.render(true);
|
|
// }, 500);
|
|
// }
|
|
// })
|
|
// .change(async event =>
|
|
// this.options.recherche = this._optionRecherche(event.currentTarget)
|
|
// );
|
|
}
|
|
|
|
showFilterGroup(groupDiv, show) {
|
|
if (groupDiv) {
|
|
HtmlUtility.showControlWhen(groupDiv.find('div.section-filters-content'), show);
|
|
HtmlUtility.showControlWhen(groupDiv.find('i.section-filters-hide'), show);
|
|
HtmlUtility.showControlWhen(groupDiv.find('i.section-filters-show'), !show);
|
|
}
|
|
}
|
|
|
|
supprimerFiltres() {
|
|
this.html.find('input:is(.activate-filter-group,.activate-filter-milieu)').prop("checked", false);
|
|
this.html.find('div.liste-resultats-recherche').html('');
|
|
this.html.find('.section-filters-text input.recherche').val('');
|
|
}
|
|
|
|
async recherche() {
|
|
const table = await this.buildTable();
|
|
const htmlResultats = await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats-recherche.hbs`, { resultats: table });
|
|
this.html.find('div.liste-resultats-recherche').html(htmlResultats);
|
|
this._dragDrop.forEach(dragDropHandler => dragDropHandler.bind(this.element[0]))
|
|
}
|
|
|
|
async buildTable() {
|
|
const milieux = this.getSelectedMilieux();
|
|
const filterItemMilieux = this.buildCheckedGroupFilter(milieux);
|
|
const filter = it => filterItemMilieux(it, milieux);
|
|
const itemFrequence = it => it.getFrequence(milieux);
|
|
return await game.system.rdd.environnement.buildTable(itemFrequence, filter)
|
|
}
|
|
|
|
buildMilieuxFilter(milieux) {
|
|
if (milieux) {
|
|
return this.buildOrFilter(this.parameters.filterMilieux.filter(it => milieux.includes(it.code)).map(f => f.check));
|
|
}
|
|
return (it, mi) => true;
|
|
}
|
|
buildFilterRechercheName() {
|
|
const recherche = this.html.find('.section-filters-text input.recherche').val();
|
|
if (recherche) {
|
|
return (it, mi) => Grammar.includesLowerCaseNoAccent(it.name, recherche);
|
|
}
|
|
return (it, mi) => true;
|
|
}
|
|
|
|
buildCheckedGroupFilter(milieux) {
|
|
const filtersList = this.getGroupCheckedFilters()
|
|
.map(gf => this.buildOrFilter(gf.filters.map(f => f.check)));
|
|
filtersList.push(this.buildMilieuxFilter(milieux));
|
|
filtersList.push(this.buildFilterRechercheName());
|
|
return this.buildAndFilter(filtersList)
|
|
}
|
|
|
|
buildAndFilter(filters) { return filters.reduce((f1, f2) => { return (it, mi) => f1(it, mi) && f2(it, mi); }); }
|
|
buildOrFilter(filters) { return filters.reduce((f1, f2) => { return (it, mi) => f1(it, mi) || f2(it, mi); }); }
|
|
|
|
changeListeFiltresActifs() {
|
|
const milieux = this.getSelectedMilieux();
|
|
const summariesList = this.getGroupCheckedFilters()
|
|
.map(gf => {
|
|
return gf.group.label + ': ' + gf.filters
|
|
.map(f => f.label)
|
|
.reduce(Misc.joining(', '))
|
|
});
|
|
if (milieux) {
|
|
summariesList.push('Milieux: ' + this.parameters.filterMilieux.filter(f => milieux.includes(f.code)).map(f => f.label).reduce(Misc.joining(', ')))
|
|
}
|
|
const fullText = summariesList.length == 0 ? "" : summariesList.reduce(Misc.joining(' - '));
|
|
this.html.find('span.liste-filtres-actifs').text(fullText);
|
|
}
|
|
|
|
getGroupCheckedFilters() {
|
|
const checkedGroupFilters = jQuery.map(this.html.find('input.activate-filter-group:checked'), it => this.html.find(it))
|
|
.map(element => {
|
|
return {
|
|
group: element.data('group'),
|
|
code: element.data('code')
|
|
};
|
|
}).filter(it => it.group);
|
|
|
|
const entries = Object.entries(Misc.classify(checkedGroupFilters, it => it.group));
|
|
return entries.map(([key, list]) => {
|
|
const group = this.parameters.filterGroups.find(g => g.group == key);
|
|
const filters = list.map(it => group.filters.find(f => it.code == f.code));
|
|
return { group, filters };
|
|
});
|
|
}
|
|
|
|
getSelectedMilieux() {
|
|
const milieux = jQuery.map(this.html.find('input.activate-filter-milieu:checked'), it => {
|
|
return this.html.find(it).data('code');
|
|
});
|
|
return milieux.length == 0 ? undefined : milieux
|
|
}
|
|
|
|
|
|
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();
|
|
}
|
|
}
|