Skip to content
Snippets Groups Projects
Forked from pregmodfan / fc-pregmod
13522 commits behind the upstream repository.
utilsMisc.js 3.02 KiB
/**
 * A categorizer is used to "slice" a value range into distinct categories in an efficient manner.
 *
 * If the values are objects their property named 'value' will be set to whatever
 * the value used for the choice was. This is important for getters, where it can be accessed
 * via this.value.
 *
 * @example Plain if
 * let r = "";
 * if (slave.muscles > 95) {
 *     r = "Musc++";
 * } else if (slave.muscles > 30) {
 *     r = "Musc+";
 * } else if (slave.muscles > 5) {
 *     r = "Toned";
 * } else if (slave.muscles > -6) {
 * } elseif (slave.muscles > -31) {
 *     r = "weak";
 * } else if (slave.muscles > -96) {
 *     r = "weak+";
 * } else {
 * 	   r = "weak++";
 * }
 *
 * @example As a categorizer
 * // Can be defined globally.
 * const muscleCat = new Categorizer([96, "Musc++"], [31, "Musc+"], [6, "Toned"], [-5, ""], [-30, "weak"], [-95, "weak+"], [-Infinity, "weak++"])
 *
 * r = muscleCat.cat(slave.muscles);
 */
globalThis.Categorizer = class {
	/**
	 * @param  {...[]} pairs
	 */
	constructor(...pairs) {
		this.cats = Array.prototype.slice.call(pairs)
			.filter(function(e, i, a) {
				return Array.isArray(e) && e.length === 2 && typeof e[0] === "number" && !isNaN(e[0]) &&
					a.findIndex(function(val) {
						return e[0] === val[0];
					}) === i; /* uniqueness test */
			})
			.sort(function(a, b) {
				return b[0] - a[0]; /* reverse sort */
			});
	}

	cat(val, def) {
		let result = def;
		if (typeof val === "number" && !isNaN(val)) {
			let foundCat = this.cats.find(function(e) {
				return val >= e[0];
			});
			if (foundCat) {
				result = foundCat[1];
			}
		}
		// Record the value for the result's getter, if it is an object
		// and doesn't have the property yet
		if (typeof result === "object" && !isNaN(result)) {
			result.value = val;
		}
		return result;
	}
};

/**
 * Converts an array of strings into a sentence parted by commas.
 * @param {Array} array ["apple", "banana", "carrot"]
 * @returns {string} "apple, banana and carrot"
 */
globalThis.arrayToSentence = function(array) {
	return array.reduce((res, ch, i, arr) => res + (i === arr.length - 1 ? ' and ' : ', ') + ch);
};

App.Utils.alphabetizeIterable = function(iterable) {
	const compare = function(a, b) {
		let aTitle = a.toLowerCase();
		let bTitle = b.toLowerCase();

		aTitle = App.Utils.removeArticles(aTitle);
		bTitle = App.Utils.removeArticles(bTitle);

		if (aTitle > bTitle) {
			return 1;
		}
		if (aTitle < bTitle) {
			return -1;
		}
		return 0;
	};

	const clonedArray = (Array.from(iterable));
	return clonedArray.sort(compare);
};

/**
 * @param {string} str
 * @returns {string}
 */
App.Utils.removeArticles = function(str) {
	const words = str.split(" ");
	if (words.length <= 1) {
		return str;
	}
	if (words[0] === "a" || words[0] === "the" || words[0] === "an") {
		return words.splice(1).join(" ");
	}
	return str;
};

/**
 * @param {FC.Zeroable<FC.Race>} badRace
 * @returns {Array<FC.Race>}
 */
App.Utils.getRaceArrayWithoutParamRace = function(badRace) {
	return Array.from(App.Data.misc.filterRaces.keys()).filter(race => race !== badRace);
};