foundryvtt-reve-de-dragon/module/misc.js
Vincent Vandemeulebrouck 8c3e7e2445 Ajout de Misc.findFirstLike
Méthode de recherche de valeur "proche" dans une liste.

Cherche un élément correspondant strictement, sinon cherche
les éléments contenant la valeur, et retourne le premier.

Notification si plusieurs valeurs peuvent correspondre.
2021-10-08 23:32:08 +02:00

153 lines
4.2 KiB
JavaScript

import { Grammar } from "./grammar.js";
import { RdDDice } from "./rdd-dice.js";
/**
* This class is intended as a placeholder for utility methods unrelated
* to actual classes of the game system or of FoundryVTT
*/
export class Misc {
static isFunction(v) {
return v && {}.toString.call(v) === '[object Function]';
}
static upperFirst(text) {
return text.charAt(0).toUpperCase() + text.slice(1);
}
static lowerFirst(text) {
return text.charAt(0).toLowerCase() + text.slice(1);
}
static toSignedString(number) {
const value = parseInt(number)
const isPositiveNumber = value != NaN && value > 0;
return isPositiveNumber ? "+" + number : number
}
static sum() {
return (a, b) => a + b;
}
static ascending(orderFunction = x => x) {
return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b));
}
static descending(orderFunction = x => x) {
return (a, b) => Misc.sortingBy(orderFunction(b), orderFunction(a));
}
static sortingBy(a, b) {
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
/**
* Converts the value to an integer, or to 0 if undefined/null/not representing integer
* @param {*} value value to convert to an integer using parseInt
*/
static toInt(value) {
if (value == undefined) {
return 0;
}
const parsed = parseInt(value);
return isNaN(parsed) ? 0 : parsed;
}
static keepDecimals(num, decimals) {
if (decimals <= 0 || decimals > 6) return num;
const decimal = Math.pow(10, parseInt(decimals));
return Math.round(num * decimal) / decimal;
}
static getFractionHtml(diviseur) {
if (!diviseur || diviseur <= 1) return undefined;
switch (diviseur || 1) {
case 2: return '&frac12;';
case 4: return '&frac14;';
default: return '1/' + diviseur;
}
}
static classify(items, classifier = it => it.type) {
let itemsBy = {};
Misc.classifyInto(itemsBy, items, classifier);
return itemsBy;
}
static classifyFirst(items, classifier) {
let itemsBy = {};
for (const item of items) {
const classification = classifier(item);
if (!itemsBy[classification]) {
itemsBy[classification] = item;
}
}
return itemsBy;
}
static classifyInto(itemsBy, items, classifier = it => it.type) {
for (const item of items) {
const classification = classifier(item);
let list = itemsBy[classification];
if (!list) {
list = [];
itemsBy[classification] = list;
}
list.push(item);
}
}
static distinct(array) {
return [...new Set(array)];
}
static data(it) {
if (it instanceof Actor || it instanceof Item || it instanceof Combatant) {
return it.data;
}
return it;
}
static templateData(it) {
return Misc.data(it)?.data ?? {}
}
static getEntityTypeLabel(entity) {
const documentName = entity?.documentName;
const type = entity?.data.type;
if (documentName === 'Actor' || documentName === 'Item') {
const label = CONFIG[documentName]?.typeLabels?.[type] ?? type;
return game.i18n.has(label) ? game.i18n.localize(label) : t;
}
return type;
}
static connectedGMOrUser(ownerId = undefined) {
if (ownerId && game.user.id == ownerId) {
return ownerId;
}
return (game.user.isGM ? game.user.id : game.users.entities.find(u => u.isGM && u.active)?.id) ?? game.user.id;
}
static isElectedUser() {
return game.user.id == Misc.connectedGMOrUser();
}
/* -------------------------------------------- */
static findFirstLike(value, elements, mapper = it=>it.name, description = 'valeurs') {
value = Grammar.toLowerCaseNoAccent(value);
const subset = elements.filter(it => Grammar.toLowerCaseNoAccent(mapper(it)).includes(value));
if (subset.length == 0) {
return undefined;
}
let single = subset.find(it => Grammar.toLowerCaseNoAccent(mapper(it)) == value);
if (!single) {
single = subset[0];
if (subset.length > 1) {
const choices = subset.map(it => mapper(it)).reduce((a, b) => `${a}<br>${b}`);
ui.notifications.info(`Plusieurs choix de ${description} possibles:<br>${choices}<br>Le premier sera choisi: ${mapper(single)}`);
}
}
return single;
}
}