foundryvtt-reve-de-dragon/module/misc.js

166 lines
4.6 KiB
JavaScript
Raw Normal View History

import { Grammar } from "./grammar.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);
}
2021-06-30 01:01:24 +02:00
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
}
2021-03-29 18:08:18 +02:00
static sum() {
return (a, b) => a + b;
}
2021-05-11 21:45:43 +02:00
static ascending(orderFunction = x => x) {
2021-03-29 18:08:18 +02:00
return (a, b) => Misc.sortingBy(orderFunction(a), orderFunction(b));
2021-05-11 21:45:43 +02:00
}
2021-03-29 18:08:18 +02:00
2021-05-11 21:45:43 +02:00
static descending(orderFunction = x => x) {
2021-03-29 18:08:18 +02:00
return (a, b) => Misc.sortingBy(orderFunction(b), orderFunction(a));
2021-05-11 21:45:43 +02:00
}
2021-03-29 18:08:18 +02:00
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;
}
2021-04-11 23:01:10 +02:00
static keepDecimals(num, decimals) {
2021-05-11 21:45:43 +02:00
if (decimals <= 0 || decimals > 6) return num;
2021-04-11 23:01:10 +02:00
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;
}
}
2021-05-07 01:47:51 +02:00
static classify(items, classifier = it => it.type) {
let itemsBy = {};
2021-05-07 01:47:51 +02:00
Misc.classifyInto(itemsBy, items, classifier);
return itemsBy;
}
2021-03-19 22:20:01 +01:00
static classifyFirst(items, classifier) {
let itemsBy = {};
for (const item of items) {
const classification = classifier(item);
if (!itemsBy[classification]) {
itemsBy[classification] = item;
}
}
return itemsBy;
}
2021-03-29 18:08:18 +02:00
2021-05-07 01:47:51 +02:00
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;
}
2021-05-07 01:47:51 +02:00
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) {
2021-05-11 21:45:43 +02:00
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 findPlayer(name) {
return Misc.findFirstLike(name, game.users, it=>it.name,'joueurs');
}
/* -------------------------------------------- */
static findActor(name, actors = game.actors, description= 'acteurs') {
return Misc.findFirstLike(name, actors, it=>it.name, description);
}
/* -------------------------------------------- */
static findFirstLike(value, elements, mapper = it=>it.name, description = 'valeurs') {
if (!value) {
return undefined;
}
value = Grammar.toLowerCaseNoAccent(value);
const subset = elements.filter(it => Grammar.toLowerCaseNoAccent(mapper(it)).includes(value));
if (subset.length == 0) {
ui.notifications.info(`Pas de ${description} correspondant à ${value}`);
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;
}
}