2023-01-13 04:54:29 +01:00
import { RdDItem } from '../item.js' ;
import { HtmlUtility } from '../html-utility.js' ;
import { Misc } from "../misc.js" ;
2023-01-18 00:11:10 +01:00
import { CompendiumTableHelpers } from '../settings/system-compendiums.js' ;
2023-01-18 01:37:22 +01:00
import { RdDRaretes } from '../item/raretes.js' ;
2023-01-30 22:07:15 +01:00
import { Grammar } from '../grammar.js' ;
2023-01-13 04:54:29 +01:00
const FILTER _GROUPS = [
{ group : 'type' , label : "Type d'objet" } ,
{ group : 'comestible' , label : 'Alimentaire' } ,
2023-01-20 23:45:57 +01:00
{ group : 'utilisation' , label : 'Utilisation' } ,
2023-01-13 04:54:29 +01:00
{ group : 'rarete' , label : 'Rarete' } ,
{ group : 'qualite' , label : 'Qualité' } ,
{ group : 'enc' , label : 'Encombrement' } ,
{ group : 'prix' , label : 'Prix' } ,
]
const FILTERS = [
2023-01-20 03:25:40 +01:00
{ 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' } ,
2023-01-20 23:45:57 +01:00
{ 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 ( ) == '' } ,
2023-01-20 03:25:40 +01:00
{ 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 } ,
2023-01-13 04:54:29 +01:00
]
2023-01-17 21:51:49 +01:00
function $filterMilieux ( milieux ) {
2023-01-20 03:25:40 +01:00
return milieux . map ( m => {
return {
code : m ,
label : m ,
check : ( item , milieux ) => item . isPresentDansMilieux ( m )
}
} )
2023-01-17 21:51:49 +01:00
}
function $filterRarete ( ) {
return RdDRaretes . raretes ( )
. filter ( it => it . frequence > 0 )
2023-01-20 03:25:40 +01:00
. map ( r => {
return {
group : 'rarete' ,
code : r . code ,
label : r . label ,
check : ( item , milieux ) => item . getRaretes ( milieux ) . map ( it => it . code ) . includes ( r . code )
}
} ) ;
2023-01-17 21:51:49 +01:00
}
function $filterTypes ( ) {
2023-01-20 03:25:40 +01:00
return RdDItem . getItemTypesInventaire ( ) . map ( type => {
return {
group : 'type' ,
code : type ,
label : Misc . typeName ( 'Item' , type ) ,
check : ( item , milieux ) => item . type == type
} ;
} ) ;
2023-01-17 21:51:49 +01:00
}
2023-01-20 03:25:40 +01:00
function $getAllFilters ( ) {
2023-01-17 21:51:49 +01:00
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 ) ) ;
}
2023-01-13 04:54:29 +01:00
export class FenetreRechercheTirage extends Application {
static get defaultOptions ( ) {
2024-05-01 09:13:21 +02:00
return foundry . utils . mergeObject ( super . defaultOptions , {
2023-01-13 04:54:29 +01:00
template : "systems/foundryvtt-reve-de-dragon/templates/tirage/fenetre-recherche-tirage.hbs" ,
title : ` Recherches et tirages ` ,
width : 600 ,
height : 600 ,
popOut : true ,
2023-01-15 23:21:19 +01:00
dragDrop : [ { dragSelector : "a.content-link" } ] ,
2023-01-13 04:54:29 +01:00
resizable : true
2024-06-01 01:53:14 +02:00
} , { inplace : false } )
2023-01-13 04:54:29 +01:00
}
2023-01-17 21:51:49 +01:00
static async create ( ) {
2023-01-20 03:25:40 +01:00
const milieux = await game . system . rdd . environnement . milieux ( ) ;
2023-01-17 21:51:49 +01:00
const parameters = {
2023-01-20 03:25:40 +01:00
milieux : milieux ,
filterMilieux : $filterMilieux ( milieux ) ,
2024-05-02 14:08:02 +02:00
filterGroups : foundry . utils . duplicate ( FILTER _GROUPS ) . filter ( it => it . group ) ,
2023-01-17 21:51:49 +01:00
}
const options = { }
$loadFilters ( parameters ) ;
2023-01-13 04:54:29 +01:00
2023-01-17 21:51:49 +01:00
new FenetreRechercheTirage ( parameters , options ) . render ( true ) ;
2023-01-13 04:54:29 +01:00
}
2023-01-17 21:51:49 +01:00
constructor ( parameters , options ) {
super ( options ) ;
this . parameters = parameters ;
2023-01-13 04:54:29 +01:00
}
async getData ( ) {
2024-05-01 09:13:21 +02:00
return foundry . utils . mergeObject ( await super . getData ( ) , this . parameters )
2023-01-13 04:54:29 +01:00
}
2023-01-20 03:25:40 +01:00
_canDragStart ( ) { return true ; }
_onDragStart ( event ) { }
2023-01-17 21:51:49 +01:00
_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
}
2023-01-13 04:54:29 +01:00
activateListeners ( html ) {
super . activateListeners ( html ) ;
this . html = html ;
2023-01-20 03:25:40 +01:00
this . showFilterGroup ( this . html , false ) ;
2023-01-13 04:54:29 +01:00
2023-01-20 03:25:40 +01:00
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" ) ;
2023-01-13 04:54:29 +01:00
this . showFilterGroup ( groupDiv , ! visible )
} ) ;
2023-01-20 03:25:40 +01:00
this . html . find ( "input:is(.activate-filter-group,.activate-filter-milieu)" ) . change ( event => this . changeListeFiltresActifs ( ) )
2023-01-13 04:54:29 +01:00
2023-01-15 23:30:32 +01:00
this . html . find ( "a.supprimer-filtres" ) . click ( async event => this . supprimerFiltres ( ) )
2023-01-13 04:54:29 +01:00
2023-01-15 23:21:19 +01:00
this . html . find ( "a.recherche-filtres" ) . click ( async event => await this . recherche ( ) )
2023-01-13 04:54:29 +01:00
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' ) ;
} )
}
2023-01-20 03:25:40 +01:00
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 ) ;
}
}
2023-01-15 23:30:32 +01:00
supprimerFiltres ( ) {
2023-01-20 03:25:40 +01:00
this . html . find ( 'input:is(.activate-filter-group,.activate-filter-milieu)' ) . prop ( "checked" , false ) ;
2023-01-30 22:07:15 +01:00
this . html . find ( 'div.liste-resultats-recherche' ) . html ( '' ) ;
this . html . find ( '.section-filters-text input.recherche' ) . val ( '' ) ;
2023-01-15 23:30:32 +01:00
}
2023-01-15 23:21:19 +01:00
async recherche ( ) {
const table = await this . buildTable ( ) ;
2023-01-30 22:07:15 +01:00
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 ) ;
2023-01-15 23:21:19 +01:00
this . _dragDrop . forEach ( dragDropHandler => dragDropHandler . bind ( this . element [ 0 ] ) )
}
2023-01-13 04:54:29 +01:00
async buildTable ( ) {
2023-01-20 03:25:40 +01:00
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 )
2023-01-13 04:54:29 +01:00
}
2023-01-20 03:25:40 +01:00
buildMilieuxFilter ( milieux ) {
if ( milieux ) {
return this . buildOrFilter ( this . parameters . filterMilieux . filter ( it => milieux . includes ( it . code ) ) . map ( f => f . check ) ) ;
2023-01-13 04:54:29 +01:00
}
2023-01-20 03:25:40 +01:00
return ( it , mi ) => true ;
2023-01-13 04:54:29 +01:00
}
2023-01-30 22:07:15 +01:00
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 ;
}
2023-01-13 04:54:29 +01:00
2023-01-20 03:25:40 +01:00
buildCheckedGroupFilter ( milieux ) {
const filtersList = this . getGroupCheckedFilters ( )
. map ( gf => this . buildOrFilter ( gf . filters . map ( f => f . check ) ) ) ;
2023-01-30 22:07:15 +01:00
filtersList . push ( this . buildMilieuxFilter ( milieux ) ) ;
filtersList . push ( this . buildFilterRechercheName ( ) ) ;
2023-01-20 03:25:40 +01:00
return this . buildAndFilter ( filtersList )
2023-01-13 04:54:29 +01:00
}
2023-01-20 03:25:40 +01:00
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 ) ; } ) ; }
2023-01-13 04:54:29 +01:00
changeListeFiltresActifs ( ) {
2023-01-20 03:25:40 +01:00
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 ( ' - ' ) ) ;
2023-01-13 04:54:29 +01:00
this . html . find ( 'span.liste-filtres-actifs' ) . text ( fullText ) ;
}
2023-01-20 03:25:40 +01:00
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 } ;
2023-01-13 04:54:29 +01:00
} ) ;
2023-01-17 21:51:49 +01:00
}
2023-01-20 03:25:40 +01:00
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
}
2023-01-17 21:51:49 +01:00
async configurer ( ) {
2023-01-18 00:11:10 +01:00
FenetreRechercheConfiguration . create ( ) ;
2023-01-17 21:51:49 +01:00
}
}
class FenetreRechercheConfiguration extends Dialog {
2023-01-18 00:11:10 +01:00
static async create ( ) {
const configuration = {
compendiums : game . packs . filter ( it => it . metadata . type == 'Item' ) . map ( it => it . metadata )
2024-05-01 09:13:21 +02:00
. map ( it => foundry . utils . mergeObject ( { selected : game . system . rdd . environnement . compendiums . includes ( it . id ) } , it ) )
2023-01-18 00:11:10 +01:00
}
2023-01-17 21:51:49 +01:00
const html = await renderTemplate ( "systems/foundryvtt-reve-de-dragon/templates/tirage/fenetre-recherche-configuration.hbs" , configuration ) ;
2023-01-18 00:11:10 +01:00
new FenetreRechercheConfiguration ( html ) . render ( true ) ;
2023-01-17 21:51:49 +01:00
}
2023-01-18 00:11:10 +01:00
constructor ( html ) {
2023-01-17 21:51:49 +01:00
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 : {
2023-01-18 00:11:10 +01:00
"Sauvegarder" : { label : "Sauvegarder" , callback : async it => { await this . sauvegarder ( ) ; } }
2023-01-17 21:51:49 +01:00
}
} ;
super ( conf , options )
}
2023-01-18 00:11:10 +01:00
2023-01-17 21:51:49 +01:00
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' ) ;
} ) ;
2023-01-18 00:11:10 +01:00
await game . system . rdd . environnement . saveCompendiums ( compendiumIds ) ;
this . close ( ) ;
2023-01-13 04:54:29 +01:00
}
2023-01-17 21:51:49 +01:00
}