moved a bunch of files

This commit is contained in:
Olivier Gagnon
2021-09-25 14:42:57 -04:00
parent 07bc697477
commit 06f716c0fa
174 changed files with 236 additions and 236 deletions
+23
View File
@@ -0,0 +1,23 @@
/**
* Adds a random offset to a number within a certain percentage
* @example
* // Returns between 95-105
* addOffset(100, 5);
* @example
* // Returns between 63-77
* addOffSet(70, 10);
* @param midpoint The number to be the midpoint of the offset range
* @param percentage The percentage (in a range of 0-100) to offset
*/
export function addOffset(midpoint: number, percentage: number): number {
const maxPercent = 100;
if (percentage < 0 || percentage > maxPercent) {
return midpoint;
}
const offset: number = midpoint * (percentage / maxPercent);
// Double the range to account for both sides of the midpoint.
// tslint:disable-next-line:no-magic-numbers
return midpoint + (Math.random() * (offset * 2) - offset);
}
+21
View File
@@ -0,0 +1,21 @@
/**
* Returns the input array as a comma separated string.
*
* Does several things that Array.toString() doesn't do
* - Adds brackets around the array
* - Adds quotation marks around strings
*/
export function arrayToString<T>(a: T[]): string {
const vals: any[] = [];
for (let i = 0; i < a.length; ++i) {
let elem: any = a[i];
if (Array.isArray(elem)) {
elem = arrayToString(elem);
} else if (typeof elem === "string") {
elem = `"${elem}"`;
}
vals.push(elem);
}
return `[${vals.join(", ")}]`;
}
+15
View File
@@ -0,0 +1,15 @@
/**
* Clears defined properties from an object.
* Does not delete up the prototype chain.
* @deprecated Look into using `Map` or `Set` rather than manipulating properties on an Object.
* @param obj the object to clear all properties
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function clearObject(obj: any): void {
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// tslint:disable-next-line:no-dynamic-delete
delete obj[key];
}
}
}
+29
View File
@@ -0,0 +1,29 @@
/**
* Does a shallow compare of two arrays to determine if they are equal.
* @param a1 The first array
* @param a2 The second array
*/
export function compareArrays<T>(a1: T[], a2: T[]): boolean {
if (a1.length !== a2.length) {
return false;
}
for (let i = 0; i < a1.length; ++i) {
if (Array.isArray(a1[i])) {
// If the other element is not an array, then these cannot be equal
if (!Array.isArray(a2[i])) {
return false;
}
const elem1 = a1[i] as any;
const elem2 = a2[i] as any;
if (!compareArrays(elem1, elem2)) {
return false;
}
} else if (a1[i] !== a2[i]) {
return false;
}
}
return true;
}
@@ -0,0 +1,47 @@
/**
* Represents the possible configuration values that can be provided when creating the progress bar text.
*/
interface IProgressBarConfiguration {
/**
* Current progress, taken as a decimal (i.e. '0.6' to represent '60%')
*/
progress?: number;
/**
* Total number of ticks in progress bar. Preferably a factor of 100.
*/
totalTicks?: number;
}
/**
* Represents concrete configuration values when creating the progress bar text.
*/
interface IProgressBarConfigurationMaterialized extends IProgressBarConfiguration {
progress: number;
totalTicks: number;
}
/**
* Creates a graphical "progress bar"
* e.g.: [||||---------------]
* @param params The configuration parameters for the progress bar
*/
export function createProgressBarText(params: IProgressBarConfiguration): string {
// Default values
const defaultParams: IProgressBarConfigurationMaterialized = {
progress: 0,
totalTicks: 20,
};
// tslint:disable-next-line:prefer-object-spread
const derived: IProgressBarConfigurationMaterialized = Object.assign({}, defaultParams, params);
// Ensure it is 0..1
derived.progress = Math.max(Math.min(derived.progress, 1), 0);
// This way there is always at least one bar filled in...
const bars: number = Math.max(Math.floor(derived.progress / (1 / derived.totalTicks)), 1);
const dashes: number = Math.max(derived.totalTicks - bars, 0);
// String.prototype.repeat isn't completley supported, but good enough for our purposes
return `[${"|".repeat(bars)}${"-".repeat(dashes)}]`;
}
+26
View File
@@ -0,0 +1,26 @@
import { dialogBoxCreate } from "../../ui/React/DialogBox";
interface IError {
fileName?: string;
lineNumber?: number;
}
export function exceptionAlert(e: IError | string): void {
console.error(e);
dialogBoxCreate(
"Caught an exception: " +
e +
"<br><br>" +
"Filename: " +
((e as any).fileName || "UNKNOWN FILE NAME") +
"<br><br>" +
"Line Number: " +
((e as any).lineNumber || "UNKNOWN LINE NUMBER") +
"<br><br>" +
"This is a bug, please report to game developer with this " +
"message as well as details about how to reproduce the bug.<br><br>" +
"If you want to be safe, I suggest refreshing the game WITHOUT saving so that your " +
"safe doesn't get corrupted",
false,
);
}
+13
View File
@@ -0,0 +1,13 @@
import { getRandomInt } from "./getRandomInt";
/**
* Gets a random value in the range of a byte (0 - 255), or up to the maximum.
* @param max The maximum value (up to 255).
*/
export function getRandomByte(max: number): number {
// Technically 2^8 is 256, but the values are 0-255, not 1-256.
const byteMaximum = 255;
const upper: number = Math.max(Math.min(max, byteMaximum), 0);
return getRandomInt(0, upper);
}
+11
View File
@@ -0,0 +1,11 @@
/**
* Gets a random integer bounded by the values passed in.
* @param min The minimum value in the range.
* @param max The maximum value in the range.
*/
export function getRandomInt(min: number, max: number): number {
const lower: number = Math.min(min, max);
const upper: number = Math.max(min, max);
return Math.floor(Math.random() * (upper - lower + 1)) + lower;
}
+12
View File
@@ -0,0 +1,12 @@
/**
* Returns a MM/DD HH:MM timestamp for the current time
*/
export function getTimestamp(): string {
const d: Date = new Date();
// A negative slice value takes from the end of the string rather than the beginning.
const stringWidth = -2;
const formattedHours: string = `0${d.getHours()}`.slice(stringWidth);
const formattedMinutes: string = `0${d.getMinutes()}`.slice(stringWidth);
return `${d.getMonth() + 1}/${d.getDate()} ${formattedHours}:${formattedMinutes}`;
}
+17
View File
@@ -0,0 +1,17 @@
/**
* Determines if the number is a power of 2
* @param n The number to check.
*/
export function isPowerOfTwo(n: number): boolean {
if (isNaN(n)) {
return false;
}
if (n === 0) {
return false;
}
// Disabiling the bitwise rule because it's honestly the most effecient way to check for this.
// tslint:disable-next-line:no-bitwise
return (n & (n - 1)) === 0;
}
+8
View File
@@ -0,0 +1,8 @@
/**
* Checks whether the value passed in can be considered a string.
* @param value The value to check if it is a string.
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export function isString(value: any): boolean {
return typeof value === "string" || value instanceof String;
}
+11
View File
@@ -0,0 +1,11 @@
/**
* Checks whether a IP Address string is valid.
* @param ipaddress A string representing a potential IP Address
*/
export function isValidIPAddress(ipaddress: string): boolean {
const byteRange = "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
const regexStr = `^${byteRange}\.${byteRange}\.${byteRange}\.${byteRange}$`;
const ipAddressRegex = new RegExp(regexStr);
return ipAddressRegex.test(ipaddress);
}
+51
View File
@@ -0,0 +1,51 @@
import { IMap } from "../../types";
/**
* Keyboard key codes
*/
export const KEY: IMap<number> = {
CTRL: 17,
DOWNARROW: 40,
ENTER: 13,
ESC: 27,
TAB: 9,
UPARROW: 38,
"0": 48,
"1": 49,
"2": 50,
"3": 51,
"4": 52,
"5": 53,
"6": 54,
"7": 55,
"8": 56,
"9": 57,
A: 65,
B: 66,
C: 67,
D: 68,
E: 69,
F: 70,
G: 71,
H: 72,
I: 73,
J: 74,
K: 75,
L: 76,
M: 77,
N: 78,
O: 79,
P: 80,
Q: 81,
R: 82,
S: 83,
T: 84,
U: 85,
V: 86,
W: 87,
X: 88,
Y: 89,
Z: 90,
};
+9
View File
@@ -0,0 +1,9 @@
/**
* Rounds a number to two decimal places.
* @param decimal A decimal value to trim to two places.
*/
export function roundToTwo(decimal: number): number {
const leftShift: number = Math.round(parseFloat(`${decimal}e+2`));
return +`${leftShift}e-2`;
}