mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-22 09:13:07 +02:00
moved a bunch of files
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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(", ")}]`;
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)}]`;
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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}`;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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,
|
||||
};
|
||||
@@ -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`;
|
||||
}
|
||||
Reference in New Issue
Block a user