This commit is contained in:
Olivier Gagnon 2021-09-25 02:36:49 -04:00
parent b0f20c8c8f
commit 8b15adda8a
25 changed files with 144 additions and 226 deletions

@ -4,3 +4,4 @@ dist/
tests/*.bundle.* tests/*.bundle.*
src/ThirdParty/* src/ThirdParty/*
src/JSInterpreter.js src/JSInterpreter.js
main.bundle.js

@ -111,8 +111,8 @@ function getRandomBonus(): any {
return bonuses[Math.floor(bonuses.length * randomNumber.random())]; return bonuses[Math.floor(bonuses.length * randomNumber.random())];
} }
function initAugmentations() { function initAugmentations(): void {
for (var name in Factions) { for (const name in Factions) {
if (Factions.hasOwnProperty(name)) { if (Factions.hasOwnProperty(name)) {
Factions[name].augmentations = []; Factions[name].augmentations = [];
} }
@ -2349,7 +2349,7 @@ function initAugmentations() {
CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][SourceFileFlags[11]], CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][SourceFileFlags[11]],
Player.queuedAugmentations.length, Player.queuedAugmentations.length,
); );
for (var name in Augmentations) { for (const name in Augmentations) {
if (Augmentations.hasOwnProperty(name)) { if (Augmentations.hasOwnProperty(name)) {
Augmentations[name].baseCost *= mult; Augmentations[name].baseCost *= mult;
} }
@ -2402,7 +2402,7 @@ function applyAugmentation(aug: IPlayerOwnedAugmentation, reapply = false): void
} }
} }
function installAugmentations() { function installAugmentations(): boolean {
if (Player.queuedAugmentations.length == 0) { if (Player.queuedAugmentations.length == 0) {
dialogBoxCreate("You have not purchased any Augmentations to install!"); dialogBoxCreate("You have not purchased any Augmentations to install!");
return false; return false;
@ -2440,9 +2440,10 @@ function installAugmentations() {
"<br>You wake up in your home...you feel different...", "<br>You wake up in your home...you feel different...",
); );
prestigeAugmentation(); prestigeAugmentation();
return true;
} }
function augmentationExists(name: string) { function augmentationExists(name: string): boolean {
return Augmentations.hasOwnProperty(name); return Augmentations.hasOwnProperty(name);
} }

@ -9,8 +9,6 @@ import { PlayerMultipliers } from "./PlayerMultipliers";
import { PurchasedAugmentations } from "./PurchasedAugmentations"; import { PurchasedAugmentations } from "./PurchasedAugmentations";
import { SourceFiles } from "./SourceFiles"; import { SourceFiles } from "./SourceFiles";
import { Player } from "../../Player";
import { StdButton } from "../../ui/React/StdButton";
import { canGetBonus } from "../../ExportBonus"; import { canGetBonus } from "../../ExportBonus";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";

@ -7,8 +7,6 @@
*/ */
import React, { useState } from "react"; import React, { useState } from "react";
import { OwnedSourceFiles } from "./OwnedSourceFiles";
import { SourceFileMinus1 } from "./SourceFileMinus1";
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion"; import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
import { Augmentations } from "../../Augmentation/Augmentations"; import { Augmentations } from "../../Augmentation/Augmentations";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
@ -16,7 +14,6 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums"; import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import List from "@mui/material/List"; import List from "@mui/material/List";

@ -8,7 +8,6 @@ import { numeralWrapper } from "../../ui/numeralFormat";
import { Augmentations } from "../Augmentations"; import { Augmentations } from "../Augmentations";
import { Table, TableCell } from "../../ui/React/Table"; import { Table, TableCell } from "../../ui/React/Table";
import TableBody from "@mui/material/TableBody"; import TableBody from "@mui/material/TableBody";
import { Table as MuiTable } from "@mui/material";
import TableRow from "@mui/material/TableRow"; import TableRow from "@mui/material/TableRow";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";

@ -1,5 +1,4 @@
import React from "react"; import React from "react";
import { use } from "../../ui/Context";
import { SourceFileMinus1 } from "./SourceFileMinus1"; import { SourceFileMinus1 } from "./SourceFileMinus1";
import { OwnedSourceFiles } from "./OwnedSourceFiles"; import { OwnedSourceFiles } from "./OwnedSourceFiles";
import List from "@mui/material/List"; import List from "@mui/material/List";
@ -7,7 +6,6 @@ import List from "@mui/material/List";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
export function SourceFiles(): React.ReactElement { export function SourceFiles(): React.ReactElement {
const player = use.Player();
return ( return (
<> <>
<Typography variant="h4">Source Files</Typography> <Typography variant="h4">Source Files</Typography>

@ -4,7 +4,6 @@ import { Console } from "./Console";
import { AllPages } from "./AllPages"; import { AllPages } from "./AllPages";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { IBladeburner } from "../IBladeburner";
export function BladeburnerRoot(): React.ReactElement { export function BladeburnerRoot(): React.ReactElement {
const player = use.Player(); const player = use.Player();

@ -7,7 +7,6 @@ import { IIndustry } from "../IIndustry";
import { NewIndustryPopup } from "./NewIndustryPopup"; import { NewIndustryPopup } from "./NewIndustryPopup";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { MainPanel } from "./MainPanel"; import { MainPanel } from "./MainPanel";
import { Industries } from "../IndustryData"; import { Industries } from "../IndustryData";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";

@ -93,7 +93,8 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
const factionInfo = fac.getInfo(); const factionInfo = fac.getInfo();
const hasPrereqs = hasAugmentationPrereqs(aug); const hasPrereqs = hasAugmentationPrereqs(aug);
if (!hasPrereqs) { if (!hasPrereqs) {
const txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " + "purchase this one."; const txt =
"You must first purchase or install " + aug.prereqs.join(",") + " before you can " + "purchase this one.";
if (sing) { if (sing) {
return txt; return txt;
} else { } else {
@ -166,14 +167,14 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
export function getNextNeurofluxLevel(): number { export function getNextNeurofluxLevel(): number {
// Get current Neuroflux level based on Player's augmentations // Get current Neuroflux level based on Player's augmentations
let currLevel = 0; let currLevel = 0;
for (var i = 0; i < Player.augmentations.length; ++i) { for (let i = 0; i < Player.augmentations.length; ++i) {
if (Player.augmentations[i].name === AugmentationNames.NeuroFluxGovernor) { if (Player.augmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
currLevel = Player.augmentations[i].level; currLevel = Player.augmentations[i].level;
} }
} }
// Account for purchased but uninstalled Augmentations // Account for purchased but uninstalled Augmentations
for (var i = 0; i < Player.queuedAugmentations.length; ++i) { for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
if (Player.queuedAugmentations[i].name == AugmentationNames.NeuroFluxGovernor) { if (Player.queuedAugmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
++currLevel; ++currLevel;
} }

@ -12,7 +12,6 @@ import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
import { hasAugmentationPrereqs } from "../FactionHelpers"; import { hasAugmentationPrereqs } from "../FactionHelpers";
import { StdButton } from "../../ui/React/StdButton";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
@ -87,7 +86,6 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
const augs = getAugs(); const augs = getAugs();
function canBuy(augName: string): boolean { function canBuy(augName: string): boolean {
const aug = Augmentations[augName]; const aug = Augmentations[augName];
const moneyCost = aug.baseCost * props.faction.getInfo().augmentationPriceMult;
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult; const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
const hasReq = props.faction.playerReputation >= repCost; const hasReq = props.faction.playerReputation >= repCost;
const hasRep = hasAugmentationPrereqs(aug); const hasRep = hasAugmentationPrereqs(aug);

@ -12,8 +12,6 @@ import { Favor } from "../../ui/React/Favor";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation"; import { Reputation } from "../../ui/React/Reputation";
import { StdButton } from "../../ui/React/StdButton";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
@ -32,11 +30,6 @@ type IProps = {
rerender: () => void; rerender: () => void;
}; };
const inputStyleMarkup = {
margin: "5px",
height: "26px",
};
export function DonateOption(props: IProps): React.ReactElement { export function DonateOption(props: IProps): React.ReactElement {
const [donateAmt, setDonateAmt] = useState<number | null>(null); const [donateAmt, setDonateAmt] = useState<number | null>(null);
const digits = (CONSTANTS.DonateMoneyToRepDivisor + "").length - 1; const digits = (CONSTANTS.DonateMoneyToRepDivisor + "").length - 1;

@ -3,7 +3,7 @@
* This is the component for displaying a single faction's UI, not the list of all * This is the component for displaying a single faction's UI, not the list of all
* accessible factions * accessible factions
*/ */
import React, { useState, useEffect } from "react"; import React, { useState } from "react";
import { AugmentationsPage } from "./AugmentationsPage"; import { AugmentationsPage } from "./AugmentationsPage";
import { DonateOption } from "./DonateOption"; import { DonateOption } from "./DonateOption";

@ -7,13 +7,10 @@ import React, { useState, useEffect } from "react";
import { Faction } from "../../Faction/Faction"; import { Faction } from "../../Faction/Faction";
import { FactionInfo } from "../../Faction/FactionInfo"; import { FactionInfo } from "../../Faction/FactionInfo";
import { AutoupdatingParagraph } from "../../ui/React/AutoupdatingParagraph";
import { ParagraphWithTooltip } from "../../ui/React/ParagraphWithTooltip";
import { Reputation } from "../../ui/React/Reputation"; import { Reputation } from "../../ui/React/Reputation";
import { Favor } from "../../ui/React/Favor"; import { Favor } from "../../ui/React/Favor";
import { MathComponent } from "mathjax-react"; import { MathComponent } from "mathjax-react";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
@ -25,7 +22,7 @@ type IProps = {
factionInfo: FactionInfo; factionInfo: FactionInfo;
}; };
const useStyles = makeStyles((theme: Theme) => const useStyles = makeStyles(() =>
createStyles({ createStyles({
noformat: { noformat: {
whiteSpace: "pre-wrap", whiteSpace: "pre-wrap",

@ -5,8 +5,6 @@
*/ */
import * as React from "react"; import * as React from "react";
import { StdButton } from "../../ui/React/StdButton";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Paper from "@mui/material/Paper"; import Paper from "@mui/material/Paper";

@ -15,9 +15,7 @@ import { Settings } from "../../Settings/Settings";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation"; import { Reputation } from "../../ui/React/Reputation";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { IMap } from "../../types";
import { StdButton } from "../../ui/React/StdButton";
import { Augmentation as AugFormat } from "../../ui/React/Augmentation"; import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
@ -51,7 +49,6 @@ function Requirements(props: IReqProps): React.ReactElement {
); );
} }
const color = !props.hasRep || !props.hasCost ? "error" : "primary";
return ( return (
<React.Fragment key="f"> <React.Fragment key="f">
<TableCell key={1}> <TableCell key={1}>
@ -80,26 +77,6 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const aug = Augmentations[props.augName]; const aug = Augmentations[props.augName];
if (aug == null) throw new Error(`aug ${props.augName} does not exists`); if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
// Whether the player has this augmentations (purchased OR installed)
function owned(): boolean {
let owned = false;
for (const queuedAug of props.p.queuedAugmentations) {
if (queuedAug.name === props.augName) {
owned = true;
break;
}
}
for (const installedAug of props.p.augmentations) {
if (installedAug.name === props.augName) {
owned = true;
break;
}
}
return owned;
}
if (aug == null) { if (aug == null) {
console.error( console.error(
`Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`, `Invalid Augmentation when trying to create PurchaseableAugmentation display element: ${props.augName}`,

@ -6,7 +6,6 @@ import { ManagementSubpage } from "./ManagementSubpage";
import { TerritorySubpage } from "./TerritorySubpage"; import { TerritorySubpage } from "./TerritorySubpage";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { Factions } from "../../Faction/Factions"; import { Factions } from "../../Faction/Factions";
import { Gang } from "../Gang";
export function GangRoot(): React.ReactElement { export function GangRoot(): React.ReactElement {
const player = use.Player(); const player = use.Player();

@ -1,5 +1,3 @@
import React from "react";
export function random(min: number, max: number): number { export function random(min: number, max: number): number {
return Math.random() * (max - min) + min; return Math.random() * (max - min) + min;
} }

@ -39,9 +39,9 @@ function addMessageToServer(msg: Message, serverHostname: string): void {
return; return;
} }
for (let i = 0; i < server.messages.length; ++i) { for (let i = 0; i < server.messages.length; ++i) {
const msg = server.messages[i]; const other = server.messages[i];
if (typeof msg === "string") continue; if (typeof other === "string") continue;
if (msg.filename === msg.filename) { if (msg.filename === other.filename) {
return; //Already exists return; //Already exists
} }
} }
@ -49,7 +49,7 @@ function addMessageToServer(msg: Message, serverHostname: string): void {
} }
//Checks if any of the 'timed' messages should be sent //Checks if any of the 'timed' messages should be sent
function checkForMessagesToSend() { function checkForMessagesToSend(): void {
if (redPillFlag) return; if (redPillFlag) return;
const jumper0 = Messages[MessageFilenames.Jumper0]; const jumper0 = Messages[MessageFilenames.Jumper0];
const jumper1 = Messages[MessageFilenames.Jumper1]; const jumper1 = Messages[MessageFilenames.Jumper1];
@ -119,7 +119,7 @@ const MessageFilenames = {
RedPill: "icarus.msg", RedPill: "icarus.msg",
}; };
function initMessages() { function initMessages(): void {
//Reset //Reset
Messages = {}; Messages = {};

@ -14,12 +14,8 @@ export function netscriptDelay(time: number, workerScript: WorkerScript): Promis
}); });
} }
export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string, exp: any = null) { export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): string {
let lineNum = ""; const lineNum = "";
if (exp != null) {
const num = getErrorLineNumber(exp, workerScript);
lineNum = " (Line " + num + ")";
}
const server = AllServers[workerScript.serverIp]; const server = AllServers[workerScript.serverIp];
if (server == null) { if (server == null) {
throw new Error(`WorkerScript constructed with invalid server ip: ${workerScript.serverIp}`); throw new Error(`WorkerScript constructed with invalid server ip: ${workerScript.serverIp}`);
@ -32,7 +28,7 @@ export function resolveNetscriptRequestedThreads(
workerScript: WorkerScript, workerScript: WorkerScript,
functionName: string, functionName: string,
requestedThreads: number, requestedThreads: number,
) { ): number {
const threads = workerScript.scriptRef.threads; const threads = workerScript.scriptRef.threads;
if (!requestedThreads) { if (!requestedThreads) {
return isNaN(threads) || threads < 1 ? 1 : threads; return isNaN(threads) || threads < 1 ? 1 : threads;
@ -53,21 +49,6 @@ export function resolveNetscriptRequestedThreads(
return requestedThreadsAsInt; return requestedThreadsAsInt;
} }
function getErrorLineNumber(exp: any, workerScript: WorkerScript): number {
return -1;
// TODO wtf is codeCode?
// var code = workerScript.scriptRef.codeCode();
// //Split code up to the start of the node
// try {
// code = code.substring(0, exp.start);
// return (code.match(/\n/g) || []).length + 1;
// } catch (e) {
// return -1;
// }
}
export function isScriptErrorMessage(msg: string): boolean { export function isScriptErrorMessage(msg: string): boolean {
if (!isString(msg)) { if (!isString(msg)) {
return false; return false;

@ -136,7 +136,6 @@ import { workerScripts } from "./Netscript/WorkerScripts";
import { WorkerScript } from "./Netscript/WorkerScript"; import { WorkerScript } from "./Netscript/WorkerScript";
import { makeRuntimeRejectMsg, netscriptDelay, resolveNetscriptRequestedThreads } from "./NetscriptEvaluator"; import { makeRuntimeRejectMsg, netscriptDelay, resolveNetscriptRequestedThreads } from "./NetscriptEvaluator";
import { Interpreter } from "./ThirdParty/JSInterpreter"; import { Interpreter } from "./ThirdParty/JSInterpreter";
import { NetscriptPort } from "./NetscriptPort";
import { SleeveTaskType } from "./PersonObjects/Sleeve/SleeveTaskTypesEnum"; import { SleeveTaskType } from "./PersonObjects/Sleeve/SleeveTaskTypesEnum";
import { findSleevePurchasableAugs } from "./PersonObjects/Sleeve/SleeveHelpers"; import { findSleevePurchasableAugs } from "./PersonObjects/Sleeve/SleeveHelpers";
import { Exploit } from "./Exploits/Exploit"; import { Exploit } from "./Exploits/Exploit";
@ -166,6 +165,12 @@ import { Faction } from "./Faction/Faction";
import { Augmentation } from "./Augmentation/Augmentation"; import { Augmentation } from "./Augmentation/Augmentation";
import { HacknetNode } from "./Hacknet/HacknetNode"; import { HacknetNode } from "./Hacknet/HacknetNode";
import { CodingContract } from "./CodingContracts";
import { GangMember } from "./Gang/GangMember";
import { GangMemberTask } from "./Gang/GangMemberTask";
import { Stock } from "./StockMarket/Stock";
import { BaseServer } from "./Server/BaseServer";
const defaultInterpreter = new Interpreter("", () => undefined); const defaultInterpreter = new Interpreter("", () => undefined);
// the acorn interpreter has a bug where it doesn't convert arrays correctly. // the acorn interpreter has a bug where it doesn't convert arrays correctly.
@ -206,7 +211,7 @@ interface NS {
} }
function NetscriptFunctions(workerScript: WorkerScript): NS { function NetscriptFunctions(workerScript: WorkerScript): NS {
const updateDynamicRam = function (fnName: string, ramCost: number) { const updateDynamicRam = function (fnName: string, ramCost: number): void {
if (workerScript.dynamicLoadedFns[fnName]) { if (workerScript.dynamicLoadedFns[fnName]) {
return; return;
} }
@ -252,7 +257,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
* @param {string} callingFnName - Name of calling function. For logging purposes * @param {string} callingFnName - Name of calling function. For logging purposes
* @returns {Server} The specified Server * @returns {Server} The specified Server
*/ */
const safeGetServer = function (ip: any, callingFnName: any = "") { const safeGetServer = function (ip: any, callingFnName: any = ""): BaseServer {
const server = getServer(ip); const server = getServer(ip);
if (server == null) { if (server == null) {
throw makeRuntimeErrorMsg(callingFnName, `Invalid IP/hostname: ${ip}`); throw makeRuntimeErrorMsg(callingFnName, `Invalid IP/hostname: ${ip}`);
@ -271,7 +276,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
* exists, or the current running script if the first argument 'fn' * exists, or the current running script if the first argument 'fn'
* is not specified. * is not specified.
*/ */
const getRunningScript = function (fn: any, ip: any, callingFnName: any, scriptArgs: any) { const getRunningScript = function (fn: any, ip: any, callingFnName: any, scriptArgs: any): RunningScript | null {
if (typeof callingFnName !== "string" || callingFnName === "") { if (typeof callingFnName !== "string" || callingFnName === "") {
callingFnName = "getRunningScript"; callingFnName = "getRunningScript";
} }
@ -298,7 +303,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return workerScript.scriptRef; return workerScript.scriptRef;
}; };
const getRunningScriptByPid = function (pid: any, callingFnName: any) { const getRunningScriptByPid = function (pid: any, callingFnName: any): RunningScript | null {
if (typeof callingFnName !== "string" || callingFnName === "") { if (typeof callingFnName !== "string" || callingFnName === "") {
callingFnName = "getRunningScriptgetRunningScriptByPid"; callingFnName = "getRunningScriptgetRunningScriptByPid";
} }
@ -319,7 +324,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
* @param {any[]} scriptArgs - Running script's arguments * @param {any[]} scriptArgs - Running script's arguments
* @returns {string} Error message to print to logs * @returns {string} Error message to print to logs
*/ */
const getCannotFindRunningScriptErrorMessage = function (fn: any, ip: any, scriptArgs: any) { const getCannotFindRunningScriptErrorMessage = function (fn: any, ip: any, scriptArgs: any): string {
if (!Array.isArray(scriptArgs)) { if (!Array.isArray(scriptArgs)) {
scriptArgs = []; scriptArgs = [];
} }
@ -330,7 +335,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
/** /**
* Checks if the player has TIX API access. Throws an error if the player does not * Checks if the player has TIX API access. Throws an error if the player does not
*/ */
const checkTixApiAccess = function (callingFn: any = "") { const checkTixApiAccess = function (callingFn: any = ""): void {
if (!Player.hasWseAccount) { if (!Player.hasWseAccount) {
throw makeRuntimeErrorMsg(callingFn, `You don't have WSE Access! Cannot use ${callingFn}()`); throw makeRuntimeErrorMsg(callingFn, `You don't have WSE Access! Cannot use ${callingFn}()`);
} }
@ -344,7 +349,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
* @param {string} symbol - Stock's symbol * @param {string} symbol - Stock's symbol
* @returns {Stock} stock object * @returns {Stock} stock object
*/ */
const getStockFromSymbol = function (symbol: any, callingFn: any = "") { const getStockFromSymbol = function (symbol: any, callingFn: any = ""): Stock {
const stock = SymbolToStockMap[symbol]; const stock = SymbolToStockMap[symbol];
if (stock == null) { if (stock == null) {
throw makeRuntimeErrorMsg(callingFn, `Invalid stock symbol: '${symbol}'`); throw makeRuntimeErrorMsg(callingFn, `Invalid stock symbol: '${symbol}'`);
@ -360,7 +365,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
* @param {string} callingFn - Name of calling function. For logging purposes * @param {string} callingFn - Name of calling function. For logging purposes
* @returns {boolean} True if the server is a Hacknet Server, false otherwise * @returns {boolean} True if the server is a Hacknet Server, false otherwise
*/ */
const failOnHacknetServer = function (server: any, callingFn: any = "") { const failOnHacknetServer = function (server: any, callingFn: any = ""): boolean {
if (server instanceof HacknetServer) { if (server instanceof HacknetServer) {
workerScript.log(callingFn, `Does not work on Hacknet Servers`); workerScript.log(callingFn, `Does not work on Hacknet Servers`);
return true; return true;
@ -398,7 +403,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const makeRuntimeErrorMsg = function (caller: string, msg: string) { const makeRuntimeErrorMsg = function (caller: string, msg: string): string {
const errstack = new Error().stack; const errstack = new Error().stack;
if (errstack === undefined) throw new Error("how did we not throw an error?"); if (errstack === undefined) throw new Error("how did we not throw an error?");
const stack = errstack.split("\n").slice(1); const stack = errstack.split("\n").slice(1);
@ -418,7 +423,12 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
if (!filename) continue; if (!filename) continue;
function parseChromeStackline(line: string) { interface ILine {
line: string;
func: string;
}
function parseChromeStackline(line: string): ILine | null {
const lineRe = /.*:(\d+):\d+.*/; const lineRe = /.*:(\d+):\d+.*/;
const funcRe = /.*at (.+) \(.*/; const funcRe = /.*at (.+) \(.*/;
@ -435,7 +445,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
call = chromeCall; call = chromeCall;
} }
function parseFirefoxStackline(line: string) { function parseFirefoxStackline(line: string): ILine | null {
const lineRe = /.*:(\d+):\d+$/; const lineRe = /.*:(\d+):\d+$/;
const lineMatch = line.match(lineRe); const lineMatch = line.match(lineRe);
@ -461,7 +471,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return makeRuntimeRejectMsg(workerScript, rejectMsg); return makeRuntimeRejectMsg(workerScript, rejectMsg);
}; };
const checkFormulasAccess = function (func: any, n: any) { const checkFormulasAccess = function (func: any, n: any): void {
if ((SourceFileFlags[5] < 1 && Player.bitNodeN !== 5) || (SourceFileFlags[n] < 1 && Player.bitNodeN !== n)) { if ((SourceFileFlags[5] < 1 && Player.bitNodeN !== 5) || (SourceFileFlags[n] < 1 && Player.bitNodeN !== n)) {
let extra = ""; let extra = "";
if (n !== 5) { if (n !== 5) {
@ -471,7 +481,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const checkSingularityAccess = function (func: any, n: any) { const checkSingularityAccess = function (func: any, n: any): void {
if (Player.bitNodeN !== 4) { if (Player.bitNodeN !== 4) {
if (SourceFileFlags[4] < n) { if (SourceFileFlags[4] < n) {
throw makeRuntimeErrorMsg(func, `This singularity function requires Source-File 4-${n} to run.`); throw makeRuntimeErrorMsg(func, `This singularity function requires Source-File 4-${n} to run.`);
@ -479,7 +489,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const checkBladeburnerAccess = function (func: any, skipjoined: any = false) { const checkBladeburnerAccess = function (func: any, skipjoined: any = false): void {
const bladeburner = Player.bladeburner; const bladeburner = Player.bladeburner;
if (bladeburner === null) throw new Error("Must have joined bladeburner"); if (bladeburner === null) throw new Error("Must have joined bladeburner");
const apiAccess = const apiAccess =
@ -500,7 +510,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const checkBladeburnerCity = function (func: any, city: any) { const checkBladeburnerCity = function (func: any, city: any): void {
const bladeburner = Player.bladeburner; const bladeburner = Player.bladeburner;
if (bladeburner === null) throw new Error("Must have joined bladeburner"); if (bladeburner === null) throw new Error("Must have joined bladeburner");
if (!bladeburner.cities.hasOwnProperty(city)) { if (!bladeburner.cities.hasOwnProperty(city)) {
@ -508,7 +518,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const checkSleeveAPIAccess = function (func: any) { const checkSleeveAPIAccess = function (func: any): void {
if (Player.bitNodeN !== 10 && !SourceFileFlags[10]) { if (Player.bitNodeN !== 10 && !SourceFileFlags[10]) {
throw makeRuntimeErrorMsg( throw makeRuntimeErrorMsg(
`sleeve.${func}`, `sleeve.${func}`,
@ -517,7 +527,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const checkSleeveNumber = function (func: any, sleeveNumber: any) { const checkSleeveNumber = function (func: any, sleeveNumber: any): void {
if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) { if (sleeveNumber >= Player.sleeves.length || sleeveNumber < 0) {
const msg = `Invalid sleeve number: ${sleeveNumber}`; const msg = `Invalid sleeve number: ${sleeveNumber}`;
workerScript.log(func, msg); workerScript.log(func, msg);
@ -525,7 +535,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const getCodingContract = function (func: any, ip: any, fn: any) { const getCodingContract = function (func: any, ip: any, fn: any): CodingContract {
const server = safeGetServer(ip, func); const server = safeGetServer(ip, func);
const contract = server.getContract(fn); const contract = server.getContract(fn);
if (contract == null) { if (contract == null) {
@ -535,7 +545,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return contract; return contract;
}; };
const checkGangApiAccess = function (func: any) { const checkGangApiAccess = function (func: any): void {
const gang = Player.gang; const gang = Player.gang;
if (gang === null) throw new Error("Must have joined gang"); if (gang === null) throw new Error("Must have joined gang");
const hasAccess = gang instanceof Gang; const hasAccess = gang instanceof Gang;
@ -544,14 +554,14 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const getGangMember = function (func: any, name: any) { const getGangMember = function (func: any, name: any): GangMember {
const gang = Player.gang; const gang = Player.gang;
if (gang === null) throw new Error("Must have joined gang"); if (gang === null) throw new Error("Must have joined gang");
for (const member of gang.members) if (member.name === name) return member; for (const member of gang.members) if (member.name === name) return member;
throw makeRuntimeErrorMsg(`gang.${func}`, `Invalid gang member: '${name}'`); throw makeRuntimeErrorMsg(`gang.${func}`, `Invalid gang member: '${name}'`);
}; };
const getGangTask = function (func: any, name: any) { const getGangTask = function (func: any, name: any): GangMemberTask {
const task = GangMemberTasks[name]; const task = GangMemberTasks[name];
if (!task) { if (!task) {
throw makeRuntimeErrorMsg(`gang.${func}`, `Invalid task: '${name}'`); throw makeRuntimeErrorMsg(`gang.${func}`, `Invalid task: '${name}'`);
@ -644,7 +654,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return employee; return employee;
} }
const runAfterReset = function (cbScript = null) { const runAfterReset = function (cbScript = null): void {
//Run a script after reset //Run a script after reset
if (cbScript && isString(cbScript)) { if (cbScript && isString(cbScript)) {
const home = Player.getHomeComputer(); const home = Player.getHomeComputer();
@ -663,7 +673,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
}; };
const hack = function (ip: any, manual: any, { threads: requestedThreads, stock }: any = {}) { const hack = function (ip: any, manual: any, { threads: requestedThreads, stock }: any = {}): Promise<number> {
if (ip === undefined) { if (ip === undefined) {
throw makeRuntimeErrorMsg("hack", "Takes 1 argument."); throw makeRuntimeErrorMsg("hack", "Takes 1 argument.");
} }
@ -764,7 +774,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
}); });
}; };
const argsToString = function (args: IArguments): string { const argsToString = function (args: any[]): string {
let out = ""; let out = "";
for (let arg of args) { for (let arg of args) {
arg = toNative(arg); arg = toNative(arg);
@ -924,7 +934,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
const out = []; const out = [];
for (let i = 0; i < server.serversOnNetwork.length; i++) { for (let i = 0; i < server.serversOnNetwork.length; i++) {
var entry; let entry;
const s = getServerOnNetwork(server, i); const s = getServerOnNetwork(server, i);
if (s === null) continue; if (s === null) continue;
if (hostnames) { if (hostnames) {
@ -1126,17 +1136,17 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads); return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads);
}); });
}, },
print: function (): any { print: function (...args: any[]): void {
if (arguments.length === 0) { if (args.length === 0) {
throw makeRuntimeErrorMsg("print", "Takes at least 1 argument."); throw makeRuntimeErrorMsg("print", "Takes at least 1 argument.");
} }
workerScript.print(argsToString(arguments)); workerScript.print(argsToString(args));
}, },
tprint: function (): any { tprint: function (...args: any[]): void {
if (arguments.length === 0) { if (args.length === 0) {
throw makeRuntimeErrorMsg("tprint", "Takes at least 1 argument."); throw makeRuntimeErrorMsg("tprint", "Takes at least 1 argument.");
} }
Terminal.print(`${workerScript.scriptRef.filename}: ${argsToString(arguments)}`); Terminal.print(`${workerScript.scriptRef.filename}: ${argsToString(args)}`);
}, },
tprintf: function (format: any, ...args: any): any { tprintf: function (format: any, ...args: any): any {
Terminal.print(vsprintf(format, args)); Terminal.print(vsprintf(format, args));
@ -1347,7 +1357,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
return true; return true;
}, },
run: function (scriptname: any, threads: any = 1): any { run: function (scriptname: any, threads: any = 1, ...args: any[]): any {
updateDynamicRam("run", getRamCost("run")); updateDynamicRam("run", getRamCost("run"));
if (scriptname === undefined) { if (scriptname === undefined) {
throw makeRuntimeErrorMsg("run", "Usage: run(scriptname, [numThreads], [arg1], [arg2]...)"); throw makeRuntimeErrorMsg("run", "Usage: run(scriptname, [numThreads], [arg1], [arg2]...)");
@ -1355,18 +1365,14 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (isNaN(threads) || threads <= 0) { if (isNaN(threads) || threads <= 0) {
throw makeRuntimeErrorMsg("run", `Invalid thread count. Must be numeric and > 0, is ${threads}`); throw makeRuntimeErrorMsg("run", `Invalid thread count. Must be numeric and > 0, is ${threads}`);
} }
const argsForNewScript = [];
for (let i = 2; i < arguments.length; ++i) {
argsForNewScript.push(arguments[i]);
}
const scriptServer = getServer(workerScript.serverIp); const scriptServer = getServer(workerScript.serverIp);
if (scriptServer == null) { if (scriptServer == null) {
throw makeRuntimeErrorMsg("run", "Could not find server. This is a bug. Report to dev."); throw makeRuntimeErrorMsg("run", "Could not find server. This is a bug. Report to dev.");
} }
return runScriptFromScript("run", scriptServer, scriptname, argsForNewScript, workerScript, threads); return runScriptFromScript("run", scriptServer, scriptname, args, workerScript, threads);
}, },
exec: function (scriptname: any, ip: any, threads: any = 1): any { exec: function (scriptname: any, ip: any, threads: any = 1, ...args: any[]): any {
updateDynamicRam("exec", getRamCost("exec")); updateDynamicRam("exec", getRamCost("exec"));
if (scriptname === undefined || ip === undefined) { if (scriptname === undefined || ip === undefined) {
throw makeRuntimeErrorMsg("exec", "Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)"); throw makeRuntimeErrorMsg("exec", "Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)");
@ -1374,17 +1380,13 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (isNaN(threads) || threads <= 0) { if (isNaN(threads) || threads <= 0) {
throw makeRuntimeErrorMsg("exec", `Invalid thread count. Must be numeric and > 0, is ${threads}`); throw makeRuntimeErrorMsg("exec", `Invalid thread count. Must be numeric and > 0, is ${threads}`);
} }
const argsForNewScript = [];
for (let i = 3; i < arguments.length; ++i) {
argsForNewScript.push(arguments[i]);
}
const server = getServer(ip); const server = getServer(ip);
if (server == null) { if (server == null) {
throw makeRuntimeErrorMsg("exec", `Invalid IP/hostname: ${ip}`); throw makeRuntimeErrorMsg("exec", `Invalid IP/hostname: ${ip}`);
} }
return runScriptFromScript("exec", server, scriptname, argsForNewScript, workerScript, threads); return runScriptFromScript("exec", server, scriptname, args, workerScript, threads);
}, },
spawn: function (scriptname: any, threads: any): any { spawn: function (scriptname: any, threads: any, ...args: any[]): any {
updateDynamicRam("spawn", getRamCost("spawn")); updateDynamicRam("spawn", getRamCost("spawn"));
if (!scriptname || !threads) { if (!scriptname || !threads) {
throw makeRuntimeErrorMsg("spawn", "Usage: spawn(scriptname, threads)"); throw makeRuntimeErrorMsg("spawn", "Usage: spawn(scriptname, threads)");
@ -1395,16 +1397,12 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (isNaN(threads) || threads <= 0) { if (isNaN(threads) || threads <= 0) {
throw makeRuntimeErrorMsg("spawn", `Invalid thread count. Must be numeric and > 0, is ${threads}`); throw makeRuntimeErrorMsg("spawn", `Invalid thread count. Must be numeric and > 0, is ${threads}`);
} }
const argsForNewScript = [];
for (let i = 2; i < arguments.length; ++i) {
argsForNewScript.push(arguments[i]);
}
const scriptServer = getServer(workerScript.serverIp); const scriptServer = getServer(workerScript.serverIp);
if (scriptServer == null) { if (scriptServer == null) {
throw makeRuntimeErrorMsg("spawn", "Could not find server. This is a bug. Report to dev"); throw makeRuntimeErrorMsg("spawn", "Could not find server. This is a bug. Report to dev");
} }
return runScriptFromScript("spawn", scriptServer, scriptname, argsForNewScript, workerScript, threads); return runScriptFromScript("spawn", scriptServer, scriptname, args, workerScript, threads);
}, spawnDelay * 1e3); }, spawnDelay * 1e3);
workerScript.log("spawn", `Will execute '${scriptname}' in ${spawnDelay} seconds`); workerScript.log("spawn", `Will execute '${scriptname}' in ${spawnDelay} seconds`);
@ -1546,7 +1544,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
// Scp for lit files // Scp for lit files
if (scriptname.endsWith(".lit")) { if (scriptname.endsWith(".lit")) {
let found = false; let found = false;
for (var i = 0; i < currServ.messages.length; ++i) { for (let i = 0; i < currServ.messages.length; ++i) {
if (!(currServ.messages[i] instanceof Message) && currServ.messages[i] == scriptname) { if (!(currServ.messages[i] instanceof Message) && currServ.messages[i] == scriptname) {
found = true; found = true;
break; break;
@ -1558,7 +1556,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return false; return false;
} }
for (var i = 0; i < destServer.messages.length; ++i) { for (let i = 0; i < destServer.messages.length; ++i) {
if (destServer.messages[i] === scriptname) { if (destServer.messages[i] === scriptname) {
workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`); workerScript.log("scp", `File '${scriptname}' copied over to '${destServer.hostname}'.`);
return true; // Already exists return true; // Already exists
@ -1572,7 +1570,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
// Scp for text files // Scp for text files
if (scriptname.endsWith(".txt")) { if (scriptname.endsWith(".txt")) {
let txtFile; let txtFile;
for (var i = 0; i < currServ.textFiles.length; ++i) { for (let i = 0; i < currServ.textFiles.length; ++i) {
if (currServ.textFiles[i].fn === scriptname) { if (currServ.textFiles[i].fn === scriptname) {
txtFile = currServ.textFiles[i]; txtFile = currServ.textFiles[i];
break; break;
@ -1583,7 +1581,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return false; return false;
} }
for (var i = 0; i < destServer.textFiles.length; ++i) { for (let i = 0; i < destServer.textFiles.length; ++i) {
if (destServer.textFiles[i].fn === scriptname) { if (destServer.textFiles[i].fn === scriptname) {
// Overwrite // Overwrite
destServer.textFiles[i].text = txtFile.text; destServer.textFiles[i].text = txtFile.text;
@ -1973,17 +1971,17 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (server == null) { if (server == null) {
throw makeRuntimeErrorMsg("fileExists", `Invalid IP/hostname: ${ip}`); throw makeRuntimeErrorMsg("fileExists", `Invalid IP/hostname: ${ip}`);
} }
for (var i = 0; i < server.scripts.length; ++i) { for (let i = 0; i < server.scripts.length; ++i) {
if (filename == server.scripts[i].filename) { if (filename == server.scripts[i].filename) {
return true; return true;
} }
} }
for (var i = 0; i < server.programs.length; ++i) { for (let i = 0; i < server.programs.length; ++i) {
if (filename.toLowerCase() == server.programs[i].toLowerCase()) { if (filename.toLowerCase() == server.programs[i].toLowerCase()) {
return true; return true;
} }
} }
for (var i = 0; i < server.messages.length; ++i) { for (let i = 0; i < server.messages.length; ++i) {
if (!(server.messages[i] instanceof Message) && filename.toLowerCase() === server.messages[i]) { if (!(server.messages[i] instanceof Message) && filename.toLowerCase() === server.messages[i]) {
return true; return true;
} }
@ -2433,7 +2431,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
// Delete from player's purchasedServers array // Delete from player's purchasedServers array
let found = false; let found = false;
for (var i = 0; i < Player.purchasedServers.length; ++i) { for (let i = 0; i < Player.purchasedServers.length; ++i) {
if (ip == Player.purchasedServers[i]) { if (ip == Player.purchasedServers[i]) {
found = true; found = true;
Player.purchasedServers.splice(i, 1); Player.purchasedServers.splice(i, 1);
@ -2455,7 +2453,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
// Delete from home computer // Delete from home computer
found = false; found = false;
const homeComputer = Player.getHomeComputer(); const homeComputer = Player.getHomeComputer();
for (var i = 0; i < homeComputer.serversOnNetwork.length; ++i) { for (let i = 0; i < homeComputer.serversOnNetwork.length; ++i) {
if (ip == homeComputer.serversOnNetwork[i]) { if (ip == homeComputer.serversOnNetwork[i]) {
homeComputer.serversOnNetwork.splice(i, 1); homeComputer.serversOnNetwork.splice(i, 1);
workerScript.log("deleteServer", `Deleted server '${hostnameStr}`); workerScript.log("deleteServer", `Deleted server '${hostnameStr}`);
@ -2750,18 +2748,18 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
} }
return 0; return 0;
}, },
getRunningScript: function (fn: any, ip: any): any { getRunningScript: function (fn: any, ip: any, ...args: any[]): any {
updateDynamicRam("getRunningScript", getRamCost("getRunningScript")); updateDynamicRam("getRunningScript", getRamCost("getRunningScript"));
let runningScript; let runningScript;
if (arguments.length === 0) { if (args.length === 0) {
runningScript = workerScript.scriptRef; runningScript = workerScript.scriptRef;
} else if (typeof fn === "number") { } else if (typeof fn === "number") {
runningScript = getRunningScriptByPid(fn, "getRunningScript"); runningScript = getRunningScriptByPid(fn, "getRunningScript");
} else { } else {
const scriptArgs = []; const scriptArgs = [];
for (let i = 2; i < arguments.length; ++i) { for (let i = 2; i < args.length; ++i) {
scriptArgs.push(arguments[i]); scriptArgs.push(args[i]);
} }
runningScript = getRunningScript(fn, ip, "getRunningScript", scriptArgs); runningScript = getRunningScript(fn, ip, "getRunningScript", scriptArgs);
} }
@ -2821,7 +2819,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
return calculateWeakenTime(server, Player); // Returns seconds return calculateWeakenTime(server, Player); // Returns seconds
}, },
getScriptIncome: function (scriptname: any, ip: any): any { getScriptIncome: function (scriptname: any, ip: any, ...args: any[]): any {
updateDynamicRam("getScriptIncome", getRamCost("getScriptIncome")); updateDynamicRam("getScriptIncome", getRamCost("getScriptIncome"));
if (arguments.length === 0) { if (arguments.length === 0) {
const res = []; const res = [];
@ -2842,22 +2840,18 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (server == null) { if (server == null) {
throw makeRuntimeErrorMsg("getScriptIncome", `Invalid IP/hostnamed: ${ip}`); throw makeRuntimeErrorMsg("getScriptIncome", `Invalid IP/hostnamed: ${ip}`);
} }
const argsForScript = []; const runningScriptObj = findRunningScript(scriptname, args, server);
for (let i = 2; i < arguments.length; ++i) {
argsForScript.push(arguments[i]);
}
const runningScriptObj = findRunningScript(scriptname, argsForScript, server);
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log( workerScript.log(
"getScriptIncome", "getScriptIncome",
`No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(argsForScript)}`, `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
); );
return -1; return -1;
} }
return runningScriptObj.onlineMoneyMade / runningScriptObj.onlineRunningTime; return runningScriptObj.onlineMoneyMade / runningScriptObj.onlineRunningTime;
} }
}, },
getScriptExpGain: function (scriptname: any, ip: any): any { getScriptExpGain: function (scriptname: any, ip: any, ...args: any[]): any {
updateDynamicRam("getScriptExpGain", getRamCost("getScriptExpGain")); updateDynamicRam("getScriptExpGain", getRamCost("getScriptExpGain"));
if (arguments.length === 0) { if (arguments.length === 0) {
let total = 0; let total = 0;
@ -2871,15 +2865,11 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
if (server == null) { if (server == null) {
throw makeRuntimeErrorMsg("getScriptExpGain", `Invalid IP/hostnamed: ${ip}`); throw makeRuntimeErrorMsg("getScriptExpGain", `Invalid IP/hostnamed: ${ip}`);
} }
const argsForScript = []; const runningScriptObj = findRunningScript(scriptname, args, server);
for (let i = 2; i < arguments.length; ++i) {
argsForScript.push(arguments[i]);
}
const runningScriptObj = findRunningScript(scriptname, argsForScript, server);
if (runningScriptObj == null) { if (runningScriptObj == null) {
workerScript.log( workerScript.log(
"getScriptExpGain", "getScriptExpGain",
`No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(argsForScript)}`, `No such script '${scriptname}' on '${server.hostname}' with args: ${arrayToString(args)}`,
); );
return -1; return -1;
} }
@ -4002,11 +3992,11 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
updateDynamicRam("getOwnedAugmentations", getRamCost("getOwnedAugmentations")); updateDynamicRam("getOwnedAugmentations", getRamCost("getOwnedAugmentations"));
checkSingularityAccess("getOwnedAugmentations", 3); checkSingularityAccess("getOwnedAugmentations", 3);
const res = []; const res = [];
for (var i = 0; i < Player.augmentations.length; ++i) { for (let i = 0; i < Player.augmentations.length; ++i) {
res.push(Player.augmentations[i].name); res.push(Player.augmentations[i].name);
} }
if (purchased) { if (purchased) {
for (var i = 0; i < Player.queuedAugmentations.length; ++i) { for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
res.push(Player.queuedAugmentations[i].name); res.push(Player.queuedAugmentations[i].name);
} }
} }
@ -4784,7 +4774,7 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
const warehouse = getWarehouse(divisionName, cityName); const warehouse = getWarehouse(divisionName, cityName);
SetSmartSupply(warehouse, enabled); SetSmartSupply(warehouse, enabled);
}, },
setSmartSupplyUseLeftovers: function (): any {}, // setSmartSupplyUseLeftovers: function (): any {},
buyMaterial: function (divisionName: any, cityName: any, materialName: any, amt: any): any { buyMaterial: function (divisionName: any, cityName: any, materialName: any, amt: any): any {
const material = getMaterial(divisionName, cityName, materialName); const material = getMaterial(divisionName, cityName, materialName);
BuyMaterial(material, amt); BuyMaterial(material, amt);

@ -16,8 +16,7 @@ function makeScriptBlob(code: string): Blob {
// (i.e. hack, grow, etc.). // (i.e. hack, grow, etc.).
// When the promise returned by this resolves, we'll have finished // When the promise returned by this resolves, we'll have finished
// running the main function of the script. // running the main function of the script.
export async function executeJSScript(scripts: Script[] = [], workerScript: WorkerScript) { export async function executeJSScript(scripts: Script[] = [], workerScript: WorkerScript): Promise<void> {
let loadedModule;
let uurls: ScriptUrl[] = []; let uurls: ScriptUrl[] = [];
const script = workerScript.getScript(); const script = workerScript.getScript();
if (script === null) throw new Error("script is null"); if (script === null) throw new Error("script is null");
@ -35,7 +34,7 @@ export async function executeJSScript(scripts: Script[] = [], workerScript: Work
script.module = new Promise((resolve) => resolve(eval("import(uurls[uurls.length - 1].url)"))); script.module = new Promise((resolve) => resolve(eval("import(uurls[uurls.length - 1].url)")));
script.dependencies = uurls; script.dependencies = uurls;
} }
loadedModule = await script.module; const loadedModule = await script.module;
const ns = workerScript.env.vars; const ns = workerScript.env.vars;

@ -14,13 +14,11 @@ import { isScriptErrorMessage, makeRuntimeRejectMsg } from "./NetscriptEvaluator
import { NetscriptFunctions } from "./NetscriptFunctions"; import { NetscriptFunctions } from "./NetscriptFunctions";
import { executeJSScript } from "./NetscriptJSEvaluator"; import { executeJSScript } from "./NetscriptJSEvaluator";
import { NetscriptPort, IPort } from "./NetscriptPort"; import { NetscriptPort, IPort } from "./NetscriptPort";
import { Player } from "./Player";
import { RunningScript } from "./Script/RunningScript"; import { RunningScript } from "./Script/RunningScript";
import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers"; import { getRamUsageFromRunningScript } from "./Script/RunningScriptHelpers";
import { scriptCalculateOfflineProduction } from "./Script/ScriptHelpers"; import { scriptCalculateOfflineProduction } from "./Script/ScriptHelpers";
import { Script } from "./Script/Script"; import { Script } from "./Script/Script";
import { AllServers } from "./Server/AllServers"; import { AllServers } from "./Server/AllServers";
import { Server } from "./Server/Server";
import { BaseServer } from "./Server/BaseServer"; import { BaseServer } from "./Server/BaseServer";
import { Settings } from "./Settings/Settings"; import { Settings } from "./Settings/Settings";
import { setTimeoutRef } from "./utils/SetTimeoutRef"; import { setTimeoutRef } from "./utils/SetTimeoutRef";
@ -42,7 +40,7 @@ for (let i = 0; i < CONSTANTS.NumNetscriptPorts; ++i) {
NetscriptPorts.push(NetscriptPort()); NetscriptPorts.push(NetscriptPort());
} }
export function prestigeWorkerScripts() { export function prestigeWorkerScripts(): void {
for (const ws of workerScripts.values()) { for (const ws of workerScripts.values()) {
ws.env.stopFlag = true; ws.env.stopFlag = true;
killWorkerScript(ws); killWorkerScript(ws);
@ -65,7 +63,7 @@ function startNetscript2Script(workerScript: WorkerScript): Promise<WorkerScript
// We need to go through the environment and wrap each function in such a way that it // We need to go through the environment and wrap each function in such a way that it
// can be called at most once at a time. This will prevent situations where multiple // can be called at most once at a time. This will prevent situations where multiple
// hack promises are outstanding, for example. // hack promises are outstanding, for example.
function wrap(propName: string, f: Function): Function { function wrap(propName: string, f: (...args: any[]) => Promise<void>): (...args: any[]) => Promise<void> {
// This function unfortunately cannot be an async function, because we don't // This function unfortunately cannot be an async function, because we don't
// know if the original one was, and there's no way to tell. // know if the original one was, and there's no way to tell.
return function (...args: any[]) { return function (...args: any[]) {
@ -85,7 +83,7 @@ function startNetscript2Script(workerScript: WorkerScript): Promise<WorkerScript
"Did you forget to await hack(), grow(), or some other " + "Did you forget to await hack(), grow(), or some other " +
"promise-returning function? (Currently running: %s tried to run: %s)"; "promise-returning function? (Currently running: %s tried to run: %s)";
if (runningFn) { if (runningFn) {
workerScript.errorMessage = makeRuntimeRejectMsg(workerScript, sprintf(msg, runningFn, propName), null); workerScript.errorMessage = makeRuntimeRejectMsg(workerScript, sprintf(msg, runningFn, propName));
throw workerScript; throw workerScript;
} }
runningFn = propName; runningFn = propName;
@ -158,7 +156,7 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<WorkerScript
return Promise.resolve(workerScript); return Promise.resolve(workerScript);
} }
const interpreterInitialization = function (int: any, scope: any) { const interpreterInitialization = function (int: any, scope: any): void {
//Add the Netscript environment //Add the Netscript environment
const ns = NetscriptFunctions(workerScript); const ns = NetscriptFunctions(workerScript);
for (const name in ns) { for (const name in ns) {
@ -173,20 +171,20 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<WorkerScript
name === "prompt" || name === "prompt" ||
name === "manualHack" name === "manualHack"
) { ) {
const tempWrapper = function () { const tempWrapper = function (...args: any[]): void {
const fnArgs = []; const fnArgs = [];
//All of the Object/array elements are in JSInterpreter format, so //All of the Object/array elements are in JSInterpreter format, so
//we have to convert them back to native format to pass them to these fns //we have to convert them back to native format to pass them to these fns
for (let i = 0; i < arguments.length - 1; ++i) { for (let i = 0; i < args.length - 1; ++i) {
if (typeof arguments[i] === "object" || arguments[i].constructor === Array) { if (typeof args[i] === "object" || args[i].constructor === Array) {
fnArgs.push(int.pseudoToNative(arguments[i])); fnArgs.push(int.pseudoToNative(args[i]));
} else { } else {
fnArgs.push(arguments[i]); fnArgs.push(args[i]);
} }
} }
const cb = arguments[arguments.length - 1]; const cb = args[args.length - 1];
const fnPromise = entry.apply(null, fnArgs); const fnPromise = entry(...fnArgs);
fnPromise fnPromise
.then(function (res: any) { .then(function (res: any) {
cb(res); cb(res);
@ -206,25 +204,25 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<WorkerScript
name === "run" || name === "run" ||
name === "exec" name === "exec"
) { ) {
const tempWrapper = function () { const tempWrapper = function (...args: any[]): void {
const fnArgs = []; const fnArgs = [];
//All of the Object/array elements are in JSInterpreter format, so //All of the Object/array elements are in JSInterpreter format, so
//we have to convert them back to native format to pass them to these fns //we have to convert them back to native format to pass them to these fns
for (let i = 0; i < arguments.length; ++i) { for (let i = 0; i < args.length; ++i) {
if (typeof arguments[i] === "object" || arguments[i].constructor === Array) { if (typeof args[i] === "object" || args[i].constructor === Array) {
fnArgs.push(int.pseudoToNative(arguments[i])); fnArgs.push(int.pseudoToNative(args[i]));
} else { } else {
fnArgs.push(arguments[i]); fnArgs.push(args[i]);
} }
} }
return entry.apply(null, fnArgs); return entry(...fnArgs);
}; };
int.setProperty(scope, name, int.createNativeFunction(tempWrapper)); int.setProperty(scope, name, int.createNativeFunction(tempWrapper));
} else { } else {
const tempWrapper = function () { const tempWrapper = function (...args: any[]): any {
const res = entry.apply(null, arguments); const res = entry(...args);
if (res == null) { if (res == null) {
return res; return res;
@ -259,7 +257,7 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<WorkerScript
} }
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
function runInterpreter() { function runInterpreter(): void {
try { try {
if (workerScript.env.stopFlag) { if (workerScript.env.stopFlag) {
return reject(workerScript); return reject(workerScript);
@ -595,7 +593,7 @@ export function createAndAddWorkerScript(
/** /**
* Updates the online running time stat of all running scripts * Updates the online running time stat of all running scripts
*/ */
export function updateOnlineScriptTimes(numCycles = 1) { export function updateOnlineScriptTimes(numCycles = 1): void {
const time = (numCycles * CONSTANTS._idleSpeed) / 1000; //seconds const time = (numCycles * CONSTANTS._idleSpeed) / 1000; //seconds
for (const ws of workerScripts.values()) { for (const ws of workerScripts.values()) {
ws.scriptRef.onlineRunningTime += time; ws.scriptRef.onlineRunningTime += time;
@ -606,7 +604,7 @@ export function updateOnlineScriptTimes(numCycles = 1) {
* Called when the game is loaded. Loads all running scripts (from all servers) * Called when the game is loaded. Loads all running scripts (from all servers)
* into worker scripts so that they will start running * into worker scripts so that they will start running
*/ */
export function loadAllRunningScripts() { export function loadAllRunningScripts(): void {
const skipScriptLoad = window.location.href.toLowerCase().indexOf("?noscripts") !== -1; const skipScriptLoad = window.location.href.toLowerCase().indexOf("?noscripts") !== -1;
if (skipScriptLoad) { if (skipScriptLoad) {
console.info("Skipping the load of any scripts during startup"); console.info("Skipping the load of any scripts during startup");

@ -409,8 +409,8 @@ export class PlayerObject implements IPlayer {
this.crimeType = ""; this.crimeType = "";
(this.timeWorked = 0), //in m; this.timeWorked = 0; //in m;
(this.timeWorkedCreateProgram = 0); this.timeWorkedCreateProgram = 0;
this.timeNeededToCompleteWork = 0; this.timeNeededToCompleteWork = 0;
this.work_money_mult = 1; this.work_money_mult = 1;
@ -438,15 +438,15 @@ export class PlayerObject implements IPlayer {
this.bladeburner = null; this.bladeburner = null;
this.bladeburner_max_stamina_mult = 1; this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1; this.bladeburner_stamina_gain_mult = 1;
(this.bladeburner_analysis_mult = 1), //Field Analysis Onl; this.bladeburner_analysis_mult = 1; //Field Analysis Onl;
(this.bladeburner_success_chance_mult = 1); this.bladeburner_success_chance_mult = 1;
// Sleeves & Re-sleeving // Sleeves & Re-sleeving
this.sleeves = []; this.sleeves = [];
this.resleeves = []; this.resleeves = [];
(this.sleevesFromCovenant = 0), // # of Duplicate sleeves purchased from the covenan; this.sleevesFromCovenant = 0; // # of Duplicate sleeves purchased from the covenan;
//bitnode //bitnode
(this.bitNodeN = 1); this.bitNodeN = 1;
//Used to store the last update time. //Used to store the last update time.
this.lastUpdate = 0; this.lastUpdate = 0;
@ -455,10 +455,10 @@ export class PlayerObject implements IPlayer {
this.playtimeSinceLastBitnode = 0; this.playtimeSinceLastBitnode = 0;
// Keep track of where money comes from // Keep track of where money comes from
(this.moneySourceA = new MoneySourceTracker()), // Where money comes from since last-installed Augmentatio; this.moneySourceA = new MoneySourceTracker(); // Where money comes from since last-installed Augmentatio;
(this.moneySourceB = new MoneySourceTracker()), // Where money comes from for this entire BitNode ru; this.moneySourceB = new MoneySourceTracker(); // Where money comes from for this entire BitNode ru;
// Production since last Augmentation installation // Production since last Augmentation installation
(this.scriptProdSinceLastAug = 0); this.scriptProdSinceLastAug = 0;
this.exploits = []; this.exploits = [];

@ -2,7 +2,7 @@ import { Bladeburner } from "../../Bladeburner/Bladeburner";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags"; import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { IPlayer } from "../IPlayer"; import { IPlayer } from "../IPlayer";
export function canAccessBladeburner(this: IPlayer) { export function canAccessBladeburner(this: IPlayer): boolean {
if (this.bitNodeN === 8) { if (this.bitNodeN === 8) {
return false; return false;
} }

@ -4,7 +4,7 @@ import { applyAugmentation } from "../../Augmentation/AugmentationHelpers";
import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation"; import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { CodingContractRewardType } from "../../CodingContracts"; import { CodingContractRewardType, ICodingContractReward } from "../../CodingContracts";
import { Company } from "../../Company/Company"; import { Company } from "../../Company/Company";
import { Companies } from "../../Company/Companies"; import { Companies } from "../../Company/Companies";
import { getNextCompanyPositionHelper } from "../../Company/GetNextCompanyPosition"; import { getNextCompanyPositionHelper } from "../../Company/GetNextCompanyPosition";
@ -15,13 +15,11 @@ import * as posNames from "../../Company/data/companypositionnames";
import { CONSTANTS } from "../../Constants"; import { CONSTANTS } from "../../Constants";
import { Programs } from "../../Programs/Programs"; import { Programs } from "../../Programs/Programs";
import { determineCrimeSuccess } from "../../Crime/CrimeHelpers"; import { determineCrimeSuccess } from "../../Crime/CrimeHelpers";
import { ICodingContractReward } from "../../CodingContracts";
import { Crimes } from "../../Crime/Crimes"; import { Crimes } from "../../Crime/Crimes";
import { Exploit } from "../../Exploits/Exploit"; import { Exploit } from "../../Exploits/Exploit";
import { Faction } from "../../Faction/Faction"; import { Faction } from "../../Faction/Faction";
import { Factions } from "../../Faction/Factions"; import { Factions } from "../../Faction/Factions";
import { resetGangs } from "../../Gang/AllGangs"; import { resetGangs } from "../../Gang/AllGangs";
import { hasHacknetServers } from "../../Hacknet/HacknetHelpers";
import { Cities } from "../../Locations/Cities"; import { Cities } from "../../Locations/Cities";
import { Locations } from "../../Locations/Locations"; import { Locations } from "../../Locations/Locations";
import { CityName } from "../../Locations/data/CityNames"; import { CityName } from "../../Locations/data/CityNames";
@ -60,7 +58,7 @@ import { Money } from "../../ui/React/Money";
import React from "react"; import React from "react";
export function init(this: IPlayer) { export function init(this: IPlayer): void {
/* Initialize Player's home computer */ /* Initialize Player's home computer */
const t_homeComp = safetlyCreateUniqueServer({ const t_homeComp = safetlyCreateUniqueServer({
adminRights: true, adminRights: true,
@ -78,7 +76,7 @@ export function init(this: IPlayer) {
this.getHomeComputer().programs.push(Programs.NukeProgram.name); this.getHomeComputer().programs.push(Programs.NukeProgram.name);
} }
export function prestigeAugmentation(this: IPlayer) { export function prestigeAugmentation(this: IPlayer): void {
const homeComp = this.getHomeComputer(); const homeComp = this.getHomeComputer();
this.currentServer = homeComp.ip; this.currentServer = homeComp.ip;
this.homeComputer = homeComp.ip; this.homeComputer = homeComp.ip;
@ -178,7 +176,7 @@ export function prestigeAugmentation(this: IPlayer) {
this.hp = this.max_hp; this.hp = this.max_hp;
} }
export function prestigeSourceFile(this: IPlayer) { export function prestigeSourceFile(this: IPlayer): void {
this.prestigeAugmentation(); this.prestigeAugmentation();
// Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists) // Duplicate sleeves are reset to level 1 every Bit Node (but the number of sleeves you have persists)
for (let i = 0; i < this.sleeves.length; ++i) { for (let i = 0; i < this.sleeves.length; ++i) {
@ -354,7 +352,7 @@ export function canAfford(this: IPlayer, cost: number): boolean {
return this.money.gte(cost); return this.money.gte(cost);
} }
export function recordMoneySource(this: IPlayer, amt: number, source: string) { export function recordMoneySource(this: IPlayer, amt: number, source: string): void {
if (!(this.moneySourceA instanceof MoneySourceTracker)) { if (!(this.moneySourceA instanceof MoneySourceTracker)) {
console.warn(`Player.moneySourceA was not properly initialized. Resetting`); console.warn(`Player.moneySourceA was not properly initialized. Resetting`);
this.moneySourceA = new MoneySourceTracker(); this.moneySourceA = new MoneySourceTracker();
@ -367,7 +365,7 @@ export function recordMoneySource(this: IPlayer, amt: number, source: string) {
this.moneySourceB.record(amt, source); this.moneySourceB.record(amt, source);
} }
export function gainHackingExp(this: IPlayer, exp: number) { export function gainHackingExp(this: IPlayer, exp: number): void {
if (isNaN(exp)) { if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainHackingExp()"); console.error("ERR: NaN passed into Player.gainHackingExp()");
return; return;
@ -380,7 +378,7 @@ export function gainHackingExp(this: IPlayer, exp: number) {
this.hacking_skill = calculateSkillF(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier); this.hacking_skill = calculateSkillF(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier);
} }
export function gainStrengthExp(this: IPlayer, exp: number) { export function gainStrengthExp(this: IPlayer, exp: number): void {
if (isNaN(exp)) { if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainStrengthExp()"); console.error("ERR: NaN passed into Player.gainStrengthExp()");
return; return;
@ -393,7 +391,7 @@ export function gainStrengthExp(this: IPlayer, exp: number) {
this.strength = calculateSkillF(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier); this.strength = calculateSkillF(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier);
} }
export function gainDefenseExp(this: IPlayer, exp: number) { export function gainDefenseExp(this: IPlayer, exp: number): void {
if (isNaN(exp)) { if (isNaN(exp)) {
console.error("ERR: NaN passed into player.gainDefenseExp()"); console.error("ERR: NaN passed into player.gainDefenseExp()");
return; return;
@ -406,7 +404,7 @@ export function gainDefenseExp(this: IPlayer, exp: number) {
this.defense = calculateSkillF(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier); this.defense = calculateSkillF(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier);
} }
export function gainDexterityExp(this: IPlayer, exp: number) { export function gainDexterityExp(this: IPlayer, exp: number): void {
if (isNaN(exp)) { if (isNaN(exp)) {
console.error("ERR: NaN passed into Player.gainDexterityExp()"); console.error("ERR: NaN passed into Player.gainDexterityExp()");
return; return;
@ -520,7 +518,7 @@ export function resetWorkStatus(this: IPlayer, generalType?: string, group?: str
this.className = ""; this.className = "";
} }
export function processWorkEarnings(this: IPlayer, numCycles = 1) { export function processWorkEarnings(this: IPlayer, numCycles = 1): void {
const focusBonus = this.focus ? 1 : 0.8; const focusBonus = this.focus ? 1 : 0.8;
const hackExpGain = focusBonus * this.workHackExpGainRate * numCycles; const hackExpGain = focusBonus * this.workHackExpGainRate * numCycles;
const strExpGain = focusBonus * this.workStrExpGainRate * numCycles; const strExpGain = focusBonus * this.workStrExpGainRate * numCycles;
@ -574,7 +572,7 @@ export function startWork(this: IPlayer, router: IRouter, companyName: string):
router.toWork(); router.toWork();
} }
export function cancelationPenalty(this: IPlayer) { export function cancelationPenalty(this: IPlayer): number {
const specialIp = SpecialServerIps[this.companyName]; const specialIp = SpecialServerIps[this.companyName];
if (typeof specialIp === "string" && specialIp !== "") { if (typeof specialIp === "string" && specialIp !== "") {
const server = AllServers[specialIp]; const server = AllServers[specialIp];
@ -2547,8 +2545,7 @@ export function gainCodingContractReward(this: IPlayer, reward: ICodingContractR
// Ignore Bladeburners and other special factions for this calculation // Ignore Bladeburners and other special factions for this calculation
const specialFactions = ["Bladeburners"]; const specialFactions = ["Bladeburners"];
const factions = this.factions.slice(); const factions = this.factions.slice().filter((f) => {
factions = factions.filter((f) => {
return !specialFactions.includes(f); return !specialFactions.includes(f);
}); });
@ -2567,7 +2564,7 @@ export function gainCodingContractReward(this: IPlayer, reward: ICodingContractR
} }
return `Gained ${gainPerFaction} reputation for each of the following factions: ${factions.toString()}`; return `Gained ${gainPerFaction} reputation for each of the following factions: ${factions.toString()}`;
break; break;
case CodingContractRewardType.CompanyReputation: case CodingContractRewardType.CompanyReputation: {
if (reward.name == null || !(Companies[reward.name] instanceof Company)) { if (reward.name == null || !(Companies[reward.name] instanceof Company)) {
//If no/invalid company was designated, just give rewards to all factions //If no/invalid company was designated, just give rewards to all factions
reward.type = CodingContractRewardType.FactionReputationAll; reward.type = CodingContractRewardType.FactionReputationAll;
@ -2576,14 +2573,14 @@ export function gainCodingContractReward(this: IPlayer, reward: ICodingContractR
const repGain = CONSTANTS.CodingContractBaseCompanyRepGain * difficulty; const repGain = CONSTANTS.CodingContractBaseCompanyRepGain * difficulty;
Companies[reward.name].playerReputation += repGain; Companies[reward.name].playerReputation += repGain;
return `Gained ${repGain} company reputation for ${reward.name}`; return `Gained ${repGain} company reputation for ${reward.name}`;
break; }
case CodingContractRewardType.Money: case CodingContractRewardType.Money:
default: default: {
const moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers.CodingContractMoney; const moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers.CodingContractMoney;
this.gainMoney(moneyGain); this.gainMoney(moneyGain);
this.recordMoneySource(moneyGain, "codingcontract"); this.recordMoneySource(moneyGain, "codingcontract");
return `Gained ${numeralWrapper.formatMoney(moneyGain)}`; return `Gained ${numeralWrapper.formatMoney(moneyGain)}`;
break; }
} }
/* eslint-enable no-case-declarations */ /* eslint-enable no-case-declarations */
} }