Fenetre de recherche et tirage
This commit is contained in:
parent
0c36cf3c47
commit
162a6a04b8
@ -2,13 +2,7 @@ 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;
|
||||
import { RdDRaretes } from "./tirage/raretes.js";
|
||||
|
||||
const SETTINGS_LISTE_MILIEUX = "liste-milieux";
|
||||
const MILIEUX = [
|
||||
@ -44,15 +38,6 @@ export class Environnement {
|
||||
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());
|
||||
}
|
||||
@ -106,26 +91,20 @@ export class Environnement {
|
||||
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);
|
||||
async buildEnvironnementTable(milieux, filter) {
|
||||
if (!milieux){
|
||||
milieux = await this.milieux()
|
||||
}
|
||||
const itemFrequenceEnMilieu = item => itemRareteEnMilieu(item)?.frequence ?? 0;
|
||||
const isPresentEnMilieu = item => itemFrequenceEnMilieu(item) > 0;
|
||||
return await this.table.buildTable(itemFrequenceEnMilieu, isPresentEnMilieu);
|
||||
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" }]
|
||||
@ -170,12 +149,9 @@ export class EnvironmentSheetHelper {
|
||||
|
||||
static $changeRarete(sheet, event, updated) {
|
||||
const name = sheet.html.find(event.currentTarget).val();
|
||||
const rarete = Environnement.getRarete(name);
|
||||
updated.rarete = rarete.name;
|
||||
const rarete = RdDRaretes.getRarete(name);
|
||||
updated.rarete = rarete.code;
|
||||
updated.frequence = rarete.frequence;
|
||||
// updated.frequence = Math.min(
|
||||
// Math.max(rarete.min, updated.frequence ?? rarete.frequence),
|
||||
// rarete.max);
|
||||
}
|
||||
|
||||
static async onAddMilieu(sheet, event) {
|
||||
@ -190,8 +166,8 @@ export class EnvironmentSheetHelper {
|
||||
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))
|
||||
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 })
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { RdDHerbes } from "./rdd-herbes.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { SystemCompendiums } from "./settings/system-compendiums.js";
|
||||
import { RdDRaretes } from "./tirage/raretes.js";
|
||||
|
||||
const typesInventaireMateriel = [
|
||||
"arme",
|
||||
@ -32,6 +33,7 @@ const typesObjetsConnaissance = ["meditation", "recettealchimique", "sort"]
|
||||
const typesObjetsEffet = ["possession", "poison", "maladie"]
|
||||
const typesObjetsCompetence = ["competence", "competencecreature"]
|
||||
const typesObjetsTemporels = ["poison", "maladie", "queue", "ombre", "souffle", "signedraconique", "rencontre"]
|
||||
const typesEnvironnement = ['herbe', 'faune', 'ingredient'];
|
||||
const encBrin = 0.00005; // un brin = 1 décigramme = 1/10g = 1/10000kg = 1/20000 enc
|
||||
const encPepin = 0.0007; /* un pépin de gemme = 1/10 cm3 = 1/1000 l = 3.5/1000 kg = 7/2000 kg = 7/1000 enc
|
||||
densité 3.5 (~2.3 à 4, parfois plus) -- https://www.juwelo.fr/guide-des-pierres/faits-et-chiffres/
|
||||
@ -107,6 +109,12 @@ export class RdDItem extends Item {
|
||||
static getItemTypesInventaire(mode = 'materiel') {
|
||||
return typesInventaire[mode ?? 'materiel']
|
||||
}
|
||||
static getItemTypesDraconiques() {
|
||||
return typesObjetsDraconiques;
|
||||
}
|
||||
static getItemTypesEnvironnement() {
|
||||
return typesEnvironnement;
|
||||
}
|
||||
|
||||
static getTypesOeuvres() {
|
||||
return typesObjetsOeuvres
|
||||
@ -159,13 +167,46 @@ export class RdDItem extends Item {
|
||||
isCompetence() { return typesObjetsCompetence.includes(this.type) }
|
||||
isTemporel() { return typesObjetsTemporels.includes(this.type) }
|
||||
isOeuvre() { return typesObjetsOeuvres.includes(this.type) }
|
||||
isDraconique() { return typesObjetsDraconiques.includes(this.type) }
|
||||
isDraconique() { return RdDItem.getItemTypesDraconiques().includes(this.type) }
|
||||
isEffet() { return typesObjetsEffet.includes(this.type) }
|
||||
isConnaissance() { return typesObjetsConnaissance.includes(this.type) }
|
||||
|
||||
isInventaire(mode = 'materiel') { return RdDItem.getItemTypesInventaire(mode).includes(this.type); }
|
||||
isAlcool() { return this.isNourritureBoisson() && this.system.boisson && this.system.alcoolise; }
|
||||
isHerbeAPotion() { return this.type == 'herbe' && (this.system.categorie == 'Soin' || this.system.categorie == 'Repos'); }
|
||||
isEnvironnement() { return RdDItem.getItemTypesEnvironnement().includes(this.type) }
|
||||
|
||||
isPresentDansMilieux(milieux) {
|
||||
return this.getEnvironnements(milieux).length > 0
|
||||
}
|
||||
getEnvironnements(milieux = undefined) {
|
||||
return this.isEnvironnement()
|
||||
? this.system?.environnement.filter(env => !milieux || milieux.includes(env.milieu))
|
||||
: []
|
||||
}
|
||||
getEnvRarete(milieux = undefined) {
|
||||
if (this.isEnvironnement()) {
|
||||
const list = this.getEnvironnements(milieux);
|
||||
const frequenceMax = Math.max(...list.map(env => env.frequence));
|
||||
return list.find(env => env.frequence == frequenceMax);
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
getRarete(milieux = undefined) {
|
||||
if (this.isEnvironnement()) {
|
||||
const env = this.getEnvRarete(milieux);
|
||||
return RdDRaretes.getRarete(env.rarete);
|
||||
}
|
||||
if (this.isInventaire()) {
|
||||
return RdDRaretes.rareteEquipement(this)
|
||||
}
|
||||
return RdDRaretes.getRareteFrequente();
|
||||
}
|
||||
getFrequence(milieux = undefined) {
|
||||
const frequence = this.getRarete(milieux)?.frequence;
|
||||
return frequence == undefined ? 1 : frequence;
|
||||
}
|
||||
|
||||
getItemGroup() {
|
||||
if (this.isInventaire()) return "equipement";
|
||||
|
@ -5,6 +5,7 @@ import { Grammar } from "./grammar.js";
|
||||
import { Monnaie } from "./item-monnaie.js";
|
||||
import { RdDItem } from "./item.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDRaretes } from "./tirage/raretes.js";
|
||||
|
||||
class Migration {
|
||||
get code() { return "sample"; }
|
||||
@ -288,10 +289,11 @@ class _10_3_0_FrequenceEnvironnement extends Migration {
|
||||
}
|
||||
|
||||
_updatesFrequences(it) {
|
||||
const rarete = RdDRaretes.getRarete(it.system.rarete);
|
||||
return {
|
||||
_id: it.id,
|
||||
'system.rarete': undefined,
|
||||
'system.environnement': [{ milieu: it.system.milieu, rarete: it.system.rarete, frequence: Environnement.getFrequenceRarete(it.system.rarete, 'frequence') }]
|
||||
'system.environnement': [{ milieu: it.system.milieu, rarete: rarete.code, frequence: rarete.frequence }]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import { RdDRollResolutionTable } from "./rdd-roll-resolution-table.js";
|
||||
import { RdDRollTables } from "./rdd-rolltables.js";
|
||||
import { RdDUtility } from "./rdd-utility.js";
|
||||
import { CompendiumTableHelpers } from "./settings/system-compendiums.js";
|
||||
import { FenetreRechercheTirage } from "./tirage/fenetre-recherche-tirage.js";
|
||||
import { TMRUtility } from "./tmr-utility.js";
|
||||
|
||||
const rddRollNumeric = /^(\d+)\s*([\+\-]?\d+)?\s*(s)?/;
|
||||
@ -23,6 +24,7 @@ export class RdDCommands {
|
||||
|
||||
static init() {
|
||||
const rddCommands = new RdDCommands();
|
||||
game.system.rdd.commands = rddCommands;
|
||||
|
||||
Hooks.on("chatMessage", (html, content, msg) => {
|
||||
if (content[0] == '/') {
|
||||
@ -35,7 +37,6 @@ export class RdDCommands {
|
||||
return true;
|
||||
});
|
||||
|
||||
game.system.rdd.commands = rddCommands;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
@ -76,6 +77,7 @@ export class RdDCommands {
|
||||
this.registerCommand({ path: ["/tirer", "desir"], func: (content, msg, params) => RdDRollTables.getDesirLancinant('chat'), descr: "Tire un Désir Lancinant" });
|
||||
this.registerCommand({ path: ["/tirer", "rencontre"], func: (content, msg, params) => this.getRencontreTMR(params), descr: `Détermine une rencontre dans les TMR (synonyme de "/tmrr")` });
|
||||
this.registerCommand({ path: ["/tirer", "milieu"], func: (content, msg, params) => this.tableMilieu(msg, params, 'chat'), descr: "Effectue un tirage dans la table des ressource naturelles pour un milieu donné" });
|
||||
this.registerCommand({ path: ["/tirage"], func: (content, msg, params) => this.tirage(), descr: "Ouvre la fenêtre de recherche et tirage" });
|
||||
|
||||
this.registerCommand({ path: ["/meteo"], func: (content, msg, params) => this.getMeteo(msg, params), descr: "Propose une météo marine" });
|
||||
this.registerCommand({ path: ["/nom"], func: (content, msg, params) => RdDNameGen.getName(msg, params), descr: "Génère un nom aléatoire" });
|
||||
@ -254,10 +256,7 @@ export class RdDCommands {
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
async help(msg) {
|
||||
this.help(msg, undefined);
|
||||
}
|
||||
async help(msg, table) {
|
||||
async help(msg, table = undefined) {
|
||||
let commands = []
|
||||
this._buildSubTableHelp(commands, table ?? this.commandsTable);
|
||||
|
||||
@ -511,5 +510,8 @@ export class RdDCommands {
|
||||
return await RdDMeteo.getMeteo();
|
||||
}
|
||||
|
||||
async tirage() {
|
||||
new FenetreRechercheTirage({}).render(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import { Environnement } from "./environnement.js";
|
||||
import { RdDItemCompetence } from "./item-competence.js";
|
||||
import { RdDResolutionTable } from "./rdd-resolution-table.js";
|
||||
import { RdDTimestamp } from "./rdd-timestamp.js";
|
||||
import { RdDRaretes } from "./tirage/raretes.js";
|
||||
|
||||
/* -------------------------------------------- */
|
||||
// This table starts at 0 -> niveau -10
|
||||
@ -202,6 +203,7 @@ export class RdDUtility {
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-periode.html',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/enum-tmr-effet.html',
|
||||
// Partials
|
||||
'systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/common/timestamp.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/common/periodicite.hbs',
|
||||
'systems/foundryvtt-reve-de-dragon/templates/common/enum-duree.hbs',
|
||||
@ -298,7 +300,7 @@ export class RdDUtility {
|
||||
Handlebars.registerHelper('linkCompendium', (pack, id, name) => RdDUtility.linkCompendium(pack, id, name));
|
||||
Handlebars.registerHelper('uniteQuantite', (itemId, actorId) => RdDUtility.getItem(itemId, actorId)?.getUniteQuantite());
|
||||
Handlebars.registerHelper('isFieldInventaireModifiable', (type, field) => RdDItem.isFieldInventaireModifiable(type, field));
|
||||
Handlebars.registerHelper('getFrequenceRarete', (rarete, field) => Environnement.getFrequenceRarete(rarete, field));
|
||||
Handlebars.registerHelper('rarete-getChamp', (rarete, field) => RdDRaretes.getChamp(rarete, field));
|
||||
return loadTemplates(templatePaths);
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ export class SystemCompendiums extends FormApplication {
|
||||
*/
|
||||
export class CompendiumTable {
|
||||
|
||||
constructor(compendium, type, subTypes, sorting = undefined) {
|
||||
constructor(compendium, type, subTypes = undefined, sorting = undefined) {
|
||||
this.compendium = compendium;
|
||||
this.type = type;
|
||||
this.subTypes = subTypes;
|
||||
@ -187,13 +187,13 @@ export class CompendiumTable {
|
||||
async getContent(itemFrequence = it => it.system.frequence, filter = it => true) {
|
||||
return await SystemCompendiums.getContent(this.compendium,
|
||||
this.type,
|
||||
it => this.subTypes.includes(it.type) && filter(it),
|
||||
it => (!this.subTypes || this.subTypes.includes(it.type)) && filter(it),
|
||||
itemFrequence,
|
||||
this.sorting);
|
||||
}
|
||||
|
||||
async buildTable(itemFrequence = it => it.system.frequence, filter = it => true) {
|
||||
const elements = await this.getContent(filter, itemFrequence);
|
||||
const elements = await this.getContent(itemFrequence, filter);
|
||||
return CompendiumTableHelpers.buildTable(elements, itemFrequence);
|
||||
}
|
||||
|
||||
@ -225,9 +225,23 @@ export class CompendiumTableHelpers {
|
||||
});
|
||||
}
|
||||
|
||||
static async getRandom(table, type, subTypes, forcedRoll = undefined, localisation = undefined) {
|
||||
static concatTables(...tables) {
|
||||
const rows = tables.reduce((a, b) => a.concat(b));
|
||||
let max = 0;
|
||||
const total = rows.map(it => it.frequence).reduce(Misc.sum(), 0);
|
||||
return rows.map(row => {
|
||||
const frequence = row.frequence;
|
||||
row.min = max + 1;
|
||||
row.max = max + frequence;
|
||||
row.total = total
|
||||
max += frequence;
|
||||
return row;
|
||||
})
|
||||
}
|
||||
static async getRandom(table, type, subTypes = ['objet'], forcedRoll = undefined, localisation = undefined) {
|
||||
if (table.length == 0) {
|
||||
ui.notifications.warn(`Aucun ${Misc.typeName(type, subTypes[0])} trouvé dans ${localisation ?? ' les compendiums'}`);
|
||||
const typeName = Misc.typeName(type, subTypes[0]);
|
||||
ui.notifications.warn(`Aucun ${typeName} trouvé dans ${localisation ?? ' les compendiums'}`);
|
||||
return undefined;
|
||||
}
|
||||
return await CompendiumTableHelpers.selectRow(table, forcedRoll);
|
||||
@ -260,7 +274,7 @@ export class CompendiumTableHelpers {
|
||||
roll: row.roll,
|
||||
document: row.document,
|
||||
percentages,
|
||||
typeName: Misc.typeName(type, row.document.type),
|
||||
typeName: Misc.typeName(type, row.document?.type ?? 'objet'),
|
||||
isGM: game.user.isGM,
|
||||
});
|
||||
const messageData = {
|
||||
|
217
module/tirage/fenetre-recherche-tirage.js
Normal file
217
module/tirage/fenetre-recherche-tirage.js
Normal file
@ -0,0 +1,217 @@
|
||||
import { RdDItem } from '../item.js';
|
||||
import { HtmlUtility } from '../html-utility.js';
|
||||
import { Misc } from "../misc.js";
|
||||
import { CompendiumTable, CompendiumTableHelpers, SystemCompendiums } 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: 'pret', label: 'Comestible', check: item => item.isComestible() == 'pret' },
|
||||
{ group: 'comestible', code: 'alcool', label: 'Alcool', check: item => item.isAlcool() },
|
||||
{ group: 'comestible', code: 'boisson', label: 'Boisson', check: item => item.isNourritureBoisson() && item.system.boisson },
|
||||
{ group: 'comestible', code: 'brut', label: 'A préparer', check: item => item.isComestible() == 'brut' },
|
||||
{ group: 'comestible', code: 'poison', label: 'Toxique', check: item => item.isComestible() == 'poison' },
|
||||
{ group: 'comestible', code: 'non', label: 'Immangeable', check: item => !item.isComestible() || item.isComestible() == '' },
|
||||
|
||||
{ group: 'categorie', code: 'alchimie', label: 'Alchimique', check: item => item.isEnvironnement() && item.system.categorie == 'Alchimie' },
|
||||
{ group: 'categorie', code: 'cuisine', label: 'Cuisine', check: item => item.isEnvironnement() && item.system.categorie == 'Cuisine' },
|
||||
{ group: 'categorie', code: 'repos', label: 'Repos', check: item => item.isEnvironnement() && item.system.categorie == 'Repos' },
|
||||
{ group: 'categorie', code: 'soins', label: 'Soins', check: item => item.isEnvironnement() && item.system.categorie == 'Soin' },
|
||||
{ group: 'categorie', code: 'autres', label: 'Autres', check: item => !item.isEnvironnement() || ['', 'Autre'].includes(item.system.categorie) },
|
||||
|
||||
{ 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) 1-9", check: item => item.isInventaire() && 0 < item.system.cout && item.system.cout < 0.1 },
|
||||
{ group: "prix", code: "bronze", label: "Bronzes 1-9", check: item => item.isInventaire() && 0.1 <= item.system.cout && item.system.cout < 1 },
|
||||
{ group: "prix", code: "sols", label: "Sols (argent) 1-9", check: item => item.isInventaire() && 1 <= item.system.cout && item.system.cout < 10 },
|
||||
{ group: "prix", code: "dragons", label: "Dragons (or) 1+ ", check: item => item.isInventaire() && 10 <= item.system.cout },
|
||||
]
|
||||
|
||||
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,
|
||||
resizable: true
|
||||
});
|
||||
}
|
||||
|
||||
static async $filterMilieux() {
|
||||
const milieux = await game.system.rdd.environnement.milieux();
|
||||
return milieux.map(m => { return { group: 'milieu', code: m, label: m, check: item => item.isPresentDansMilieux(m) } })
|
||||
}
|
||||
|
||||
static $filterRarete() {
|
||||
return RdDRaretes.raretes()
|
||||
.map(r => { return { group: 'rarete', code: r.code, label: r.label, check: item => item.getRarete()?.code == r.code }; });
|
||||
}
|
||||
|
||||
static $filterTypes() {
|
||||
return [
|
||||
{ group: 'type', code: 'inventaire', label: 'Inventaire', check: item => item.isInventaire() && !item.isEnvironnement() },
|
||||
]
|
||||
.concat(['arme', 'armure'].map(it => FenetreRechercheTirage.$typeToFilter(it)))
|
||||
.concat([{ group: 'type', code: 'environement', label: 'Faune, Flore, Ingrédients', check: item => item.isEnvironnement() }])
|
||||
.concat(RdDItem.getItemTypesEnvironnement().map(it => FenetreRechercheTirage.$typeToFilter(it)))
|
||||
}
|
||||
static $typeToFilter(type) { return { group: 'type', code: type, label: Misc.typeName('Item', type), check: item => item.type == type }; }
|
||||
|
||||
static async create(tirage = {}) {
|
||||
new FenetreRechercheTirage(tirage).render(true);
|
||||
}
|
||||
|
||||
constructor(tirage) {
|
||||
super();
|
||||
this.tirage = tirage;
|
||||
this.compendiums = [
|
||||
SystemCompendiums.getCompendium('faune-flore-mineraux'),
|
||||
SystemCompendiums.getCompendium('equipement')
|
||||
]
|
||||
}
|
||||
|
||||
async getData() {
|
||||
const filterGroups = duplicate(FILTER_GROUPS);
|
||||
FILTERS
|
||||
.concat(FenetreRechercheTirage.$filterTypes())
|
||||
.concat(await FenetreRechercheTirage.$filterMilieux())
|
||||
.concat(FenetreRechercheTirage.$filterRarete())
|
||||
.forEach(f => addFilterToGroup(filterGroups, f))
|
||||
mergeObject(this.tirage,
|
||||
{
|
||||
filterGroups: filterGroups.filter(it => it.group)
|
||||
})
|
||||
|
||||
let formData = super.getData();
|
||||
mergeObject(formData, this.tirage)
|
||||
return formData;
|
||||
|
||||
function addFilterToGroup(filterGroups, filter) {
|
||||
if (filter.group && filter.code && filter.label) {
|
||||
let fg = filterGroups.find(g => g.group == filter.group);
|
||||
if (fg == undefined) {
|
||||
filterGroups.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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.html.find('input.activate-filter:checked').prop("checked", false))
|
||||
|
||||
this.html.find("a.recherche-filtres").click(async event => {
|
||||
const table = await this.buildTable();
|
||||
this.html.find('div.liste-resultats').html(await renderTemplate(`systems/foundryvtt-reve-de-dragon/templates/tirage/liste-resultats.hbs`, { resultats: table }));
|
||||
})
|
||||
|
||||
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');
|
||||
})
|
||||
}
|
||||
|
||||
async buildTable() {
|
||||
const filter = this.getSelectedItemsFilter();
|
||||
const equipementCompendiumTable = new CompendiumTable('equipement', 'Item');
|
||||
const equipements = await equipementCompendiumTable.buildTable(it => it.getFrequence(), filter)
|
||||
const environnements = await game.system.rdd.environnement.buildEnvironnementTable(undefined, filter);
|
||||
return CompendiumTableHelpers.concatTables(environnements, equipements);
|
||||
}
|
||||
|
||||
getSelectedItemsFilter() {
|
||||
const byGroup = this.getSelectedFiltersByGroup();
|
||||
const groupSummaries = Object.entries(byGroup).map(([key, list]) => {
|
||||
const group = this.tirage.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.getSelectedFiltersByGroup();
|
||||
const groupSummaries = Object.entries(byGroup).map(([key, list]) => {
|
||||
const group = this.tirage.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);
|
||||
}
|
||||
|
||||
getSelectedFiltersByGroup() {
|
||||
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') };
|
||||
});
|
||||
const byGroup = Misc.classify(selectedFilters, it => it.group);
|
||||
return byGroup;
|
||||
}
|
||||
}
|
45
module/tirage/raretes.js
Normal file
45
module/tirage/raretes.js
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
const RARETES = [
|
||||
{ code: 'Commune', label: 'Commune', frequence: 54, min: 27, max: 108 },
|
||||
{ code: 'Frequente', label: 'Fréquente', frequence: 18, min: 9, max: 36 },
|
||||
{ code: 'Rare', label: 'Rare', frequence: 6, min: 3, max: 12 },
|
||||
{ code: 'Rarissime', label: 'Rarissime', frequence: 2, min: 1, max: 4 }]
|
||||
const DEFAULT_RARETE = 1;
|
||||
|
||||
export class RdDRaretes {
|
||||
|
||||
static getRarete(code = undefined) {
|
||||
return RARETES.find(it => it.code == code) ?? RARETES[DEFAULT_RARETE];
|
||||
}
|
||||
|
||||
static getChamp(rarete, field = undefined) {
|
||||
const selected = this.getRarete(rarete);
|
||||
return field ? selected[field] : selected[frequence];
|
||||
}
|
||||
|
||||
static getRareteFrequente() {
|
||||
return RARETES[DEFAULT_RARETE];
|
||||
}
|
||||
|
||||
static raretes() {
|
||||
return RARETES;
|
||||
}
|
||||
|
||||
static frequenceEquipement(item) {
|
||||
return RdDRaretes.rareteEquipement(item).frequence
|
||||
}
|
||||
|
||||
static rareteEquipement(item) {
|
||||
const qualite = item.system.qualite ?? 0;
|
||||
if (qualite <= 0) {
|
||||
return RARETES[0]
|
||||
}
|
||||
if (qualite <= 3) {
|
||||
return RARETES[1]
|
||||
}
|
||||
if (qualite <= 6) {
|
||||
return RARETES[2]
|
||||
}
|
||||
return RARETES[3]
|
||||
}
|
||||
}
|
@ -7,5 +7,6 @@
|
||||
{"name":"Appel à la chance","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/commodities/flowers/clover.webp","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.rollAppelChance();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671233849101,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"UzAWljmFq5sY702w"}
|
||||
{"name":"Encaissement","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/svg/bones.svg","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.encaisser();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671234017623,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"WD6T8AdRbX2Ylxqe"}
|
||||
{"name":"Jet quelconque","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/sundries/gaming/dice-runed-tan.webp","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.roll();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671233500655,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"bnJnbKDHpbqY8Pr9"}
|
||||
{"name":"Recherche et tirage","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/tools/scribal/magnifying-glass.webp","command":"game.system.rdd.commands.tirage()","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.ZFWPNdQBjQs9z0YW"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.5.4","coreVersion":"10.291","createdTime":1673472449426,"modifiedTime":1673655461651,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"iVZnxOxhCMpkvYh3"}
|
||||
{"name":"Jet d'éthylisme","type":"script","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"icons/consumables/drinks/alcohol-beer-stein-wooden-metal-brown.webp","command":"const selected = game.system.rdd.RdDUtility.getSelectedActor();\nif (selected) {\n selected.jetEthylisme();\n}\nelse {\n ui.notifications.info('Pas de personnage sélectionné');\n}","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.XHNbjnGKXaCiCadq"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1671220038331,"modifiedTime":1671233646086,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"mvub1dRHNFmWjRr7"}
|
||||
{"name":"Tirer le tarot","type":"chat","scope":"global","author":"Hp9ImM4o9YRTSdfu","img":"systems/foundryvtt-reve-de-dragon/icons/tarots/dos-tarot.webp","command":"/tirer tarot","ownership":{"default":0,"Hp9ImM4o9YRTSdfu":3},"flags":{"core":{"sourceId":"Macro.HBZSKR9OHCQbLcTC"}},"_stats":{"systemId":"foundryvtt-reve-de-dragon","systemVersion":"10.3.15","coreVersion":"10.291","createdTime":1669469547231,"modifiedTime":1671237401618,"lastModifiedBy":"Hp9ImM4o9YRTSdfu"},"folder":null,"sort":0,"_id":"vTfJTFYYiRu8X5LM"}
|
||||
|
@ -469,6 +469,16 @@ input:is(.blessure-premiers_soins, .blessure-soins_complets) {
|
||||
.dice-img {
|
||||
border-width: 0;
|
||||
}
|
||||
.in-text-img {
|
||||
max-width: 1.2em;
|
||||
max-height: 1.2em;
|
||||
flex-grow: 0;
|
||||
margin-right: 0.2rem;
|
||||
vertical-align: bottom;
|
||||
border: none;
|
||||
padding: 0.1rem;
|
||||
}
|
||||
|
||||
.button-img {
|
||||
vertical-align: baseline;
|
||||
max-width: 32px;
|
||||
@ -677,10 +687,11 @@ div.dimmed .img-signe-heure {
|
||||
.competence-list .item-controls.hidden-controls {
|
||||
display: none !important;
|
||||
}
|
||||
.item-controls i:is(.fas,.far) {
|
||||
.item-controls i:is(.fas, .fa, .fa-solid) {
|
||||
font-size: 0.8em;
|
||||
color: var(--color-controls);
|
||||
}
|
||||
.item-controls i:is(.fas,.far):hover {
|
||||
.item-controls i:is(.fas, .far, .fa-solid):hover {
|
||||
opacity: 0.7 ;
|
||||
}
|
||||
|
||||
@ -1929,3 +1940,37 @@ display: inline-flex;
|
||||
width: 80px;
|
||||
height: 68px;
|
||||
}
|
||||
|
||||
div.vl {
|
||||
border: 1px solid ;
|
||||
border-color: hsla(0, 0%, 0%, 0.5);
|
||||
height: inherit;
|
||||
min-height: max-content;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
width: 1px;
|
||||
flex-grow: 0;
|
||||
}
|
||||
div.fenetre-recherche div.recherche {
|
||||
display: flex;
|
||||
}
|
||||
div.fenetre-recherche div.recherche div.filtres {
|
||||
width: fit-content;
|
||||
min-width: 200px;
|
||||
float: left;
|
||||
}
|
||||
div.fenetre-recherche div.titre-fenetre-recherche {
|
||||
flex-basis: 0;
|
||||
max-height: fit-content;
|
||||
}
|
||||
div.fenetre-recherche div.liste-resultats {
|
||||
display: flex;
|
||||
flex: auto;
|
||||
flex-flow: row wrap;
|
||||
flex-direction: row;
|
||||
align-content: flex-start ;
|
||||
}
|
||||
div.fenetre-recherche div.liste-resultats div.resultat {
|
||||
width: fit-content;
|
||||
margin: 0.2rem 0.5rem;
|
||||
}
|
||||
|
@ -5,10 +5,16 @@
|
||||
data-pack="{{pack}}"
|
||||
{{#if doctype}}data-doctype="{{doctype}}"{{/if}}
|
||||
data-id="{{id}}"
|
||||
><i class="fas fa-suitcase"></i>{{name}}</a>
|
||||
>
|
||||
{{else}}
|
||||
<a class="rdd-world-content-link"
|
||||
{{#if doctype}}data-doctype="{{doctype}}"{{/if}}
|
||||
data-id="{{id}}"
|
||||
><i class="fas fa-suitcase"></i>{{name}}</a>
|
||||
>
|
||||
{{/if}}
|
||||
{{#if img}}
|
||||
<img class="in-text-img" src="{{img}}" alt="{{name}}" />
|
||||
{{else}}
|
||||
<i class="fas fa-suitcase"></i>
|
||||
{{/if}}
|
||||
{{name}}</a>
|
||||
|
@ -29,8 +29,8 @@
|
||||
{{>"systems/foundryvtt-reve-de-dragon/templates/enum-rarete.html"}}
|
||||
{{/select}}
|
||||
</select>
|
||||
{{rangePicker name="milieu-{{key}}-frequence" value=env.frequence min=(getFrequenceRarete env.rarete 'min') max=(getFrequenceRarete env.rarete 'max') step=1}}
|
||||
<label>[{{getFrequenceRarete env.rarete 'min'}}-{{getFrequenceRarete env.rarete 'max'}}]</label>
|
||||
{{rangePicker name="milieu-{{key}}-frequence" value=env.frequence min=(rarete-getChamp env.rarete 'min') max=(rarete-getChamp env.rarete 'max') step=1}}
|
||||
<label>[{{rarete-getChamp env.rarete 'min'}}-{{rarete-getChamp env.rarete 'max'}}]</label>
|
||||
</span>
|
||||
</div>
|
||||
{{/each}}
|
||||
|
49
templates/tirage/fenetre-recherche-tirage.hbs
Normal file
49
templates/tirage/fenetre-recherche-tirage.hbs
Normal file
@ -0,0 +1,49 @@
|
||||
<div class="fenetre-recherche">
|
||||
<div>
|
||||
<span><a class="supprimer-filtres chat-card-button">Tout</a></span>
|
||||
<span><a class="recherche-filtres chat-card-button">Appliquer les filtres</a></span>
|
||||
<span><a class="tirage-filtres chat-card-button">Tirage aléatoire</a></span>
|
||||
<span class="liste-filtres-actifs"></span>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="recherche">
|
||||
<div class="filtres">
|
||||
<div class="titre-fenetre-recherche">
|
||||
<h3>Filtres</h3>
|
||||
</div>
|
||||
{{#each filterGroups as |group|}}
|
||||
<div class="filter-group" data-group="{{group.group}}" >
|
||||
<h4><a class="filter-group-toggle" >{{group.label}}
|
||||
<span class="item-controls">
|
||||
<i class="filter-group-show fa-solid fa-chevrons-down"></i>
|
||||
<i class="filter-group-hide fa-solid fa-chevrons-up"></i>
|
||||
</span>
|
||||
</a>
|
||||
</h4>
|
||||
<div class="flexcol group-filters">
|
||||
{{#each group.filters as |filter|}}
|
||||
<div class="flexrow">
|
||||
<input type="checkbox" class="activate-filter" name="{{filter.group}}-{{filter.code}}"
|
||||
data-group="{{filter.group}}" data-code="{{filter.code}}"/>
|
||||
<label for="{{filter.group}}-{{filter.code}}">{{filter.label}}</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
<div class="flex-grow"></div>
|
||||
</div>
|
||||
<div class="vl"></div>
|
||||
<div class="resultats">
|
||||
<div class="titre-fenetre-recherche">
|
||||
<h3>Résultat de recherche</h3>
|
||||
</div>
|
||||
<div class="liste-resultats">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{!--
|
||||
--}}
|
||||
</form>
|
9
templates/tirage/liste-resultats.hbs
Normal file
9
templates/tirage/liste-resultats.hbs
Normal file
@ -0,0 +1,9 @@
|
||||
{{#each resultats as |row|}}
|
||||
<div class="resultat">
|
||||
{{>'systems/foundryvtt-reve-de-dragon/templates/common/compendium-link.hbs'
|
||||
pack=row.document.pack
|
||||
id=row.document.id
|
||||
name=row.document.name
|
||||
img=row.document.img}}
|
||||
</div>
|
||||
{{/each}}
|
Loading…
Reference in New Issue
Block a user