diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index acbf35dd8..fa6a33e79 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -20,7 +20,6 @@ import { SpecialServers } from "../Server/data/SpecialServers"; import { Server } from "../Server/Server"; import { Router } from "../ui/GameRoot"; import { Page } from "../ui/Router"; -import { IMap } from "../types"; import * as data from "./AchievementData.json"; import { FactionNames } from "../Faction/data/FactionNames"; import { BlackOperationNames } from "../Bladeburner/data/BlackOperationNames"; @@ -47,7 +46,7 @@ export interface PlayerAchievement { } export interface AchievementDataJson { - achievements: IMap; + achievements: Record; } export interface AchievementData { @@ -87,7 +86,7 @@ function sfAchievement(): Achievement[] { return achs; } -export const achievements: IMap = { +export const achievements: Record = { [FactionNames.CyberSec.toUpperCase()]: { ...achievementData[FactionNames.CyberSec.toUpperCase()], Icon: "CSEC", diff --git a/src/Alias.ts b/src/Alias.ts index ee2801564..aa65642a1 100644 --- a/src/Alias.ts +++ b/src/Alias.ts @@ -1,8 +1,7 @@ -import { IMap } from "./types"; import { Terminal } from "./Terminal"; -export let Aliases: IMap = {}; -export let GlobalAliases: IMap = {}; +export let Aliases: Record = {}; +export let GlobalAliases: Record = {}; export function loadAliases(saveString: string): void { if (saveString === "") { diff --git a/src/Augmentation/StaticAugmentations.ts b/src/Augmentation/StaticAugmentations.ts index 768e52770..68ea0046a 100644 --- a/src/Augmentation/StaticAugmentations.ts +++ b/src/Augmentation/StaticAugmentations.ts @@ -1,4 +1,3 @@ import { Augmentation } from "./Augmentation"; -import { IMap } from "../types"; -export const StaticAugmentations: IMap = {}; +export const StaticAugmentations: Record = {}; diff --git a/src/BitNode/BitNode.tsx b/src/BitNode/BitNode.tsx index 2abb4eea6..ade41b3e0 100644 --- a/src/BitNode/BitNode.tsx +++ b/src/BitNode/BitNode.tsx @@ -1,7 +1,6 @@ import React from "react"; import { Player } from "../Player"; import { BitNodeMultipliers, IBitNodeMultipliers } from "./BitNodeMultipliers"; -import { IMap } from "../types"; import { FactionNames } from "../Faction/data/FactionNames"; import { CityName } from "../Locations/data/CityNames"; @@ -29,7 +28,7 @@ class BitNode { } } -export const BitNodes: IMap = {}; +export const BitNodes: Record = {}; export function initBitNodes() { BitNodes["BitNode1"] = new BitNode( 1, diff --git a/src/Bladeburner/BlackOperations.tsx b/src/Bladeburner/BlackOperations.tsx index 588543c23..b369ce2f6 100644 --- a/src/Bladeburner/BlackOperations.tsx +++ b/src/Bladeburner/BlackOperations.tsx @@ -1,8 +1,7 @@ import { BlackOperation } from "./BlackOperation"; -import { IMap } from "../types"; import { BlackOperationNames } from "./data/BlackOperationNames"; -export const BlackOperations: IMap = {}; +export const BlackOperations: Record = {}; (function () { BlackOperations[BlackOperationNames.OperationTyphoon] = new BlackOperation({ diff --git a/src/Bladeburner/GeneralActions.tsx b/src/Bladeburner/GeneralActions.tsx index dfe5b3d8e..d41973ed6 100644 --- a/src/Bladeburner/GeneralActions.tsx +++ b/src/Bladeburner/GeneralActions.tsx @@ -1,7 +1,6 @@ import { Action } from "./Action"; -import { IMap } from "../types"; -export const GeneralActions: IMap = {}; +export const GeneralActions: Record = {}; const actionNames: Array = [ "Training", diff --git a/src/Bladeburner/Skills.ts b/src/Bladeburner/Skills.ts index a8bc0810c..df56154d2 100644 --- a/src/Bladeburner/Skills.ts +++ b/src/Bladeburner/Skills.ts @@ -1,8 +1,7 @@ import { Skill } from "./Skill"; import { SkillNames } from "./data/SkillNames"; -import { IMap } from "../types"; -export const Skills: IMap = {}; +export const Skills: Record = {}; (function () { Skills[SkillNames.BladesIntuition] = new Skill({ diff --git a/src/CodingContracts.ts b/src/CodingContracts.ts index 0ffa743aa..caf8cba1d 100644 --- a/src/CodingContracts.ts +++ b/src/CodingContracts.ts @@ -1,7 +1,5 @@ import { codingContractTypesMetadata, DescriptionFunc, GeneratorFunc, SolverFunc } from "./data/codingcontracttypes"; -import { IMap } from "./types"; - import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "./utils/JSONReviver"; import { CodingContractEvent } from "./ui/React/CodingContractModal"; @@ -58,7 +56,7 @@ class CodingContractType { /* Contract Types */ // tslint:disable-next-line -export const CodingContractTypes: IMap = {}; +export const CodingContractTypes: Record = {}; for (const md of codingContractTypesMetadata) { // tslint:disable-next-line diff --git a/src/Company/Companies.ts b/src/Company/Companies.ts index 7ad6d9d39..37721fc81 100644 --- a/src/Company/Companies.ts +++ b/src/Company/Companies.ts @@ -1,10 +1,9 @@ // Constructs all CompanyPosition objects using the metadata in data/companypositions.ts import { companiesMetadata } from "./data/CompaniesMetadata"; import { Company, IConstructorParams } from "./Company"; -import { IMap } from "../types"; import { Reviver } from "../utils/JSONReviver"; -export let Companies: IMap = {}; +export let Companies: Record = {}; function addCompany(params: IConstructorParams): void { if (Companies[params.name] != null) { diff --git a/src/Company/Company.ts b/src/Company/Company.ts index 492ed4ad3..70081eaf3 100644 --- a/src/Company/Company.ts +++ b/src/Company/Company.ts @@ -2,14 +2,12 @@ import { CompanyPosition } from "./CompanyPosition"; import * as posNames from "./data/companypositionnames"; import { favorToRep, repToFavor } from "../Faction/formulas/favor"; -import { IMap } from "../types"; - import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver"; export interface IConstructorParams { name: string; info: string; - companyPositions: IMap; + companyPositions: Record; expMultiplier: number; salaryMultiplier: number; jobStatReqOffset: number; @@ -48,7 +46,7 @@ export class Company { * * Must match names of Company Positions, defined in data/companypositionnames.ts */ - companyPositions: IMap; + companyPositions: Record; /** * Company-specific multiplier for earnings diff --git a/src/Company/CompanyPositions.ts b/src/Company/CompanyPositions.ts index 3075808a4..b4147e116 100644 --- a/src/Company/CompanyPositions.ts +++ b/src/Company/CompanyPositions.ts @@ -1,9 +1,8 @@ // Constructs all CompanyPosition objects using the metadata in data/companypositions.ts import { companyPositionMetadata } from "./data/CompanyPositionsMetadata"; import { CompanyPosition, IConstructorParams } from "./CompanyPosition"; -import { IMap } from "../types"; -export const CompanyPositions: IMap = {}; +export const CompanyPositions: Record = {}; function addCompanyPosition(params: IConstructorParams): void { if (CompanyPositions[params.name] != null) { diff --git a/src/Company/data/CompaniesMetadata.ts b/src/Company/data/CompaniesMetadata.ts index 74acb3d6b..85af9e2ca 100644 --- a/src/Company/data/CompaniesMetadata.ts +++ b/src/Company/data/CompaniesMetadata.ts @@ -1,30 +1,29 @@ import * as posNames from "./companypositionnames"; import { IConstructorParams } from "../Company"; -import { IMap } from "../../types"; import { LocationName } from "../../Locations/data/LocationNames"; // Create Objects containing Company Positions by category // Will help in metadata construction later -const AllSoftwarePositions: IMap = {}; -const AllITPositions: IMap = {}; -const AllNetworkEngineerPositions: IMap = {}; -const SecurityEngineerPositions: IMap = {}; -const AllTechnologyPositions: IMap = {}; -const AllBusinessPositions: IMap = {}; -const AllAgentPositions: IMap = {}; -const AllSecurityPositions: IMap = {}; -const AllSoftwareConsultantPositions: IMap = {}; -const AllBusinessConsultantPositions: IMap = {}; -const SoftwarePositionsUpToHeadOfEngineering: IMap = {}; -const SoftwarePositionsUpToLeadDeveloper: IMap = {}; -const BusinessPositionsUpToOperationsManager: IMap = {}; -const WaiterOnly: IMap = {}; -const EmployeeOnly: IMap = {}; -const PartTimeWaiterOnly: IMap = {}; -const PartTimeEmployeeOnly: IMap = {}; -const OperationsManagerOnly: IMap = {}; -const CEOOnly: IMap = {}; +const AllSoftwarePositions: Record = {}; +const AllITPositions: Record = {}; +const AllNetworkEngineerPositions: Record = {}; +const SecurityEngineerPositions: Record = {}; +const AllTechnologyPositions: Record = {}; +const AllBusinessPositions: Record = {}; +const AllAgentPositions: Record = {}; +const AllSecurityPositions: Record = {}; +const AllSoftwareConsultantPositions: Record = {}; +const AllBusinessConsultantPositions: Record = {}; +const SoftwarePositionsUpToHeadOfEngineering: Record = {}; +const SoftwarePositionsUpToLeadDeveloper: Record = {}; +const BusinessPositionsUpToOperationsManager: Record = {}; +const WaiterOnly: Record = {}; +const EmployeeOnly: Record = {}; +const PartTimeWaiterOnly: Record = {}; +const PartTimeEmployeeOnly: Record = {}; +const OperationsManagerOnly: Record = {}; +const CEOOnly: Record = {}; posNames.SoftwareCompanyPositions.forEach((e) => { AllSoftwarePositions[e] = true; diff --git a/src/Corporation/Actions.ts b/src/Corporation/Actions.ts index 3b65654a7..5cdfc5e9f 100644 --- a/src/Corporation/Actions.ts +++ b/src/Corporation/Actions.ts @@ -14,6 +14,7 @@ import { Cities } from "../Locations/Cities"; import { EmployeePositions } from "./EmployeePositions"; import { ResearchMap } from "./ResearchMap"; import { isRelevantMaterial } from "./ui/Helpers"; +import { checkObjContainsValue } from "../utils/helpers/checkObjContains"; export function NewIndustry(corporation: Corporation, industry: string, name: string): void { if (corporation.divisions.find(({ type }) => industry == type)) @@ -303,16 +304,13 @@ export function BuyBackShares(corporation: Corporation, numShares: number): bool export function AssignJob(office: OfficeSpace, employeeName: string, job: string): void { const employee = office.employees.find((e) => e.name === employeeName); - if (!employee) throw new Error(`Could not find employee '${name}'.`); - if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`); - + if (!checkObjContainsValue(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`) office.assignSingleJob(employee, job); } export function AutoAssignJob(office: OfficeSpace, job: string, count: number): boolean { - if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`); - + if (!checkObjContainsValue(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`) return office.autoAssignJob(job, count); } diff --git a/src/Corporation/EmployeePositions.ts b/src/Corporation/EmployeePositions.ts index ed7d524cd..e560314c6 100644 --- a/src/Corporation/EmployeePositions.ts +++ b/src/Corporation/EmployeePositions.ts @@ -1,6 +1,4 @@ -import { IMap } from "../types"; - -export const EmployeePositions: IMap = { +export const EmployeePositions = { Operations: "Operations", Engineer: "Engineer", Business: "Business", @@ -8,4 +6,4 @@ export const EmployeePositions: IMap = { RandD: "Research & Development", Training: "Training", Unassigned: "Unassigned", -}; +} as const; diff --git a/src/Corporation/MaterialSizes.ts b/src/Corporation/MaterialSizes.ts index 74a19cb7e..b7e402a54 100644 --- a/src/Corporation/MaterialSizes.ts +++ b/src/Corporation/MaterialSizes.ts @@ -1,7 +1,5 @@ -import { IMap } from "../types"; - // Map of material (by name) to their sizes (how much space it takes in warehouse) -export const MaterialSizes: IMap = { +export const MaterialSizes: Record = { Water: 0.05, Energy: 0.01, Food: 0.03, diff --git a/src/Corporation/Product.ts b/src/Corporation/Product.ts index e85380372..1700f683f 100644 --- a/src/Corporation/Product.ts +++ b/src/Corporation/Product.ts @@ -4,7 +4,6 @@ import { Industry } from "./Industry"; import { ProductRatingWeights, IProductRatingWeight } from "./ProductRatingWeights"; import { createCityMap } from "../Locations/createCityMap"; -import { IMap } from "../types"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver"; import { getRandomInt } from "../utils/helpers/getRandomInt"; @@ -25,7 +24,7 @@ interface IConstructorParams { features?: number; loc?: string; size?: number; - req?: IMap; + req?: Record; } export class Product { @@ -81,7 +80,7 @@ export class Product { // Data refers to the production, sale, and quantity of the products // These values are specific to a city // For each city, the data is [qty, prod, sell] - data: IMap = createCityMap([0, 0, 0]); + data: Record = createCityMap([0, 0, 0]); // Location of this Product // Only applies for location-based products like restaurants/hospitals @@ -93,18 +92,18 @@ export class Product { // Material requirements. An object that maps the name of a material to how much it requires // to make 1 unit of the product. - reqMats: IMap = {}; + reqMats: Record = {}; // Data to keep track of whether production/sale of this Product is // manually limited. These values are specific to a city // [Whether production/sale is limited, limit amount] - prdman: IMap = createCityMap([false, 0]); - sllman: IMap = createCityMap([false, 0]); + prdman: Record = createCityMap([false, 0]); + sllman: Record = createCityMap([false, 0]); // Flags that signal whether automatic sale pricing through Market TA is enabled marketTa1 = false; marketTa2 = false; - marketTa2Price: IMap = createCityMap(0); + marketTa2Price: Record = createCityMap(0); // Determines the maximum amount of this product that can be sold in one market cycle maxsll = 0; diff --git a/src/Corporation/ProductRatingWeights.ts b/src/Corporation/ProductRatingWeights.ts index 667a59f0b..01997180f 100644 --- a/src/Corporation/ProductRatingWeights.ts +++ b/src/Corporation/ProductRatingWeights.ts @@ -1,5 +1,4 @@ import { Industries } from "./IndustryData"; -import { IMap } from "../types"; export interface IProductRatingWeight { Aesthetics?: number; @@ -10,7 +9,7 @@ export interface IProductRatingWeight { Reliability?: number; } -export const ProductRatingWeights: IMap = { +export const ProductRatingWeights: Record = { [Industries.Food]: { Quality: 0.7, Durability: 0.1, diff --git a/src/Corporation/ResearchMap.ts b/src/Corporation/ResearchMap.ts index 7b2ab3928..606faf3d7 100644 --- a/src/Corporation/ResearchMap.ts +++ b/src/Corporation/ResearchMap.ts @@ -2,9 +2,8 @@ // as values. They are identified by their names import { Research, IConstructorParams } from "./Research"; import { researchMetadata } from "./data/ResearchMetadata"; -import { IMap } from "../types"; -export const ResearchMap: IMap = {}; +export const ResearchMap: Record = {}; function addResearch(p: IConstructorParams): void { if (ResearchMap[p.name] != null) { diff --git a/src/Corporation/ResearchTree.ts b/src/Corporation/ResearchTree.ts index a76d2aaa1..82313d107 100644 --- a/src/Corporation/ResearchTree.ts +++ b/src/Corporation/ResearchTree.ts @@ -6,8 +6,6 @@ import { Research } from "./Research"; import { ResearchMap } from "./ResearchMap"; -import { IMap } from "../types"; - interface IConstructorParams { children?: Node[]; cost: number; @@ -86,7 +84,7 @@ export class Node { // The root node in a Research Tree must always be the "Hi-Tech R&D Laboratory" export class ResearchTree { // Object containing names of all acquired Research by name - researched: IMap = {}; + researched: Record = {}; // Root Node root: Node | null = null; diff --git a/src/Corporation/Warehouse.ts b/src/Corporation/Warehouse.ts index 874651399..8edbe3cfa 100644 --- a/src/Corporation/Warehouse.ts +++ b/src/Corporation/Warehouse.ts @@ -2,7 +2,6 @@ import { Material } from "./Material"; import { Corporation } from "./Corporation"; import { Industry } from "./Industry"; import { MaterialSizes } from "./MaterialSizes"; -import { IMap } from "../types"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver"; import { exceptionAlert } from "../utils/helpers/exceptionAlert"; @@ -21,7 +20,7 @@ export class Warehouse { loc: string; // Map of Materials held by this Warehouse - materials: IMap; + materials: Record; // Maximum amount warehouse can hold size: number; diff --git a/src/Crime/Crimes.ts b/src/Crime/Crimes.ts index d1f24b646..b3cf29060 100644 --- a/src/Crime/Crimes.ts +++ b/src/Crime/Crimes.ts @@ -1,11 +1,10 @@ import { Crime } from "./Crime"; import { CONSTANTS } from "../Constants"; -import { IMap } from "../types"; import { CrimeType } from "../utils/WorkType"; -export const Crimes: IMap = { +export const Crimes: Record = { Shoplift: new Crime("Shoplift", "to shoplift", CrimeType.SHOPLIFT, 2e3, 15e3, 1 / 20, 0.1, { dexterity_success_weight: 1, agility_success_weight: 1, diff --git a/src/DarkWeb/DarkWebItems.ts b/src/DarkWeb/DarkWebItems.ts index 191540fbf..1af0c4226 100644 --- a/src/DarkWeb/DarkWebItems.ts +++ b/src/DarkWeb/DarkWebItems.ts @@ -1,8 +1,7 @@ import { DarkWebItem } from "./DarkWebItem"; -import { IMap } from "../types"; import { Programs, initPrograms } from "../Programs/Programs"; -export const DarkWebItems: IMap = {}; +export const DarkWebItems: Record = {}; export function initDarkWebItems() { initPrograms(); Object.assign(DarkWebItems, { diff --git a/src/DevMenu/ui/SaveFile.tsx b/src/DevMenu/ui/SaveFile.tsx index 8f7d9003b..0d2ff3391 100644 --- a/src/DevMenu/ui/SaveFile.tsx +++ b/src/DevMenu/ui/SaveFile.tsx @@ -7,7 +7,7 @@ import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import Typography from "@mui/material/Typography"; import { saveObject } from "../../SaveObject"; -import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar"; +import { SnackbarEvents } from "../../ui/React/Snackbar"; import { Upload } from "@mui/icons-material"; import { Button } from "@mui/material"; import { OptionSwitch } from "../../ui/React/OptionSwitch"; @@ -25,7 +25,7 @@ export function SaveFile(): React.ReactElement { const save = atob(base64Save); setSaveFile(save); } catch (e: unknown) { - SnackbarEvents.emit(String(e), ToastVariant.ERROR, 5000); + SnackbarEvents.emit(String(e), "error", 5000); } } diff --git a/src/Electron.tsx b/src/Electron.tsx index a07621afc..89d61112c 100644 --- a/src/Electron.tsx +++ b/src/Electron.tsx @@ -3,7 +3,7 @@ import { Router } from "./ui/GameRoot"; import { removeLeadingSlash } from "./Terminal/DirectoryHelpers"; import { Terminal } from "./Terminal"; import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar"; -import { IMap, IReturnStatus } from "./types"; +import { IReturnStatus } from "./types"; import { GetServer } from "./Server/AllServers"; import { ImportPlayerData, SaveData, saveObject } from "./SaveObject"; import { Settings } from "./Settings/Settings"; @@ -125,7 +125,7 @@ function initWebserver(): void { function initAppNotifier(): void { const funcs = { terminal: (message: string, type?: string) => { - const typesFn: IMap<(s: string) => void> = { + const typesFn: Record void> = { info: Terminal.info, warn: Terminal.warn, error: Terminal.error, @@ -151,7 +151,7 @@ function initSaveFunctions(): void { saveObject.exportGame(); } catch (error) { console.error(error); - SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000); + SnackbarEvents.emit("Could not export game.", "error", 2000); } }, triggerScriptsExport: (): void => exportScripts("*", Player.getHomeComputer()), @@ -203,7 +203,7 @@ function initElectronBridge(): void { }) .catch((error: unknown) => { console.error(error); - SnackbarEvents.emit("Could not save game.", ToastVariant.ERROR, 2000); + SnackbarEvents.emit("Could not save game.", "error", 2000); }); }); bridge.receive("trigger-game-export", () => { @@ -211,7 +211,7 @@ function initElectronBridge(): void { window.appSaveFns.triggerGameExport(); } catch (error) { console.error(error); - SnackbarEvents.emit("Could not export game.", ToastVariant.ERROR, 2000); + SnackbarEvents.emit("Could not export game.", "error", 2000); } }); bridge.receive("trigger-scripts-export", () => { @@ -219,7 +219,7 @@ function initElectronBridge(): void { window.appSaveFns.triggerScriptsExport(); } catch (error) { console.error(error); - SnackbarEvents.emit("Could not export scripts.", ToastVariant.ERROR, 2000); + SnackbarEvents.emit("Could not export scripts.", "error", 2000); } }); } diff --git a/src/Faction/FactionInfo.tsx b/src/Faction/FactionInfo.tsx index 0a63d868d..1dfd62b5a 100644 --- a/src/Faction/FactionInfo.tsx +++ b/src/Faction/FactionInfo.tsx @@ -1,5 +1,4 @@ import React from "react"; -import { IMap } from "../types"; import { FactionNames } from "./data/FactionNames"; import { Router } from "../ui/GameRoot"; import { Option } from "./ui/Option"; @@ -81,7 +80,7 @@ export class FactionInfo { * A map of all factions and associated info to them. */ // tslint:disable-next-line:variable-name -export const FactionInfos: IMap = { +export const FactionInfos: Record = { // Endgame [FactionNames.Illuminati]: new FactionInfo({ infoText: ( diff --git a/src/Faction/Factions.ts b/src/Faction/Factions.ts index 7469dee72..f0dd88620 100644 --- a/src/Faction/Factions.ts +++ b/src/Faction/Factions.ts @@ -5,11 +5,9 @@ import { Faction } from "./Faction"; import { FactionInfos } from "./FactionInfo"; -import { IMap } from "../types"; - import { Reviver } from "../utils/JSONReviver"; -export let Factions: IMap = {}; +export let Factions: Record = {}; export function loadFactions(saveString: string): void { Factions = JSON.parse(saveString, Reviver); diff --git a/src/GameOptions/ui/GameOptionsSidebar.tsx b/src/GameOptions/ui/GameOptionsSidebar.tsx index 5c8d707ff..2cfc90f77 100644 --- a/src/GameOptions/ui/GameOptionsSidebar.tsx +++ b/src/GameOptions/ui/GameOptionsSidebar.tsx @@ -19,7 +19,7 @@ import { StyleEditorButton } from "../../Themes/ui/StyleEditorButton"; import { ThemeEditorButton } from "../../Themes/ui/ThemeEditorButton"; import { ConfirmationModal } from "../../ui/React/ConfirmationModal"; import { DeleteGameButton } from "../../ui/React/DeleteGameButton"; -import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar"; +import { SnackbarEvents } from "../../ui/React/Snackbar"; import { SoftResetButton } from "../../ui/React/SoftResetButton"; import { Router } from "../../ui/GameRoot"; import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; @@ -72,7 +72,7 @@ export const GameOptionsSidebar = (props: IProps): React.ReactElement => { setImportData(data); setImportSaveOpen(true); } catch (e: unknown) { - SnackbarEvents.emit(String(e), ToastVariant.ERROR, 5000); + SnackbarEvents.emit(String(e), "error", 5000); } } @@ -82,7 +82,7 @@ export const GameOptionsSidebar = (props: IProps): React.ReactElement => { try { await saveObject.importGame(importData.base64); } catch (e: unknown) { - SnackbarEvents.emit(String(e), ToastVariant.ERROR, 5000); + SnackbarEvents.emit(String(e), "error", 5000); } setImportSaveOpen(false); diff --git a/src/Hacknet/HashManager.ts b/src/Hacknet/HashManager.ts index 8d12051d4..85d3ecd0a 100644 --- a/src/Hacknet/HashManager.ts +++ b/src/Hacknet/HashManager.ts @@ -9,7 +9,6 @@ import { HashUpgrades } from "./HashUpgrades"; import { HashUpgrade } from "./HashUpgrade"; -import { IMap } from "../types"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver"; export class HashManager { @@ -21,7 +20,7 @@ export class HashManager { hashes = 0; // Map of Hash Upgrade Name -> levels in that upgrade - upgrades: IMap = {}; + upgrades: Record = {}; constructor() { for (const name of Object.keys(HashUpgrades)) { diff --git a/src/Hacknet/HashUpgrades.ts b/src/Hacknet/HashUpgrades.ts index 59b8644dd..6b817824b 100644 --- a/src/Hacknet/HashUpgrades.ts +++ b/src/Hacknet/HashUpgrades.ts @@ -4,9 +4,8 @@ */ import { HashUpgrade, IConstructorParams } from "./HashUpgrade"; import { HashUpgradesMetadata } from "./data/HashUpgradesMetadata"; -import { IMap } from "../types"; -export const HashUpgrades: IMap = {}; +export const HashUpgrades: Record = {}; function createHashUpgrade(p: IConstructorParams): void { HashUpgrades[p.name] = new HashUpgrade(p); diff --git a/src/Literature/Literatures.ts b/src/Literature/Literatures.ts index 8f923edf7..3df893a24 100644 --- a/src/Literature/Literatures.ts +++ b/src/Literature/Literatures.ts @@ -1,10 +1,9 @@ import { CityName } from "./../Locations/data/CityNames"; import { Literature } from "./Literature"; import { LiteratureNames } from "./data/LiteratureNames"; -import { IMap } from "../types"; import { FactionNames } from "../Faction/data/FactionNames"; -export const Literatures: IMap = {}; +export const Literatures: Record = {}; (function () { let title, fn, txt; diff --git a/src/Literature/data/LiteratureNames.ts b/src/Literature/data/LiteratureNames.ts index 4d1a2c49e..712134bd5 100644 --- a/src/Literature/data/LiteratureNames.ts +++ b/src/Literature/data/LiteratureNames.ts @@ -1,6 +1,4 @@ -import { IMap } from "../../types"; - -export const LiteratureNames: IMap = { +export const LiteratureNames = { HackersStartingHandbook: "hackers-starting-handbook.lit", CorporationManagementHandbook: "corporation-management-handbook.lit", HistoryOfSynthoids: "history-of-synthoids.lit", @@ -22,4 +20,4 @@ export const LiteratureNames: IMap = { TheNewGod: "the-new-god.lit", NewTriads: "new-triads.lit", TheSecretWar: "the-secret-war.lit", -}; +} as const; diff --git a/src/Locations/Cities.ts b/src/Locations/Cities.ts index 1ec9d970a..058108950 100644 --- a/src/Locations/Cities.ts +++ b/src/Locations/Cities.ts @@ -3,6 +3,5 @@ * Key = City Name, Value = City object */ import { City } from "./City"; -import { IMap } from "../types"; -export const Cities: IMap = {}; +export const Cities: Record = {}; diff --git a/src/Locations/Locations.ts b/src/Locations/Locations.ts index 33da0eade..9171f893f 100644 --- a/src/Locations/Locations.ts +++ b/src/Locations/Locations.ts @@ -8,9 +8,7 @@ import { Location, IConstructorParams } from "./Location"; import { CityName } from "./data/CityNames"; import { LocationsMetadata } from "./data/LocationsMetadata"; -import { IMap } from "../types"; - -export const Locations: IMap = {}; +export const Locations: Record = {}; /** * Here, we'll initialize both Locations and Cities data. These can both diff --git a/src/Locations/createCityMap.ts b/src/Locations/createCityMap.ts index 590da9305..91b4cbf5b 100644 --- a/src/Locations/createCityMap.ts +++ b/src/Locations/createCityMap.ts @@ -5,10 +5,9 @@ * This map uses the official name of the city, NOT its key in the 'Cities' object */ import { Cities } from "./Cities"; -import { IMap } from "../types"; -export function createCityMap(initValue: T): IMap { - const map: IMap = {}; +export function createCityMap(initValue: T): Record { + const map: Record = {}; const cities = Object.keys(Cities); for (let i = 0; i < cities.length; ++i) { map[cities[i]] = initValue; diff --git a/src/Locations/ui/SpecialLocation.tsx b/src/Locations/ui/SpecialLocation.tsx index 0b12edf82..e003cd1f7 100644 --- a/src/Locations/ui/SpecialLocation.tsx +++ b/src/Locations/ui/SpecialLocation.tsx @@ -25,7 +25,7 @@ import { Router } from "../../ui/GameRoot"; import { Player } from "../../Player"; import { dialogBoxCreate } from "../../ui/React/DialogBox"; -import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar"; +import { SnackbarEvents } from "../../ui/React/Snackbar"; import { N00dles } from "../../utils/helpers/N00dles"; import { Exploit } from "../../Exploits/Exploit"; import { applyAugmentation } from "../../Augmentation/AugmentationHelpers"; @@ -95,7 +95,7 @@ export function SpecialLocation(props: IProps): React.ReactElement { function renderNoodleBar(): React.ReactElement { function EatNoodles(): void { - SnackbarEvents.emit("You ate some delicious noodles and feel refreshed", ToastVariant.SUCCESS, 2000); + SnackbarEvents.emit("You ate some delicious noodles and feel refreshed", "success", 2000); N00dles(); // This is the true power of the noodles. if (Player.sourceFiles.length > 0) Player.giveExploit(Exploit.N00dles); if (Player.sourceFileLvl(5) > 0 || Player.bitNodeN === 5) { diff --git a/src/Netscript/RamCostGenerator.ts b/src/Netscript/RamCostGenerator.ts index c6b04629f..280c3b417 100644 --- a/src/Netscript/RamCostGenerator.ts +++ b/src/Netscript/RamCostGenerator.ts @@ -1,5 +1,4 @@ import { Player } from "../Player"; -import { IMap } from "../types"; import { NS as INS } from "../ScriptEditor/NetscriptDefinitions"; import { INetscriptExtra } from "../NetscriptFunctions/Extra"; @@ -15,7 +14,7 @@ type RamCostTree = { // TODO remember to update RamCalculations.js and WorkerScript.js // RAM costs for Netscript functions -export const RamCostConstants: IMap = { +export const RamCostConstants: Record = { ScriptBaseRamCost: 1.6, ScriptDomRamCost: 25, ScriptCorporationRamCost: 1024 - 1.6, @@ -604,7 +603,7 @@ const SourceRamCosts = { }, }; -export const RamCosts: IMap = SourceRamCosts; +export const RamCosts: Record = SourceRamCosts; // This line in particular is there so typescript typechecks that we are not missing any static ram cost. // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/src/Netscript/WorkerScript.ts b/src/Netscript/WorkerScript.ts index 3ef23d884..238b0be43 100644 --- a/src/Netscript/WorkerScript.ts +++ b/src/Netscript/WorkerScript.ts @@ -13,7 +13,6 @@ import { RunningScript } from "../Script/RunningScript"; import { Script } from "../Script/Script"; import { GetServer } from "../Server/AllServers"; import { BaseServer } from "../Server/BaseServer"; -import { IMap } from "../types"; import { NS } from "../ScriptEditor/NetscriptDefinitions"; import { ScriptDeath } from "./ScriptDeath"; import { ScriptArg } from "./ScriptArg"; @@ -43,14 +42,14 @@ export class WorkerScript { /** * Stores names of all functions that have logging disabled */ - disableLogs: IMap = {}; + disableLogs: Record = {}; /** * Used for dynamic RAM calculation. Stores names of all functions that have * already been checked by this script. * TODO: Could probably just combine this with loadedFns? */ - dynamicLoadedFns: IMap = {}; + dynamicLoadedFns: Record = {}; /** * Tracks dynamic RAM usage @@ -71,7 +70,7 @@ export class WorkerScript { * Used for static RAM calculation. Stores names of all functions that have * already been checked by this script */ - loadedFns: IMap = {}; + loadedFns: Record = {}; /** * Filename of script diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 143515678..c15235c54 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -71,7 +71,7 @@ import { NetscriptSingularity } from "./NetscriptFunctions/Singularity"; import { dialogBoxCreate } from "./ui/React/DialogBox"; import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar"; -import { checkEnum } from "./utils/helpers/checkEnum"; +import { checkObjContainsValue } from "./utils/helpers/checkObjContains"; import { Flags } from "./NetscriptFunctions/Flags"; import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence"; @@ -80,7 +80,17 @@ import { recentScripts } from "./Netscript/RecentScripts"; import { InternalAPI, NetscriptContext, wrapAPI } from "./Netscript/APIWrapper"; import { INetscriptExtra } from "./NetscriptFunctions/Extra"; import { ScriptDeath } from "./Netscript/ScriptDeath"; +import { TypeEquality, ValuesFrom } from "./types"; +// "Enums" as object +export const enums = { + toast: { + SUCCESS: "success", + WARNING: "warning", + ERROR: "error", + INFO: "info", + } as const, +}; export type NSFull = NS & INetscriptExtra; export function NetscriptFunctions(workerScript: WorkerScript): NSFull { @@ -89,10 +99,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NSFull { const base: InternalAPI = { args: [], - enums: { - toast: ToastVariant, - }, - + //The next line will error if enums does not match the definition in NetscriptDefinitions.d.ts + enums, singularity: NetscriptSingularity(), gang: NetscriptGang(), bladeburner: NetscriptBladeburner(), @@ -1782,12 +1790,12 @@ const base: InternalAPI = { }, toast: (ctx: NetscriptContext) => - (_message: unknown, _variant: unknown = ToastVariant.SUCCESS, _duration: unknown = 2000): void => { + (_message: unknown, _variant: unknown = enums.toast.SUCCESS, _duration: unknown = 2000): void => { const message = helpers.string(ctx, "message", _message); const variant = helpers.string(ctx, "variant", _variant); const duration = _duration === null ? null : helpers.number(ctx, "duration", _duration); - if (!checkEnum(ToastVariant, variant)) - throw new Error(`variant must be one of ${Object.values(ToastVariant).join(", ")}`); + if (!checkObjContainsValue(enums.toast, variant)) + throw new Error(`variant must be one of ${Object.values(enums.toast).join(", ")}`); SnackbarEvents.emit(message, variant, duration); }, prompt: diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index 8c0940245..23c82bf0e 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -66,6 +66,7 @@ import { Factions } from "../Faction/Factions"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { helpers } from "../Netscript/NetscriptHelpers"; +import { checkObjContainsValue } from "../utils/helpers/checkObjContains"; export function NetscriptCorporation(): InternalAPI { function createCorporation(corporationName: string, selfFund = true): boolean { @@ -711,7 +712,7 @@ export function NetscriptCorporation(): InternalAPI { const employeeName = helpers.string(ctx, "employeeName", _employeeName); const job = helpers.string(ctx, "job", _job); - if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`); + if (!checkObjContainsValue(EmployeePositions, job)) throw new Error(`'${job}' is not a valid job.`); const office = getOffice(divisionName, cityName); AssignJob(office, employeeName, job); @@ -725,7 +726,7 @@ export function NetscriptCorporation(): InternalAPI { const amount = helpers.number(ctx, "amount", _amount); const job = helpers.string(ctx, "job", _job); - if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`); + if (!checkObjContainsValue(EmployeePositions,job)) throw new Error(`'${job}' is not a valid job.`); const office = getOffice(divisionName, cityName); return AutoAssignJob(office, job, amount); diff --git a/src/NetscriptFunctions/Infiltration.ts b/src/NetscriptFunctions/Infiltration.ts index 620e5a4bf..dd419a11c 100644 --- a/src/NetscriptFunctions/Infiltration.ts +++ b/src/NetscriptFunctions/Infiltration.ts @@ -14,7 +14,7 @@ import { import { FactionNames } from "../Faction/data/FactionNames"; import { Factions } from "../Faction/Factions"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; -import { checkEnum } from "../utils/helpers/checkEnum"; +import { checkObjContainsValue } from "../utils/helpers/checkObjContains"; import { LocationName } from "../Locations/data/LocationNames"; import { helpers } from "../Netscript/NetscriptHelpers"; @@ -24,7 +24,7 @@ export function NetscriptInfiltration(): InternalAPI { ); const calculateInfiltrationData = (ctx: NetscriptContext, locationName: string): InfiltrationLocation => { - if (!checkEnum(LocationName, locationName)) throw new Error(`Location '${locationName}' does not exists.`); + if (!checkObjContainsValue(LocationName, locationName)) throw new Error(`Location '${locationName}' does not exists.`); const location = Locations[locationName]; if (location === undefined) throw helpers.makeRuntimeErrorMsg(ctx, `Location '${location}' does not exists.`); if (location.infiltrationData === undefined) diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts index db24151dd..1359b36d6 100644 --- a/src/NetscriptFunctions/Sleeve.ts +++ b/src/NetscriptFunctions/Sleeve.ts @@ -11,7 +11,7 @@ import { SleeveSkills, SleeveTask, } from "../ScriptEditor/NetscriptDefinitions"; -import { checkEnum } from "../utils/helpers/checkEnum"; +import { checkObjContainsValue } from "../utils/helpers/checkObjContains"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork"; import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork"; @@ -102,7 +102,7 @@ export function NetscriptSleeve(): InternalAPI { const cityName = helpers.string(ctx, "cityName", _cityName); checkSleeveAPIAccess(ctx); checkSleeveNumber(ctx, sleeveNumber); - if (checkEnum(CityName, cityName)) { + if (checkObjContainsValue(CityName, cityName)) { return Player.sleeves[sleeveNumber].travel(cityName); } else { throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city name: '${cityName}'.`); diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index 6d5e31182..faa16699d 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -6,7 +6,6 @@ import * as generalMethods from "./PlayerObjectGeneralMethods"; import * as serverMethods from "./PlayerObjectServerMethods"; import * as workMethods from "./PlayerObjectWorkMethods"; -import { IMap } from "../../types"; import { Sleeve } from "../Sleeve/Sleeve"; import { PlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile"; import { Exploit } from "../../Exploits/Exploit"; @@ -43,7 +42,7 @@ export class PlayerObject extends Person { hashManager = new HashManager(); hasTixApiAccess = false; hasWseAccount = false; - jobs: IMap = {}; + jobs: Record = {}; karma = 0; numPeopleKilled = 0; location = LocationName.TravelAgency; diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index 21dde3745..bc378cfa9 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -39,7 +39,7 @@ import { numeralWrapper } from "../../ui/numeralFormat"; import { MoneySourceTracker } from "../../utils/MoneySourceTracker"; import { dialogBoxCreate } from "../../ui/React/DialogBox"; -import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar"; +import { SnackbarEvents } from "../../ui/React/Snackbar"; import { achievements } from "../../Achievements/Achievements"; import { FactionNames } from "../../Faction/data/FactionNames"; @@ -257,7 +257,7 @@ export function takeDamage(this: PlayerObject, amt: number): boolean { export function hospitalize(this: PlayerObject): number { const cost = getHospitalizationCost(); - SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, ToastVariant.WARNING, 2000); + SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, "warning", 2000); this.loseMoney(cost, "hospitalization"); this.hp.current = this.hp.max; @@ -1193,7 +1193,7 @@ export function canAccessGrafting(this: PlayerObject): boolean { export function giveExploit(this: PlayerObject, exploit: Exploit): void { if (!this.exploits.includes(exploit)) { this.exploits.push(exploit); - SnackbarEvents.emit("SF -1 acquired!", ToastVariant.SUCCESS, 2000); + SnackbarEvents.emit("SF -1 acquired!", "success", 2000); } } @@ -1202,7 +1202,7 @@ export function giveAchievement(this: PlayerObject, achievementId: string): void if (!achievement) return; if (!this.achievements.map((a) => a.ID).includes(achievementId)) { this.achievements.push({ ID: achievementId, unlockedOn: new Date().getTime() }); - SnackbarEvents.emit(`Unlocked Achievement: "${achievement.Name}"`, ToastVariant.SUCCESS, 2000); + SnackbarEvents.emit(`Unlocked Achievement: "${achievement.Name}"`, "success", 2000); } } diff --git a/src/Programs/Programs.ts b/src/Programs/Programs.ts index c6885dbaa..5c457de21 100644 --- a/src/Programs/Programs.ts +++ b/src/Programs/Programs.ts @@ -1,8 +1,7 @@ import { Program } from "./Program"; import { programsMetadata } from "./data/ProgramsMetadata"; -import { IMap } from "../types"; -export const Programs: IMap = {}; +export const Programs: Record = {}; export function initPrograms() { for (const params of programsMetadata) { Programs[params.key] = new Program(params.name, params.create, params.run); diff --git a/src/RemoteFileAPI/Remote.ts b/src/RemoteFileAPI/Remote.ts index ed83fbc21..5a5806a65 100644 --- a/src/RemoteFileAPI/Remote.ts +++ b/src/RemoteFileAPI/Remote.ts @@ -1,6 +1,6 @@ import { RFAMessage } from "./MessageDefinitions"; import { RFARequestHandler } from "./MessageHandlers"; -import { SnackbarEvents, ToastVariant } from "../ui/React/Snackbar"; +import { SnackbarEvents } from "../ui/React/Snackbar"; export class Remote { connection?: WebSocket; @@ -22,18 +22,18 @@ export class Remote { this.connection = new WebSocket(address); this.connection.addEventListener("error", (e: Event) => - SnackbarEvents.emit(`Error with websocket ${address}, details: ${JSON.stringify(e)}`, ToastVariant.ERROR, 5000), + SnackbarEvents.emit(`Error with websocket ${address}, details: ${JSON.stringify(e)}`, "error", 5000), ); this.connection.addEventListener("message", handleMessageEvent); this.connection.addEventListener("open", () => SnackbarEvents.emit( `Remote API connection established on ${this.ipaddr}:${this.port}`, - ToastVariant.SUCCESS, + "success", 2000, ), ); this.connection.addEventListener("close", () => - SnackbarEvents.emit("Remote API connection closed", ToastVariant.WARNING, 2000), + SnackbarEvents.emit("Remote API connection closed", "warning", 2000), ); } } diff --git a/src/SaveObject.tsx b/src/SaveObject.tsx index 8262f1faf..9b1c47faf 100755 --- a/src/SaveObject.tsx +++ b/src/SaveObject.tsx @@ -16,7 +16,7 @@ import { Settings } from "./Settings/Settings"; import { loadStockMarket, StockMarket } from "./StockMarket/StockMarket"; import { staneksGift, loadStaneksGift } from "./CotMG/Helper"; -import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar"; +import { SnackbarEvents } from "./ui/React/Snackbar"; import * as ExportBonus from "./ExportBonus"; @@ -120,7 +120,7 @@ class BitburnerSaveObject { pushGameSaved(saveData); if (emitToastEvent) { - SnackbarEvents.emit("Game Saved!", ToastVariant.INFO, 2000); + SnackbarEvents.emit("Game Saved!", "info", 2000); } return resolve(); }) @@ -707,13 +707,9 @@ function loadGame(saveString: string): boolean { } if (saveObj.hasOwnProperty("SettingsSave")) { try { + // Try to set saved settings. Settings.load(saveObj.SettingsSave); - } catch (e) { - console.error("ERROR: Failed to parse Settings. Re-initing default values"); - Settings.init(); - } - } else { - Settings.init(); + } catch (e) {} } if (saveObj.hasOwnProperty("LastExportBonus")) { try { diff --git a/src/Script/RunningScript.ts b/src/Script/RunningScript.ts index c51cd83c6..78af0583b 100644 --- a/src/Script/RunningScript.ts +++ b/src/Script/RunningScript.ts @@ -5,7 +5,6 @@ import { Script } from "./Script"; import { ScriptUrl } from "./ScriptUrl"; import { Settings } from "../Settings/Settings"; -import { IMap } from "../types"; import { Terminal } from "../Terminal"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver"; @@ -18,7 +17,7 @@ export class RunningScript { // Map of [key: hostname] -> Hacking data. Used for offline progress calculations. // Hacking data format: [MoneyStolen, NumTimesHacked, NumTimesGrown, NumTimesWeaken] - dataMap: IMap = {}; + dataMap: Record = {}; // Script filename filename = ""; diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 7599e4fc8..a6efb5bd4 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -6573,22 +6573,16 @@ export interface NS { enums: NSEnums; } -/** @public */ -export enum ToastVariant { - SUCCESS = "success", - WARNING = "warning", - ERROR = "error", - INFO = "info", -} - -/** @public */ -export type ToastVariantValues = `${ToastVariant}`; - -/** @public */ -export interface NSEnums { - toast: typeof ToastVariant; -} +export const enums = { + toast: { + SUCCESS: "success", + WARNING: "warning", + ERROR: "error", + INFO: "info", + }, +} as const; +export type NSEnums = typeof enums; /** * Corporation Office API * @remarks diff --git a/src/Server/AllServers.ts b/src/Server/AllServers.ts index 580213bc5..13727c4da 100644 --- a/src/Server/AllServers.ts +++ b/src/Server/AllServers.ts @@ -4,7 +4,7 @@ import { serverMetadata } from "./data/servers"; import { HacknetServer } from "../Hacknet/HacknetServer"; -import { IMap, IMinMaxRange } from "../types"; +import { IMinMaxRange } from "../types"; import { createRandomIp } from "../utils/IPAddress"; import { getRandomInt } from "../utils/helpers/getRandomInt"; import { Reviver } from "../utils/JSONReviver"; @@ -17,7 +17,7 @@ import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; * Key (string) = IP * Value = Server object */ -let AllServers: IMap = {}; +let AllServers: Record = {}; function GetServerByIP(ip: string): BaseServer | undefined { for (const key of Object.keys(AllServers)) { diff --git a/src/Settings/Settings.ts b/src/Settings/Settings.ts index d477ba6e3..7846aad23 100644 --- a/src/Settings/Settings.ts +++ b/src/Settings/Settings.ts @@ -1,303 +1,98 @@ -import { ISelfInitializer, ISelfLoading } from "../types"; import { OwnedAugmentationsOrderSetting, PurchaseAugmentationsOrderSetting } from "./SettingEnums"; -import { defaultTheme, ITheme } from "../Themes/Themes"; +import { defaultTheme } from "../Themes/Themes"; import { defaultStyles } from "../Themes/Styles"; import { WordWrapOptions } from "../ScriptEditor/ui/Options"; -import { OverviewSettings } from "../ui/React/Overview"; -import { IStyleSettings } from "../ScriptEditor/NetscriptDefinitions"; -import { defaultMonacoTheme, IScriptEditorTheme } from "../ScriptEditor/ui/themes"; +import { defaultMonacoTheme } from "../ScriptEditor/ui/themes"; -/** - * Represents the default settings the player could customize. - */ -interface IDefaultSettings { - /** - * How many servers per page - */ - ActiveScriptsServerPageSize: number; - /** - * How many scripts per page - */ - ActiveScriptsScriptPageSize: number; - /** - * How often the game should autosave the player's progress, in seconds. - */ - AutosaveInterval: number; - - /** - * How many milliseconds between execution points for Netscript 1 statements. - */ - CodeInstructionRunTime: number; - - /** - * Render city as list of buttons. - */ - DisableASCIIArt: boolean; - - /** - * Whether global keyboard shortcuts should be recognized throughout the game. - */ - DisableHotkeys: boolean; - - /** - * Whether text effects such as corruption should be visible. - */ - DisableTextEffects: boolean; - - /** - * Whether overview progress bars should be visible. - */ - DisableOverviewProgressBars: boolean; - - /** - * Enable bash hotkeys - */ - EnableBashHotkeys: boolean; - - /** - * Timestamps format - */ - TimestampsFormat: string; - - /** - * Locale used for display numbers - */ - Locale: string; - - /** - * Limit the number of recently killed script entries being tracked. - */ - MaxRecentScriptsCapacity: number; - - /** - * Limit the number of log entries for each script being executed on each server. - */ - MaxLogCapacity: number; - - /** - * Limit how many entries can be written to a Netscript Port before entries start to get pushed out. - */ - MaxPortCapacity: number; - - /** - * Limit the number of entries in the terminal. - */ - MaxTerminalCapacity: number; - - /** - * Port the Remote File API client will try to connect to. - */ - RemoteFileApiPort: number; - - /** - * Save the game when you save any file. - */ - SaveGameOnFileSave: boolean; - - /** - * Whether the player should be asked to confirm purchasing each and every augmentation. - */ - SuppressBuyAugmentationConfirmation: boolean; - - /** - * Whether the user should be prompted to join each faction via a dialog box. - */ - SuppressFactionInvites: boolean; - - /** - * Whether the user should be shown a dialog box whenever they receive a new message file. - */ - SuppressMessages: boolean; - - /** - * Whether the user should be asked to confirm travelling between cities. - */ - SuppressTravelConfirmation: boolean; - - /** - * Whether the user should be displayed a popup message when his Bladeburner actions are cancelled. - */ - SuppressBladeburnerPopup: boolean; - - /** - * Whether the user should be displayed a popup message on stock market actions. - */ - SuppressTIXPopup: boolean; - - /** - * Whether the user should be displayed a toast alert when the game is saved. - */ - SuppressSavedGameToast: boolean; - - /** - * Whether the user should be displayed a toast warning when the autosave is disabled. - */ - SuppressAutosaveDisabledWarnings: boolean; - - /* - * Whether the game should skip saving the running scripts for late game - */ - ExcludeRunningScriptsFromSave: boolean; - - /* - * Theme colors - */ - theme: ITheme; - - /* - * Interface styles - */ - styles: IStyleSettings; - - /* - * Use GiB instead of GB - */ - UseIEC60027_2: boolean; - - /* - * Display intermediary time unit when their value is null - */ - ShowMiddleNullTimeUnit: boolean; - - /* - * Character overview settings - */ - overview: OverviewSettings; - - /** - * If the game's sidebar is opened - */ - IsSidebarOpened: boolean; - - /** - * Script editor theme data - */ - EditorTheme: IScriptEditorTheme; -} - -/** - * Represents all possible settings the player wants to customize to their play style. - */ -interface ISettings extends IDefaultSettings { - /** - * What order the player's owned Augmentations/Source Files should be displayed in - */ - OwnedAugmentationsOrder: OwnedAugmentationsOrderSetting; - - /** - * What order the Augmentations should be displayed in when purchasing from a Faction - */ - PurchaseAugmentationsOrder: PurchaseAugmentationsOrderSetting; - - MonacoTheme: string; - - MonacoInsertSpaces: boolean; - - MonacoFontSize: number; - - MonacoVim: boolean; - - MonacoWordWrap: WordWrapOptions; -} - -export const defaultSettings: IDefaultSettings = { +/** The current options the player has customized to their play style. */ +export const Settings = { + /** How many servers per page */ ActiveScriptsServerPageSize: 10, + /** How many scripts per page */ ActiveScriptsScriptPageSize: 10, + /** How often the game should autosave the player's progress, in seconds. */ AutosaveInterval: 60, - CodeInstructionRunTime: 50, - DisableASCIIArt: false, - DisableHotkeys: false, - DisableTextEffects: false, - DisableOverviewProgressBars: false, - EnableBashHotkeys: false, - TimestampsFormat: "", - Locale: "en", - MaxRecentScriptsCapacity: 50, - MaxLogCapacity: 50, - MaxPortCapacity: 50, - MaxTerminalCapacity: 500, - RemoteFileApiPort: 0, - SaveGameOnFileSave: true, - SuppressBuyAugmentationConfirmation: false, - SuppressFactionInvites: false, - SuppressMessages: false, - SuppressTravelConfirmation: false, - SuppressBladeburnerPopup: false, - SuppressTIXPopup: false, - SuppressSavedGameToast: false, - SuppressAutosaveDisabledWarnings: false, - UseIEC60027_2: false, - ShowMiddleNullTimeUnit: false, - ExcludeRunningScriptsFromSave: false, - IsSidebarOpened: true, - - theme: defaultTheme, - styles: defaultStyles, - overview: { x: 0, y: 0, opened: true }, - - EditorTheme: defaultMonacoTheme, -}; - -/** - * The current options the player has customized to their play style. - */ -// tslint:disable-next-line:variable-name -export const Settings: ISettings & ISelfInitializer & ISelfLoading = { - ActiveScriptsServerPageSize: defaultSettings.ActiveScriptsServerPageSize, - ActiveScriptsScriptPageSize: defaultSettings.ActiveScriptsScriptPageSize, - AutosaveInterval: defaultSettings.AutosaveInterval, + /** How many milliseconds between execution points for Netscript 1 statements. */ CodeInstructionRunTime: 25, - DisableASCIIArt: defaultSettings.DisableASCIIArt, - DisableHotkeys: defaultSettings.DisableHotkeys, - DisableTextEffects: defaultSettings.DisableTextEffects, - DisableOverviewProgressBars: defaultSettings.DisableOverviewProgressBars, - EnableBashHotkeys: defaultSettings.EnableBashHotkeys, - TimestampsFormat: defaultSettings.TimestampsFormat, + /** Whether to render city as list of buttons. */ + DisableASCIIArt: false, + /** Whether global keyboard shortcuts should be disabled throughout the game. */ + DisableHotkeys: false, + /** Whether text effects such as corruption should be disabled. */ + DisableTextEffects: false, + /** Whether overview progress bars should be visible. */ + DisableOverviewProgressBars: false, + /** Whether to enable bash hotkeys */ + EnableBashHotkeys: false, + /** Timestamps format string */ + TimestampsFormat: "", + /** Locale used for display numbers. */ Locale: "en", - MaxRecentScriptsCapacity: defaultSettings.MaxRecentScriptsCapacity, - MaxLogCapacity: defaultSettings.MaxLogCapacity, - MaxPortCapacity: defaultSettings.MaxPortCapacity, - MaxTerminalCapacity: defaultSettings.MaxTerminalCapacity, + /** Limit the number of recently killed script entries being tracked. */ + MaxRecentScriptsCapacity: 50, + /** Limit the number of log entries for each script being executed on each server. */ + MaxLogCapacity: 50, + /** Limit how many entries can be written to a Netscript Port before entries start to get pushed out. */ + MaxPortCapacity: 50, + /** Limit the number of entries in the terminal. */ + MaxTerminalCapacity: 500, + /** Port the Remote File API client will try to connect to. 0 to disable. */ + RemoteFileApiPort: 0, + /** Whether to save the game when the player saves any file. */ + SaveGameOnFileSave: true, + /** Whether to hide the confirmation dialog for augmentation purchases. */ + SuppressBuyAugmentationConfirmation: false, + /** Whether to hide the dialog showing new faction invites. */ + SuppressFactionInvites: false, + /** Whether to hide the dialog when the player receives a new message file. */ + SuppressMessages: false, + /** Whether to hide the confirmation dialog when the player attempts to travel between cities. */ + SuppressTravelConfirmation: false, + /** Whether to hide the dialog when the player's Bladeburner actions are cancelled. */ + SuppressBladeburnerPopup: false, + /** Whether to hide dialogs for stock market actions. */ + SuppressTIXPopup: false, + /** Whether to hide the toast alert when the game is saved. */ + SuppressSavedGameToast: false, + /** Whether to hide the toast warning when the autosave is disabled. */ + SuppressAutosaveDisabledWarnings: false, + /** Whether to GiB instead of GB. */ + UseIEC60027_2: false, + /** Whether to display intermediary time unit when their value is null */ + ShowMiddleNullTimeUnit: false, + /** Whether the game should skip saving the running scripts to the save file. */ + ExcludeRunningScriptsFromSave: false, + /** Whether the game's sidebar is opened. */ + IsSidebarOpened: true, + /** Theme colors. */ + theme: {...defaultTheme}, + /** Interface styles. */ + styles: {...defaultStyles}, + /** Character overview settings. */ + overview: { x: 0, y: 0, opened: true }, + /** Script editor theme data. */ + EditorTheme: {...defaultMonacoTheme}, + /** Order to display the player's owned Augmentations/Source Files. */ OwnedAugmentationsOrder: OwnedAugmentationsOrderSetting.AcquirementTime, + /** What order the Augmentations should be displayed in when purchasing from a Faction. */ PurchaseAugmentationsOrder: PurchaseAugmentationsOrderSetting.Default, - RemoteFileApiPort: defaultSettings.RemoteFileApiPort, - SaveGameOnFileSave: defaultSettings.SaveGameOnFileSave, - SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation, - SuppressFactionInvites: defaultSettings.SuppressFactionInvites, - SuppressMessages: defaultSettings.SuppressMessages, - SuppressTravelConfirmation: defaultSettings.SuppressTravelConfirmation, - SuppressBladeburnerPopup: defaultSettings.SuppressBladeburnerPopup, - SuppressTIXPopup: defaultSettings.SuppressTIXPopup, - SuppressSavedGameToast: defaultSettings.SuppressSavedGameToast, - SuppressAutosaveDisabledWarnings: defaultSettings.SuppressAutosaveDisabledWarnings, - UseIEC60027_2: defaultSettings.UseIEC60027_2, - ShowMiddleNullTimeUnit: defaultSettings.ShowMiddleNullTimeUnit, - ExcludeRunningScriptsFromSave: defaultSettings.ExcludeRunningScriptsFromSave, - IsSidebarOpened: defaultSettings.IsSidebarOpened, - + /** Script editor theme. */ MonacoTheme: "monokai", MonacoInsertSpaces: false, + /** Text size for script editor. */ MonacoFontSize: 20, + /** Whether to use Vim mod by default in the script editor */ MonacoVim: false, - MonacoWordWrap: "off", - - theme: { ...defaultTheme }, - styles: { ...defaultStyles }, - overview: defaultSettings.overview, - EditorTheme: { ...defaultMonacoTheme }, - init() { - Object.assign(Settings, defaultSettings); - }, + /** Word wrap setting for Script Editor. */ + MonacoWordWrap: "off" as WordWrapOptions, + load(saveString: string) { const save = JSON.parse(saveString); - Object.assign(Settings.theme, save.theme); - delete save.theme; - Object.assign(Settings.styles, save.styles); - delete save.styles; - Object.assign(Settings.overview, save.overview); - delete save.overview; - Object.assign(Settings.EditorTheme, save.EditorTheme); - delete save.EditorTheme; + save.theme && Object.assign(Settings.theme, save.theme); + save.styles && Object.assign(Settings.styles, save.styles); + save.overview && Object.assign(Settings.overview, save.overview); + save.EditorTheme && Object.assign(Settings.EditorTheme, save.EditorTheme); + delete save.theme, save.styles, save.overview, save.EditorTheme; Object.assign(Settings, save); }, }; diff --git a/src/SourceFile/SourceFiles.tsx b/src/SourceFile/SourceFiles.tsx index 8d8f23818..086a58abd 100644 --- a/src/SourceFile/SourceFiles.tsx +++ b/src/SourceFile/SourceFiles.tsx @@ -1,9 +1,8 @@ import React from "react"; import { SourceFile } from "./SourceFile"; -import { IMap } from "../types"; import { initBitNodes, initBitNodeMultipliers } from "../BitNode/BitNode"; -export const SourceFiles: IMap = {}; +export const SourceFiles: Record = {}; /** Engine initializer for SourceFiles, BitNodes, and BitNodeMultipliers. Run once at engine load. */ export function initSourceFiles() { initBitNodes(); diff --git a/src/StockMarket/OrderProcessing.tsx b/src/StockMarket/OrderProcessing.tsx index 7c5ba6bcb..51d14a0bd 100644 --- a/src/StockMarket/OrderProcessing.tsx +++ b/src/StockMarket/OrderProcessing.tsx @@ -11,8 +11,6 @@ import { Stock } from "./Stock"; import { OrderTypes } from "./data/OrderTypes"; import { PositionTypes } from "./data/PositionTypes"; -import { IMap } from "../types"; - import { numeralWrapper } from "../ui/numeralFormat"; import { Money } from "../ui/React/Money"; @@ -23,7 +21,7 @@ import * as React from "react"; export interface IProcessOrderRefs { stockMarket: IStockMarket; - symbolToStockMap: IMap; + symbolToStockMap: Record; } /** diff --git a/src/StockMarket/StockMarket.tsx b/src/StockMarket/StockMarket.tsx index ae80b9a0d..dabc29afd 100644 --- a/src/StockMarket/StockMarket.tsx +++ b/src/StockMarket/StockMarket.tsx @@ -10,8 +10,6 @@ import { PositionTypes } from "./data/PositionTypes"; import { StockSymbols } from "./data/StockSymbols"; import { CONSTANTS } from "../Constants"; -import { IMap } from "../types"; - import { numeralWrapper } from "../ui/numeralFormat"; import { dialogBoxCreate } from "../ui/React/DialogBox"; @@ -25,7 +23,7 @@ export let StockMarket: IStockMarket = { storedCycles: 0, ticksUntilCycle: 0, } as IStockMarket; // Maps full stock name -> Stock object -export const SymbolToStockMap: IMap = {}; // Maps symbol -> Stock object +export const SymbolToStockMap: Record = {}; // Maps symbol -> Stock object export function placeOrder( stock: Stock, @@ -172,7 +170,7 @@ export function initStockMarket(): void { } export function initSymbolToStockMap(): void { - for (const name of Object.keys(StockSymbols)) { + for (const name of Object.keys(StockSymbols) as Array) { if (StockSymbols.hasOwnProperty(name)) { const stock = StockMarket[name]; if (stock == null) { diff --git a/src/StockMarket/data/StockSymbols.ts b/src/StockMarket/data/StockSymbols.ts index 707f47ca6..d41ddcf69 100644 --- a/src/StockMarket/data/StockSymbols.ts +++ b/src/StockMarket/data/StockSymbols.ts @@ -1,41 +1,40 @@ -import { IMap } from "../../types"; import { LocationName } from "../../Locations/data/LocationNames"; -export const StockSymbols: IMap = {}; +export const StockSymbols = { + // Stocks for companies at which you can work + [LocationName.AevumECorp]: "ECP", + [LocationName.Sector12MegaCorp]: "MGCP", + [LocationName.Sector12BladeIndustries]: "BLD", + [LocationName.AevumClarkeIncorporated]: "CLRK", + [LocationName.VolhavenOmniTekIncorporated]: "OMTK", + [LocationName.Sector12FourSigma]: "FSIG", + [LocationName.ChongqingKuaiGongInternational]: "KGI", + [LocationName.AevumFulcrumTechnologies]: "FLCM", + [LocationName.IshimaStormTechnologies]: "STM", + [LocationName.NewTokyoDefComm]: "DCOMM", + [LocationName.VolhavenHeliosLabs]: "HLS", + [LocationName.NewTokyoVitaLife]: "VITA", + [LocationName.Sector12IcarusMicrosystems]: "ICRS", + [LocationName.Sector12UniversalEnergy]: "UNV", + [LocationName.AevumAeroCorp]: "AERO", + [LocationName.VolhavenOmniaCybersystems]: "OMN", + [LocationName.ChongqingSolarisSpaceSystems]: "SLRS", + [LocationName.NewTokyoGlobalPharmaceuticals]: "GPH", + [LocationName.IshimaNovaMedical]: "NVMD", + [LocationName.AevumWatchdogSecurity]: "WDS", + [LocationName.VolhavenLexoCorp]: "LXO", + [LocationName.AevumRhoConstruction]: "RHOC", + [LocationName.Sector12AlphaEnterprises]: "APHE", + [LocationName.VolhavenSysCoreSecurities]: "SYSC", + [LocationName.VolhavenCompuTek]: "CTK", + [LocationName.AevumNetLinkTechnologies]: "NTLK", + [LocationName.IshimaOmegaSoftware]: "OMGA", + [LocationName.Sector12FoodNStuff]: "FNS", + [LocationName.Sector12JoesGuns]: "JGN", -// Stocks for companies at which you can work -StockSymbols[LocationName.AevumECorp] = "ECP"; -StockSymbols[LocationName.Sector12MegaCorp] = "MGCP"; -StockSymbols[LocationName.Sector12BladeIndustries] = "BLD"; -StockSymbols[LocationName.AevumClarkeIncorporated] = "CLRK"; -StockSymbols[LocationName.VolhavenOmniTekIncorporated] = "OMTK"; -StockSymbols[LocationName.Sector12FourSigma] = "FSIG"; -StockSymbols[LocationName.ChongqingKuaiGongInternational] = "KGI"; -StockSymbols[LocationName.AevumFulcrumTechnologies] = "FLCM"; -StockSymbols[LocationName.IshimaStormTechnologies] = "STM"; -StockSymbols[LocationName.NewTokyoDefComm] = "DCOMM"; -StockSymbols[LocationName.VolhavenHeliosLabs] = "HLS"; -StockSymbols[LocationName.NewTokyoVitaLife] = "VITA"; -StockSymbols[LocationName.Sector12IcarusMicrosystems] = "ICRS"; -StockSymbols[LocationName.Sector12UniversalEnergy] = "UNV"; -StockSymbols[LocationName.AevumAeroCorp] = "AERO"; -StockSymbols[LocationName.VolhavenOmniaCybersystems] = "OMN"; -StockSymbols[LocationName.ChongqingSolarisSpaceSystems] = "SLRS"; -StockSymbols[LocationName.NewTokyoGlobalPharmaceuticals] = "GPH"; -StockSymbols[LocationName.IshimaNovaMedical] = "NVMD"; -StockSymbols[LocationName.AevumWatchdogSecurity] = "WDS"; -StockSymbols[LocationName.VolhavenLexoCorp] = "LXO"; -StockSymbols[LocationName.AevumRhoConstruction] = "RHOC"; -StockSymbols[LocationName.Sector12AlphaEnterprises] = "APHE"; -StockSymbols[LocationName.VolhavenSysCoreSecurities] = "SYSC"; -StockSymbols[LocationName.VolhavenCompuTek] = "CTK"; -StockSymbols[LocationName.AevumNetLinkTechnologies] = "NTLK"; -StockSymbols[LocationName.IshimaOmegaSoftware] = "OMGA"; -StockSymbols[LocationName.Sector12FoodNStuff] = "FNS"; -StockSymbols[LocationName.Sector12JoesGuns] = "JGN"; - -// Stocks for other companies -StockSymbols["Sigma Cosmetics"] = "SGC"; -StockSymbols["Catalyst Ventures"] = "CTYS"; -StockSymbols["Microdyne Technologies"] = "MDYN"; -StockSymbols["Titan Laboratories"] = "TITN"; + // Stocks for other companies + ["Sigma Cosmetics"]: "SGC", + ["Catalyst Ventures"]: "CTYS", + ["Microdyne Technologies"]: "MDYN", + ["Titan Laboratories"]: "TITN", +} as const; diff --git a/src/StockMarket/data/TickerHeaderFormatData.ts b/src/StockMarket/data/TickerHeaderFormatData.ts index 42664268b..1ad7e8f49 100644 --- a/src/StockMarket/data/TickerHeaderFormatData.ts +++ b/src/StockMarket/data/TickerHeaderFormatData.ts @@ -5,7 +5,7 @@ export const TickerHeaderFormatData = { longestSymbol: 0, }; -for (const key of Object.keys(StockSymbols)) { +for (const key of Object.keys(StockSymbols) as Array) { TickerHeaderFormatData.longestName = Math.max(key.length, TickerHeaderFormatData.longestName); TickerHeaderFormatData.longestSymbol = Math.max(StockSymbols[key].length, TickerHeaderFormatData.longestSymbol); } diff --git a/src/Terminal/HelpText.ts b/src/Terminal/HelpText.ts index f9c85a92b..f1fff1696 100644 --- a/src/Terminal/HelpText.ts +++ b/src/Terminal/HelpText.ts @@ -1,5 +1,4 @@ /* tslint:disable:max-line-length completed-docs variable-name*/ -import { IMap } from "../types"; export const TerminalHelpText: string[] = [ "Type 'help name' to learn more about the command ", @@ -47,7 +46,7 @@ export const TerminalHelpText: string[] = [ " ", ]; -const TemplatedHelpTexts: IMap<(command: string) => string[]> = { +const TemplatedHelpTexts: Record string[]> = { scriptEditor: (command) => { return [ `Usage: ${command} [file ...] | [glob]`, @@ -70,7 +69,7 @@ const TemplatedHelpTexts: IMap<(command: string) => string[]> = { }, }; -export const HelpTexts: IMap = { +export const HelpTexts: Record = { alias: [ 'Usage: alias [-g] [name="value"] ', " ", diff --git a/src/Terminal/commands/cat.ts b/src/Terminal/commands/cat.ts index 0807e8a84..b8fcc9dd0 100644 --- a/src/Terminal/commands/cat.ts +++ b/src/Terminal/commands/cat.ts @@ -3,7 +3,7 @@ import { BaseServer } from "../../Server/BaseServer"; import { MessageFilenames, showMessage } from "../../Message/MessageHelpers"; import { showLiterature } from "../../Literature/LiteratureHelpers"; import { dialogBoxCreate } from "../../ui/React/DialogBox"; -import { checkEnum } from "../../utils/helpers/checkEnum"; +import { checkObjContainsValue } from "../../utils/helpers/checkObjContains"; export function cat(args: (string | number | boolean)[], server: BaseServer): void { if (args.length !== 1) { @@ -35,7 +35,7 @@ export function cat(args: (string | number | boolean)[], server: BaseServer): vo } else if (filename.endsWith(".msg")) { const file = server.messages[i]; if (file !== filename) continue; - if (!checkEnum(MessageFilenames, file)) return; + if (!checkObjContainsValue(MessageFilenames, file)) return; showMessage(file); return; } diff --git a/src/Themes/Themes.ts b/src/Themes/Themes.ts index 847c6fb3e..d5ec62f41 100644 --- a/src/Themes/Themes.ts +++ b/src/Themes/Themes.ts @@ -1,4 +1,3 @@ -import { IMap } from "../types"; import * as predefined from "./data"; export interface ITheme { @@ -51,6 +50,6 @@ export const defaultTheme: ITheme = { ...predefined.Default.colors, }; -export const getPredefinedThemes = (): IMap => ({ +export const getPredefinedThemes = (): Record => ({ ...predefined, }); diff --git a/src/Themes/ui/ThemeBrowser.tsx b/src/Themes/ui/ThemeBrowser.tsx index e8cee63c7..d7d9275bb 100644 --- a/src/Themes/ui/ThemeBrowser.tsx +++ b/src/Themes/ui/ThemeBrowser.tsx @@ -10,7 +10,7 @@ import { StyleEditorButton } from "./StyleEditorButton"; import { ThemeEntry } from "./ThemeEntry"; import { ThemeCollaborate } from "./ThemeCollaborate"; import { Modal } from "../../ui/React/Modal"; -import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar"; +import { SnackbarEvents } from "../../ui/React/Snackbar"; // Everything dies when the theme gets reloaded, so we'll keep the current scroll to not jump around. let previousScrollY = 0; @@ -49,7 +49,7 @@ export function ThemeBrowser(): React.ReactElement { UNDO , - ToastVariant.INFO, + "info", 30000, ); } diff --git a/src/Themes/ui/ThemeEditorModal.tsx b/src/Themes/ui/ThemeEditorModal.tsx index f8fd3d823..e70db847a 100644 --- a/src/Themes/ui/ThemeEditorModal.tsx +++ b/src/Themes/ui/ThemeEditorModal.tsx @@ -12,7 +12,7 @@ import PaletteSharpIcon from "@mui/icons-material/PaletteSharp"; import HistoryIcon from "@mui/icons-material/History"; import { Color, ColorPicker } from "material-ui-color"; import { ThemeEvents } from "./Theme"; -import { Settings, defaultSettings } from "../../Settings/Settings"; +import { Settings } from "../../Settings/Settings"; import { defaultTheme } from "../Themes"; import { UserInterfaceTheme } from "../../ScriptEditor/NetscriptDefinitions"; import { Router } from "../../ui/GameRoot"; @@ -150,19 +150,19 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="primarylight" onColorChange={onColorChange} color={customTheme["primarylight"]} - defaultColor={defaultSettings.theme["primarylight"]} + defaultColor={defaultTheme["primarylight"]} />
@@ -170,19 +170,19 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="successlight" onColorChange={onColorChange} color={customTheme["successlight"]} - defaultColor={defaultSettings.theme["successlight"]} + defaultColor={defaultTheme["successlight"]} />
@@ -190,19 +190,19 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="errorlight" onColorChange={onColorChange} color={customTheme["errorlight"]} - defaultColor={defaultSettings.theme["errorlight"]} + defaultColor={defaultTheme["errorlight"]} />
@@ -210,19 +210,19 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="secondarylight" onColorChange={onColorChange} color={customTheme["secondarylight"]} - defaultColor={defaultSettings.theme["secondarylight"]} + defaultColor={defaultTheme["secondarylight"]} />
@@ -230,19 +230,19 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="warninglight" onColorChange={onColorChange} color={customTheme["warninglight"]} - defaultColor={defaultSettings.theme["warninglight"]} + defaultColor={defaultTheme["warninglight"]} />
@@ -250,19 +250,19 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="infolight" onColorChange={onColorChange} color={customTheme["infolight"]} - defaultColor={defaultSettings.theme["infolight"]} + defaultColor={defaultTheme["infolight"]} />
@@ -270,43 +270,43 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="welllight" onColorChange={onColorChange} color={customTheme["welllight"]} - defaultColor={defaultSettings.theme["welllight"]} + defaultColor={defaultTheme["welllight"]} />
@@ -314,49 +314,49 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { name="hp" onColorChange={onColorChange} color={customTheme["hp"]} - defaultColor={defaultSettings.theme["hp"]} + defaultColor={defaultTheme["hp"]} /> diff --git a/src/engine.tsx b/src/engine.tsx index 78f3d7bb5..81380c1a6 100644 --- a/src/engine.tsx +++ b/src/engine.tsx @@ -46,7 +46,7 @@ import { calculateAchievements } from "./Achievements/Achievements"; import React from "react"; import { setupUncaughtPromiseHandler } from "./UncaughtPromiseHandler"; import { Button, Typography } from "@mui/material"; -import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar"; +import { SnackbarEvents } from "./ui/React/Snackbar"; const Engine: { _lastUpdate: number; @@ -431,7 +431,7 @@ function warnAutosaveDisabled(): void { ); - SnackbarEvents.emit(warningToast, ToastVariant.WARNING, 5000); + SnackbarEvents.emit(warningToast, "warning", 5000); } export { Engine }; diff --git a/src/types.ts b/src/types.ts index 86bcfdead..9a5388765 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,35 +1,8 @@ -/** - * Performs an equality check between two instances of the same type. - */ -export type EqualityFunc = (a: T, b: T) => boolean; +/** Construct a type using the values from an object. Requires object to be defined "as const" */ +export type ValuesFrom = T[keyof T]; -/** - * A map is an object that holds a mapping between string keys and some consistent type. - */ -export interface IMap { - [key: string]: T; -} - -/** - * Contains a method to initialize itself to a known state. - */ -export interface ISelfInitializer { - /** - * Initialize/reset the object to a known, default state. - */ - init(): void; -} - -/** - * Contains a method to repopulate itself based on a JSON string. - */ -export interface ISelfLoading { - /** - * Loads the save state onto the current object. - * @param saveState JSON string representing the save state. - */ - load(saveState: string): void; -} +/** Only allowed to be true if the types are equal. */ +export type TypeEquality = [T1] extends [T2] ? ([T2] extends [T1] ? true : false) : false; /** * Status object for functions that return a boolean indicating success/failure diff --git a/src/ui/React/Snackbar.tsx b/src/ui/React/Snackbar.tsx index 1f3087a5a..c851129bb 100644 --- a/src/ui/React/Snackbar.tsx +++ b/src/ui/React/Snackbar.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { useSnackbar, SnackbarProvider as SB } from "notistack"; import makeStyles from "@mui/styles/makeStyles"; import { EventEmitter } from "../../utils/EventEmitter"; -import Alert from "@mui/material/Alert"; +import Alert, { AlertColor } from "@mui/material/Alert"; import Paper from "@mui/material/Paper"; import { logBoxBaseZIndex } from "./LogBoxManager"; @@ -10,12 +10,7 @@ interface IProps { children: React.ReactNode | React.ReactNode[]; } -export enum ToastVariant { - SUCCESS = "success", - WARNING = "warning", - ERROR = "error", - INFO = "info", -} +export type ToastVariant = AlertColor; const useStyles = makeStyles(() => ({ snackbar: { diff --git a/src/utils/StringHelperFunctions.ts b/src/utils/StringHelperFunctions.ts index eecf5db15..94133e3aa 100644 --- a/src/utils/StringHelperFunctions.ts +++ b/src/utils/StringHelperFunctions.ts @@ -1,5 +1,4 @@ import { Settings } from "../Settings/Settings"; -import { EqualityFunc } from "../types"; import { isString } from "./helpers/isString"; /* @@ -65,7 +64,7 @@ function longestCommonStart(strings: string[]): string { const a2: string = A[A.length - 1]; const L: number = a1.length; let i = 0; - const areEqualCaseInsensitive: EqualityFunc = (a: string, b: string) => a.toUpperCase() === b.toUpperCase(); + const areEqualCaseInsensitive = (a: string, b: string) => a.toUpperCase() === b.toUpperCase(); while (i < L && areEqualCaseInsensitive(a1.charAt(i), a2.charAt(i))) { i++; } diff --git a/src/utils/helpers/checkEnum.ts b/src/utils/helpers/checkEnum.ts deleted file mode 100644 index db61323fe..000000000 --- a/src/utils/helpers/checkEnum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function checkEnum( - enumVariable: { [key in T]: TEnumValue }, - value: string, -): value is TEnumValue { - return Object.values(enumVariable).includes(value); -} diff --git a/src/utils/helpers/checkObjContains.ts b/src/utils/helpers/checkObjContains.ts new file mode 100644 index 000000000..a0df51d7a --- /dev/null +++ b/src/utils/helpers/checkObjContains.ts @@ -0,0 +1,7 @@ +// This works for both enums and regular objects. +export function checkObjContainsValue>( + obj: T, + value: string, +): value is T[keyof T] { + return Object.values(obj).includes(value); +} diff --git a/test/jest/StockMarket.test.ts b/test/jest/StockMarket.test.ts index 7b1e03df4..debd53885 100644 --- a/test/jest/StockMarket.test.ts +++ b/test/jest/StockMarket.test.ts @@ -1,6 +1,5 @@ import { CONSTANTS } from "../../src/Constants"; import { Player } from "../../src/Player"; -import { IMap } from "../../src/types"; import { Company } from "../../src/Company/Company"; import { Server } from "../../src/Server/Server"; @@ -457,7 +456,7 @@ describe("Stock Market Tests", function () { it("should trigger a price update when it has enough cycles", function () { // Get the initial prices - const initialValues: IMap = {}; + const initialValues: Record = {}; for (const stockName in StockMarket) { const stock = StockMarket[stockName]; if (!(stock instanceof Stock)) {