mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-19 06:03:50 +01:00
Merge branch 'dev' of github.com:danielyxie/bitburner into dev
This commit is contained in:
commit
07538d6509
@ -26,6 +26,10 @@ export const CorporationConstants: {
|
|||||||
BaseMaxProducts: number;
|
BaseMaxProducts: number;
|
||||||
AllCorporationStates: string[];
|
AllCorporationStates: string[];
|
||||||
AllMaterials: string[];
|
AllMaterials: string[];
|
||||||
|
AllIndustryTypes: string[];
|
||||||
|
AllUnlocks: string[];
|
||||||
|
AllUpgrades: string[];
|
||||||
|
AllResearch: string[];
|
||||||
FundingRoundShares: number[];
|
FundingRoundShares: number[];
|
||||||
FundingRoundMultiplier: number[];
|
FundingRoundMultiplier: number[];
|
||||||
AvgProfitLength: number;
|
AvgProfitLength: number;
|
||||||
@ -82,6 +86,70 @@ export const CorporationConstants: {
|
|||||||
"AI Cores",
|
"AI Cores",
|
||||||
"Real Estate",
|
"Real Estate",
|
||||||
],
|
],
|
||||||
|
AllIndustryTypes: [
|
||||||
|
"Energy",
|
||||||
|
"Utilities",
|
||||||
|
"Agriculture",
|
||||||
|
"Fishing",
|
||||||
|
"Mining",
|
||||||
|
"Food",
|
||||||
|
"Tobacco",
|
||||||
|
"Chemical",
|
||||||
|
"Pharmaceutical",
|
||||||
|
"Hardware",
|
||||||
|
"Robotics",
|
||||||
|
"Software",
|
||||||
|
"Healthcare",
|
||||||
|
"RealEstate",
|
||||||
|
],
|
||||||
|
AllUnlocks: [
|
||||||
|
"Export",
|
||||||
|
"Smart Supply",
|
||||||
|
"Market Research - Demand",
|
||||||
|
"Market Data - Competition",
|
||||||
|
"VeChain",
|
||||||
|
"Shady Accounting",
|
||||||
|
"Government Partnership",
|
||||||
|
"Warehouse API",
|
||||||
|
"Office API",
|
||||||
|
],
|
||||||
|
AllUpgrades: [
|
||||||
|
"Smart Factories",
|
||||||
|
"Smart Storage",
|
||||||
|
"DreamSense",
|
||||||
|
"Wilson Analytics",
|
||||||
|
"Nuoptimal Nootropic Injector Implants",
|
||||||
|
"Speech Processor Implants",
|
||||||
|
"Neural Accelerators",
|
||||||
|
"FocusWires",
|
||||||
|
"ABC SalesBots",
|
||||||
|
"Project Insight",
|
||||||
|
],
|
||||||
|
AllResearch: [
|
||||||
|
"Hi-Tech R&D Laboratory",
|
||||||
|
"AutoBrew",
|
||||||
|
"AutoPartyManager",
|
||||||
|
"Automatic Drug Administration",
|
||||||
|
"Bulk Purchasing",
|
||||||
|
"CPH4 Injections",
|
||||||
|
"Drones",
|
||||||
|
"Drones - Assembly",
|
||||||
|
"Drones - Transport",
|
||||||
|
"Go-Juice",
|
||||||
|
"HRBuddy-Recruitment",
|
||||||
|
"HRBuddy-Training",
|
||||||
|
"JoyWire",
|
||||||
|
"Market-TA.I",
|
||||||
|
"Market-TA.II",
|
||||||
|
"Overclock",
|
||||||
|
"Self-Correcting Assemblers",
|
||||||
|
"Sti.mu",
|
||||||
|
"sudo.Assist",
|
||||||
|
"uPgrade: Capacity.I",
|
||||||
|
"uPgrade: Capacity.II",
|
||||||
|
"uPgrade: Dashboard",
|
||||||
|
"uPgrade: Fulcrum",
|
||||||
|
],
|
||||||
FundingRoundShares: [0.1, 0.35, 0.25, 0.2],
|
FundingRoundShares: [0.1, 0.35, 0.25, 0.2],
|
||||||
FundingRoundMultiplier: [4, 3, 3, 2.5],
|
FundingRoundMultiplier: [4, 3, 3, 2.5],
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
|||||||
{!division.hasResearch("AutoBrew") && (
|
{!division.hasResearch("AutoBrew") && (
|
||||||
<>
|
<>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
|
title={<Typography>Provide your employees with coffee, increasing their energy by 5%</Typography>}
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
<Button
|
<Button
|
||||||
|
@ -151,7 +151,7 @@ const positive = [
|
|||||||
"patient",
|
"patient",
|
||||||
"dynamic",
|
"dynamic",
|
||||||
"loyal",
|
"loyal",
|
||||||
"based",
|
"straightforward",
|
||||||
];
|
];
|
||||||
|
|
||||||
const negative = [
|
const negative = [
|
||||||
|
@ -1,22 +1,15 @@
|
|||||||
import { getRamCost } from "./RamCostGenerator";
|
import { getRamCost } from "./RamCostGenerator";
|
||||||
import type { IPort } from "../NetscriptPort";
|
|
||||||
import type { BaseServer } from "../Server/BaseServer";
|
|
||||||
import type { WorkerScript } from "./WorkerScript";
|
import type { WorkerScript } from "./WorkerScript";
|
||||||
import { makeRuntimeRejectMsg } from "../NetscriptEvaluator";
|
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { helpers } from "./NetscriptHelpers";
|
||||||
import { BasicHGWOptions } from "../ScriptEditor/NetscriptDefinitions";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { Server } from "../Server/Server";
|
|
||||||
import { FormulaGang } from "../Gang/formulas/formulas";
|
|
||||||
import { INetscriptHelper, ScriptIdentifier } from "../NetscriptFunctions/INetscriptHelper";
|
|
||||||
import { GangMember } from "../Gang/GangMember";
|
|
||||||
import { GangMemberTask } from "../Gang/GangMemberTask";
|
|
||||||
import { ScriptArg } from "./ScriptArg";
|
import { ScriptArg } from "./ScriptArg";
|
||||||
|
import { NSEnums } from "src/ScriptEditor/NetscriptDefinitions";
|
||||||
|
import { NSFull } from "src/NetscriptFunctions";
|
||||||
|
|
||||||
type ExternalFunction = (...args: unknown[]) => unknown;
|
type ExternalFunction = (...args: unknown[]) => unknown;
|
||||||
export type ExternalAPI = {
|
|
||||||
[string: string]: ExternalAPI | ExternalFunction;
|
export type ExternalAPILayer = {
|
||||||
|
[key: string]: ExternalAPILayer | ExternalFunction | ScriptArg[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type InternalFunction<F extends (...args: unknown[]) => unknown> = (ctx: NetscriptContext) => F;
|
type InternalFunction<F extends (...args: unknown[]) => unknown> = (ctx: NetscriptContext) => F;
|
||||||
@ -24,48 +17,23 @@ type InternalFunction<F extends (...args: unknown[]) => unknown> = (ctx: Netscri
|
|||||||
export type InternalAPI<API> = {
|
export type InternalAPI<API> = {
|
||||||
[Property in keyof API]: API[Property] extends ExternalFunction
|
[Property in keyof API]: API[Property] extends ExternalFunction
|
||||||
? InternalFunction<API[Property]>
|
? InternalFunction<API[Property]>
|
||||||
|
: API[Property] extends NSEnums
|
||||||
|
? NSEnums
|
||||||
|
: API[Property] extends ScriptArg[]
|
||||||
|
? ScriptArg[]
|
||||||
: API[Property] extends object
|
: API[Property] extends object
|
||||||
? InternalAPI<API[Property]>
|
? InternalAPI<API[Property]>
|
||||||
: never;
|
: never;
|
||||||
};
|
};
|
||||||
|
|
||||||
type WrappedNetscriptFunction = (...args: unknown[]) => unknown;
|
|
||||||
type WrappedNetscriptAPI = {
|
|
||||||
readonly [string: string]: WrappedNetscriptAPI | WrappedNetscriptFunction;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NetscriptContext = {
|
export type NetscriptContext = {
|
||||||
makeRuntimeErrorMsg: (message: string) => string;
|
|
||||||
log: (message: () => string) => void;
|
|
||||||
workerScript: WorkerScript;
|
workerScript: WorkerScript;
|
||||||
function: string;
|
function: string;
|
||||||
helper: WrappedNetscriptHelpers;
|
functionPath: string;
|
||||||
};
|
|
||||||
|
|
||||||
type WrappedNetscriptHelpers = {
|
|
||||||
makeRuntimeErrorMsg: (msg: string) => string;
|
|
||||||
string: (argName: string, v: unknown) => string;
|
|
||||||
number: (argName: string, v: unknown) => number;
|
|
||||||
ustring: (argName: string, v: unknown) => string | undefined;
|
|
||||||
unumber: (argName: string, v: unknown) => number | undefined;
|
|
||||||
scriptArgs(args: unknown): ScriptArg[];
|
|
||||||
scriptIdentifier: (fn: unknown, hostname: unknown, args: unknown) => ScriptIdentifier;
|
|
||||||
city: (argName: string, v: unknown) => CityName;
|
|
||||||
boolean: (v: unknown) => boolean;
|
|
||||||
getServer: (hostname: string) => BaseServer;
|
|
||||||
checkSingularityAccess: () => void;
|
|
||||||
hack: (hostname: string, manual: boolean, { threads: requestedThreads, stock }?: BasicHGWOptions) => Promise<number>;
|
|
||||||
getValidPort: (port: number) => IPort;
|
|
||||||
player(p: unknown): IPlayer;
|
|
||||||
server(s: unknown): Server;
|
|
||||||
gang(g: unknown): FormulaGang;
|
|
||||||
gangMember: (m: unknown) => GangMember;
|
|
||||||
gangTask: (t: unknown) => GangMemberTask;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function wrapFunction(
|
function wrapFunction(
|
||||||
helpers: INetscriptHelper,
|
wrappedAPI: ExternalAPILayer,
|
||||||
wrappedAPI: ExternalAPI,
|
|
||||||
workerScript: WorkerScript,
|
workerScript: WorkerScript,
|
||||||
func: (_ctx: NetscriptContext) => (...args: unknown[]) => unknown,
|
func: (_ctx: NetscriptContext) => (...args: unknown[]) => unknown,
|
||||||
...tree: string[]
|
...tree: string[]
|
||||||
@ -73,44 +41,19 @@ function wrapFunction(
|
|||||||
const functionPath = tree.join(".");
|
const functionPath = tree.join(".");
|
||||||
const functionName = tree.pop();
|
const functionName = tree.pop();
|
||||||
if (typeof functionName !== "string") {
|
if (typeof functionName !== "string") {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Failure occured while wrapping netscript api");
|
throw helpers.makeRuntimeRejectMsg(workerScript, "Failure occured while wrapping netscript api");
|
||||||
}
|
}
|
||||||
const ctx = {
|
const ctx = {
|
||||||
makeRuntimeErrorMsg: (message: string) => {
|
|
||||||
return helpers.makeRuntimeErrorMsg(functionPath, message);
|
|
||||||
},
|
|
||||||
log: (message: () => string) => {
|
|
||||||
workerScript.log(functionPath, message);
|
|
||||||
},
|
|
||||||
workerScript,
|
workerScript,
|
||||||
function: functionName,
|
function: functionName,
|
||||||
helper: {
|
functionPath,
|
||||||
makeRuntimeErrorMsg: (msg: string) => helpers.makeRuntimeErrorMsg(functionPath, msg),
|
|
||||||
string: (argName: string, v: unknown) => helpers.string(functionPath, argName, v),
|
|
||||||
number: (argName: string, v: unknown) => helpers.number(functionPath, argName, v),
|
|
||||||
ustring: (argName: string, v: unknown) => helpers.ustring(functionPath, argName, v),
|
|
||||||
unumber: (argName: string, v: unknown) => helpers.unumber(functionPath, argName, v),
|
|
||||||
scriptArgs: (v: unknown) => helpers.scriptArgs(functionPath, v),
|
|
||||||
scriptIdentifier: (fn: unknown, hostname: unknown, args: unknown) =>
|
|
||||||
helpers.scriptIdentifier(functionPath, fn, hostname, args),
|
|
||||||
city: (argName: string, v: unknown) => helpers.city(functionPath, argName, v),
|
|
||||||
boolean: helpers.boolean,
|
|
||||||
getServer: (hostname: string) => helpers.getServer(hostname, ctx),
|
|
||||||
checkSingularityAccess: () => helpers.checkSingularityAccess(functionName),
|
|
||||||
hack: (hostname: string, manual: boolean, extra?: BasicHGWOptions) => helpers.hack(ctx, hostname, manual, extra),
|
|
||||||
getValidPort: (port: number) => helpers.getValidPort(functionPath, port),
|
|
||||||
player: (p: unknown) => helpers.player(functionPath, p),
|
|
||||||
server: (s: unknown) => helpers.server(functionPath, s),
|
|
||||||
gang: (g: unknown) => helpers.gang(functionPath, g),
|
|
||||||
gangMember: (m: unknown) => helpers.gangMember(functionPath, m),
|
|
||||||
gangTask: (t: unknown) => helpers.gangTask(functionPath, t),
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
function wrappedFunction(...args: unknown[]): unknown {
|
function wrappedFunction(...args: unknown[]): unknown {
|
||||||
helpers.updateDynamicRam(ctx.function, getRamCost(Player, ...tree, ctx.function));
|
helpers.checkEnvFlags(ctx);
|
||||||
|
helpers.updateDynamicRam(ctx, getRamCost(Player, ...tree, ctx.function));
|
||||||
return func(ctx)(...args);
|
return func(ctx)(...args);
|
||||||
}
|
}
|
||||||
const parent = getNestedProperty(wrappedAPI, ...tree);
|
const parent = getNestedProperty(wrappedAPI, tree);
|
||||||
Object.defineProperty(parent, functionName, {
|
Object.defineProperty(parent, functionName, {
|
||||||
value: wrappedFunction,
|
value: wrappedFunction,
|
||||||
writable: true,
|
writable: true,
|
||||||
@ -118,20 +61,25 @@ function wrapFunction(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrapAPI(
|
export function wrapAPI(workerScript: WorkerScript, namespace: object, args: ScriptArg[]): NSFull {
|
||||||
helpers: INetscriptHelper,
|
const wrappedAPI = wrapAPILayer({}, workerScript, namespace);
|
||||||
wrappedAPI: ExternalAPI,
|
wrappedAPI.args = args;
|
||||||
|
return wrappedAPI as unknown as NSFull;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function wrapAPILayer(
|
||||||
|
wrappedAPI: ExternalAPILayer,
|
||||||
workerScript: WorkerScript,
|
workerScript: WorkerScript,
|
||||||
namespace: object,
|
namespace: object,
|
||||||
...tree: string[]
|
...tree: string[]
|
||||||
): WrappedNetscriptAPI {
|
) {
|
||||||
for (const [key, value] of Object.entries(namespace)) {
|
for (const [key, value] of Object.entries(namespace)) {
|
||||||
if (typeof value === "function") {
|
if (typeof value === "function") {
|
||||||
wrapFunction(helpers, wrappedAPI, workerScript, value, ...tree, key);
|
wrapFunction(wrappedAPI, workerScript, value, ...tree, key);
|
||||||
} else if (Array.isArray(value)) {
|
} else if (Array.isArray(value)) {
|
||||||
setNestedProperty(wrappedAPI, value, key);
|
setNestedProperty(wrappedAPI, value.slice(), key);
|
||||||
} else if (typeof value === "object") {
|
} else if (typeof value === "object") {
|
||||||
wrapAPI(helpers, wrappedAPI, workerScript, value, ...tree, key);
|
wrapAPILayer(wrappedAPI, workerScript, value, ...tree, key);
|
||||||
} else {
|
} else {
|
||||||
setNestedProperty(wrappedAPI, value, ...tree, key);
|
setNestedProperty(wrappedAPI, value, ...tree, key);
|
||||||
}
|
}
|
||||||
@ -139,28 +87,21 @@ export function wrapAPI(
|
|||||||
return wrappedAPI;
|
return wrappedAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This doesn't even work properly.
|
function setNestedProperty(root: any, value: unknown, ...tree: string[]): void {
|
||||||
function setNestedProperty(root: object, value: unknown, ...tree: string[]): void {
|
|
||||||
let target = root;
|
let target = root;
|
||||||
const key = tree.pop();
|
const key = tree.pop();
|
||||||
if (!key) {
|
if (!key) throw new Error("Failure occured while wrapping netscript api (setNestedProperty)");
|
||||||
throw new Error("Failure occured while wrapping netscript api (setNestedProperty)");
|
for (const branch of tree) {
|
||||||
|
target[branch] ??= {};
|
||||||
|
target = target[branch];
|
||||||
}
|
}
|
||||||
for (let branch of Object.values(target)) {
|
target[key] = value;
|
||||||
if (branch === undefined) {
|
|
||||||
branch = {};
|
|
||||||
}
|
|
||||||
target = branch;
|
|
||||||
}
|
|
||||||
Object.assign(target, { [key]: value });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNestedProperty(root: any, ...tree: string[]): unknown {
|
function getNestedProperty(root: any, tree: string[]): unknown {
|
||||||
let target = root;
|
let target = root;
|
||||||
for (const branch of tree) {
|
for (const branch of tree) {
|
||||||
if (target[branch] === undefined) {
|
target[branch] ??= {};
|
||||||
target[branch] = {};
|
|
||||||
}
|
|
||||||
target = target[branch];
|
target = target[branch];
|
||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
|
@ -10,6 +10,12 @@ export class Environment {
|
|||||||
*/
|
*/
|
||||||
stopFlag = false;
|
stopFlag = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The currently running function
|
||||||
|
*/
|
||||||
|
|
||||||
|
runningFn = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Environment variables (currently only Netscript functions)
|
* Environment variables (currently only Netscript functions)
|
||||||
*/
|
*/
|
||||||
|
665
src/Netscript/NetscriptHelpers.ts
Normal file
665
src/Netscript/NetscriptHelpers.ts
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
import { NetscriptContext } from "./APIWrapper";
|
||||||
|
import { WorkerScript } from "./WorkerScript";
|
||||||
|
import { GetAllServers, GetServer } from "../Server/AllServers";
|
||||||
|
import { Player } from "../Player";
|
||||||
|
import { ScriptDeath } from "./ScriptDeath";
|
||||||
|
import { isString } from "../utils/helpers/isString";
|
||||||
|
import { numeralWrapper } from "../ui/numeralFormat";
|
||||||
|
import { ScriptArg } from "./ScriptArg";
|
||||||
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
|
import { BasicHGWOptions } from "src/ScriptEditor/NetscriptDefinitions";
|
||||||
|
import { Server } from "../Server/Server";
|
||||||
|
import {
|
||||||
|
calculateHackingChance,
|
||||||
|
calculateHackingExpGain,
|
||||||
|
calculateHackingTime,
|
||||||
|
calculatePercentMoneyHacked,
|
||||||
|
} from "../Hacking";
|
||||||
|
import { netscriptCanHack } from "../Hacking/netscriptCanHack";
|
||||||
|
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||||
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
|
import { CONSTANTS } from "../Constants";
|
||||||
|
import { influenceStockThroughServerHack } from "../StockMarket/PlayerInfluencing";
|
||||||
|
import { IPort } from "../NetscriptPort";
|
||||||
|
import { NetscriptPorts } from "../NetscriptWorker";
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { FormulaGang } from "../Gang/formulas/formulas";
|
||||||
|
import { GangMember } from "../Gang/GangMember";
|
||||||
|
import { GangMemberTask } from "../Gang/GangMemberTask";
|
||||||
|
import { RunningScript } from "../Script/RunningScript";
|
||||||
|
import { toNative } from "../NetscriptFunctions/toNative";
|
||||||
|
import { ScriptIdentifier } from "./ScriptIdentifier";
|
||||||
|
import { findRunningScript, findRunningScriptByPid } from "../Script/ScriptHelpers";
|
||||||
|
import { RunningScript as IRunningScript } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
|
import { arrayToString } from "../utils/helpers/arrayToString";
|
||||||
|
import { HacknetServer } from "../Hacknet/HacknetServer";
|
||||||
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
|
|
||||||
|
export const helpers = {
|
||||||
|
string,
|
||||||
|
number,
|
||||||
|
scriptArgs,
|
||||||
|
argsToString,
|
||||||
|
isScriptErrorMessage,
|
||||||
|
makeRuntimeRejectMsg,
|
||||||
|
makeRuntimeErrorMsg,
|
||||||
|
resolveNetscriptRequestedThreads,
|
||||||
|
checkEnvFlags,
|
||||||
|
checkSingularityAccess,
|
||||||
|
netscriptDelay,
|
||||||
|
updateDynamicRam,
|
||||||
|
city,
|
||||||
|
getServer,
|
||||||
|
scriptIdentifier,
|
||||||
|
hack,
|
||||||
|
getValidPort,
|
||||||
|
player,
|
||||||
|
server,
|
||||||
|
gang,
|
||||||
|
gangMember,
|
||||||
|
gangTask,
|
||||||
|
log,
|
||||||
|
getFunctionNames,
|
||||||
|
getRunningScript,
|
||||||
|
getRunningScriptByArgs,
|
||||||
|
getCannotFindRunningScriptErrorMessage,
|
||||||
|
createPublicRunningScript,
|
||||||
|
failOnHacknetServer,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Convert a provided value v for argument argName to string. If it wasn't originally a string or number, throw. */
|
||||||
|
function string(ctx: NetscriptContext, argName: string, v: unknown): string {
|
||||||
|
if (typeof v === "string") return v;
|
||||||
|
if (typeof v === "number") return v + ""; // cast to string;
|
||||||
|
throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a string.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert provided value v for argument argName to number. Throw if could not convert to a non-NaN number. */
|
||||||
|
function number(ctx: NetscriptContext, argName: string, v: unknown): number {
|
||||||
|
if (typeof v === "string") {
|
||||||
|
const x = parseFloat(v);
|
||||||
|
if (!isNaN(x)) return x; // otherwise it wasn't even a string representing a number.
|
||||||
|
} else if (typeof v === "number") {
|
||||||
|
if (isNaN(v)) throw makeRuntimeErrorMsg(ctx, `'${argName}' is NaN.`);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
throw makeRuntimeErrorMsg(ctx, `'${argName}' should be a number.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns args back if it is a ScriptArg[]. Throws an error if it is not. */
|
||||||
|
function scriptArgs(ctx: NetscriptContext, args: unknown) {
|
||||||
|
if (!isScriptArgs(args)) throw makeRuntimeErrorMsg(ctx, "'args' is not an array of script args");
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Determines if the given msg string is an error created by makeRuntimeRejectMsg. */
|
||||||
|
function isScriptErrorMessage(msg: string): boolean {
|
||||||
|
if (!isString(msg)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const splitMsg = msg.split("|DELIMITER|");
|
||||||
|
return splitMsg.length == 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Convert multiple arguments for tprint or print into a single string. */
|
||||||
|
function argsToString(args: unknown[]): string {
|
||||||
|
let out = "";
|
||||||
|
for (let arg of args) {
|
||||||
|
if (arg === null) {
|
||||||
|
out += "null";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (arg === undefined) {
|
||||||
|
out += "undefined";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
arg = toNative(arg);
|
||||||
|
out += typeof arg === "object" ? JSON.stringify(arg) : `${arg}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates an error message string containing hostname, scriptname, and the error message msg */
|
||||||
|
function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): string {
|
||||||
|
for (const scriptUrl of workerScript.scriptRef.dependencies) {
|
||||||
|
msg = msg.replace(new RegExp(scriptUrl.url, "g"), scriptUrl.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "|DELIMITER|" + workerScript.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Creates an error message string with a stack trace. */
|
||||||
|
function makeRuntimeErrorMsg(ctx: NetscriptContext, msg: string): string {
|
||||||
|
const errstack = new Error().stack;
|
||||||
|
if (errstack === undefined) throw new Error("how did we not throw an error?");
|
||||||
|
const stack = errstack.split("\n").slice(1);
|
||||||
|
const workerScript = ctx.workerScript;
|
||||||
|
const caller = ctx.function;
|
||||||
|
const scripts = workerScript.getServer().scripts;
|
||||||
|
const userstack = [];
|
||||||
|
for (const stackline of stack) {
|
||||||
|
let filename;
|
||||||
|
for (const script of scripts) {
|
||||||
|
if (script.url && stackline.includes(script.url)) {
|
||||||
|
filename = script.filename;
|
||||||
|
}
|
||||||
|
for (const dependency of script.dependencies) {
|
||||||
|
if (stackline.includes(dependency.url)) {
|
||||||
|
filename = dependency.filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!filename) continue;
|
||||||
|
|
||||||
|
interface ILine {
|
||||||
|
line: string;
|
||||||
|
func: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseChromeStackline(line: string): ILine | null {
|
||||||
|
const lineRe = /.*:(\d+):\d+.*/;
|
||||||
|
const funcRe = /.*at (.+) \(.*/;
|
||||||
|
|
||||||
|
const lineMatch = line.match(lineRe);
|
||||||
|
const funcMatch = line.match(funcRe);
|
||||||
|
if (lineMatch && funcMatch) {
|
||||||
|
return { line: lineMatch[1], func: funcMatch[1] };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let call = { line: "-1", func: "unknown" };
|
||||||
|
const chromeCall = parseChromeStackline(stackline);
|
||||||
|
if (chromeCall) {
|
||||||
|
call = chromeCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseFirefoxStackline(line: string): ILine | null {
|
||||||
|
const lineRe = /.*:(\d+):\d+$/;
|
||||||
|
const lineMatch = line.match(lineRe);
|
||||||
|
|
||||||
|
const lio = line.lastIndexOf("@");
|
||||||
|
|
||||||
|
if (lineMatch && lio !== -1) {
|
||||||
|
return { line: lineMatch[1], func: line.slice(0, lio) };
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firefoxCall = parseFirefoxStackline(stackline);
|
||||||
|
if (firefoxCall) {
|
||||||
|
call = firefoxCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
userstack.push(`${filename}:L${call.line}@${call.func}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
workerScript.log(caller, () => msg);
|
||||||
|
let rejectMsg = `${caller}: ${msg}`;
|
||||||
|
if (userstack.length !== 0) rejectMsg += `<br><br>Stack:<br>${userstack.join("<br>")}`;
|
||||||
|
return makeRuntimeRejectMsg(workerScript, rejectMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Validate requested number of threads for h/g/w options */
|
||||||
|
function resolveNetscriptRequestedThreads(ctx: NetscriptContext, requestedThreads?: number): number {
|
||||||
|
const threads = ctx.workerScript.scriptRef.threads;
|
||||||
|
if (!requestedThreads) {
|
||||||
|
return isNaN(threads) || threads < 1 ? 1 : threads;
|
||||||
|
}
|
||||||
|
const requestedThreadsAsInt = requestedThreads | 0;
|
||||||
|
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
||||||
|
throw makeRuntimeRejectMsg(
|
||||||
|
ctx.workerScript,
|
||||||
|
`Invalid thread count passed to ${ctx.function}: ${requestedThreads}. Threads must be a positive number.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (requestedThreadsAsInt > threads) {
|
||||||
|
throw makeRuntimeRejectMsg(
|
||||||
|
ctx.workerScript,
|
||||||
|
`Too many threads requested by ${ctx.function}. Requested: ${requestedThreads}. Has: ${threads}.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return requestedThreadsAsInt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Validate singularity access by throwing an error if the player does not have access. */
|
||||||
|
function checkSingularityAccess(ctx: NetscriptContext): void {
|
||||||
|
if (Player.bitNodeN !== 4 && Player.sourceFileLvl(4) === 0) {
|
||||||
|
throw makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
`This singularity function requires Source-File 4 to run. A power up you obtain later in the game.
|
||||||
|
It will be very obvious when and how you can obtain it.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create an error if a script is dead or if concurrent ns function calls are made */
|
||||||
|
function checkEnvFlags(ctx: NetscriptContext): void {
|
||||||
|
const ws = ctx.workerScript;
|
||||||
|
if (ws.env.stopFlag) throw new ScriptDeath(ws);
|
||||||
|
if (ws.env.runningFn && ctx.function !== "asleep") {
|
||||||
|
ws.errorMessage = makeRuntimeRejectMsg(
|
||||||
|
ws,
|
||||||
|
`Concurrent calls to Netscript functions are not allowed!
|
||||||
|
Did you forget to await hack(), grow(), or some other
|
||||||
|
promise-returning function?
|
||||||
|
Currently running: ${ws.env.runningFn} tried to run: ${ctx.function}`,
|
||||||
|
);
|
||||||
|
if (ws.delayReject) ws.delayReject(new ScriptDeath(ws));
|
||||||
|
throw new ScriptDeath(ws); //No idea if this is the right thing to throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set a timeout for performing a task, mark the script as busy in the meantime. */
|
||||||
|
function netscriptDelay(ctx: NetscriptContext, time: number): Promise<void> {
|
||||||
|
const ws = ctx.workerScript;
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
ws.delay = window.setTimeout(() => {
|
||||||
|
ws.delay = null;
|
||||||
|
ws.delayReject = undefined;
|
||||||
|
ws.env.runningFn = "";
|
||||||
|
if (ws.env.stopFlag) reject(new ScriptDeath(ws));
|
||||||
|
else resolve();
|
||||||
|
}, time);
|
||||||
|
ws.delayReject = reject;
|
||||||
|
ws.env.runningFn = ctx.function;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Adds to dynamic ram cost when calling new ns functions from a script */
|
||||||
|
function updateDynamicRam(ctx: NetscriptContext, ramCost: number): void {
|
||||||
|
const ws = ctx.workerScript;
|
||||||
|
const fnName = ctx.function;
|
||||||
|
if (ws.dynamicLoadedFns[fnName]) return;
|
||||||
|
ws.dynamicLoadedFns[fnName] = true;
|
||||||
|
|
||||||
|
let threads = ws.scriptRef.threads;
|
||||||
|
if (typeof threads !== "number") {
|
||||||
|
console.warn(`WorkerScript detected NaN for threadcount for ${ws.name} on ${ws.hostname}`);
|
||||||
|
threads = 1;
|
||||||
|
}
|
||||||
|
ws.dynamicRamUsage += ramCost;
|
||||||
|
if (ws.dynamicRamUsage > 1.01 * ws.ramUsage) {
|
||||||
|
ws.errorMessage = makeRuntimeRejectMsg(
|
||||||
|
ws,
|
||||||
|
`Dynamic RAM usage calculated to be greater than initial RAM usage on fn: ${fnName}.
|
||||||
|
This is probably because you somehow circumvented the static RAM calculation.
|
||||||
|
|
||||||
|
Threads: ${threads}
|
||||||
|
Dynamic RAM Usage: ${numeralWrapper.formatRAM(ws.dynamicRamUsage)}
|
||||||
|
Static RAM Usage: ${numeralWrapper.formatRAM(ws.ramUsage)}
|
||||||
|
|
||||||
|
One of these could be the reason:
|
||||||
|
* Using eval() to get a reference to a ns function
|
||||||
|
const myScan = eval('ns.scan');
|
||||||
|
|
||||||
|
* Using map access to do the same
|
||||||
|
const myScan = ns['scan'];
|
||||||
|
|
||||||
|
Sorry :(`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Validates the input v as being a CityName. Throws an error if it is not. */
|
||||||
|
function city(ctx: NetscriptContext, argName: string, v: unknown): CityName {
|
||||||
|
if (typeof v !== "string") throw makeRuntimeErrorMsg(ctx, `${argName} should be a city name.`);
|
||||||
|
const s = v as CityName;
|
||||||
|
if (!Object.values(CityName).includes(s)) throw makeRuntimeErrorMsg(ctx, `${argName} should be a city name.`);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
function scriptIdentifier(
|
||||||
|
ctx: NetscriptContext,
|
||||||
|
scriptID: unknown,
|
||||||
|
_hostname: unknown,
|
||||||
|
_args: unknown,
|
||||||
|
): ScriptIdentifier {
|
||||||
|
const ws = ctx.workerScript;
|
||||||
|
// Provide the pid for the current script if no identifier provided
|
||||||
|
if (scriptID === undefined) return ws.pid;
|
||||||
|
if (typeof scriptID === "number") return scriptID;
|
||||||
|
if (typeof scriptID === "string") {
|
||||||
|
const hostname = _hostname === undefined ? ctx.workerScript.hostname : string(ctx, "hostname", _hostname);
|
||||||
|
const args = _args === undefined ? [] : scriptArgs(ctx, _args);
|
||||||
|
return {
|
||||||
|
scriptname: scriptID,
|
||||||
|
hostname,
|
||||||
|
args,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw new Error("not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Server for a specific hostname/ip, throwing an error
|
||||||
|
* if the server doesn't exist.
|
||||||
|
* @param {NetscriptContext} ctx - Context from which getServer is being called. For logging purposes.
|
||||||
|
* @param {string} hostname - Hostname of the server
|
||||||
|
* @returns {BaseServer} The specified server as a BaseServer
|
||||||
|
*/
|
||||||
|
function getServer(ctx: NetscriptContext, hostname: string) {
|
||||||
|
const server = GetServer(hostname);
|
||||||
|
if (server == null) {
|
||||||
|
const str = hostname === "" ? "'' (empty string)" : "'" + hostname + "'";
|
||||||
|
throw makeRuntimeErrorMsg(ctx, `Invalid hostname: ${str}`);
|
||||||
|
}
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isScriptArgs(args: unknown): args is ScriptArg[] {
|
||||||
|
const isScriptArg = (arg: unknown) => typeof arg === "string" || typeof arg === "number" || typeof arg === "boolean";
|
||||||
|
return Array.isArray(args) && args.every(isScriptArg);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function hack(
|
||||||
|
ctx: NetscriptContext,
|
||||||
|
hostname: string,
|
||||||
|
manual: boolean,
|
||||||
|
{ threads: requestedThreads, stock }: BasicHGWOptions = {},
|
||||||
|
): Promise<number> {
|
||||||
|
const ws = ctx.workerScript;
|
||||||
|
const threads = helpers.resolveNetscriptRequestedThreads(ctx, requestedThreads);
|
||||||
|
const server = getServer(ctx, hostname);
|
||||||
|
if (!(server instanceof Server)) {
|
||||||
|
throw makeRuntimeErrorMsg(ctx, "Cannot be executed on this server.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the hacking time
|
||||||
|
const hackingTime = calculateHackingTime(server, Player); // This is in seconds
|
||||||
|
|
||||||
|
// No root access or skill level too low
|
||||||
|
const canHack = netscriptCanHack(server, Player);
|
||||||
|
if (!canHack.res) {
|
||||||
|
throw makeRuntimeErrorMsg(ctx, canHack.msg || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
log(
|
||||||
|
ctx,
|
||||||
|
() =>
|
||||||
|
`Executing on '${server.hostname}' in ${convertTimeMsToTimeElapsedString(
|
||||||
|
hackingTime * 1000,
|
||||||
|
true,
|
||||||
|
)} (t=${numeralWrapper.formatThreads(threads)})`,
|
||||||
|
);
|
||||||
|
|
||||||
|
return helpers.netscriptDelay(ctx, hackingTime * 1000).then(function () {
|
||||||
|
const hackChance = calculateHackingChance(server, Player);
|
||||||
|
const rand = Math.random();
|
||||||
|
let expGainedOnSuccess = calculateHackingExpGain(server, Player) * threads;
|
||||||
|
const expGainedOnFailure = expGainedOnSuccess / 4;
|
||||||
|
if (rand < hackChance) {
|
||||||
|
// Success!
|
||||||
|
const percentHacked = calculatePercentMoneyHacked(server, Player);
|
||||||
|
let maxThreadNeeded = Math.ceil(1 / percentHacked);
|
||||||
|
if (isNaN(maxThreadNeeded)) {
|
||||||
|
// Server has a 'max money' of 0 (probably). We'll set this to an arbitrarily large value
|
||||||
|
maxThreadNeeded = 1e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
let moneyDrained = Math.floor(server.moneyAvailable * percentHacked) * threads;
|
||||||
|
|
||||||
|
// Over-the-top safety checks
|
||||||
|
if (moneyDrained <= 0) {
|
||||||
|
moneyDrained = 0;
|
||||||
|
expGainedOnSuccess = expGainedOnFailure;
|
||||||
|
}
|
||||||
|
if (moneyDrained > server.moneyAvailable) {
|
||||||
|
moneyDrained = server.moneyAvailable;
|
||||||
|
}
|
||||||
|
server.moneyAvailable -= moneyDrained;
|
||||||
|
if (server.moneyAvailable < 0) {
|
||||||
|
server.moneyAvailable = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
let moneyGained = moneyDrained * BitNodeMultipliers.ScriptHackMoneyGain;
|
||||||
|
if (manual) {
|
||||||
|
moneyGained = moneyDrained * BitNodeMultipliers.ManualHackMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player.gainMoney(moneyGained, "hacking");
|
||||||
|
ws.scriptRef.onlineMoneyMade += moneyGained;
|
||||||
|
Player.scriptProdSinceLastAug += moneyGained;
|
||||||
|
ws.scriptRef.recordHack(server.hostname, moneyGained, threads);
|
||||||
|
Player.gainHackingExp(expGainedOnSuccess);
|
||||||
|
if (manual) Player.gainIntelligenceExp(0.005);
|
||||||
|
ws.scriptRef.onlineExpGained += expGainedOnSuccess;
|
||||||
|
log(
|
||||||
|
ctx,
|
||||||
|
() =>
|
||||||
|
`Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(
|
||||||
|
moneyGained,
|
||||||
|
)} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${numeralWrapper.formatThreads(threads)})`,
|
||||||
|
);
|
||||||
|
server.fortify(CONSTANTS.ServerFortifyAmount * Math.min(threads, maxThreadNeeded));
|
||||||
|
if (stock) {
|
||||||
|
influenceStockThroughServerHack(server, moneyDrained);
|
||||||
|
}
|
||||||
|
if (manual) {
|
||||||
|
server.backdoorInstalled = true;
|
||||||
|
}
|
||||||
|
return Promise.resolve(moneyGained);
|
||||||
|
} else {
|
||||||
|
// Player only gains 25% exp for failure?
|
||||||
|
Player.gainHackingExp(expGainedOnFailure);
|
||||||
|
ws.scriptRef.onlineExpGained += expGainedOnFailure;
|
||||||
|
log(
|
||||||
|
ctx,
|
||||||
|
() =>
|
||||||
|
`Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(
|
||||||
|
expGainedOnFailure,
|
||||||
|
)} exp (t=${numeralWrapper.formatThreads(threads)})`,
|
||||||
|
);
|
||||||
|
return Promise.resolve(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidPort(ctx: NetscriptContext, port: number): IPort {
|
||||||
|
if (isNaN(port)) {
|
||||||
|
throw makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
`Invalid argument. Must be a port number between 1 and ${CONSTANTS.NumNetscriptPorts}, is ${port}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
port = Math.round(port);
|
||||||
|
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||||
|
throw makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
`Trying to use an invalid port: ${port}. Only ports 1-${CONSTANTS.NumNetscriptPorts} are valid.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const iport = NetscriptPorts[port - 1];
|
||||||
|
if (iport == null || !(iport instanceof Object)) {
|
||||||
|
throw makeRuntimeErrorMsg(ctx, `Could not find port: ${port}. This is a bug. Report to dev.`);
|
||||||
|
}
|
||||||
|
return iport;
|
||||||
|
}
|
||||||
|
|
||||||
|
function player(ctx: NetscriptContext, p: unknown): IPlayer {
|
||||||
|
const fakePlayer = {
|
||||||
|
hp: undefined,
|
||||||
|
mults: undefined,
|
||||||
|
numPeopleKilled: undefined,
|
||||||
|
money: undefined,
|
||||||
|
city: undefined,
|
||||||
|
location: undefined,
|
||||||
|
bitNodeN: undefined,
|
||||||
|
totalPlaytime: undefined,
|
||||||
|
playtimeSinceLastAug: undefined,
|
||||||
|
playtimeSinceLastBitnode: undefined,
|
||||||
|
jobs: undefined,
|
||||||
|
factions: undefined,
|
||||||
|
tor: undefined,
|
||||||
|
inBladeburner: undefined,
|
||||||
|
hasCorporation: undefined,
|
||||||
|
entropy: undefined,
|
||||||
|
};
|
||||||
|
if (!roughlyIs(fakePlayer, p)) throw makeRuntimeErrorMsg(ctx, `player should be a Player.`);
|
||||||
|
return p as IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function server(ctx: NetscriptContext, s: unknown): Server {
|
||||||
|
if (!roughlyIs(new Server(), s)) throw makeRuntimeErrorMsg(ctx, `server should be a Server.`);
|
||||||
|
return s as Server;
|
||||||
|
}
|
||||||
|
|
||||||
|
function roughlyIs(expect: object, actual: unknown): boolean {
|
||||||
|
if (typeof actual !== "object" || actual == null) return false;
|
||||||
|
const expects = Object.keys(expect);
|
||||||
|
const actuals = Object.keys(actual);
|
||||||
|
for (const expect of expects)
|
||||||
|
if (!actuals.includes(expect)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gang(ctx: NetscriptContext, g: unknown): FormulaGang {
|
||||||
|
if (!roughlyIs({ respect: 0, territory: 0, wantedLevel: 0 }, g))
|
||||||
|
throw makeRuntimeErrorMsg(ctx, `gang should be a Gang.`);
|
||||||
|
return g as FormulaGang;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gangMember(ctx: NetscriptContext, m: unknown): GangMember {
|
||||||
|
if (!roughlyIs(new GangMember(), m)) throw makeRuntimeErrorMsg(ctx, `member should be a GangMember.`);
|
||||||
|
return m as GangMember;
|
||||||
|
}
|
||||||
|
|
||||||
|
function gangTask(ctx: NetscriptContext, t: unknown): GangMemberTask {
|
||||||
|
if (!roughlyIs(new GangMemberTask("", "", false, false, {}), t))
|
||||||
|
throw makeRuntimeErrorMsg(ctx, `task should be a GangMemberTask.`);
|
||||||
|
return t as GangMemberTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
function log(ctx: NetscriptContext, message: () => string) {
|
||||||
|
ctx.workerScript.log(ctx.functionPath, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for and returns the RunningScript object for the specified script.
|
||||||
|
* If the 'fn' argument is not specified, this returns the current RunningScript.
|
||||||
|
* @param {string} fn - Filename of script
|
||||||
|
* @param {string} hostname - Hostname/ip of the server on which the script resides
|
||||||
|
* @param {any[]} scriptArgs - Running script's arguments
|
||||||
|
* @returns {RunningScript}
|
||||||
|
* Running script identified by the parameters, or null if no such script
|
||||||
|
* exists, or the current running script if the first argument 'fn'
|
||||||
|
* is not specified.
|
||||||
|
*/
|
||||||
|
function getRunningScriptByArgs(
|
||||||
|
ctx: NetscriptContext,
|
||||||
|
fn: string,
|
||||||
|
hostname: string,
|
||||||
|
scriptArgs: ScriptArg[],
|
||||||
|
): RunningScript | null {
|
||||||
|
if (!Array.isArray(scriptArgs)) {
|
||||||
|
throw helpers.makeRuntimeRejectMsg(
|
||||||
|
ctx.workerScript,
|
||||||
|
`Invalid scriptArgs argument passed into getRunningScript() from ${ctx.function}(). ` +
|
||||||
|
`This is probably a bug. Please report to game developer`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fn != null && typeof fn === "string") {
|
||||||
|
// Get Logs of another script
|
||||||
|
if (hostname == null) {
|
||||||
|
hostname = ctx.workerScript.hostname;
|
||||||
|
}
|
||||||
|
const server = helpers.getServer(ctx, hostname);
|
||||||
|
|
||||||
|
return findRunningScript(fn, scriptArgs, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no arguments are specified, return the current RunningScript
|
||||||
|
return ctx.workerScript.scriptRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Provides an array of all function names on a nested object */
|
||||||
|
function getFunctionNames(obj: object, prefix: string): string[] {
|
||||||
|
const functionNames: string[] = [];
|
||||||
|
for (const [key, value] of Object.entries(obj)) {
|
||||||
|
if (key === "args") {
|
||||||
|
continue;
|
||||||
|
} else if (typeof value == "function") {
|
||||||
|
functionNames.push(prefix + key);
|
||||||
|
} else if (typeof value == "object") {
|
||||||
|
functionNames.push(...getFunctionNames(value, key + "."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return functionNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRunningScriptByPid(pid: number): RunningScript | null {
|
||||||
|
for (const server of GetAllServers()) {
|
||||||
|
const runningScript = findRunningScriptByPid(pid, server);
|
||||||
|
if (runningScript) return runningScript;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRunningScript(ctx: NetscriptContext, ident: ScriptIdentifier): RunningScript | null {
|
||||||
|
if (typeof ident === "number") {
|
||||||
|
return getRunningScriptByPid(ident);
|
||||||
|
} else {
|
||||||
|
return getRunningScriptByArgs(ctx, ident.scriptname, ident.hostname, ident.args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for getting the error log message when the user specifies
|
||||||
|
* a nonexistent running script
|
||||||
|
* @param {string} fn - Filename of script
|
||||||
|
* @param {string} hostname - Hostname/ip of the server on which the script resides
|
||||||
|
* @param {any[]} scriptArgs - Running script's arguments
|
||||||
|
* @returns {string} Error message to print to logs
|
||||||
|
*/
|
||||||
|
function getCannotFindRunningScriptErrorMessage(ident: ScriptIdentifier): string {
|
||||||
|
if (typeof ident === "number") return `Cannot find running script with pid: ${ident}`;
|
||||||
|
|
||||||
|
return `Cannot find running script ${ident.scriptname} on server ${ident.hostname} with args: ${arrayToString(
|
||||||
|
ident.args,
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitizes a `RunningScript` to remove sensitive information, making it suitable for
|
||||||
|
* return through an NS function.
|
||||||
|
* @see NS.getRecentScripts
|
||||||
|
* @see NS.getRunningScript
|
||||||
|
* @param runningScript Existing, internal RunningScript
|
||||||
|
* @returns A sanitized, NS-facing copy of the RunningScript
|
||||||
|
*/
|
||||||
|
function createPublicRunningScript(runningScript: RunningScript): IRunningScript {
|
||||||
|
return {
|
||||||
|
args: runningScript.args.slice(),
|
||||||
|
filename: runningScript.filename,
|
||||||
|
logs: runningScript.logs.slice(),
|
||||||
|
offlineExpGained: runningScript.offlineExpGained,
|
||||||
|
offlineMoneyMade: runningScript.offlineMoneyMade,
|
||||||
|
offlineRunningTime: runningScript.offlineRunningTime,
|
||||||
|
onlineExpGained: runningScript.onlineExpGained,
|
||||||
|
onlineMoneyMade: runningScript.onlineMoneyMade,
|
||||||
|
onlineRunningTime: runningScript.onlineRunningTime,
|
||||||
|
pid: runningScript.pid,
|
||||||
|
ramUsage: runningScript.ramUsage,
|
||||||
|
server: runningScript.server,
|
||||||
|
threads: runningScript.threads,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to fail a function if the function's target is a Hacknet Server.
|
||||||
|
* This is used for functions that should run on normal Servers, but not Hacknet Servers
|
||||||
|
* @param {Server} server - Target server
|
||||||
|
* @param {string} callingFn - Name of calling function. For logging purposes
|
||||||
|
* @returns {boolean} True if the server is a Hacknet Server, false otherwise
|
||||||
|
*/
|
||||||
|
function failOnHacknetServer(ctx: NetscriptContext, server: BaseServer, callingFn = ""): boolean {
|
||||||
|
if (server instanceof HacknetServer) {
|
||||||
|
ctx.workerScript.log(callingFn, () => `Does not work on Hacknet Servers`);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -346,6 +346,11 @@ const grafting = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const corporation = {
|
const corporation = {
|
||||||
|
getMaterialNames: 0,
|
||||||
|
getIndustryTypes: 0,
|
||||||
|
getUnlockables: 0,
|
||||||
|
getUpgradeNames: 0,
|
||||||
|
getResearchNames: 0,
|
||||||
createCorporation: 0,
|
createCorporation: 0,
|
||||||
hasUnlockUpgrade: 0,
|
hasUnlockUpgrade: 0,
|
||||||
getUnlockUpgradeCost: 0,
|
getUnlockUpgradeCost: 0,
|
||||||
|
9
src/Netscript/ScriptIdentifier.ts
Normal file
9
src/Netscript/ScriptIdentifier.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { ScriptArg } from "./ScriptArg";
|
||||||
|
|
||||||
|
export type ScriptIdentifier = //This was previously in INetscriptHelper.ts, may move to its own file or a generic types file.
|
||||||
|
| number
|
||||||
|
| {
|
||||||
|
scriptname: string;
|
||||||
|
hostname: string;
|
||||||
|
args: ScriptArg[];
|
||||||
|
};
|
@ -10,7 +10,6 @@ import { WorkerScriptStartStopEventEmitter } from "./WorkerScriptStartStopEventE
|
|||||||
import { RunningScript } from "../Script/RunningScript";
|
import { RunningScript } from "../Script/RunningScript";
|
||||||
import { GetServer } from "../Server/AllServers";
|
import { GetServer } from "../Server/AllServers";
|
||||||
|
|
||||||
import { compareArrays } from "../utils/helpers/compareArrays";
|
|
||||||
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||||
import { AddRecentScript } from "./RecentScripts";
|
import { AddRecentScript } from "./RecentScripts";
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
@ -33,13 +32,8 @@ export function killWorkerScript(params: killScriptParams): boolean {
|
|||||||
|
|
||||||
// If for some reason that doesn't work, we'll try the old way
|
// If for some reason that doesn't work, we'll try the old way
|
||||||
for (const ws of workerScripts.values()) {
|
for (const ws of workerScripts.values()) {
|
||||||
if (
|
if (ws.scriptRef === params.runningScript) {
|
||||||
ws.name == params.runningScript.filename &&
|
|
||||||
ws.hostname == params.hostname &&
|
|
||||||
compareArrays(ws.args, params.runningScript.args)
|
|
||||||
) {
|
|
||||||
stopAndCleanUpWorkerScript(ws);
|
stopAndCleanUpWorkerScript(ws);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,7 +46,6 @@ function killWorkerScriptByPid(pid: number): boolean {
|
|||||||
const ws = workerScripts.get(pid);
|
const ws = workerScripts.get(pid);
|
||||||
if (ws instanceof WorkerScript) {
|
if (ws instanceof WorkerScript) {
|
||||||
stopAndCleanUpWorkerScript(ws);
|
stopAndCleanUpWorkerScript(ws);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +79,6 @@ function stopAndCleanUpWorkerScript(workerScript: WorkerScript): void {
|
|||||||
*/
|
*/
|
||||||
function removeWorkerScript(workerScript: WorkerScript): void {
|
function removeWorkerScript(workerScript: WorkerScript): void {
|
||||||
const ip = workerScript.hostname;
|
const ip = workerScript.hostname;
|
||||||
const name = workerScript.name;
|
|
||||||
|
|
||||||
// Get the server on which the script runs
|
// Get the server on which the script runs
|
||||||
const server = GetServer(ip);
|
const server = GetServer(ip);
|
||||||
@ -98,7 +90,7 @@ function removeWorkerScript(workerScript: WorkerScript): void {
|
|||||||
// Delete the RunningScript object from that server
|
// Delete the RunningScript object from that server
|
||||||
for (let i = 0; i < server.runningScripts.length; ++i) {
|
for (let i = 0; i < server.runningScripts.length; ++i) {
|
||||||
const runningScript = server.runningScripts[i];
|
const runningScript = server.runningScripts[i];
|
||||||
if (runningScript.filename === name && compareArrays(runningScript.args, workerScript.args)) {
|
if (runningScript === workerScript.scriptRef) {
|
||||||
server.runningScripts.splice(i, 1);
|
server.runningScripts.splice(i, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
import { isString } from "./utils/helpers/isString";
|
|
||||||
import { GetServer } from "./Server/AllServers";
|
|
||||||
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
|
||||||
import { WorkerScript } from "./Netscript/WorkerScript";
|
|
||||||
import { NetscriptContext } from "./Netscript/APIWrapper";
|
|
||||||
|
|
||||||
export function netscriptDelay(time: number, workerScript: WorkerScript): Promise<void> {
|
|
||||||
// Cancel any pre-existing netscriptDelay'ed function call
|
|
||||||
// TODO: the rejection almost certainly ends up in the uncaught rejection handler.
|
|
||||||
// Maybe reject with a stack-trace'd error message?
|
|
||||||
if (workerScript.delayReject) workerScript.delayReject();
|
|
||||||
|
|
||||||
return new Promise(function (resolve, reject) {
|
|
||||||
workerScript.delay = window.setTimeout(() => {
|
|
||||||
workerScript.delay = null;
|
|
||||||
workerScript.delayReject = undefined;
|
|
||||||
if (workerScript.env.stopFlag) reject(new ScriptDeath(workerScript));
|
|
||||||
else resolve();
|
|
||||||
}, time);
|
|
||||||
workerScript.delayReject = reject;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): string {
|
|
||||||
const server = GetServer(workerScript.hostname);
|
|
||||||
if (server == null) {
|
|
||||||
throw new Error(`WorkerScript constructed with invalid server ip: ${workerScript.hostname}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const scriptUrl of workerScript.scriptRef.dependencies) {
|
|
||||||
// Return just the original msg if it's nullish so that we don't get a workerscript error
|
|
||||||
msg = msg?.replace(new RegExp(scriptUrl.url, "g"), scriptUrl.filename) ?? msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return "|DELIMITER|" + server.hostname + "|DELIMITER|" + workerScript.name + "|DELIMITER|" + msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function resolveNetscriptRequestedThreads(ctx: NetscriptContext, requestedThreads?: number): number {
|
|
||||||
const threads = ctx.workerScript.scriptRef.threads;
|
|
||||||
if (!requestedThreads) {
|
|
||||||
return isNaN(threads) || threads < 1 ? 1 : threads;
|
|
||||||
}
|
|
||||||
const requestedThreadsAsInt = requestedThreads | 0;
|
|
||||||
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
|
||||||
throw makeRuntimeRejectMsg(
|
|
||||||
ctx.workerScript,
|
|
||||||
`Invalid thread count passed to ${ctx.function}: ${requestedThreads}. Threads must be a positive number.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (requestedThreadsAsInt > threads) {
|
|
||||||
throw makeRuntimeRejectMsg(
|
|
||||||
ctx.workerScript,
|
|
||||||
`Too many threads requested by ${ctx.function}. Requested: ${requestedThreads}. Has: ${threads}.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return requestedThreadsAsInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isScriptErrorMessage(msg: string): boolean {
|
|
||||||
if (!isString(msg)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const splitMsg = msg.split("|DELIMITER|");
|
|
||||||
return splitMsg.length == 4;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,13 @@
|
|||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { Player as player } from "../Player";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { Bladeburner } from "../Bladeburner/Bladeburner";
|
import { Bladeburner } from "../Bladeburner/Bladeburner";
|
||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { Bladeburner as INetscriptBladeburner, BladeburnerCurAction } from "../ScriptEditor/NetscriptDefinitions";
|
import { Bladeburner as INetscriptBladeburner, BladeburnerCurAction } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { IAction } from "src/Bladeburner/IAction";
|
import { IAction } from "src/Bladeburner/IAction";
|
||||||
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
||||||
import { BlackOperation } from "../Bladeburner/BlackOperation";
|
import { BlackOperation } from "../Bladeburner/BlackOperation";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript): InternalAPI<INetscriptBladeburner> {
|
export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||||
const checkBladeburnerAccess = function (ctx: NetscriptContext, skipjoined = false): void {
|
const checkBladeburnerAccess = function (ctx: NetscriptContext, skipjoined = 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");
|
||||||
@ -18,13 +18,13 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
});
|
});
|
||||||
if (!apiAccess) {
|
if (!apiAccess) {
|
||||||
const apiDenied = `You do not currently have access to the Bladeburner API. You must either be in BitNode-7 or have Source-File 7.`;
|
const apiDenied = `You do not currently have access to the Bladeburner API. You must either be in BitNode-7 or have Source-File 7.`;
|
||||||
throw ctx.makeRuntimeErrorMsg(apiDenied);
|
throw helpers.makeRuntimeErrorMsg(ctx, apiDenied);
|
||||||
}
|
}
|
||||||
if (!skipjoined) {
|
if (!skipjoined) {
|
||||||
const bladeburnerAccess = bladeburner instanceof Bladeburner;
|
const bladeburnerAccess = bladeburner instanceof Bladeburner;
|
||||||
if (!bladeburnerAccess) {
|
if (!bladeburnerAccess) {
|
||||||
const bladeburnerDenied = `You must be a member of the Bladeburner division to use this API.`;
|
const bladeburnerDenied = `You must be a member of the Bladeburner division to use this API.`;
|
||||||
throw ctx.makeRuntimeErrorMsg(bladeburnerDenied);
|
throw helpers.makeRuntimeErrorMsg(ctx, bladeburnerDenied);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -33,7 +33,7 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
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)) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid city: ${city}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city: ${city}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -42,11 +42,11 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
if (bladeburner === null) throw new Error("Must have joined bladeburner");
|
if (bladeburner === null) throw new Error("Must have joined bladeburner");
|
||||||
const actionId = bladeburner.getActionIdFromTypeAndName(type, name);
|
const actionId = bladeburner.getActionIdFromTypeAndName(type, name);
|
||||||
if (!actionId) {
|
if (!actionId) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid action type='${type}', name='${name}'`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid action type='${type}', name='${name}'`);
|
||||||
}
|
}
|
||||||
const actionObj = bladeburner.getActionObject(actionId);
|
const actionObj = bladeburner.getActionObject(actionId);
|
||||||
if (!actionObj) {
|
if (!actionObj) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid action type='${type}', name='${name}'`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid action type='${type}', name='${name}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return actionObj;
|
return actionObj;
|
||||||
@ -74,7 +74,7 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getBlackOpRank:
|
getBlackOpRank:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_blackOpName: unknown): number => {
|
(_blackOpName: unknown): number => {
|
||||||
const blackOpName = ctx.helper.string("blackOpName", _blackOpName);
|
const blackOpName = helpers.string(ctx, "blackOpName", _blackOpName);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, "blackops", blackOpName);
|
const action = getBladeburnerActionObject(ctx, "blackops", blackOpName);
|
||||||
if (!(action instanceof BlackOperation)) throw new Error("action was not a black operation");
|
if (!(action instanceof BlackOperation)) throw new Error("action was not a black operation");
|
||||||
@ -95,15 +95,15 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
startAction:
|
startAction:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): boolean => {
|
(_type: unknown, _name: unknown): boolean => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.startActionNetscriptFn(player, type, name, workerScript);
|
return bladeburner.startActionNetscriptFn(player, type, name, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
stopBladeburnerAction: (ctx: NetscriptContext) => (): void => {
|
stopBladeburnerAction: (ctx: NetscriptContext) => (): void => {
|
||||||
@ -121,8 +121,8 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getActionTime:
|
getActionTime:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): number => {
|
(_type: unknown, _name: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
@ -130,13 +130,13 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
const time = bladeburner.getActionTimeNetscriptFn(player, type, name);
|
const time = bladeburner.getActionTimeNetscriptFn(player, type, name);
|
||||||
if (typeof time === "string") {
|
if (typeof time === "string") {
|
||||||
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
||||||
ctx.log(() => errorLogText);
|
helpers.log(ctx, () => errorLogText);
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getActionCurrentTime: (ctx: NetscriptContext) => (): number => {
|
getActionCurrentTime: (ctx: NetscriptContext) => (): number => {
|
||||||
@ -149,14 +149,14 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
1000;
|
1000;
|
||||||
return timecomputed;
|
return timecomputed;
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getActionEstimatedSuccessChance:
|
getActionEstimatedSuccessChance:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): [number, number] => {
|
(_type: unknown, _name: unknown): [number, number] => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
@ -164,21 +164,21 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
const chance = bladeburner.getActionEstimatedSuccessChanceNetscriptFn(player, type, name);
|
const chance = bladeburner.getActionEstimatedSuccessChanceNetscriptFn(player, type, name);
|
||||||
if (typeof chance === "string") {
|
if (typeof chance === "string") {
|
||||||
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
||||||
ctx.log(() => errorLogText);
|
helpers.log(ctx, () => errorLogText);
|
||||||
return [-1, -1];
|
return [-1, -1];
|
||||||
} else {
|
} else {
|
||||||
return chance;
|
return chance;
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getActionRepGain:
|
getActionRepGain:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown, _level: unknown): number => {
|
(_type: unknown, _name: unknown, _level: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
const level = ctx.helper.number("level", _level);
|
const level = helpers.number(ctx, "level", _level);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, type, name);
|
const action = getBladeburnerActionObject(ctx, type, name);
|
||||||
let rewardMultiplier;
|
let rewardMultiplier;
|
||||||
@ -193,22 +193,22 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getActionCountRemaining:
|
getActionCountRemaining:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): number => {
|
(_type: unknown, _name: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.getActionCountRemainingNetscriptFn(type, name, workerScript);
|
return bladeburner.getActionCountRemainingNetscriptFn(type, name, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getActionMaxLevel:
|
getActionMaxLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): number => {
|
(_type: unknown, _name: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, type, name);
|
const action = getBladeburnerActionObject(ctx, type, name);
|
||||||
return action.maxLevel;
|
return action.maxLevel;
|
||||||
@ -216,8 +216,8 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getActionCurrentLevel:
|
getActionCurrentLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): number => {
|
(_type: unknown, _name: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, type, name);
|
const action = getBladeburnerActionObject(ctx, type, name);
|
||||||
return action.level;
|
return action.level;
|
||||||
@ -225,8 +225,8 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getActionAutolevel:
|
getActionAutolevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): boolean => {
|
(_type: unknown, _name: unknown): boolean => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, type, name);
|
const action = getBladeburnerActionObject(ctx, type, name);
|
||||||
return action.autoLevel;
|
return action.autoLevel;
|
||||||
@ -234,9 +234,9 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
setActionAutolevel:
|
setActionAutolevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown, _autoLevel: unknown = true): void => {
|
(_type: unknown, _name: unknown, _autoLevel: unknown = true): void => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
const autoLevel = ctx.helper.boolean(_autoLevel);
|
const autoLevel = !!_autoLevel;
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, type, name);
|
const action = getBladeburnerActionObject(ctx, type, name);
|
||||||
action.autoLevel = autoLevel;
|
action.autoLevel = autoLevel;
|
||||||
@ -244,13 +244,13 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
setActionLevel:
|
setActionLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown, _level: unknown = 1): void => {
|
(_type: unknown, _name: unknown, _level: unknown = 1): void => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
const level = ctx.helper.number("level", _level);
|
const level = helpers.number(ctx, "level", _level);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const action = getBladeburnerActionObject(ctx, type, name);
|
const action = getBladeburnerActionObject(ctx, type, name);
|
||||||
if (level < 1 || level > action.maxLevel) {
|
if (level < 1 || level > action.maxLevel) {
|
||||||
ctx.helper.makeRuntimeErrorMsg(`Level must be between 1 and ${action.maxLevel}, is ${level}`);
|
helpers.makeRuntimeErrorMsg(ctx, `Level must be between 1 and ${action.maxLevel}, is ${level}`);
|
||||||
}
|
}
|
||||||
action.level = level;
|
action.level = level;
|
||||||
},
|
},
|
||||||
@ -269,77 +269,77 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getSkillLevel:
|
getSkillLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_skillName: unknown): number => {
|
(_skillName: unknown): number => {
|
||||||
const skillName = ctx.helper.string("skillName", _skillName);
|
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.getSkillLevelNetscriptFn(skillName, workerScript);
|
return bladeburner.getSkillLevelNetscriptFn(skillName, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getSkillUpgradeCost:
|
getSkillUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_skillName: unknown, _count: unknown = 1): number => {
|
(_skillName: unknown, _count: unknown = 1): number => {
|
||||||
const skillName = ctx.helper.string("skillName", _skillName);
|
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||||
const count = ctx.helper.number("count", _count);
|
const count = helpers.number(ctx, "count", _count);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.getSkillUpgradeCostNetscriptFn(skillName, count, workerScript);
|
return bladeburner.getSkillUpgradeCostNetscriptFn(skillName, count, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
upgradeSkill:
|
upgradeSkill:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_skillName: unknown, _count: unknown = 1): boolean => {
|
(_skillName: unknown, _count: unknown = 1): boolean => {
|
||||||
const skillName = ctx.helper.string("skillName", _skillName);
|
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||||
const count = ctx.helper.number("count", _count);
|
const count = helpers.number(ctx, "count", _count);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.upgradeSkillNetscriptFn(skillName, count, workerScript);
|
return bladeburner.upgradeSkillNetscriptFn(skillName, count, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getTeamSize:
|
getTeamSize:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown): number => {
|
(_type: unknown, _name: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.getTeamSizeNetscriptFn(type, name, workerScript);
|
return bladeburner.getTeamSizeNetscriptFn(type, name, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setTeamSize:
|
setTeamSize:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_type: unknown, _name: unknown, _size: unknown): number => {
|
(_type: unknown, _name: unknown, _size: unknown): number => {
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const name = ctx.helper.string("name", _name);
|
const name = helpers.string(ctx, "name", _name);
|
||||||
const size = ctx.helper.number("size", _size);
|
const size = helpers.number(ctx, "size", _size);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
try {
|
try {
|
||||||
return bladeburner.setTeamSizeNetscriptFn(type, name, size, workerScript);
|
return bladeburner.setTeamSizeNetscriptFn(type, name, size, ctx.workerScript);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
throw ctx.makeRuntimeErrorMsg(String(e));
|
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getCityEstimatedPopulation:
|
getCityEstimatedPopulation:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_cityName: unknown): number => {
|
(_cityName: unknown): number => {
|
||||||
const cityName = ctx.helper.string("cityName", _cityName);
|
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
checkBladeburnerCity(ctx, cityName);
|
checkBladeburnerCity(ctx, cityName);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
@ -349,7 +349,7 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getCityCommunities:
|
getCityCommunities:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_cityName: unknown): number => {
|
(_cityName: unknown): number => {
|
||||||
const cityName = ctx.helper.string("cityName", _cityName);
|
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
checkBladeburnerCity(ctx, cityName);
|
checkBladeburnerCity(ctx, cityName);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
@ -359,7 +359,7 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
getCityChaos:
|
getCityChaos:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_cityName: unknown): number => {
|
(_cityName: unknown): number => {
|
||||||
const cityName = ctx.helper.string("cityName", _cityName);
|
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
checkBladeburnerCity(ctx, cityName);
|
checkBladeburnerCity(ctx, cityName);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
@ -375,7 +375,7 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
switchCity:
|
switchCity:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_cityName: unknown): boolean => {
|
(_cityName: unknown): boolean => {
|
||||||
const cityName = ctx.helper.string("cityName", _cityName);
|
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||||
checkBladeburnerAccess(ctx);
|
checkBladeburnerAccess(ctx);
|
||||||
checkBladeburnerCity(ctx, cityName);
|
checkBladeburnerCity(ctx, cityName);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
@ -393,7 +393,7 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
checkBladeburnerAccess(ctx, true);
|
checkBladeburnerAccess(ctx, true);
|
||||||
const bladeburner = player.bladeburner;
|
const bladeburner = player.bladeburner;
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||||
return bladeburner.joinBladeburnerFactionNetscriptFn(workerScript);
|
return bladeburner.joinBladeburnerFactionNetscriptFn(ctx.workerScript);
|
||||||
},
|
},
|
||||||
joinBladeburnerDivision: (ctx: NetscriptContext) => (): boolean => {
|
joinBladeburnerDivision: (ctx: NetscriptContext) => (): boolean => {
|
||||||
if (player.bitNodeN === 7 || player.sourceFileLvl(7) > 0) {
|
if (player.bitNodeN === 7 || player.sourceFileLvl(7) > 0) {
|
||||||
@ -409,11 +409,11 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
|
|||||||
player.skills.agility >= 100
|
player.skills.agility >= 100
|
||||||
) {
|
) {
|
||||||
player.bladeburner = new Bladeburner(player);
|
player.bladeburner = new Bladeburner(player);
|
||||||
ctx.log(() => "You have been accepted into the Bladeburner division");
|
helpers.log(ctx, () => "You have been accepted into the Bladeburner division");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ctx.log(() => "You do not meet the requirements for joining the Bladeburner division");
|
helpers.log(ctx, () => "You do not meet the requirements for joining the Bladeburner division");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { Player as player } from "../Player";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { is2DArray } from "../utils/helpers/is2DArray";
|
import { is2DArray } from "../utils/helpers/is2DArray";
|
||||||
import { CodingContract } from "../CodingContracts";
|
import { CodingContract } from "../CodingContracts";
|
||||||
import { CodingAttemptOptions, CodingContract as ICodingContract } from "../ScriptEditor/NetscriptDefinitions";
|
import { CodingAttemptOptions, CodingContract as ICodingContract } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptCodingContract(player: IPlayer, workerScript: WorkerScript): InternalAPI<ICodingContract> {
|
export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||||
const getCodingContract = function (
|
const getCodingContract = function (
|
||||||
ctx: NetscriptContext,
|
ctx: NetscriptContext,
|
||||||
func: string,
|
func: string,
|
||||||
hostname: string,
|
hostname: string,
|
||||||
filename: string,
|
filename: string,
|
||||||
): CodingContract {
|
): CodingContract {
|
||||||
const server = ctx.helper.getServer(hostname);
|
const server = helpers.getServer(ctx, hostname);
|
||||||
const contract = server.getContract(filename);
|
const contract = server.getContract(filename);
|
||||||
if (contract == null) {
|
if (contract == null) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Cannot find contract '${filename}' on server '${hostname}'`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Cannot find contract '${filename}' on server '${hostname}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return contract;
|
return contract;
|
||||||
@ -27,11 +27,11 @@ export function NetscriptCodingContract(player: IPlayer, workerScript: WorkerScr
|
|||||||
(
|
(
|
||||||
answer: unknown,
|
answer: unknown,
|
||||||
_filename: unknown,
|
_filename: unknown,
|
||||||
_hostname: unknown = workerScript.hostname,
|
_hostname: unknown = ctx.workerScript.hostname,
|
||||||
{ returnReward }: CodingAttemptOptions = { returnReward: false },
|
{ returnReward }: CodingAttemptOptions = { returnReward: false },
|
||||||
): boolean | string => {
|
): boolean | string => {
|
||||||
const filename = ctx.helper.string("filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
const hostname = ctx.helper.string("hostname", _hostname);
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||||
const contract = getCodingContract(ctx, "attempt", hostname, filename);
|
const contract = getCodingContract(ctx, "attempt", hostname, filename);
|
||||||
|
|
||||||
// Convert answer to string. If the answer is a 2D array, then we have to
|
// Convert answer to string. If the answer is a 2D array, then we have to
|
||||||
@ -51,19 +51,20 @@ export function NetscriptCodingContract(player: IPlayer, workerScript: WorkerScr
|
|||||||
const creward = contract.reward;
|
const creward = contract.reward;
|
||||||
if (creward === null) throw new Error("Somehow solved a contract that didn't have a reward");
|
if (creward === null) throw new Error("Somehow solved a contract that didn't have a reward");
|
||||||
|
|
||||||
const serv = ctx.helper.getServer(hostname);
|
const serv = helpers.getServer(ctx, hostname);
|
||||||
if (contract.isSolution(answerStr)) {
|
if (contract.isSolution(answerStr)) {
|
||||||
const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
|
const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
|
||||||
ctx.log(() => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
helpers.log(ctx, () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
||||||
serv.removeContract(filename);
|
serv.removeContract(filename);
|
||||||
return returnReward ? reward : true;
|
return returnReward ? reward : true;
|
||||||
} else {
|
} else {
|
||||||
++contract.tries;
|
++contract.tries;
|
||||||
if (contract.tries >= contract.getMaxNumTries()) {
|
if (contract.tries >= contract.getMaxNumTries()) {
|
||||||
ctx.log(() => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
helpers.log(ctx, () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
||||||
serv.removeContract(filename);
|
serv.removeContract(filename);
|
||||||
} else {
|
} else {
|
||||||
ctx.log(
|
helpers.log(
|
||||||
|
ctx,
|
||||||
() =>
|
() =>
|
||||||
`Coding Contract attempt '${filename}' failed. ${
|
`Coding Contract attempt '${filename}' failed. ${
|
||||||
contract.getMaxNumTries() - contract.tries
|
contract.getMaxNumTries() - contract.tries
|
||||||
@ -76,17 +77,17 @@ export function NetscriptCodingContract(player: IPlayer, workerScript: WorkerScr
|
|||||||
},
|
},
|
||||||
getContractType:
|
getContractType:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_filename: unknown, _hostname: unknown = workerScript.hostname): string => {
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
|
||||||
const filename = ctx.helper.string("filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
const hostname = ctx.helper.string("hostname", _hostname);
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||||
const contract = getCodingContract(ctx, "getContractType", hostname, filename);
|
const contract = getCodingContract(ctx, "getContractType", hostname, filename);
|
||||||
return contract.getType();
|
return contract.getType();
|
||||||
},
|
},
|
||||||
getData:
|
getData:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_filename: unknown, _hostname: unknown = workerScript.hostname): unknown => {
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): unknown => {
|
||||||
const filename = ctx.helper.string("filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
const hostname = ctx.helper.string("hostname", _hostname);
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||||
const contract = getCodingContract(ctx, "getData", hostname, filename);
|
const contract = getCodingContract(ctx, "getData", hostname, filename);
|
||||||
const data = contract.getData();
|
const data = contract.getData();
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
@ -107,17 +108,17 @@ export function NetscriptCodingContract(player: IPlayer, workerScript: WorkerScr
|
|||||||
},
|
},
|
||||||
getDescription:
|
getDescription:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_filename: unknown, _hostname: unknown = workerScript.hostname): string => {
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
|
||||||
const filename = ctx.helper.string("filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
const hostname = ctx.helper.string("hostname", _hostname);
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||||
const contract = getCodingContract(ctx, "getDescription", hostname, filename);
|
const contract = getCodingContract(ctx, "getDescription", hostname, filename);
|
||||||
return contract.getDescription();
|
return contract.getDescription();
|
||||||
},
|
},
|
||||||
getNumTriesRemaining:
|
getNumTriesRemaining:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_filename: unknown, _hostname: unknown = workerScript.hostname): number => {
|
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): number => {
|
||||||
const filename = ctx.helper.string("filename", _filename);
|
const filename = helpers.string(ctx, "filename", _filename);
|
||||||
const hostname = ctx.helper.string("hostname", _hostname);
|
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||||
const contract = getCodingContract(ctx, "getNumTriesRemaining", hostname, filename);
|
const contract = getCodingContract(ctx, "getNumTriesRemaining", hostname, filename);
|
||||||
return contract.getMaxNumTries() - contract.tries;
|
return contract.getMaxNumTries() - contract.tries;
|
||||||
},
|
},
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
|
|
||||||
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
import { OfficeSpace } from "../Corporation/OfficeSpace";
|
||||||
import { Employee } from "../Corporation/Employee";
|
import { Employee } from "../Corporation/Employee";
|
||||||
@ -65,9 +65,10 @@ import { CorporationConstants } from "../Corporation/data/Constants";
|
|||||||
import { ResearchMap } from "../Corporation/ResearchMap";
|
import { ResearchMap } from "../Corporation/ResearchMap";
|
||||||
import { Factions } from "../Faction/Factions";
|
import { Factions } from "../Faction/Factions";
|
||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation> {
|
export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||||
function createCorporation(corporationName: string, selfFund = true): boolean {
|
function createCorporation(corporationName: string, selfFund = true): boolean {
|
||||||
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
|
if (!player.canAccessCorporation() || player.hasCorporation()) return false;
|
||||||
if (!corporationName) return false;
|
if (!corporationName) return false;
|
||||||
@ -101,7 +102,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getUpgradeLevel(ctx: NetscriptContext, _upgradeName: string): number {
|
function getUpgradeLevel(ctx: NetscriptContext, _upgradeName: string): number {
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
||||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||||
@ -110,7 +111,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getUpgradeLevelCost(ctx: NetscriptContext, _upgradeName: string): number {
|
function getUpgradeLevelCost(ctx: NetscriptContext, _upgradeName: string): number {
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
||||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||||
@ -274,10 +275,11 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
}
|
}
|
||||||
|
|
||||||
function checkAccess(ctx: NetscriptContext, api?: number): void {
|
function checkAccess(ctx: NetscriptContext, api?: number): void {
|
||||||
if (player.corporation === null) throw ctx.makeRuntimeErrorMsg("Must own a corporation.");
|
if (player.corporation === null) throw helpers.makeRuntimeErrorMsg(ctx, "Must own a corporation.");
|
||||||
if (!api) return;
|
if (!api) return;
|
||||||
|
|
||||||
if (!player.corporation.unlockUpgrades[api]) throw ctx.makeRuntimeErrorMsg("You do not have access to this API.");
|
if (!player.corporation.unlockUpgrades[api])
|
||||||
|
throw helpers.makeRuntimeErrorMsg(ctx, "You do not have access to this API.");
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSafeDivision(division: Industry): NSDivision {
|
function getSafeDivision(division: Industry): NSDivision {
|
||||||
@ -314,11 +316,11 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _amt: unknown = 1): number => {
|
(_divisionName: unknown, _cityName: unknown, _amt: unknown = 1): number => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const amt = ctx.helper.number("amount", _amt);
|
const amt = helpers.number(ctx, "amount", _amt);
|
||||||
if (amt < 1) {
|
if (amt < 1) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must provide a positive number");
|
throw helpers.makeRuntimeErrorMsg(ctx, "You must provide a positive number");
|
||||||
}
|
}
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
return UpgradeWarehouseCost(warehouse, amt);
|
return UpgradeWarehouseCost(warehouse, amt);
|
||||||
@ -327,8 +329,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): boolean => {
|
(_divisionName: unknown, _cityName: unknown): boolean => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const division = getDivision(divisionName);
|
const division = getDivision(divisionName);
|
||||||
if (!(cityName in division.warehouses)) throw new Error(`Invalid city name '${cityName}'`);
|
if (!(cityName in division.warehouses)) throw new Error(`Invalid city name '${cityName}'`);
|
||||||
const warehouse = division.warehouses[cityName];
|
const warehouse = division.warehouses[cityName];
|
||||||
@ -338,8 +340,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): NSWarehouse => {
|
(_divisionName: unknown, _cityName: unknown): NSWarehouse => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
return {
|
return {
|
||||||
level: warehouse.level,
|
level: warehouse.level,
|
||||||
@ -353,9 +355,9 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown): NSMaterial => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown): NSMaterial => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
return {
|
return {
|
||||||
@ -374,8 +376,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _productName: unknown): NSProduct => {
|
(_divisionName: unknown, _productName: unknown): NSProduct => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const product = getProduct(divisionName, productName);
|
const product = getProduct(divisionName, productName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
return {
|
return {
|
||||||
@ -401,8 +403,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
PurchaseWarehouse(corporation, getDivision(divisionName), cityName);
|
PurchaseWarehouse(corporation, getDivision(divisionName), cityName);
|
||||||
},
|
},
|
||||||
@ -410,12 +412,12 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _amt: unknown = 1): void => {
|
(_divisionName: unknown, _cityName: unknown, _amt: unknown = 1): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const amt = ctx.helper.number("amount", _amt);
|
const amt = helpers.number(ctx, "amount", _amt);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
if (amt < 1) {
|
if (amt < 1) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must provide a positive number");
|
throw helpers.makeRuntimeErrorMsg(ctx, "You must provide a positive number");
|
||||||
}
|
}
|
||||||
UpgradeWarehouse(corporation, getDivision(divisionName), getWarehouse(divisionName, cityName), amt);
|
UpgradeWarehouse(corporation, getDivision(divisionName), getWarehouse(divisionName, cityName), amt);
|
||||||
},
|
},
|
||||||
@ -423,11 +425,11 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown, _price: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown, _price: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const amt = ctx.helper.string("amt", _amt);
|
const amt = helpers.string(ctx, "amt", _amt);
|
||||||
const price = ctx.helper.string("price", _price);
|
const price = helpers.string(ctx, "price", _price);
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
SellMaterial(material, amt, price);
|
SellMaterial(material, amt, price);
|
||||||
},
|
},
|
||||||
@ -442,12 +444,12 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
_all: unknown,
|
_all: unknown,
|
||||||
): void => {
|
): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const amt = ctx.helper.string("amt", _amt);
|
const amt = helpers.string(ctx, "amt", _amt);
|
||||||
const price = ctx.helper.string("price", _price);
|
const price = helpers.string(ctx, "price", _price);
|
||||||
const all = ctx.helper.boolean(_all);
|
const all = !!_all;
|
||||||
const product = getProduct(divisionName, productName);
|
const product = getProduct(divisionName, productName);
|
||||||
SellProduct(product, cityName, amt, price, all);
|
SellProduct(product, cityName, amt, price, all);
|
||||||
},
|
},
|
||||||
@ -455,44 +457,44 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _productName: unknown): void => {
|
(_divisionName: unknown, _productName: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
getDivision(divisionName).discontinueProduct(getProduct(divisionName, productName));
|
getDivision(divisionName).discontinueProduct(getProduct(divisionName, productName));
|
||||||
},
|
},
|
||||||
setSmartSupply:
|
setSmartSupply:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _enabled: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _enabled: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const enabled = ctx.helper.boolean(_enabled);
|
const enabled = !!_enabled;
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
if (!hasUnlockUpgrade("Smart Supply"))
|
if (!hasUnlockUpgrade("Smart Supply"))
|
||||||
throw ctx.makeRuntimeErrorMsg(`You have not purchased the Smart Supply upgrade!`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
|
||||||
SetSmartSupply(warehouse, enabled);
|
SetSmartSupply(warehouse, enabled);
|
||||||
},
|
},
|
||||||
setSmartSupplyUseLeftovers:
|
setSmartSupplyUseLeftovers:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _enabled: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _enabled: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const enabled = ctx.helper.boolean(_enabled);
|
const enabled = !!_enabled;
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
if (!hasUnlockUpgrade("Smart Supply"))
|
if (!hasUnlockUpgrade("Smart Supply"))
|
||||||
throw ctx.makeRuntimeErrorMsg(`You have not purchased the Smart Supply upgrade!`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not purchased the Smart Supply upgrade!`);
|
||||||
SetSmartSupplyUseLeftovers(warehouse, material, enabled);
|
SetSmartSupplyUseLeftovers(warehouse, material, enabled);
|
||||||
},
|
},
|
||||||
buyMaterial:
|
buyMaterial:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const amt = ctx.helper.number("amt", _amt);
|
const amt = helpers.number(ctx, "amt", _amt);
|
||||||
if (amt < 0) throw new Error("Invalid value for amount field! Must be numeric and greater than 0");
|
if (amt < 0) throw new Error("Invalid value for amount field! Must be numeric and greater than 0");
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
BuyMaterial(material, amt);
|
BuyMaterial(material, amt);
|
||||||
@ -501,13 +503,13 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
if (!hasResearched(getDivision(divisionName), "Bulk Purchasing"))
|
if (!hasResearched(getDivision(divisionName), "Bulk Purchasing"))
|
||||||
throw new Error(`You have not researched Bulk Purchasing in ${divisionName}`);
|
throw new Error(`You have not researched Bulk Purchasing in ${divisionName}`);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const amt = ctx.helper.number("amt", _amt);
|
const amt = helpers.number(ctx, "amt", _amt);
|
||||||
const warehouse = getWarehouse(divisionName, cityName);
|
const warehouse = getWarehouse(divisionName, cityName);
|
||||||
const material = getMaterial(divisionName, cityName, materialName);
|
const material = getMaterial(divisionName, cityName, materialName);
|
||||||
BulkPurchase(corporation, warehouse, material, amt);
|
BulkPurchase(corporation, warehouse, material, amt);
|
||||||
@ -522,11 +524,11 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
_marketingInvest: unknown,
|
_marketingInvest: unknown,
|
||||||
): void => {
|
): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const designInvest = ctx.helper.number("designInvest", _designInvest);
|
const designInvest = helpers.number(ctx, "designInvest", _designInvest);
|
||||||
const marketingInvest = ctx.helper.number("marketingInvest", _marketingInvest);
|
const marketingInvest = helpers.number(ctx, "marketingInvest", _marketingInvest);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
MakeProduct(corporation, getDivision(divisionName), cityName, productName, designInvest, marketingInvest);
|
MakeProduct(corporation, getDivision(divisionName), cityName, productName, designInvest, marketingInvest);
|
||||||
},
|
},
|
||||||
@ -534,10 +536,10 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _productName: unknown, _cityName: unknown, _qty: unknown): void => {
|
(_divisionName: unknown, _productName: unknown, _cityName: unknown, _qty: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const qty = ctx.helper.number("qty", _qty);
|
const qty = helpers.number(ctx, "qty", _qty);
|
||||||
LimitProductProduction(getProduct(divisionName, productName), cityName, qty);
|
LimitProductProduction(getProduct(divisionName, productName), cityName, qty);
|
||||||
},
|
},
|
||||||
exportMaterial:
|
exportMaterial:
|
||||||
@ -551,12 +553,12 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
_amt: unknown,
|
_amt: unknown,
|
||||||
): void => {
|
): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const sourceDivision = ctx.helper.string("sourceDivision", _sourceDivision);
|
const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision);
|
||||||
const sourceCity = ctx.helper.string("sourceCity", _sourceCity);
|
const sourceCity = helpers.string(ctx, "sourceCity", _sourceCity);
|
||||||
const targetDivision = ctx.helper.string("targetDivision", _targetDivision);
|
const targetDivision = helpers.string(ctx, "targetDivision", _targetDivision);
|
||||||
const targetCity = ctx.helper.string("targetCity", _targetCity);
|
const targetCity = helpers.string(ctx, "targetCity", _targetCity);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const amt = ctx.helper.string("amt", _amt);
|
const amt = helpers.string(ctx, "amt", _amt);
|
||||||
ExportMaterial(
|
ExportMaterial(
|
||||||
targetDivision,
|
targetDivision,
|
||||||
targetCity,
|
targetCity,
|
||||||
@ -576,12 +578,12 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
_amt: unknown,
|
_amt: unknown,
|
||||||
): void => {
|
): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const sourceDivision = ctx.helper.string("sourceDivision", _sourceDivision);
|
const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision);
|
||||||
const sourceCity = ctx.helper.string("sourceCity", _sourceCity);
|
const sourceCity = helpers.string(ctx, "sourceCity", _sourceCity);
|
||||||
const targetDivision = ctx.helper.string("targetDivision", _targetDivision);
|
const targetDivision = helpers.string(ctx, "targetDivision", _targetDivision);
|
||||||
const targetCity = ctx.helper.string("targetCity", _targetCity);
|
const targetCity = helpers.string(ctx, "targetCity", _targetCity);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const amt = ctx.helper.string("amt", _amt);
|
const amt = helpers.string(ctx, "amt", _amt);
|
||||||
CancelExportMaterial(
|
CancelExportMaterial(
|
||||||
targetDivision,
|
targetDivision,
|
||||||
targetCity,
|
targetCity,
|
||||||
@ -593,56 +595,56 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _qty: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _qty: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const qty = ctx.helper.number("qty", _qty);
|
const qty = helpers.number(ctx, "qty", _qty);
|
||||||
LimitMaterialProduction(getMaterial(divisionName, cityName, materialName), qty);
|
LimitMaterialProduction(getMaterial(divisionName, cityName, materialName), qty);
|
||||||
},
|
},
|
||||||
setMaterialMarketTA1:
|
setMaterialMarketTA1:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _on: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _on: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const on = ctx.helper.boolean(_on);
|
const on = !!_on;
|
||||||
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
|
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
|
||||||
throw ctx.makeRuntimeErrorMsg(`You have not researched MarketTA.I for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.I for division: ${divisionName}`);
|
||||||
SetMaterialMarketTA1(getMaterial(divisionName, cityName, materialName), on);
|
SetMaterialMarketTA1(getMaterial(divisionName, cityName, materialName), on);
|
||||||
},
|
},
|
||||||
setMaterialMarketTA2:
|
setMaterialMarketTA2:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _on: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _on: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const materialName = ctx.helper.string("materialName", _materialName);
|
const materialName = helpers.string(ctx, "materialName", _materialName);
|
||||||
const on = ctx.helper.boolean(_on);
|
const on = !!_on;
|
||||||
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
|
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
|
||||||
throw ctx.makeRuntimeErrorMsg(`You have not researched MarketTA.II for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
|
||||||
SetMaterialMarketTA2(getMaterial(divisionName, cityName, materialName), on);
|
SetMaterialMarketTA2(getMaterial(divisionName, cityName, materialName), on);
|
||||||
},
|
},
|
||||||
setProductMarketTA1:
|
setProductMarketTA1:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _productName: unknown, _on: unknown): void => {
|
(_divisionName: unknown, _productName: unknown, _on: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const on = ctx.helper.boolean(_on);
|
const on = !!_on;
|
||||||
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
|
if (!getDivision(divisionName).hasResearch("Market-TA.I"))
|
||||||
throw ctx.makeRuntimeErrorMsg(`You have not researched MarketTA.I for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.I for division: ${divisionName}`);
|
||||||
SetProductMarketTA1(getProduct(divisionName, productName), on);
|
SetProductMarketTA1(getProduct(divisionName, productName), on);
|
||||||
},
|
},
|
||||||
setProductMarketTA2:
|
setProductMarketTA2:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _productName: unknown, _on: unknown): void => {
|
(_divisionName: unknown, _productName: unknown, _on: unknown): void => {
|
||||||
checkAccess(ctx, 7);
|
checkAccess(ctx, 7);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const productName = ctx.helper.string("productName", _productName);
|
const productName = helpers.string(ctx, "productName", _productName);
|
||||||
const on = ctx.helper.boolean(_on);
|
const on = !!_on;
|
||||||
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
|
if (!getDivision(divisionName).hasResearch("Market-TA.II"))
|
||||||
throw ctx.makeRuntimeErrorMsg(`You have not researched MarketTA.II for division: ${divisionName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You have not researched MarketTA.II for division: ${divisionName}`);
|
||||||
SetProductMarketTA2(getProduct(divisionName, productName), on);
|
SetProductMarketTA2(getProduct(divisionName, productName), on);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -652,7 +654,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown): number => {
|
(_divisionName: unknown): number => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const division = getDivision(divisionName);
|
const division = getDivision(divisionName);
|
||||||
return division.getAdVertCost();
|
return division.getAdVertCost();
|
||||||
},
|
},
|
||||||
@ -660,7 +662,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown): number => {
|
(_divisionName: unknown): number => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const division = getDivision(divisionName);
|
const division = getDivision(divisionName);
|
||||||
return division.numAdVerts;
|
return division.numAdVerts;
|
||||||
},
|
},
|
||||||
@ -668,25 +670,25 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _researchName: unknown): number => {
|
(_divisionName: unknown, _researchName: unknown): number => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const researchName = ctx.helper.string("researchName", _researchName);
|
const researchName = helpers.string(ctx, "researchName", _researchName);
|
||||||
return getResearchCost(getDivision(divisionName), researchName);
|
return getResearchCost(getDivision(divisionName), researchName);
|
||||||
},
|
},
|
||||||
hasResearched:
|
hasResearched:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _researchName: unknown): boolean => {
|
(_divisionName: unknown, _researchName: unknown): boolean => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const researchName = ctx.helper.string("researchName", _researchName);
|
const researchName = helpers.string(ctx, "researchName", _researchName);
|
||||||
return hasResearched(getDivision(divisionName), researchName);
|
return hasResearched(getDivision(divisionName), researchName);
|
||||||
},
|
},
|
||||||
getOfficeSizeUpgradeCost:
|
getOfficeSizeUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _size: unknown): number => {
|
(_divisionName: unknown, _cityName: unknown, _size: unknown): number => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const size = ctx.helper.number("size", _size);
|
const size = helpers.number(ctx, "size", _size);
|
||||||
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and greater than 0");
|
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and greater than 0");
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
const initialPriceMult = Math.round(office.size / CorporationConstants.OfficeInitialSize);
|
const initialPriceMult = Math.round(office.size / CorporationConstants.OfficeInitialSize);
|
||||||
@ -701,10 +703,10 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _employeeName: unknown, _job: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _employeeName: unknown, _job: unknown): void => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const employeeName = ctx.helper.string("employeeName", _employeeName);
|
const employeeName = helpers.string(ctx, "employeeName", _employeeName);
|
||||||
const job = ctx.helper.string("job", _job);
|
const job = helpers.string(ctx, "job", _job);
|
||||||
|
|
||||||
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
@ -715,10 +717,10 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _job: unknown, _amount: unknown): boolean => {
|
(_divisionName: unknown, _cityName: unknown, _job: unknown, _amount: unknown): boolean => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const amount = ctx.helper.number("amount", _amount);
|
const amount = helpers.number(ctx, "amount", _amount);
|
||||||
const job = ctx.helper.string("job", _job);
|
const job = helpers.string(ctx, "job", _job);
|
||||||
|
|
||||||
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
if (!Object.values(EmployeePositions).includes(job)) throw new Error(`'${job}' is not a valid job.`);
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
@ -729,8 +731,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): NSEmployee | undefined => {
|
(_divisionName: unknown, _cityName: unknown): NSEmployee | undefined => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
const employee = office.hireRandomEmployee();
|
const employee = office.hireRandomEmployee();
|
||||||
if (employee === undefined) return undefined;
|
if (employee === undefined) return undefined;
|
||||||
@ -753,9 +755,9 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _size: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown, _size: unknown): void => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const size = ctx.helper.number("size", _size);
|
const size = helpers.number(ctx, "size", _size);
|
||||||
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and greater than 0");
|
if (size < 0) throw new Error("Invalid value for size field! Must be numeric and greater than 0");
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
@ -765,9 +767,9 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _costPerEmployee: unknown): number => {
|
(_divisionName: unknown, _cityName: unknown, _costPerEmployee: unknown): number => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const costPerEmployee = ctx.helper.number("costPerEmployee", _costPerEmployee);
|
const costPerEmployee = helpers.number(ctx, "costPerEmployee", _costPerEmployee);
|
||||||
|
|
||||||
if (costPerEmployee < 0) {
|
if (costPerEmployee < 0) {
|
||||||
throw new Error("Invalid value for Cost Per Employee field! Must be numeric and greater than 0");
|
throw new Error("Invalid value for Cost Per Employee field! Must be numeric and greater than 0");
|
||||||
@ -782,8 +784,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): boolean => {
|
(_divisionName: unknown, _cityName: unknown): boolean => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
|
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
@ -794,7 +796,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown): void => {
|
(_divisionName: unknown): void => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
HireAdVert(corporation, getDivision(divisionName));
|
HireAdVert(corporation, getDivision(divisionName));
|
||||||
},
|
},
|
||||||
@ -802,16 +804,16 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _researchName: unknown): void => {
|
(_divisionName: unknown, _researchName: unknown): void => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const researchName = ctx.helper.string("researchName", _researchName);
|
const researchName = helpers.string(ctx, "researchName", _researchName);
|
||||||
Research(getDivision(divisionName), researchName);
|
Research(getDivision(divisionName), researchName);
|
||||||
},
|
},
|
||||||
getOffice:
|
getOffice:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): NSOffice => {
|
(_divisionName: unknown, _cityName: unknown): NSOffice => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const office = getOffice(divisionName, cityName);
|
const office = getOffice(divisionName, cityName);
|
||||||
return {
|
return {
|
||||||
loc: office.loc,
|
loc: office.loc,
|
||||||
@ -847,9 +849,9 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown, _employeeName: unknown): NSEmployee => {
|
(_divisionName: unknown, _cityName: unknown, _employeeName: unknown): NSEmployee => {
|
||||||
checkAccess(ctx, 8);
|
checkAccess(ctx, 8);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
const employeeName = ctx.helper.string("employeeName", _employeeName);
|
const employeeName = helpers.string(ctx, "employeeName", _employeeName);
|
||||||
const employee = getEmployee(divisionName, cityName, employeeName);
|
const employee = getEmployee(divisionName, cityName, employeeName);
|
||||||
return {
|
return {
|
||||||
name: employee.name,
|
name: employee.name,
|
||||||
@ -871,12 +873,27 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
return {
|
return {
|
||||||
...warehouseAPI,
|
...warehouseAPI,
|
||||||
...officeAPI,
|
...officeAPI,
|
||||||
|
getMaterialNames: () => (): string[] => {
|
||||||
|
return CorporationConstants.AllMaterials;
|
||||||
|
},
|
||||||
|
getIndustryTypes: () => (): string[] => {
|
||||||
|
return CorporationConstants.AllIndustryTypes;
|
||||||
|
},
|
||||||
|
getUnlockables: () => (): string[] => {
|
||||||
|
return CorporationConstants.AllUnlocks;
|
||||||
|
},
|
||||||
|
getUpgradeNames: () => (): string[] => {
|
||||||
|
return CorporationConstants.AllUpgrades;
|
||||||
|
},
|
||||||
|
getResearchNames: () => (): string[] => {
|
||||||
|
return CorporationConstants.AllResearch;
|
||||||
|
},
|
||||||
expandIndustry:
|
expandIndustry:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_industryName: unknown, _divisionName: unknown): void => {
|
(_industryName: unknown, _divisionName: unknown): void => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const industryName = ctx.helper.string("industryName", _industryName);
|
const industryName = helpers.string(ctx, "industryName", _industryName);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
NewIndustry(corporation, industryName, divisionName);
|
NewIndustry(corporation, industryName, divisionName);
|
||||||
},
|
},
|
||||||
@ -884,8 +901,8 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown, _cityName: unknown): void => {
|
(_divisionName: unknown, _cityName: unknown): void => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const cityName = ctx.helper.city("cityName", _cityName);
|
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||||
if (!CorporationConstants.Cities.includes(cityName)) throw new Error("Invalid city name");
|
if (!CorporationConstants.Cities.includes(cityName)) throw new Error("Invalid city name");
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const division = getDivision(divisionName);
|
const division = getDivision(divisionName);
|
||||||
@ -895,7 +912,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgradeName: unknown): void => {
|
(_upgradeName: unknown): void => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const upgrade = Object.values(CorporationUnlockUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
const upgrade = Object.values(CorporationUnlockUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
||||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||||
@ -905,7 +922,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgradeName: unknown): void => {
|
(_upgradeName: unknown): void => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
const upgrade = Object.values(CorporationUpgrades).find((upgrade) => upgrade.name === upgradeName);
|
||||||
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
|
||||||
@ -915,12 +932,12 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_rate: unknown): void => {
|
(_rate: unknown): void => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const rate = ctx.helper.number("rate", _rate);
|
const rate = helpers.number(ctx, "rate", _rate);
|
||||||
const max = CorporationConstants.DividendMaxRate;
|
const max = CorporationConstants.DividendMaxRate;
|
||||||
if (rate < 0 || rate > max)
|
if (rate < 0 || rate > max)
|
||||||
throw new Error(`Invalid value for rate field! Must be numeric, greater than 0, and less than ${max}`);
|
throw new Error(`Invalid value for rate field! Must be numeric, greater than 0, and less than ${max}`);
|
||||||
const corporation = getCorporation();
|
const corporation = getCorporation();
|
||||||
if (!corporation.public) throw ctx.makeRuntimeErrorMsg(`Your company has not gone public!`);
|
if (!corporation.public) throw helpers.makeRuntimeErrorMsg(ctx, `Your company has not gone public!`);
|
||||||
IssueDividends(corporation, rate);
|
IssueDividends(corporation, rate);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -930,7 +947,7 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_divisionName: unknown): NSDivision => {
|
(_divisionName: unknown): NSDivision => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const divisionName = ctx.helper.string("divisionName", _divisionName);
|
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||||
const division = getDivision(divisionName);
|
const division = getDivision(divisionName);
|
||||||
return getSafeDivision(division);
|
return getSafeDivision(division);
|
||||||
},
|
},
|
||||||
@ -958,43 +975,43 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
createCorporation:
|
createCorporation:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_corporationName: unknown, _selfFund: unknown = true): boolean => {
|
(_corporationName: unknown, _selfFund: unknown = true): boolean => {
|
||||||
const corporationName = ctx.helper.string("corporationName", _corporationName);
|
const corporationName = helpers.string(ctx, "corporationName", _corporationName);
|
||||||
const selfFund = ctx.helper.boolean(_selfFund);
|
const selfFund = !_selfFund;
|
||||||
return createCorporation(corporationName, selfFund);
|
return createCorporation(corporationName, selfFund);
|
||||||
},
|
},
|
||||||
hasUnlockUpgrade:
|
hasUnlockUpgrade:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgradeName: unknown): boolean => {
|
(_upgradeName: unknown): boolean => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
return hasUnlockUpgrade(upgradeName);
|
return hasUnlockUpgrade(upgradeName);
|
||||||
},
|
},
|
||||||
getUnlockUpgradeCost:
|
getUnlockUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgradeName: unknown): number => {
|
(_upgradeName: unknown): number => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
return getUnlockUpgradeCost(upgradeName);
|
return getUnlockUpgradeCost(upgradeName);
|
||||||
},
|
},
|
||||||
getUpgradeLevel:
|
getUpgradeLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgradeName: unknown): number => {
|
(_upgradeName: unknown): number => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
return getUpgradeLevel(ctx, upgradeName);
|
return getUpgradeLevel(ctx, upgradeName);
|
||||||
},
|
},
|
||||||
getUpgradeLevelCost:
|
getUpgradeLevelCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgradeName: unknown): number => {
|
(_upgradeName: unknown): number => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const upgradeName = ctx.helper.string("upgradeName", _upgradeName);
|
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
|
||||||
return getUpgradeLevelCost(ctx, upgradeName);
|
return getUpgradeLevelCost(ctx, upgradeName);
|
||||||
},
|
},
|
||||||
getExpandIndustryCost:
|
getExpandIndustryCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_industryName: unknown): number => {
|
(_industryName: unknown): number => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const industryName = ctx.helper.string("industryName", _industryName);
|
const industryName = helpers.string(ctx, "industryName", _industryName);
|
||||||
return getExpandIndustryCost(industryName);
|
return getExpandIndustryCost(industryName);
|
||||||
},
|
},
|
||||||
getExpandCityCost: (ctx: NetscriptContext) => (): number => {
|
getExpandCityCost: (ctx: NetscriptContext) => (): number => {
|
||||||
@ -1013,29 +1030,29 @@ export function NetscriptCorporation(player: IPlayer): InternalAPI<NSCorporation
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_numShares: unknown): boolean => {
|
(_numShares: unknown): boolean => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const numShares = ctx.helper.number("numShares", _numShares);
|
const numShares = helpers.number(ctx, "numShares", _numShares);
|
||||||
return goPublic(numShares);
|
return goPublic(numShares);
|
||||||
},
|
},
|
||||||
sellShares:
|
sellShares:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_numShares: unknown): number => {
|
(_numShares: unknown): number => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const numShares = ctx.helper.number("numShares", _numShares);
|
const numShares = helpers.number(ctx, "numShares", _numShares);
|
||||||
return SellShares(getCorporation(), player, numShares);
|
return SellShares(getCorporation(), player, numShares);
|
||||||
},
|
},
|
||||||
buyBackShares:
|
buyBackShares:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_numShares: unknown): boolean => {
|
(_numShares: unknown): boolean => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const numShares = ctx.helper.number("numShares", _numShares);
|
const numShares = helpers.number(ctx, "numShares", _numShares);
|
||||||
return BuyBackShares(getCorporation(), player, numShares);
|
return BuyBackShares(getCorporation(), player, numShares);
|
||||||
},
|
},
|
||||||
bribe:
|
bribe:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_factionName: unknown, _amountCash: unknown): boolean => {
|
(_factionName: unknown, _amountCash: unknown): boolean => {
|
||||||
checkAccess(ctx);
|
checkAccess(ctx);
|
||||||
const factionName = ctx.helper.string("factionName", _factionName);
|
const factionName = helpers.string(ctx, "factionName", _factionName);
|
||||||
const amountCash = ctx.helper.number("amountCash", _amountCash);
|
const amountCash = helpers.number(ctx, "amountCash", _amountCash);
|
||||||
return bribe(factionName, amountCash);
|
return bribe(factionName, amountCash);
|
||||||
},
|
},
|
||||||
getBonusTime: (ctx: NetscriptContext) => (): number => {
|
getBonusTime: (ctx: NetscriptContext) => (): number => {
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
import { Exploit } from "../Exploits/Exploit";
|
import { Exploit } from "../Exploits/Exploit";
|
||||||
import * as bcrypt from "bcryptjs";
|
import * as bcrypt from "bcryptjs";
|
||||||
import { Apr1Events as devMenu } from "../ui/Apr1";
|
import { Apr1Events as devMenu } from "../ui/Apr1";
|
||||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export interface INetscriptExtra {
|
export interface INetscriptExtra {
|
||||||
heart: {
|
heart: {
|
||||||
@ -15,7 +16,7 @@ export interface INetscriptExtra {
|
|||||||
rainbow(guess: string): void;
|
rainbow(guess: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NetscriptExtra(player: IPlayer): InternalAPI<INetscriptExtra> {
|
export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
|
||||||
return {
|
return {
|
||||||
heart: {
|
heart: {
|
||||||
// Easter egg function
|
// Easter egg function
|
||||||
@ -67,7 +68,7 @@ export function NetscriptExtra(player: IPlayer): InternalAPI<INetscriptExtra> {
|
|||||||
function tryGuess(): boolean {
|
function tryGuess(): boolean {
|
||||||
// eslint-disable-next-line no-sync
|
// eslint-disable-next-line no-sync
|
||||||
const verified = bcrypt.compareSync(
|
const verified = bcrypt.compareSync(
|
||||||
ctx.helper.string("guess", guess),
|
helpers.string(ctx, "guess", guess),
|
||||||
"$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO",
|
"$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO",
|
||||||
);
|
);
|
||||||
if (verified) {
|
if (verified) {
|
||||||
|
@ -1,41 +1,42 @@
|
|||||||
import { toNative } from "./toNative";
|
import { toNative } from "./toNative";
|
||||||
import libarg from "arg";
|
import libarg from "arg";
|
||||||
import { ScriptArg } from "../Netscript/ScriptArg";
|
import { ScriptArg } from "../Netscript/ScriptArg";
|
||||||
|
import { NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
|
||||||
type FlagType = StringConstructor | NumberConstructor | BooleanConstructor | StringConstructor[];
|
type FlagType = StringConstructor | NumberConstructor | BooleanConstructor | StringConstructor[];
|
||||||
type FlagsRet = { [key: string]: ScriptArg };
|
type FlagsRet = { [key: string]: ScriptArg };
|
||||||
export function Flags(vargs: string[]): () => (data: unknown) => FlagsRet {
|
export function Flags(ctx: NetscriptContext | string[]): (data: unknown) => FlagsRet {
|
||||||
return (/* ctx: NetscriptContext */) =>
|
const vargs = Array.isArray(ctx) ? ctx : ctx.workerScript.args;
|
||||||
(schema: unknown): FlagsRet => {
|
return (schema: unknown): FlagsRet => {
|
||||||
schema = toNative(schema);
|
schema = toNative(schema);
|
||||||
if (!Array.isArray(schema)) throw new Error("flags schema passed in is invalid.");
|
if (!Array.isArray(schema)) throw new Error("flags schema passed in is invalid.");
|
||||||
const args: {
|
const args: {
|
||||||
[key: string]: FlagType;
|
[key: string]: FlagType;
|
||||||
} = {};
|
} = {};
|
||||||
|
|
||||||
for (const d of schema) {
|
for (const d of schema) {
|
||||||
let t: FlagType = String;
|
let t: FlagType = String;
|
||||||
if (typeof d[1] === "number") {
|
if (typeof d[1] === "number") {
|
||||||
t = Number;
|
t = Number;
|
||||||
} else if (typeof d[1] === "boolean") {
|
} else if (typeof d[1] === "boolean") {
|
||||||
t = Boolean;
|
t = Boolean;
|
||||||
} else if (Array.isArray(d[1])) {
|
} else if (Array.isArray(d[1])) {
|
||||||
t = [String];
|
t = [String];
|
||||||
}
|
|
||||||
const numDashes = d[0].length > 1 ? 2 : 1;
|
|
||||||
args["-".repeat(numDashes) + d[0]] = t;
|
|
||||||
}
|
}
|
||||||
const ret: FlagsRet = libarg(args, { argv: vargs });
|
const numDashes = d[0].length > 1 ? 2 : 1;
|
||||||
for (const d of schema) {
|
args["-".repeat(numDashes) + d[0]] = t;
|
||||||
if (!ret.hasOwnProperty("--" + d[0]) || !ret.hasOwnProperty("-" + d[0])) ret[d[0]] = d[1];
|
}
|
||||||
}
|
const ret: FlagsRet = libarg(args, { argv: vargs });
|
||||||
for (const key of Object.keys(ret)) {
|
for (const d of schema) {
|
||||||
if (!key.startsWith("-")) continue;
|
if (!ret.hasOwnProperty("--" + d[0]) || !ret.hasOwnProperty("-" + d[0])) ret[d[0]] = d[1];
|
||||||
const value = ret[key];
|
}
|
||||||
delete ret[key];
|
for (const key of Object.keys(ret)) {
|
||||||
const numDashes = key.length === 2 ? 1 : 2;
|
if (!key.startsWith("-")) continue;
|
||||||
ret[key.slice(numDashes)] = value;
|
const value = ret[key];
|
||||||
}
|
delete ret[key];
|
||||||
return ret;
|
const numDashes = key.length === 2 ? 1 : 2;
|
||||||
};
|
ret[key.slice(numDashes)] = value;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { INetscriptHelper } from "./INetscriptHelper";
|
import { Player as player } from "../Player";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { calculateServerGrowth } from "../Server/formulas/grow";
|
import { calculateServerGrowth } from "../Server/formulas/grow";
|
||||||
import {
|
import {
|
||||||
calculateMoneyGainRate,
|
calculateMoneyGainRate,
|
||||||
@ -43,11 +42,12 @@ import {
|
|||||||
import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor } from "../Faction/formulas/favor";
|
import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor } from "../Faction/formulas/favor";
|
||||||
import { repFromDonation } from "../Faction/formulas/donation";
|
import { repFromDonation } from "../Faction/formulas/donation";
|
||||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): InternalAPI<IFormulas> {
|
export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||||
const checkFormulasAccess = function (ctx: NetscriptContext): void {
|
const checkFormulasAccess = function (ctx: NetscriptContext): void {
|
||||||
if (!player.hasProgram(Programs.Formulas.name)) {
|
if (!player.hasProgram(Programs.Formulas.name)) {
|
||||||
throw helper.makeRuntimeErrorMsg(`formulas.${ctx.function}`, `Requires Formulas.exe to run.`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Requires Formulas.exe to run.`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
@ -55,22 +55,22 @@ export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): In
|
|||||||
calculateFavorToRep:
|
calculateFavorToRep:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_favor: unknown): number => {
|
(_favor: unknown): number => {
|
||||||
const favor = ctx.helper.number("favor", _favor);
|
const favor = helpers.number(ctx, "favor", _favor);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateFavorToRep(favor);
|
return calculateFavorToRep(favor);
|
||||||
},
|
},
|
||||||
calculateRepToFavor:
|
calculateRepToFavor:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_rep: unknown): number => {
|
(_rep: unknown): number => {
|
||||||
const rep = ctx.helper.number("rep", _rep);
|
const rep = helpers.number(ctx, "rep", _rep);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateRepToFavor(rep);
|
return calculateRepToFavor(rep);
|
||||||
},
|
},
|
||||||
repFromDonation:
|
repFromDonation:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_amount: unknown, _player: unknown): number => {
|
(_amount: unknown, _player: unknown): number => {
|
||||||
const amount = ctx.helper.number("amount", _amount);
|
const amount = helpers.number(ctx, "amount", _amount);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return repFromDonation(amount, player);
|
return repFromDonation(amount, player);
|
||||||
},
|
},
|
||||||
@ -79,16 +79,16 @@ export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): In
|
|||||||
calculateSkill:
|
calculateSkill:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_exp: unknown, _mult: unknown = 1): number => {
|
(_exp: unknown, _mult: unknown = 1): number => {
|
||||||
const exp = ctx.helper.number("exp", _exp);
|
const exp = helpers.number(ctx, "exp", _exp);
|
||||||
const mult = ctx.helper.number("mult", _mult);
|
const mult = helpers.number(ctx, "mult", _mult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateSkill(exp, mult);
|
return calculateSkill(exp, mult);
|
||||||
},
|
},
|
||||||
calculateExp:
|
calculateExp:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_skill: unknown, _mult: unknown = 1): number => {
|
(_skill: unknown, _mult: unknown = 1): number => {
|
||||||
const skill = ctx.helper.number("skill", _skill);
|
const skill = helpers.number(ctx, "skill", _skill);
|
||||||
const mult = ctx.helper.number("mult", _mult);
|
const mult = helpers.number(ctx, "mult", _mult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateExp(skill, mult);
|
return calculateExp(skill, mult);
|
||||||
},
|
},
|
||||||
@ -97,58 +97,58 @@ export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): In
|
|||||||
hackChance:
|
hackChance:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _player: unknown): number => {
|
(_server: unknown, _player: unknown): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateHackingChance(server, player);
|
return calculateHackingChance(server, player);
|
||||||
},
|
},
|
||||||
hackExp:
|
hackExp:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _player: unknown): number => {
|
(_server: unknown, _player: unknown): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateHackingExpGain(server, player);
|
return calculateHackingExpGain(server, player);
|
||||||
},
|
},
|
||||||
hackPercent:
|
hackPercent:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _player: unknown): number => {
|
(_server: unknown, _player: unknown): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculatePercentMoneyHacked(server, player);
|
return calculatePercentMoneyHacked(server, player);
|
||||||
},
|
},
|
||||||
growPercent:
|
growPercent:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _threads: unknown, _player: unknown, _cores: unknown = 1): number => {
|
(_server: unknown, _threads: unknown, _player: unknown, _cores: unknown = 1): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
const threads = ctx.helper.number("threads", _threads);
|
const threads = helpers.number(ctx, "threads", _threads);
|
||||||
const cores = ctx.helper.number("cores", _cores);
|
const cores = helpers.number(ctx, "cores", _cores);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateServerGrowth(server, threads, player, cores);
|
return calculateServerGrowth(server, threads, player, cores);
|
||||||
},
|
},
|
||||||
hackTime:
|
hackTime:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _player: unknown): number => {
|
(_server: unknown, _player: unknown): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateHackingTime(server, player) * 1000;
|
return calculateHackingTime(server, player) * 1000;
|
||||||
},
|
},
|
||||||
growTime:
|
growTime:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _player: unknown): number => {
|
(_server: unknown, _player: unknown): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateGrowTime(server, player) * 1000;
|
return calculateGrowTime(server, player) * 1000;
|
||||||
},
|
},
|
||||||
weakenTime:
|
weakenTime:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_server: unknown, _player: unknown): number => {
|
(_server: unknown, _player: unknown): number => {
|
||||||
const server = ctx.helper.server(_server);
|
const server = helpers.server(ctx, _server);
|
||||||
const player = ctx.helper.player(_player);
|
const player = helpers.player(ctx, _player);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateWeakenTime(server, player) * 1000;
|
return calculateWeakenTime(server, player) * 1000;
|
||||||
},
|
},
|
||||||
@ -157,45 +157,45 @@ export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): In
|
|||||||
moneyGainRate:
|
moneyGainRate:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
(_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
||||||
const level = ctx.helper.number("level", _level);
|
const level = helpers.number(ctx, "level", _level);
|
||||||
const ram = ctx.helper.number("ram", _ram);
|
const ram = helpers.number(ctx, "ram", _ram);
|
||||||
const cores = ctx.helper.number("cores", _cores);
|
const cores = helpers.number(ctx, "cores", _cores);
|
||||||
const mult = ctx.helper.number("mult", _mult);
|
const mult = helpers.number(ctx, "mult", _mult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateMoneyGainRate(level, ram, cores, mult);
|
return calculateMoneyGainRate(level, ram, cores, mult);
|
||||||
},
|
},
|
||||||
levelUpgradeCost:
|
levelUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingLevel = ctx.helper.number("startingLevel", _startingLevel);
|
const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel);
|
||||||
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||||
const costMult = ctx.helper.number("costMult", _costMult);
|
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
ramUpgradeCost:
|
ramUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingRam = ctx.helper.number("startingRam", _startingRam);
|
const startingRam = helpers.number(ctx, "startingRam", _startingRam);
|
||||||
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||||
const costMult = ctx.helper.number("costMult", _costMult);
|
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
coreUpgradeCost:
|
coreUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingCore = ctx.helper.number("startingCore", _startingCore);
|
const startingCore = helpers.number(ctx, "startingCore", _startingCore);
|
||||||
const extraCores = ctx.helper.number("extraCores", _extraCores);
|
const extraCores = helpers.number(ctx, "extraCores", _extraCores);
|
||||||
const costMult = ctx.helper.number("costMult", _costMult);
|
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||||
},
|
},
|
||||||
hacknetNodeCost:
|
hacknetNodeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_n: unknown, _mult: unknown): number => {
|
(_n: unknown, _mult: unknown): number => {
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const mult = ctx.helper.number("mult", _mult);
|
const mult = helpers.number(ctx, "mult", _mult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateNodeCost(n, mult);
|
return calculateNodeCost(n, mult);
|
||||||
},
|
},
|
||||||
@ -208,69 +208,66 @@ export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): In
|
|||||||
hashGainRate:
|
hashGainRate:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_level: unknown, _ramUsed: unknown, _maxRam: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
(_level: unknown, _ramUsed: unknown, _maxRam: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
||||||
const level = ctx.helper.number("level", _level);
|
const level = helpers.number(ctx, "level", _level);
|
||||||
const ramUsed = ctx.helper.number("ramUsed", _ramUsed);
|
const ramUsed = helpers.number(ctx, "ramUsed", _ramUsed);
|
||||||
const maxRam = ctx.helper.number("maxRam", _maxRam);
|
const maxRam = helpers.number(ctx, "maxRam", _maxRam);
|
||||||
const cores = ctx.helper.number("cores", _cores);
|
const cores = helpers.number(ctx, "cores", _cores);
|
||||||
const mult = ctx.helper.number("mult", _mult);
|
const mult = helpers.number(ctx, "mult", _mult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
||||||
},
|
},
|
||||||
levelUpgradeCost:
|
levelUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingLevel = ctx.helper.number("startingLevel", _startingLevel);
|
const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel);
|
||||||
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||||
const costMult = ctx.helper.number("costMult", _costMult);
|
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
ramUpgradeCost:
|
ramUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingRam = ctx.helper.number("startingRam", _startingRam);
|
const startingRam = helpers.number(ctx, "startingRam", _startingRam);
|
||||||
const extraLevels = ctx.helper.number("extraLevels", _extraLevels);
|
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||||
const costMult = ctx.helper.number("costMult", _costMult);
|
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
coreUpgradeCost:
|
coreUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
||||||
const startingCore = ctx.helper.number("startingCore", _startingCore);
|
const startingCore = helpers.number(ctx, "startingCore", _startingCore);
|
||||||
const extraCores = ctx.helper.number("extraCores", _extraCores);
|
const extraCores = helpers.number(ctx, "extraCores", _extraCores);
|
||||||
const costMult = ctx.helper.number("costMult", _costMult);
|
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||||
},
|
},
|
||||||
cacheUpgradeCost:
|
cacheUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_startingCache: unknown, _extraCache: unknown = 1): number => {
|
(_startingCache: unknown, _extraCache: unknown = 1): number => {
|
||||||
const startingCache = ctx.helper.number("startingCache", _startingCache);
|
const startingCache = helpers.number(ctx, "startingCache", _startingCache);
|
||||||
const extraCache = ctx.helper.number("extraCache", _extraCache);
|
const extraCache = helpers.number(ctx, "extraCache", _extraCache);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
||||||
},
|
},
|
||||||
hashUpgradeCost:
|
hashUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgName: unknown, _level: unknown): number => {
|
(_upgName: unknown, _level: unknown): number => {
|
||||||
const upgName = helper.string("hashUpgradeCost", "upgName", _upgName);
|
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||||
const level = ctx.helper.number("level", _level);
|
const level = helpers.number(ctx, "level", _level);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
const upg = player.hashManager.getUpgrade(upgName);
|
const upg = player.hashManager.getUpgrade(upgName);
|
||||||
if (!upg) {
|
if (!upg) {
|
||||||
throw helper.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid Hash Upgrade: ${upgName}`);
|
||||||
"formulas.hacknetServers.calculateHashUpgradeCost",
|
|
||||||
`Invalid Hash Upgrade: ${upgName}`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return upg.getCost(level);
|
return upg.getCost(level);
|
||||||
},
|
},
|
||||||
hacknetServerCost:
|
hacknetServerCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_n: unknown, _mult: unknown = 1): number => {
|
(_n: unknown, _mult: unknown = 1): number => {
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const mult = ctx.helper.number("mult", _mult);
|
const mult = helpers.number(ctx, "mult", _mult);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return HScalculateServerCost(n, mult);
|
return HScalculateServerCost(n, mult);
|
||||||
},
|
},
|
||||||
@ -283,48 +280,48 @@ export function NetscriptFormulas(player: IPlayer, helper: INetscriptHelper): In
|
|||||||
wantedPenalty:
|
wantedPenalty:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_gang: unknown): number => {
|
(_gang: unknown): number => {
|
||||||
const gang = ctx.helper.gang(_gang);
|
const gang = helpers.gang(ctx, _gang);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateWantedPenalty(gang);
|
return calculateWantedPenalty(gang);
|
||||||
},
|
},
|
||||||
respectGain:
|
respectGain:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
||||||
const gang = ctx.helper.gang(_gang);
|
const gang = helpers.gang(ctx, _gang);
|
||||||
const member = ctx.helper.gangMember(_member);
|
const member = helpers.gangMember(ctx, _member);
|
||||||
const task = ctx.helper.gangTask(_task);
|
const task = helpers.gangTask(ctx, _task);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateRespectGain(gang, member, task);
|
return calculateRespectGain(gang, member, task);
|
||||||
},
|
},
|
||||||
wantedLevelGain:
|
wantedLevelGain:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
||||||
const gang = ctx.helper.gang(_gang);
|
const gang = helpers.gang(ctx, _gang);
|
||||||
const member = ctx.helper.gangMember(_member);
|
const member = helpers.gangMember(ctx, _member);
|
||||||
const task = ctx.helper.gangTask(_task);
|
const task = helpers.gangTask(ctx, _task);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateWantedLevelGain(gang, member, task);
|
return calculateWantedLevelGain(gang, member, task);
|
||||||
},
|
},
|
||||||
moneyGain:
|
moneyGain:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
||||||
const gang = ctx.helper.gang(_gang);
|
const gang = helpers.gang(ctx, _gang);
|
||||||
const member = ctx.helper.gangMember(_member);
|
const member = helpers.gangMember(ctx, _member);
|
||||||
const task = ctx.helper.gangTask(_task);
|
const task = helpers.gangTask(ctx, _task);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateMoneyGain(gang, member, task);
|
return calculateMoneyGain(gang, member, task);
|
||||||
},
|
},
|
||||||
ascensionPointsGain:
|
ascensionPointsGain:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_exp: unknown): number => {
|
(_exp: unknown): number => {
|
||||||
const exp = ctx.helper.number("exp", _exp);
|
const exp = helpers.number(ctx, "exp", _exp);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateAscensionPointsGain(exp);
|
return calculateAscensionPointsGain(exp);
|
||||||
},
|
},
|
||||||
ascensionMultiplier:
|
ascensionMultiplier:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_points: unknown): number => {
|
(_points: unknown): number => {
|
||||||
const points = ctx.helper.number("points", _points);
|
const points = helpers.number(ctx, "points", _points);
|
||||||
checkFormulasAccess(ctx);
|
checkFormulasAccess(ctx);
|
||||||
return calculateAscensionMult(points);
|
return calculateAscensionMult(points);
|
||||||
},
|
},
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import { FactionNames } from "../Faction/data/FactionNames";
|
import { FactionNames } from "../Faction/data/FactionNames";
|
||||||
import { GangConstants } from "../Gang/data/Constants";
|
import { GangConstants } from "../Gang/data/Constants";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
import { Gang } from "../Gang/Gang";
|
import { Gang } from "../Gang/Gang";
|
||||||
import { AllGangs } from "../Gang/AllGangs";
|
import { AllGangs } from "../Gang/AllGangs";
|
||||||
import { GangMemberTasks } from "../Gang/GangMemberTasks";
|
import { GangMemberTasks } from "../Gang/GangMemberTasks";
|
||||||
import { GangMemberUpgrades } from "../Gang/GangMemberUpgrades";
|
import { GangMemberUpgrades } from "../Gang/GangMemberUpgrades";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
|
||||||
import { GangMember } from "../Gang/GangMember";
|
import { GangMember } from "../Gang/GangMember";
|
||||||
import { GangMemberTask } from "../Gang/GangMemberTask";
|
import { GangMemberTask } from "../Gang/GangMemberTask";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Gang as IGang,
|
Gang as IGang,
|
||||||
@ -21,13 +21,13 @@ import {
|
|||||||
} from "../ScriptEditor/NetscriptDefinitions";
|
} from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
|
||||||
export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): InternalAPI<IGang> {
|
export function NetscriptGang(): InternalAPI<IGang> {
|
||||||
const checkGangApiAccess = function (ctx: NetscriptContext): void {
|
const checkGangApiAccess = function (ctx: NetscriptContext): 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;
|
||||||
if (!hasAccess) {
|
if (!hasAccess) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`You do not currently have a Gang`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You do not currently have a Gang`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,13 +35,13 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
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 ctx.makeRuntimeErrorMsg(`Invalid gang member: '${name}'`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid gang member: '${name}'`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getGangTask = function (ctx: NetscriptContext, name: string): GangMemberTask {
|
const getGangTask = function (ctx: NetscriptContext, name: string): GangMemberTask {
|
||||||
const task = GangMemberTasks[name];
|
const task = GangMemberTasks[name];
|
||||||
if (!task) {
|
if (!task) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid task: '${name}'`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid task: '${name}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
@ -51,7 +51,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
createGang:
|
createGang:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_faction: unknown): boolean => {
|
(_faction: unknown): boolean => {
|
||||||
const faction = ctx.helper.string("faction", _faction);
|
const faction = helpers.string(ctx, "faction", _faction);
|
||||||
// this list is copied from Faction/ui/Root.tsx
|
// this list is copied from Faction/ui/Root.tsx
|
||||||
|
|
||||||
if (!player.canAccessGang() || !GangConstants.Names.includes(faction)) return false;
|
if (!player.canAccessGang() || !GangConstants.Names.includes(faction)) return false;
|
||||||
@ -102,7 +102,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
getMemberInformation:
|
getMemberInformation:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_memberName: unknown): GangMemberInfo => {
|
(_memberName: unknown): GangMemberInfo => {
|
||||||
const memberName = ctx.helper.string("memberName", _memberName);
|
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
@ -163,15 +163,15 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
recruitMember:
|
recruitMember:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_memberName: unknown): boolean => {
|
(_memberName: unknown): boolean => {
|
||||||
const memberName = ctx.helper.string("memberName", _memberName);
|
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
const recruited = gang.recruitMember(memberName);
|
const recruited = gang.recruitMember(memberName);
|
||||||
if (recruited) {
|
if (recruited) {
|
||||||
workerScript.log("gang.recruitMember", () => `Successfully recruited Gang Member '${memberName}'`);
|
ctx.workerScript.log("gang.recruitMember", () => `Successfully recruited Gang Member '${memberName}'`);
|
||||||
} else {
|
} else {
|
||||||
workerScript.log("gang.recruitMember", () => `Failed to recruit Gang Member '${memberName}'`);
|
ctx.workerScript.log("gang.recruitMember", () => `Failed to recruit Gang Member '${memberName}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return recruited;
|
return recruited;
|
||||||
@ -187,14 +187,14 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
setMemberTask:
|
setMemberTask:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_memberName: unknown, _taskName: unknown): boolean => {
|
(_memberName: unknown, _taskName: unknown): boolean => {
|
||||||
const memberName = ctx.helper.string("memberName", _memberName);
|
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||||
const taskName = ctx.helper.string("taskName", _taskName);
|
const taskName = helpers.string(ctx, "taskName", _taskName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const member = getGangMember(ctx, memberName);
|
const member = getGangMember(ctx, memberName);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
if (!gang.getAllTaskNames().includes(taskName)) {
|
if (!gang.getAllTaskNames().includes(taskName)) {
|
||||||
workerScript.log(
|
ctx.workerScript.log(
|
||||||
"gang.setMemberTask",
|
"gang.setMemberTask",
|
||||||
() =>
|
() =>
|
||||||
`Failed to assign Gang Member '${memberName}' to Invalid task '${taskName}'. '${memberName}' is now Unassigned`,
|
`Failed to assign Gang Member '${memberName}' to Invalid task '${taskName}'. '${memberName}' is now Unassigned`,
|
||||||
@ -203,12 +203,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
}
|
}
|
||||||
const success = member.assignToTask(taskName);
|
const success = member.assignToTask(taskName);
|
||||||
if (success) {
|
if (success) {
|
||||||
workerScript.log(
|
ctx.workerScript.log(
|
||||||
"gang.setMemberTask",
|
"gang.setMemberTask",
|
||||||
() => `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`,
|
() => `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
workerScript.log(
|
ctx.workerScript.log(
|
||||||
"gang.setMemberTask",
|
"gang.setMemberTask",
|
||||||
() =>
|
() =>
|
||||||
`Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
|
`Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
|
||||||
@ -220,7 +220,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
getTaskStats:
|
getTaskStats:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_taskName: unknown): GangTaskStats => {
|
(_taskName: unknown): GangTaskStats => {
|
||||||
const taskName = ctx.helper.string("taskName", _taskName);
|
const taskName = helpers.string(ctx, "taskName", _taskName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const task = getGangTask(ctx, taskName);
|
const task = getGangTask(ctx, taskName);
|
||||||
const copy = Object.assign({}, task);
|
const copy = Object.assign({}, task);
|
||||||
@ -234,7 +234,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
getEquipmentCost:
|
getEquipmentCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_equipName: unknown): number => {
|
(_equipName: unknown): number => {
|
||||||
const equipName = ctx.helper.string("equipName", _equipName);
|
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
@ -245,7 +245,7 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
getEquipmentType:
|
getEquipmentType:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_equipName: unknown): string => {
|
(_equipName: unknown): string => {
|
||||||
const equipName = ctx.helper.string("equipName", _equipName);
|
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const upg = GangMemberUpgrades[equipName];
|
const upg = GangMemberUpgrades[equipName];
|
||||||
if (upg == null) return "";
|
if (upg == null) return "";
|
||||||
@ -254,11 +254,11 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
getEquipmentStats:
|
getEquipmentStats:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_equipName: unknown): EquipmentStats => {
|
(_equipName: unknown): EquipmentStats => {
|
||||||
const equipName = ctx.helper.string("equipName", _equipName);
|
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const equipment = GangMemberUpgrades[equipName];
|
const equipment = GangMemberUpgrades[equipName];
|
||||||
if (!equipment) {
|
if (!equipment) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid equipment: ${equipName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid equipment: ${equipName}`);
|
||||||
}
|
}
|
||||||
const typecheck: EquipmentStats = equipment.mults;
|
const typecheck: EquipmentStats = equipment.mults;
|
||||||
return Object.assign({}, typecheck) as any;
|
return Object.assign({}, typecheck) as any;
|
||||||
@ -266,8 +266,8 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
purchaseEquipment:
|
purchaseEquipment:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_memberName: unknown, _equipName: unknown): boolean => {
|
(_memberName: unknown, _equipName: unknown): boolean => {
|
||||||
const memberName = ctx.helper.string("memberName", _memberName);
|
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||||
const equipName = ctx.helper.string("equipName", _equipName);
|
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
@ -276,9 +276,12 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
if (!equipment) return false;
|
if (!equipment) return false;
|
||||||
const res = member.buyUpgrade(equipment, player, gang);
|
const res = member.buyUpgrade(equipment, player, gang);
|
||||||
if (res) {
|
if (res) {
|
||||||
workerScript.log("gang.purchaseEquipment", () => `Purchased '${equipName}' for Gang member '${memberName}'`);
|
ctx.workerScript.log(
|
||||||
|
"gang.purchaseEquipment",
|
||||||
|
() => `Purchased '${equipName}' for Gang member '${memberName}'`,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
workerScript.log(
|
ctx.workerScript.log(
|
||||||
"gang.purchaseEquipment",
|
"gang.purchaseEquipment",
|
||||||
() => `Failed to purchase '${equipName}' for Gang member '${memberName}'`,
|
() => `Failed to purchase '${equipName}' for Gang member '${memberName}'`,
|
||||||
);
|
);
|
||||||
@ -289,18 +292,18 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
ascendMember:
|
ascendMember:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_memberName: unknown): GangMemberAscension | undefined => {
|
(_memberName: unknown): GangMemberAscension | undefined => {
|
||||||
const memberName = ctx.helper.string("memberName", _memberName);
|
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
const member = getGangMember(ctx, memberName);
|
const member = getGangMember(ctx, memberName);
|
||||||
if (!member.canAscend()) return;
|
if (!member.canAscend()) return;
|
||||||
return gang.ascendMember(member, workerScript);
|
return gang.ascendMember(member, ctx.workerScript);
|
||||||
},
|
},
|
||||||
getAscensionResult:
|
getAscensionResult:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_memberName: unknown): GangMemberAscension | undefined => {
|
(_memberName: unknown): GangMemberAscension | undefined => {
|
||||||
const memberName = ctx.helper.string("memberName", _memberName);
|
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
@ -314,27 +317,27 @@ export function NetscriptGang(player: IPlayer, workerScript: WorkerScript): Inte
|
|||||||
setTerritoryWarfare:
|
setTerritoryWarfare:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_engage: unknown): void => {
|
(_engage: unknown): void => {
|
||||||
const engage = ctx.helper.boolean(_engage);
|
const engage = !!_engage;
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
if (engage) {
|
if (engage) {
|
||||||
gang.territoryWarfareEngaged = true;
|
gang.territoryWarfareEngaged = true;
|
||||||
workerScript.log("gang.setTerritoryWarfare", () => "Engaging in Gang Territory Warfare");
|
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Engaging in Gang Territory Warfare");
|
||||||
} else {
|
} else {
|
||||||
gang.territoryWarfareEngaged = false;
|
gang.territoryWarfareEngaged = false;
|
||||||
workerScript.log("gang.setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
|
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getChanceToWinClash:
|
getChanceToWinClash:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_otherGang: unknown): number => {
|
(_otherGang: unknown): number => {
|
||||||
const otherGang = ctx.helper.string("otherGang", _otherGang);
|
const otherGang = helpers.string(ctx, "otherGang", _otherGang);
|
||||||
checkGangApiAccess(ctx);
|
checkGangApiAccess(ctx);
|
||||||
const gang = player.gang;
|
const gang = player.gang;
|
||||||
if (gang === null) throw new Error("Should not be called without Gang");
|
if (gang === null) throw new Error("Should not be called without Gang");
|
||||||
if (AllGangs[otherGang] == null) {
|
if (AllGangs[otherGang] == null) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid gang: ${otherGang}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid gang: ${otherGang}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const playerPower = AllGangs[gang.facName].power;
|
const playerPower = AllGangs[gang.facName].power;
|
||||||
|
@ -4,15 +4,17 @@ import { hasAugmentationPrereqs } from "../Faction/FactionHelpers";
|
|||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation";
|
import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation";
|
||||||
import { getGraftingAvailableAugs, calculateGraftingTimeWithBonus } from "../PersonObjects/Grafting/GraftingHelpers";
|
import { getGraftingAvailableAugs, calculateGraftingTimeWithBonus } from "../PersonObjects/Grafting/GraftingHelpers";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
import { Grafting as IGrafting } from "../ScriptEditor/NetscriptDefinitions";
|
import { Grafting as IGrafting } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { Router } from "../ui/GameRoot";
|
import { Router } from "../ui/GameRoot";
|
||||||
import { GraftingWork } from "../Work/GraftingWork";
|
import { GraftingWork } from "../Work/GraftingWork";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
export function NetscriptGrafting(): InternalAPI<IGrafting> {
|
||||||
const checkGraftingAPIAccess = (ctx: NetscriptContext): void => {
|
const checkGraftingAPIAccess = (ctx: NetscriptContext): void => {
|
||||||
if (!player.canAccessGrafting()) {
|
if (!player.canAccessGrafting()) {
|
||||||
throw ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
"You do not currently have access to the Grafting API. This is either because you are not in BitNode 10 or because you do not have Source-File 10",
|
"You do not currently have access to the Grafting API. This is either because you are not in BitNode 10 or because you do not have Source-File 10",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -22,10 +24,10 @@ export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
|||||||
getAugmentationGraftPrice:
|
getAugmentationGraftPrice:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_augName: unknown): number => {
|
(_augName: unknown): number => {
|
||||||
const augName = ctx.helper.string("augName", _augName);
|
const augName = helpers.string(ctx, "augName", _augName);
|
||||||
checkGraftingAPIAccess(ctx);
|
checkGraftingAPIAccess(ctx);
|
||||||
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid aug: ${augName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||||
}
|
}
|
||||||
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||||
return graftableAug.cost;
|
return graftableAug.cost;
|
||||||
@ -34,10 +36,10 @@ export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
|||||||
getAugmentationGraftTime:
|
getAugmentationGraftTime:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_augName: string): number => {
|
(_augName: string): number => {
|
||||||
const augName = ctx.helper.string("augName", _augName);
|
const augName = helpers.string(ctx, "augName", _augName);
|
||||||
checkGraftingAPIAccess(ctx);
|
checkGraftingAPIAccess(ctx);
|
||||||
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid aug: ${augName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||||
}
|
}
|
||||||
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||||
return calculateGraftingTimeWithBonus(player, graftableAug);
|
return calculateGraftingTimeWithBonus(player, graftableAug);
|
||||||
@ -52,14 +54,14 @@ export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
|||||||
graftAugmentation:
|
graftAugmentation:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_augName: string, _focus: unknown = true): boolean => {
|
(_augName: string, _focus: unknown = true): boolean => {
|
||||||
const augName = ctx.helper.string("augName", _augName);
|
const augName = helpers.string(ctx, "augName", _augName);
|
||||||
const focus = ctx.helper.boolean(_focus);
|
const focus = !!_focus;
|
||||||
checkGraftingAPIAccess(ctx);
|
checkGraftingAPIAccess(ctx);
|
||||||
if (player.city !== CityName.NewTokyo) {
|
if (player.city !== CityName.NewTokyo) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must be in New Tokyo to begin grafting an Augmentation.");
|
throw helpers.makeRuntimeErrorMsg(ctx, "You must be in New Tokyo to begin grafting an Augmentation.");
|
||||||
}
|
}
|
||||||
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
if (!getGraftingAvailableAugs(player).includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||||
ctx.log(() => `Invalid aug: ${augName}`);
|
helpers.log(ctx, () => `Invalid aug: ${augName}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +69,12 @@ export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
|||||||
|
|
||||||
const craftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
const craftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||||
if (player.money < craftableAug.cost) {
|
if (player.money < craftableAug.cost) {
|
||||||
ctx.log(() => `You don't have enough money to craft ${augName}`);
|
helpers.log(ctx, () => `You don't have enough money to craft ${augName}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasAugmentationPrereqs(craftableAug.augmentation)) {
|
if (!hasAugmentationPrereqs(craftableAug.augmentation)) {
|
||||||
ctx.log(() => `You don't have the pre-requisites for ${augName}`);
|
helpers.log(ctx, () => `You don't have the pre-requisites for ${augName}`);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +94,7 @@ export function NetscriptGrafting(player: IPlayer): InternalAPI<IGrafting> {
|
|||||||
Router.toTerminal();
|
Router.toTerminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.log(() => `Began grafting Augmentation ${augName}.`);
|
helpers.log(ctx, () => `Began grafting Augmentation ${augName}.`);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
|
||||||
import { HacknetServerConstants } from "../Hacknet/data/Constants";
|
import { HacknetServerConstants } from "../Hacknet/data/Constants";
|
||||||
import {
|
import {
|
||||||
getCostOfNextHacknetNode,
|
getCostOfNextHacknetNode,
|
||||||
@ -21,12 +20,13 @@ import { GetServer } from "../Server/AllServers";
|
|||||||
|
|
||||||
import { Hacknet as IHacknet, NodeStats } from "../ScriptEditor/NetscriptDefinitions";
|
import { Hacknet as IHacknet, NodeStats } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): InternalAPI<IHacknet> {
|
export function NetscriptHacknet(): InternalAPI<IHacknet> {
|
||||||
// Utility function to get Hacknet Node object
|
// Utility function to get Hacknet Node object
|
||||||
const getHacknetNode = function (ctx: NetscriptContext, i: number): HacknetNode | HacknetServer {
|
const getHacknetNode = function (ctx: NetscriptContext, i: number): HacknetNode | HacknetServer {
|
||||||
if (i < 0 || i >= player.hacknetNodes.length) {
|
if (i < 0 || i >= player.hacknetNodes.length) {
|
||||||
throw ctx.makeRuntimeErrorMsg("Index specified for Hacknet Node is out-of-bounds: " + i);
|
throw helpers.makeRuntimeErrorMsg(ctx, "Index specified for Hacknet Node is out-of-bounds: " + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasHacknetServers(player)) {
|
if (hasHacknetServers(player)) {
|
||||||
@ -35,7 +35,8 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
const hserver = GetServer(hi);
|
const hserver = GetServer(hi);
|
||||||
if (!(hserver instanceof HacknetServer)) throw new Error("hacknet server was not actually hacknet server");
|
if (!(hserver instanceof HacknetServer)) throw new Error("hacknet server was not actually hacknet server");
|
||||||
if (hserver == null) {
|
if (hserver == null) {
|
||||||
throw ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
`Could not get Hacknet Server for index ${i}. This is probably a bug, please report to game dev`,
|
`Could not get Hacknet Server for index ${i}. This is probably a bug, please report to game dev`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
getNodeStats:
|
getNodeStats:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown): NodeStats => {
|
(_i: unknown): NodeStats => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
const hasUpgraded = hasHacknetServers(player);
|
const hasUpgraded = hasHacknetServers(player);
|
||||||
const res: NodeStats = {
|
const res: NodeStats = {
|
||||||
@ -95,38 +96,38 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
upgradeLevel:
|
upgradeLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): boolean => {
|
(_i: unknown, _n: unknown = 1): boolean => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
return purchaseLevelUpgrade(player, node, n);
|
return purchaseLevelUpgrade(player, node, n);
|
||||||
},
|
},
|
||||||
upgradeRam:
|
upgradeRam:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): boolean => {
|
(_i: unknown, _n: unknown = 1): boolean => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
return purchaseRamUpgrade(player, node, n);
|
return purchaseRamUpgrade(player, node, n);
|
||||||
},
|
},
|
||||||
upgradeCore:
|
upgradeCore:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): boolean => {
|
(_i: unknown, _n: unknown = 1): boolean => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
return purchaseCoreUpgrade(player, node, n);
|
return purchaseCoreUpgrade(player, node, n);
|
||||||
},
|
},
|
||||||
upgradeCache:
|
upgradeCache:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): boolean => {
|
(_i: unknown, _n: unknown = 1): boolean => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
if (!(node instanceof HacknetServer)) {
|
if (!(node instanceof HacknetServer)) {
|
||||||
workerScript.log("hacknet.upgradeCache", () => "Can only be called on hacknet servers");
|
helpers.log(ctx, () => "Can only be called on hacknet servers");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const res = purchaseCacheUpgrade(player, node, n);
|
const res = purchaseCacheUpgrade(player, node, n);
|
||||||
@ -138,38 +139,38 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
getLevelUpgradeCost:
|
getLevelUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): number => {
|
(_i: unknown, _n: unknown = 1): number => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
return node.calculateLevelUpgradeCost(n, player.mults.hacknet_node_level_cost);
|
return node.calculateLevelUpgradeCost(n, player.mults.hacknet_node_level_cost);
|
||||||
},
|
},
|
||||||
getRamUpgradeCost:
|
getRamUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): number => {
|
(_i: unknown, _n: unknown = 1): number => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
return node.calculateRamUpgradeCost(n, player.mults.hacknet_node_ram_cost);
|
return node.calculateRamUpgradeCost(n, player.mults.hacknet_node_ram_cost);
|
||||||
},
|
},
|
||||||
getCoreUpgradeCost:
|
getCoreUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): number => {
|
(_i: unknown, _n: unknown = 1): number => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
return node.calculateCoreUpgradeCost(n, player.mults.hacknet_node_core_cost);
|
return node.calculateCoreUpgradeCost(n, player.mults.hacknet_node_core_cost);
|
||||||
},
|
},
|
||||||
getCacheUpgradeCost:
|
getCacheUpgradeCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_i: unknown, _n: unknown = 1): number => {
|
(_i: unknown, _n: unknown = 1): number => {
|
||||||
const i = ctx.helper.number("i", _i);
|
const i = helpers.number(ctx, "i", _i);
|
||||||
const n = ctx.helper.number("n", _n);
|
const n = helpers.number(ctx, "n", _n);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
const node = getHacknetNode(ctx, i);
|
const node = getHacknetNode(ctx, i);
|
||||||
if (!(node instanceof HacknetServer)) {
|
if (!(node instanceof HacknetServer)) {
|
||||||
workerScript.log("hacknet.getCacheUpgradeCost", () => "Can only be called on hacknet servers");
|
helpers.log(ctx, () => "Can only be called on hacknet servers");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return node.calculateCacheUpgradeCost(n);
|
return node.calculateCacheUpgradeCost(n);
|
||||||
@ -189,8 +190,8 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
hashCost:
|
hashCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgName: unknown, _count: unknown = 1): number => {
|
(_upgName: unknown, _count: unknown = 1): number => {
|
||||||
const upgName = ctx.helper.string("upgName", _upgName);
|
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||||
const count = ctx.helper.number("count", _count);
|
const count = helpers.number(ctx, "count", _count);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
@ -200,9 +201,9 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
spendHashes:
|
spendHashes:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgName: unknown, _upgTarget: unknown = "", _count: unknown = 1): boolean => {
|
(_upgName: unknown, _upgTarget: unknown = "", _count: unknown = 1): boolean => {
|
||||||
const upgName = ctx.helper.string("upgName", _upgName);
|
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||||
const upgTarget = ctx.helper.string("upgTarget", _upgTarget);
|
const upgTarget = helpers.string(ctx, "upgTarget", _upgTarget);
|
||||||
const count = ctx.helper.number("count", _count);
|
const count = helpers.number(ctx, "count", _count);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -217,10 +218,10 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
|
|||||||
getHashUpgradeLevel:
|
getHashUpgradeLevel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_upgName: unknown): number => {
|
(_upgName: unknown): number => {
|
||||||
const upgName = ctx.helper.string("upgName", _upgName);
|
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||||
const level = player.hashManager.upgrades[upgName];
|
const level = player.hashManager.upgrades[upgName];
|
||||||
if (level === undefined) {
|
if (level === undefined) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid Hash Upgrade: ${upgName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid Hash Upgrade: ${upgName}`);
|
||||||
}
|
}
|
||||||
return level;
|
return level;
|
||||||
},
|
},
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
import { CityName } from "../Locations/data/CityNames";
|
|
||||||
import { NetscriptContext } from "../Netscript/APIWrapper";
|
|
||||||
import { IPort } from "../NetscriptPort";
|
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { Server } from "../Server/Server";
|
|
||||||
import { BaseServer } from "../Server/BaseServer";
|
|
||||||
import { FormulaGang } from "../Gang/formulas/formulas";
|
|
||||||
import { GangMember } from "../Gang/GangMember";
|
|
||||||
import { GangMemberTask } from "../Gang/GangMemberTask";
|
|
||||||
import { BasicHGWOptions } from "../ScriptEditor/NetscriptDefinitions";
|
|
||||||
import { ScriptArg } from "../Netscript/ScriptArg";
|
|
||||||
|
|
||||||
export type ScriptIdentifier =
|
|
||||||
| number
|
|
||||||
| {
|
|
||||||
fn: string;
|
|
||||||
hostname: string;
|
|
||||||
args: ScriptArg[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export interface INetscriptHelper {
|
|
||||||
updateDynamicRam(functionName: string, ram: number): void;
|
|
||||||
makeRuntimeErrorMsg(functionName: string, message: string): string;
|
|
||||||
string(funcName: string, argName: string, v: unknown): string;
|
|
||||||
number(funcName: string, argName: string, v: unknown): number;
|
|
||||||
ustring(funcName: string, argName: string, v: unknown): string | undefined;
|
|
||||||
unumber(funcName: string, argName: string, v: unknown): number | undefined;
|
|
||||||
scriptArgs(funcName: string, args: unknown): ScriptArg[];
|
|
||||||
scriptIdentifier(funcName: string, fn: unknown, hostname: unknown, args: unknown): ScriptIdentifier;
|
|
||||||
city(funcName: string, argName: string, v: unknown): CityName;
|
|
||||||
boolean(v: unknown): boolean;
|
|
||||||
getServer(ip: string, ctx: NetscriptContext): BaseServer;
|
|
||||||
checkSingularityAccess(func: string): void;
|
|
||||||
hack(ctx: NetscriptContext, hostname: string, manual: boolean, extra?: BasicHGWOptions): Promise<number>;
|
|
||||||
getValidPort(funcName: string, port: number): IPort;
|
|
||||||
player(funcName: string, p: unknown): IPlayer;
|
|
||||||
server(funcName: string, s: unknown): Server;
|
|
||||||
gang(funcName: string, g: unknown): FormulaGang;
|
|
||||||
gangMember(funcName: string, m: unknown): GangMember;
|
|
||||||
gangTask(funcName: string, m: unknown): GangMemberTask;
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Infiltration as IInfiltration,
|
Infiltration as IInfiltration,
|
||||||
@ -18,8 +18,9 @@ import { Factions } from "../Faction/Factions";
|
|||||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||||
import { LocationName } from "../Locations/data/LocationNames";
|
import { LocationName } from "../Locations/data/LocationNames";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptInfiltration(player: IPlayer): InternalAPI<IInfiltration> {
|
export function NetscriptInfiltration(): InternalAPI<IInfiltration> {
|
||||||
const getLocationsWithInfiltrations = Object.values(Locations).filter(
|
const getLocationsWithInfiltrations = Object.values(Locations).filter(
|
||||||
(location: Location) => location.infiltrationData,
|
(location: Location) => location.infiltrationData,
|
||||||
);
|
);
|
||||||
@ -27,9 +28,9 @@ export function NetscriptInfiltration(player: IPlayer): InternalAPI<IInfiltratio
|
|||||||
const calculateInfiltrationData = (ctx: NetscriptContext, locationName: string): InfiltrationLocation => {
|
const calculateInfiltrationData = (ctx: NetscriptContext, locationName: string): InfiltrationLocation => {
|
||||||
if (!checkEnum(LocationName, locationName)) throw new Error(`Location '${locationName}' does not exists.`);
|
if (!checkEnum(LocationName, locationName)) throw new Error(`Location '${locationName}' does not exists.`);
|
||||||
const location = Locations[locationName];
|
const location = Locations[locationName];
|
||||||
if (location === undefined) throw ctx.makeRuntimeErrorMsg(`Location '${location}' does not exists.`);
|
if (location === undefined) throw helpers.makeRuntimeErrorMsg(ctx, `Location '${location}' does not exists.`);
|
||||||
if (location.infiltrationData === undefined)
|
if (location.infiltrationData === undefined)
|
||||||
throw ctx.makeRuntimeErrorMsg(`Location '${location}' does not provide infiltrations.`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Location '${location}' does not provide infiltrations.`);
|
||||||
const startingSecurityLevel = location.infiltrationData.startingSecurityLevel;
|
const startingSecurityLevel = location.infiltrationData.startingSecurityLevel;
|
||||||
const difficulty = calculateDifficulty(player, startingSecurityLevel);
|
const difficulty = calculateDifficulty(player, startingSecurityLevel);
|
||||||
const reward = calculateReward(player, startingSecurityLevel);
|
const reward = calculateReward(player, startingSecurityLevel);
|
||||||
@ -54,7 +55,7 @@ export function NetscriptInfiltration(player: IPlayer): InternalAPI<IInfiltratio
|
|||||||
getInfiltration:
|
getInfiltration:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_location: unknown): InfiltrationLocation => {
|
(_location: unknown): InfiltrationLocation => {
|
||||||
const location = ctx.helper.string("location", _location);
|
const location = helpers.string(ctx, "location", _location);
|
||||||
return calculateInfiltrationData(ctx, location);
|
return calculateInfiltrationData(ctx, location);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { Player as player } from "../Player";
|
||||||
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
|
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
|
||||||
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
import { StaticAugmentations } from "../Augmentation/StaticAugmentations";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
@ -17,11 +17,13 @@ import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
|||||||
import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork";
|
import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork";
|
||||||
import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork";
|
import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionWork";
|
||||||
import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork";
|
import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext): void {
|
const checkSleeveAPIAccess = function (ctx: NetscriptContext): void {
|
||||||
if (player.bitNodeN !== 10 && !player.sourceFileLvl(10)) {
|
if (player.bitNodeN !== 10 && !player.sourceFileLvl(10)) {
|
||||||
throw ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
"You do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10",
|
"You do not currently have access to the Sleeve API. This is either because you are not in BitNode-10 or because you do not have Source-File 10",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -30,8 +32,8 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
const checkSleeveNumber = function (ctx: NetscriptContext, sleeveNumber: number): void {
|
const checkSleeveNumber = function (ctx: NetscriptContext, sleeveNumber: number): 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}`;
|
||||||
ctx.log(() => msg);
|
helpers.log(ctx, () => msg);
|
||||||
throw ctx.makeRuntimeErrorMsg(msg);
|
throw helpers.makeRuntimeErrorMsg(ctx, msg);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -58,7 +60,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
setToShockRecovery:
|
setToShockRecovery:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): boolean => {
|
(_sleeveNumber: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
return player.sleeves[sleeveNumber].shockRecovery(player);
|
return player.sleeves[sleeveNumber].shockRecovery(player);
|
||||||
@ -66,7 +68,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
setToSynchronize:
|
setToSynchronize:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): boolean => {
|
(_sleeveNumber: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
return player.sleeves[sleeveNumber].synchronize(player);
|
return player.sleeves[sleeveNumber].synchronize(player);
|
||||||
@ -74,8 +76,8 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
setToCommitCrime:
|
setToCommitCrime:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _crimeRoughName: unknown): boolean => {
|
(_sleeveNumber: unknown, _crimeRoughName: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const crimeRoughName = ctx.helper.string("crimeName", _crimeRoughName);
|
const crimeRoughName = helpers.string(ctx, "crimeName", _crimeRoughName);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
const crime = findCrime(crimeRoughName);
|
const crime = findCrime(crimeRoughName);
|
||||||
@ -87,9 +89,9 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
setToUniversityCourse:
|
setToUniversityCourse:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _universityName: unknown, _className: unknown): boolean => {
|
(_sleeveNumber: unknown, _universityName: unknown, _className: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const universityName = ctx.helper.string("universityName", _universityName);
|
const universityName = helpers.string(ctx, "universityName", _universityName);
|
||||||
const className = ctx.helper.string("className", _className);
|
const className = helpers.string(ctx, "className", _className);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
return player.sleeves[sleeveNumber].takeUniversityCourse(player, universityName, className);
|
return player.sleeves[sleeveNumber].takeUniversityCourse(player, universityName, className);
|
||||||
@ -97,21 +99,21 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
travel:
|
travel:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _cityName: unknown): boolean => {
|
(_sleeveNumber: unknown, _cityName: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const cityName = ctx.helper.string("cityName", _cityName);
|
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
if (checkEnum(CityName, cityName)) {
|
if (checkEnum(CityName, cityName)) {
|
||||||
return player.sleeves[sleeveNumber].travel(player, cityName);
|
return player.sleeves[sleeveNumber].travel(player, cityName);
|
||||||
} else {
|
} else {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid city name: '${cityName}'.`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city name: '${cityName}'.`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setToCompanyWork:
|
setToCompanyWork:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, acompanyName: unknown): boolean => {
|
(_sleeveNumber: unknown, acompanyName: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const companyName = ctx.helper.string("companyName", acompanyName);
|
const companyName = helpers.string(ctx, "companyName", acompanyName);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -122,7 +124,8 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
}
|
}
|
||||||
const other = player.sleeves[i];
|
const other = player.sleeves[i];
|
||||||
if (isSleeveCompanyWork(other.currentWork) && other.currentWork.companyName === companyName) {
|
if (isSleeveCompanyWork(other.currentWork) && other.currentWork.companyName === companyName) {
|
||||||
throw ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
`Sleeve ${sleeveNumber} cannot work for company ${companyName} because Sleeve ${i} is already working for them.`,
|
`Sleeve ${sleeveNumber} cannot work for company ${companyName} because Sleeve ${i} is already working for them.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -133,9 +136,9 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
setToFactionWork:
|
setToFactionWork:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _factionName: unknown, _workType: unknown): boolean | undefined => {
|
(_sleeveNumber: unknown, _factionName: unknown, _workType: unknown): boolean | undefined => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const factionName = ctx.helper.string("factionName", _factionName);
|
const factionName = helpers.string(ctx, "factionName", _factionName);
|
||||||
const workType = ctx.helper.string("workType", _workType);
|
const workType = helpers.string(ctx, "workType", _workType);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -146,14 +149,16 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
}
|
}
|
||||||
const other = player.sleeves[i];
|
const other = player.sleeves[i];
|
||||||
if (isSleeveFactionWork(other.currentWork) && other.currentWork.factionName === factionName) {
|
if (isSleeveFactionWork(other.currentWork) && other.currentWork.factionName === factionName) {
|
||||||
throw ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because Sleeve ${i} is already working for them.`,
|
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because Sleeve ${i} is already working for them.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.gang && player.gang.facName == factionName) {
|
if (player.gang && player.gang.facName == factionName) {
|
||||||
throw ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because you have started a gang with them.`,
|
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because you have started a gang with them.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -163,9 +168,9 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
setToGymWorkout:
|
setToGymWorkout:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _gymName: unknown, _stat: unknown): boolean => {
|
(_sleeveNumber: unknown, _gymName: unknown, _stat: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const gymName = ctx.helper.string("gymName", _gymName);
|
const gymName = helpers.string(ctx, "gymName", _gymName);
|
||||||
const stat = ctx.helper.string("stat", _stat);
|
const stat = helpers.string(ctx, "stat", _stat);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -174,7 +179,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
getSleeveStats:
|
getSleeveStats:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): SleeveSkills => {
|
(_sleeveNumber: unknown): SleeveSkills => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
return getSleeveStats(sleeveNumber);
|
return getSleeveStats(sleeveNumber);
|
||||||
@ -182,7 +187,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
getTask:
|
getTask:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): SleeveTask | null => {
|
(_sleeveNumber: unknown): SleeveTask | null => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -193,7 +198,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
getInformation:
|
getInformation:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): SleeveInformation => {
|
(_sleeveNumber: unknown): SleeveInformation => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -229,7 +234,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
getSleeveAugmentations:
|
getSleeveAugmentations:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): string[] => {
|
(_sleeveNumber: unknown): string[] => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -242,7 +247,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
getSleevePurchasableAugs:
|
getSleevePurchasableAugs:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown): AugmentPair[] => {
|
(_sleeveNumber: unknown): AugmentPair[] => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
@ -261,18 +266,18 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
purchaseSleeveAug:
|
purchaseSleeveAug:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _augName: unknown): boolean => {
|
(_sleeveNumber: unknown, _augName: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const augName = ctx.helper.string("augName", _augName);
|
const augName = helpers.string(ctx, "augName", _augName);
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
|
|
||||||
if (getSleeveStats(sleeveNumber).shock > 0) {
|
if (getSleeveStats(sleeveNumber).shock > 0) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const aug = StaticAugmentations[augName];
|
const aug = StaticAugmentations[augName];
|
||||||
if (!aug) {
|
if (!aug) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid aug: ${augName}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return player.sleeves[sleeveNumber].tryBuyAugmentation(player, aug);
|
return player.sleeves[sleeveNumber].tryBuyAugmentation(player, aug);
|
||||||
@ -281,7 +286,7 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_augName: unknown): number => {
|
(_augName: unknown): number => {
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
const augName = ctx.helper.string("augName", _augName);
|
const augName = helpers.string(ctx, "augName", _augName);
|
||||||
const aug: Augmentation = StaticAugmentations[augName];
|
const aug: Augmentation = StaticAugmentations[augName];
|
||||||
return aug.baseCost;
|
return aug.baseCost;
|
||||||
},
|
},
|
||||||
@ -289,20 +294,20 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_augName: unknown): number => {
|
(_augName: unknown): number => {
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
const augName = ctx.helper.string("augName", _augName);
|
const augName = helpers.string(ctx, "augName", _augName);
|
||||||
const aug: Augmentation = StaticAugmentations[augName];
|
const aug: Augmentation = StaticAugmentations[augName];
|
||||||
return aug.getCost(player).repCost;
|
return aug.getCost(player).repCost;
|
||||||
},
|
},
|
||||||
setToBladeburnerAction:
|
setToBladeburnerAction:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_sleeveNumber: unknown, _action: unknown, _contract?: unknown): boolean => {
|
(_sleeveNumber: unknown, _action: unknown, _contract?: unknown): boolean => {
|
||||||
const sleeveNumber = ctx.helper.number("sleeveNumber", _sleeveNumber);
|
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||||
const action = ctx.helper.string("action", _action);
|
const action = helpers.string(ctx, "action", _action);
|
||||||
let contract: string;
|
let contract: string;
|
||||||
if (typeof _contract === "undefined") {
|
if (typeof _contract === "undefined") {
|
||||||
contract = "------";
|
contract = "------";
|
||||||
} else {
|
} else {
|
||||||
contract = ctx.helper.string("contract", _contract);
|
contract = helpers.string(ctx, "contract", _contract);
|
||||||
}
|
}
|
||||||
checkSleeveAPIAccess(ctx);
|
checkSleeveAPIAccess(ctx);
|
||||||
checkSleeveNumber(ctx, sleeveNumber);
|
checkSleeveNumber(ctx, sleeveNumber);
|
||||||
@ -315,7 +320,8 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
|
|||||||
}
|
}
|
||||||
const other = player.sleeves[i];
|
const other = player.sleeves[i];
|
||||||
if (isSleeveBladeburnerWork(other.currentWork) && other.currentWork.actionName === contract) {
|
if (isSleeveBladeburnerWork(other.currentWork) && other.currentWork.actionName === contract) {
|
||||||
throw ctx.helper.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
`Sleeve ${sleeveNumber} cannot take on contracts because Sleeve ${i} is already performing that action.`,
|
`Sleeve ${sleeveNumber} cannot take on contracts because Sleeve ${i} is already performing that action.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,4 @@
|
|||||||
import { INetscriptHelper } from "./INetscriptHelper";
|
import { Player as player } from "../Player";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
|
||||||
import { netscriptDelay } from "../NetscriptEvaluator";
|
|
||||||
|
|
||||||
import { staneksGift } from "../CotMG/Helper";
|
import { staneksGift } from "../CotMG/Helper";
|
||||||
import { Fragments, FragmentById } from "../CotMG/Fragment";
|
import { Fragments, FragmentById } from "../CotMG/Fragment";
|
||||||
@ -18,111 +15,109 @@ import { applyAugmentation } from "../Augmentation/AugmentationHelpers";
|
|||||||
import { FactionNames } from "../Faction/data/FactionNames";
|
import { FactionNames } from "../Faction/data/FactionNames";
|
||||||
import { joinFaction } from "../Faction/FactionHelpers";
|
import { joinFaction } from "../Faction/FactionHelpers";
|
||||||
import { Factions } from "../Faction/Factions";
|
import { Factions } from "../Faction/Factions";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptStanek(
|
export function NetscriptStanek(): InternalAPI<IStanek> {
|
||||||
player: IPlayer,
|
function checkStanekAPIAccess(ctx: NetscriptContext): void {
|
||||||
workerScript: WorkerScript,
|
|
||||||
helper: INetscriptHelper,
|
|
||||||
): InternalAPI<IStanek> {
|
|
||||||
function checkStanekAPIAccess(func: string): void {
|
|
||||||
if (!player.hasAugmentation(AugmentationNames.StaneksGift1, true)) {
|
if (!player.hasAugmentation(AugmentationNames.StaneksGift1, true)) {
|
||||||
throw helper.makeRuntimeErrorMsg(func, "Stanek's Gift is not installed");
|
throw helpers.makeRuntimeErrorMsg(ctx, "Stanek's Gift is not installed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
giftWidth: () =>
|
giftWidth: (ctx: NetscriptContext) =>
|
||||||
function (): number {
|
function (): number {
|
||||||
checkStanekAPIAccess("giftWidth");
|
checkStanekAPIAccess(ctx);
|
||||||
return staneksGift.width();
|
return staneksGift.width();
|
||||||
},
|
},
|
||||||
giftHeight: () =>
|
giftHeight: (ctx: NetscriptContext) =>
|
||||||
function (): number {
|
function (): number {
|
||||||
checkStanekAPIAccess("giftHeight");
|
checkStanekAPIAccess(ctx);
|
||||||
return staneksGift.height();
|
return staneksGift.height();
|
||||||
},
|
},
|
||||||
chargeFragment: (_ctx: NetscriptContext) =>
|
chargeFragment: (ctx: NetscriptContext) =>
|
||||||
function (_rootX: unknown, _rootY: unknown): Promise<void> {
|
function (_rootX: unknown, _rootY: unknown): Promise<void> {
|
||||||
//Get the fragment object using the given coordinates
|
//Get the fragment object using the given coordinates
|
||||||
const rootX = _ctx.helper.number("rootX", _rootX);
|
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||||
const rootY = _ctx.helper.number("rootY", _rootY);
|
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||||
checkStanekAPIAccess("chargeFragment");
|
checkStanekAPIAccess(ctx);
|
||||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||||
//Check whether the selected fragment can ge charged
|
//Check whether the selected fragment can ge charged
|
||||||
if (!fragment) throw _ctx.makeRuntimeErrorMsg(`No fragment with root (${rootX}, ${rootY}).`);
|
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `No fragment with root (${rootX}, ${rootY}).`);
|
||||||
if (fragment.fragment().type == FragmentType.Booster) {
|
if (fragment.fragment().type == FragmentType.Booster) {
|
||||||
throw _ctx.makeRuntimeErrorMsg(
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
`The fragment with root (${rootX}, ${rootY}) is a Booster Fragment and thus cannot be charged.`,
|
`The fragment with root (${rootX}, ${rootY}) is a Booster Fragment and thus cannot be charged.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
//Charge the fragment
|
//Charge the fragment
|
||||||
const time = staneksGift.inBonus() ? 200 : 1000;
|
const time = staneksGift.inBonus() ? 200 : 1000;
|
||||||
return netscriptDelay(time, workerScript).then(function () {
|
return helpers.netscriptDelay(ctx, time).then(function () {
|
||||||
staneksGift.charge(player, fragment, workerScript.scriptRef.threads);
|
staneksGift.charge(player, fragment, ctx.workerScript.scriptRef.threads);
|
||||||
_ctx.log(() => `Charged fragment with ${_ctx.workerScript.scriptRef.threads} threads.`);
|
helpers.log(ctx, () => `Charged fragment with ${ctx.workerScript.scriptRef.threads} threads.`);
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
fragmentDefinitions: (_ctx: NetscriptContext) =>
|
fragmentDefinitions: (ctx: NetscriptContext) =>
|
||||||
function (): IFragment[] {
|
function (): IFragment[] {
|
||||||
checkStanekAPIAccess("fragmentDefinitions");
|
checkStanekAPIAccess(ctx);
|
||||||
_ctx.log(() => `Returned ${Fragments.length} fragments`);
|
helpers.log(ctx, () => `Returned ${Fragments.length} fragments`);
|
||||||
return Fragments.map((f) => f.copy());
|
return Fragments.map((f) => f.copy());
|
||||||
},
|
},
|
||||||
activeFragments: (_ctx: NetscriptContext) =>
|
activeFragments: (ctx: NetscriptContext) =>
|
||||||
function (): IActiveFragment[] {
|
function (): IActiveFragment[] {
|
||||||
checkStanekAPIAccess("activeFragments");
|
checkStanekAPIAccess(ctx);
|
||||||
_ctx.log(() => `Returned ${staneksGift.fragments.length} fragments`);
|
helpers.log(ctx, () => `Returned ${staneksGift.fragments.length} fragments`);
|
||||||
return staneksGift.fragments.map((af) => {
|
return staneksGift.fragments.map((af) => {
|
||||||
return { ...af.copy(), ...af.fragment().copy() };
|
return { ...af.copy(), ...af.fragment().copy() };
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
clearGift: (_ctx: NetscriptContext) =>
|
clearGift: (ctx: NetscriptContext) =>
|
||||||
function (): void {
|
function (): void {
|
||||||
checkStanekAPIAccess("clearGift");
|
checkStanekAPIAccess(ctx);
|
||||||
_ctx.log(() => `Cleared Stanek's Gift.`);
|
helpers.log(ctx, () => `Cleared Stanek's Gift.`);
|
||||||
staneksGift.clear();
|
staneksGift.clear();
|
||||||
},
|
},
|
||||||
canPlaceFragment: (_ctx: NetscriptContext) =>
|
canPlaceFragment: (ctx: NetscriptContext) =>
|
||||||
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
||||||
const rootX = _ctx.helper.number("rootX", _rootX);
|
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||||
const rootY = _ctx.helper.number("rootY", _rootY);
|
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||||
const rotation = _ctx.helper.number("rotation", _rotation);
|
const rotation = helpers.number(ctx, "rotation", _rotation);
|
||||||
const fragmentId = _ctx.helper.number("fragmentId", _fragmentId);
|
const fragmentId = helpers.number(ctx, "fragmentId", _fragmentId);
|
||||||
checkStanekAPIAccess("canPlaceFragment");
|
checkStanekAPIAccess(ctx);
|
||||||
const fragment = FragmentById(fragmentId);
|
const fragment = FragmentById(fragmentId);
|
||||||
if (!fragment) throw _ctx.makeRuntimeErrorMsg(`Invalid fragment id: ${fragmentId}`);
|
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid fragment id: ${fragmentId}`);
|
||||||
const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
|
const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
|
||||||
return can;
|
return can;
|
||||||
},
|
},
|
||||||
placeFragment: (_ctx: NetscriptContext) =>
|
placeFragment: (ctx: NetscriptContext) =>
|
||||||
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
||||||
const rootX = _ctx.helper.number("rootX", _rootX);
|
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||||
const rootY = _ctx.helper.number("rootY", _rootY);
|
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||||
const rotation = _ctx.helper.number("rotation", _rotation);
|
const rotation = helpers.number(ctx, "rotation", _rotation);
|
||||||
const fragmentId = _ctx.helper.number("fragmentId", _fragmentId);
|
const fragmentId = helpers.number(ctx, "fragmentId", _fragmentId);
|
||||||
checkStanekAPIAccess("placeFragment");
|
checkStanekAPIAccess(ctx);
|
||||||
const fragment = FragmentById(fragmentId);
|
const fragment = FragmentById(fragmentId);
|
||||||
if (!fragment) throw _ctx.makeRuntimeErrorMsg(`Invalid fragment id: ${fragmentId}`);
|
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid fragment id: ${fragmentId}`);
|
||||||
return staneksGift.place(rootX, rootY, rotation, fragment);
|
return staneksGift.place(rootX, rootY, rotation, fragment);
|
||||||
},
|
},
|
||||||
getFragment: (_ctx: NetscriptContext) =>
|
getFragment: (ctx: NetscriptContext) =>
|
||||||
function (_rootX: unknown, _rootY: unknown): IActiveFragment | undefined {
|
function (_rootX: unknown, _rootY: unknown): IActiveFragment | undefined {
|
||||||
const rootX = _ctx.helper.number("rootX", _rootX);
|
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||||
const rootY = _ctx.helper.number("rootY", _rootY);
|
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||||
checkStanekAPIAccess("getFragment");
|
checkStanekAPIAccess(ctx);
|
||||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||||
if (fragment !== undefined) return fragment.copy();
|
if (fragment !== undefined) return fragment.copy();
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
removeFragment: (_ctx: NetscriptContext) =>
|
removeFragment: (ctx: NetscriptContext) =>
|
||||||
function (_rootX: unknown, _rootY: unknown): boolean {
|
function (_rootX: unknown, _rootY: unknown): boolean {
|
||||||
const rootX = _ctx.helper.number("rootX", _rootX);
|
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||||
const rootY = _ctx.helper.number("rootY", _rootY);
|
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||||
checkStanekAPIAccess("removeFragment");
|
checkStanekAPIAccess(ctx);
|
||||||
return staneksGift.delete(rootX, rootY);
|
return staneksGift.delete(rootX, rootY);
|
||||||
},
|
},
|
||||||
acceptGift: (_ctx: NetscriptContext) =>
|
acceptGift: (ctx: NetscriptContext) =>
|
||||||
function (): boolean {
|
function (): boolean {
|
||||||
//Check if the player is eligible to join the church
|
//Check if the player is eligible to join the church
|
||||||
if (
|
if (
|
||||||
@ -138,7 +133,8 @@ export function NetscriptStanek(
|
|||||||
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
|
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
|
||||||
) {
|
) {
|
||||||
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
|
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
|
||||||
_ctx.log(
|
helpers.log(
|
||||||
|
ctx,
|
||||||
() => `'${FactionNames.ChurchOfTheMachineGod}' joined and '${AugmentationNames.StaneksGift1}' installed.`,
|
() => `'${FactionNames.ChurchOfTheMachineGod}' joined and '${AugmentationNames.StaneksGift1}' installed.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { Player as player } from "../Player";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
||||||
import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling";
|
import { buyStock, sellStock, shortStock, sellShort } from "../StockMarket/BuyingAndSelling";
|
||||||
import { StockMarket, SymbolToStockMap, placeOrder, cancelOrder, initStockMarketFn } from "../StockMarket/StockMarket";
|
import { StockMarket, SymbolToStockMap, placeOrder, cancelOrder, initStockMarketFn } from "../StockMarket/StockMarket";
|
||||||
import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/StockMarketHelpers";
|
import { getBuyTransactionCost, getSellTransactionGain } from "../StockMarket/StockMarketHelpers";
|
||||||
@ -14,25 +13,26 @@ import {
|
|||||||
} from "../StockMarket/StockMarketCosts";
|
} from "../StockMarket/StockMarketCosts";
|
||||||
import { Stock } from "../StockMarket/Stock";
|
import { Stock } from "../StockMarket/Stock";
|
||||||
import { StockOrder, TIX } from "../ScriptEditor/NetscriptDefinitions";
|
import { StockOrder, TIX } from "../ScriptEditor/NetscriptDefinitions";
|
||||||
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript): InternalAPI<TIX> {
|
export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||||
/**
|
/**
|
||||||
* 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 (ctx: NetscriptContext): void {
|
const checkTixApiAccess = function (ctx: NetscriptContext): void {
|
||||||
if (!player.hasWseAccount) {
|
if (!player.hasWseAccount) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`You don't have WSE Access! Cannot use ${ctx.function}()`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You don't have WSE Access! Cannot use ${ctx.function}()`);
|
||||||
}
|
}
|
||||||
if (!player.hasTixApiAccess) {
|
if (!player.hasTixApiAccess) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`You don't have TIX API Access! Cannot use ${ctx.function}()`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `You don't have TIX API Access! Cannot use ${ctx.function}()`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStockFromSymbol = function (ctx: NetscriptContext, symbol: string): Stock {
|
const getStockFromSymbol = function (ctx: NetscriptContext, symbol: string): Stock {
|
||||||
const stock = SymbolToStockMap[symbol];
|
const stock = SymbolToStockMap[symbol];
|
||||||
if (stock == null) {
|
if (stock == null) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid stock symbol: '${symbol}'`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid stock symbol: '${symbol}'`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stock;
|
return stock;
|
||||||
@ -58,7 +58,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getPrice:
|
getPrice:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): number => {
|
(_symbol: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
|
|
||||||
@ -67,7 +67,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getAskPrice:
|
getAskPrice:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): number => {
|
(_symbol: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getBidPrice:
|
getBidPrice:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): number => {
|
(_symbol: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
|
|
||||||
@ -85,18 +85,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getPosition:
|
getPosition:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): [number, number, number, number] => {
|
(_symbol: unknown): [number, number, number, number] => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = SymbolToStockMap[symbol];
|
const stock = SymbolToStockMap[symbol];
|
||||||
if (stock == null) {
|
if (stock == null) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid stock symbol: ${symbol}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid stock symbol: ${symbol}`);
|
||||||
}
|
}
|
||||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||||
},
|
},
|
||||||
getMaxShares:
|
getMaxShares:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): number => {
|
(_symbol: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
|
|
||||||
@ -105,9 +105,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getPurchaseCost:
|
getPurchaseCost:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
|
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
let shares = ctx.helper.number("shares", _shares);
|
let shares = helpers.number(ctx, "shares", _shares);
|
||||||
const posType = ctx.helper.string("posType", _posType);
|
const posType = helpers.string(ctx, "posType", _posType);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
shares = Math.round(shares);
|
shares = Math.round(shares);
|
||||||
@ -132,9 +132,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getSaleGain:
|
getSaleGain:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
|
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
let shares = ctx.helper.number("shares", _shares);
|
let shares = helpers.number(ctx, "shares", _shares);
|
||||||
const posType = ctx.helper.string("posType", _posType);
|
const posType = helpers.string(ctx, "posType", _posType);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
shares = Math.round(shares);
|
shares = Math.round(shares);
|
||||||
@ -159,68 +159,77 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
buyStock:
|
buyStock:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown): number => {
|
(_symbol: unknown, _shares: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
const shares = ctx.helper.number("shares", _shares);
|
const shares = helpers.number(ctx, "shares", _shares);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
const res = buyStock(stock, shares, workerScript, {});
|
const res = buyStock(stock, shares, ctx.workerScript, {});
|
||||||
return res ? stock.getAskPrice() : 0;
|
return res ? stock.getAskPrice() : 0;
|
||||||
},
|
},
|
||||||
sellStock:
|
sellStock:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown): number => {
|
(_symbol: unknown, _shares: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
const shares = ctx.helper.number("shares", _shares);
|
const shares = helpers.number(ctx, "shares", _shares);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
const res = sellStock(stock, shares, workerScript, {});
|
const res = sellStock(stock, shares, ctx.workerScript, {});
|
||||||
|
|
||||||
return res ? stock.getBidPrice() : 0;
|
return res ? stock.getBidPrice() : 0;
|
||||||
},
|
},
|
||||||
buyShort:
|
buyShort:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown): number => {
|
(_symbol: unknown, _shares: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
const shares = ctx.helper.number("shares", _shares);
|
const shares = helpers.number(ctx, "shares", _shares);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
if (player.sourceFileLvl(8) <= 1) {
|
if (player.sourceFileLvl(8) <= 1) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must either be in BitNode-8 or you must have Source-File 8 Level 2.");
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
const res = shortStock(stock, shares, workerScript, {});
|
const res = shortStock(stock, shares, ctx.workerScript, {});
|
||||||
|
|
||||||
return res ? stock.getBidPrice() : 0;
|
return res ? stock.getBidPrice() : 0;
|
||||||
},
|
},
|
||||||
sellShort:
|
sellShort:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown): number => {
|
(_symbol: unknown, _shares: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
const shares = ctx.helper.number("shares", _shares);
|
const shares = helpers.number(ctx, "shares", _shares);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
if (player.sourceFileLvl(8) <= 1) {
|
if (player.sourceFileLvl(8) <= 1) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must either be in BitNode-8 or you must have Source-File 8 Level 2.");
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
const res = sellShort(stock, shares, workerScript, {});
|
const res = sellShort(stock, shares, ctx.workerScript, {});
|
||||||
|
|
||||||
return res ? stock.getAskPrice() : 0;
|
return res ? stock.getAskPrice() : 0;
|
||||||
},
|
},
|
||||||
placeOrder:
|
placeOrder:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
|
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
const shares = ctx.helper.number("shares", _shares);
|
const shares = helpers.number(ctx, "shares", _shares);
|
||||||
const price = ctx.helper.number("price", _price);
|
const price = helpers.number(ctx, "price", _price);
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const pos = ctx.helper.string("pos", _pos);
|
const pos = helpers.string(ctx, "pos", _pos);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
if (player.sourceFileLvl(8) <= 2) {
|
if (player.sourceFileLvl(8) <= 2) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must either be in BitNode-8 or you must have Source-File 8 Level 3.");
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
@ -237,7 +246,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||||
orderType = OrderTypes.StopSell;
|
orderType = OrderTypes.StopSell;
|
||||||
} else {
|
} else {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid order type: ${type}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid order type: ${type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lpos = pos.toLowerCase();
|
const lpos = pos.toLowerCase();
|
||||||
@ -246,28 +255,34 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
} else if (lpos.includes("s")) {
|
} else if (lpos.includes("s")) {
|
||||||
orderPos = PositionTypes.Short;
|
orderPos = PositionTypes.Short;
|
||||||
} else {
|
} else {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid position type: ${pos}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position type: ${pos}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
return placeOrder(stock, shares, price, orderType, orderPos, ctx.workerScript);
|
||||||
},
|
},
|
||||||
cancelOrder:
|
cancelOrder:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
|
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
const shares = ctx.helper.number("shares", _shares);
|
const shares = helpers.number(ctx, "shares", _shares);
|
||||||
const price = ctx.helper.number("price", _price);
|
const price = helpers.number(ctx, "price", _price);
|
||||||
const type = ctx.helper.string("type", _type);
|
const type = helpers.string(ctx, "type", _type);
|
||||||
const pos = ctx.helper.string("pos", _pos);
|
const pos = helpers.string(ctx, "pos", _pos);
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
if (player.sourceFileLvl(8) <= 2) {
|
if (player.sourceFileLvl(8) <= 2) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must either be in BitNode-8 or you must have Source-File 8 Level 3.");
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
if (isNaN(shares) || isNaN(price)) {
|
if (isNaN(shares) || isNaN(price)) {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid shares or price. Must be numeric. shares=${shares}, price=${price}`);
|
throw helpers.makeRuntimeErrorMsg(
|
||||||
|
ctx,
|
||||||
|
`Invalid shares or price. Must be numeric. shares=${shares}, price=${price}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let orderType;
|
let orderType;
|
||||||
let orderPos;
|
let orderPos;
|
||||||
@ -281,7 +296,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||||
orderType = OrderTypes.StopSell;
|
orderType = OrderTypes.StopSell;
|
||||||
} else {
|
} else {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid order type: ${type}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid order type: ${type}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lpos = pos.toLowerCase();
|
const lpos = pos.toLowerCase();
|
||||||
@ -290,7 +305,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
} else if (lpos.includes("s")) {
|
} else if (lpos.includes("s")) {
|
||||||
orderPos = PositionTypes.Short;
|
orderPos = PositionTypes.Short;
|
||||||
} else {
|
} else {
|
||||||
throw ctx.makeRuntimeErrorMsg(`Invalid position type: ${pos}`);
|
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position type: ${pos}`);
|
||||||
}
|
}
|
||||||
const params = {
|
const params = {
|
||||||
stock: stock,
|
stock: stock,
|
||||||
@ -299,13 +314,13 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
type: orderType,
|
type: orderType,
|
||||||
pos: orderPos,
|
pos: orderPos,
|
||||||
};
|
};
|
||||||
return cancelOrder(params, workerScript);
|
return cancelOrder(params, ctx.workerScript);
|
||||||
},
|
},
|
||||||
getOrders: (ctx: NetscriptContext) => (): StockOrder => {
|
getOrders: (ctx: NetscriptContext) => (): StockOrder => {
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
if (player.sourceFileLvl(8) <= 2) {
|
if (player.sourceFileLvl(8) <= 2) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You must either be in BitNode-8 or have Source-File 8 Level 3.");
|
throw helpers.makeRuntimeErrorMsg(ctx, "You must either be in BitNode-8 or have Source-File 8 Level 3.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,9 +347,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getVolatility:
|
getVolatility:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): number => {
|
(_symbol: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
if (!player.has4SDataTixApi) {
|
if (!player.has4SDataTixApi) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You don't have 4S Market Data TIX API Access!");
|
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
|
|
||||||
@ -343,9 +358,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
getForecast:
|
getForecast:
|
||||||
(ctx: NetscriptContext) =>
|
(ctx: NetscriptContext) =>
|
||||||
(_symbol: unknown): number => {
|
(_symbol: unknown): number => {
|
||||||
const symbol = ctx.helper.string("symbol", _symbol);
|
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||||
if (!player.has4SDataTixApi) {
|
if (!player.has4SDataTixApi) {
|
||||||
throw ctx.makeRuntimeErrorMsg("You don't have 4S Market Data TIX API Access!");
|
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
|
||||||
}
|
}
|
||||||
const stock = getStockFromSymbol(ctx, symbol);
|
const stock = getStockFromSymbol(ctx, symbol);
|
||||||
|
|
||||||
@ -355,69 +370,69 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
},
|
},
|
||||||
purchase4SMarketData: (ctx: NetscriptContext) => (): boolean => {
|
purchase4SMarketData: (ctx: NetscriptContext) => (): boolean => {
|
||||||
if (player.has4SData) {
|
if (player.has4SData) {
|
||||||
ctx.log(() => "Already purchased 4S Market Data.");
|
helpers.log(ctx, () => "Already purchased 4S Market Data.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.money < getStockMarket4SDataCost()) {
|
if (player.money < getStockMarket4SDataCost()) {
|
||||||
ctx.log(() => "Not enough money to purchase 4S Market Data.");
|
helpers.log(ctx, () => "Not enough money to purchase 4S Market Data.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
player.has4SData = true;
|
player.has4SData = true;
|
||||||
player.loseMoney(getStockMarket4SDataCost(), "stock");
|
player.loseMoney(getStockMarket4SDataCost(), "stock");
|
||||||
ctx.log(() => "Purchased 4S Market Data");
|
helpers.log(ctx, () => "Purchased 4S Market Data");
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
purchase4SMarketDataTixApi: (ctx: NetscriptContext) => (): boolean => {
|
purchase4SMarketDataTixApi: (ctx: NetscriptContext) => (): boolean => {
|
||||||
checkTixApiAccess(ctx);
|
checkTixApiAccess(ctx);
|
||||||
|
|
||||||
if (player.has4SDataTixApi) {
|
if (player.has4SDataTixApi) {
|
||||||
ctx.log(() => "Already purchased 4S Market Data TIX API");
|
helpers.log(ctx, () => "Already purchased 4S Market Data TIX API");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.money < getStockMarket4STixApiCost()) {
|
if (player.money < getStockMarket4STixApiCost()) {
|
||||||
ctx.log(() => "Not enough money to purchase 4S Market Data TIX API");
|
helpers.log(ctx, () => "Not enough money to purchase 4S Market Data TIX API");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
player.has4SDataTixApi = true;
|
player.has4SDataTixApi = true;
|
||||||
player.loseMoney(getStockMarket4STixApiCost(), "stock");
|
player.loseMoney(getStockMarket4STixApiCost(), "stock");
|
||||||
ctx.log(() => "Purchased 4S Market Data TIX API");
|
helpers.log(ctx, () => "Purchased 4S Market Data TIX API");
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
purchaseWseAccount: (ctx: NetscriptContext) => (): boolean => {
|
purchaseWseAccount: (ctx: NetscriptContext) => (): boolean => {
|
||||||
if (player.hasWseAccount) {
|
if (player.hasWseAccount) {
|
||||||
ctx.log(() => "Already purchased WSE Account");
|
helpers.log(ctx, () => "Already purchased WSE Account");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.money < getStockMarketWseCost()) {
|
if (player.money < getStockMarketWseCost()) {
|
||||||
ctx.log(() => "Not enough money to purchase WSE Account Access");
|
helpers.log(ctx, () => "Not enough money to purchase WSE Account Access");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
player.hasWseAccount = true;
|
player.hasWseAccount = true;
|
||||||
initStockMarketFn();
|
initStockMarketFn();
|
||||||
player.loseMoney(getStockMarketWseCost(), "stock");
|
player.loseMoney(getStockMarketWseCost(), "stock");
|
||||||
ctx.log(() => "Purchased WSE Account Access");
|
helpers.log(ctx, () => "Purchased WSE Account Access");
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
purchaseTixApi: (ctx: NetscriptContext) => (): boolean => {
|
purchaseTixApi: (ctx: NetscriptContext) => (): boolean => {
|
||||||
if (player.hasTixApiAccess) {
|
if (player.hasTixApiAccess) {
|
||||||
ctx.log(() => "Already purchased TIX API");
|
helpers.log(ctx, () => "Already purchased TIX API");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.money < getStockMarketTixApiCost()) {
|
if (player.money < getStockMarketTixApiCost()) {
|
||||||
ctx.log(() => "Not enough money to purchase TIX API Access");
|
helpers.log(ctx, () => "Not enough money to purchase TIX API Access");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
player.hasTixApiAccess = true;
|
player.hasTixApiAccess = true;
|
||||||
player.loseMoney(getStockMarketTixApiCost(), "stock");
|
player.loseMoney(getStockMarketTixApiCost(), "stock");
|
||||||
ctx.log(() => "Purchased TIX API");
|
helpers.log(ctx, () => "Purchased TIX API");
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -10,8 +10,9 @@ import { defaultTheme } from "../Themes/Themes";
|
|||||||
import { defaultStyles } from "../Themes/Styles";
|
import { defaultStyles } from "../Themes/Styles";
|
||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
import { hash } from "../hash/hash";
|
import { hash } from "../hash/hash";
|
||||||
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||||
import { Terminal } from "../../src/Terminal";
|
import { Terminal } from "../../src/Terminal";
|
||||||
|
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||||
|
|
||||||
export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
||||||
return {
|
return {
|
||||||
@ -43,9 +44,9 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
|||||||
if (errors.length === 0) {
|
if (errors.length === 0) {
|
||||||
Object.assign(Settings.theme, currentTheme);
|
Object.assign(Settings.theme, currentTheme);
|
||||||
ThemeEvents.emit();
|
ThemeEvents.emit();
|
||||||
ctx.log(() => `Successfully set theme`);
|
helpers.log(ctx, () => `Successfully set theme`);
|
||||||
} else {
|
} else {
|
||||||
ctx.log(() => `Failed to set theme. Errors: ${errors.join(", ")}`);
|
helpers.log(ctx, () => `Failed to set theme. Errors: ${errors.join(", ")}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -66,22 +67,22 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
|||||||
if (errors.length === 0) {
|
if (errors.length === 0) {
|
||||||
Object.assign(Settings.styles, currentStyles);
|
Object.assign(Settings.styles, currentStyles);
|
||||||
ThemeEvents.emit();
|
ThemeEvents.emit();
|
||||||
ctx.log(() => `Successfully set styles`);
|
helpers.log(ctx, () => `Successfully set styles`);
|
||||||
} else {
|
} else {
|
||||||
ctx.log(() => `Failed to set styles. Errors: ${errors.join(", ")}`);
|
helpers.log(ctx, () => `Failed to set styles. Errors: ${errors.join(", ")}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
resetTheme: (ctx: NetscriptContext) => (): void => {
|
resetTheme: (ctx: NetscriptContext) => (): void => {
|
||||||
Settings.theme = { ...defaultTheme };
|
Settings.theme = { ...defaultTheme };
|
||||||
ThemeEvents.emit();
|
ThemeEvents.emit();
|
||||||
ctx.log(() => `Reinitialized theme to default`);
|
helpers.log(ctx, () => `Reinitialized theme to default`);
|
||||||
},
|
},
|
||||||
|
|
||||||
resetStyles: (ctx: NetscriptContext) => (): void => {
|
resetStyles: (ctx: NetscriptContext) => (): void => {
|
||||||
Settings.styles = { ...defaultStyles };
|
Settings.styles = { ...defaultStyles };
|
||||||
ThemeEvents.emit();
|
ThemeEvents.emit();
|
||||||
ctx.log(() => `Reinitialized styles to default`);
|
helpers.log(ctx, () => `Reinitialized styles to default`);
|
||||||
},
|
},
|
||||||
|
|
||||||
getGameInfo: () => (): GameInfo => {
|
getGameInfo: () => (): GameInfo => {
|
||||||
@ -99,7 +100,7 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
|||||||
},
|
},
|
||||||
|
|
||||||
clearTerminal: (ctx: NetscriptContext) => (): void => {
|
clearTerminal: (ctx: NetscriptContext) => (): void => {
|
||||||
ctx.log(() => `Clearing terminal`);
|
helpers.log(ctx, () => `Clearing terminal`);
|
||||||
Terminal.clear();
|
Terminal.clear();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import * as walk from "acorn-walk";
|
import * as walk from "acorn-walk";
|
||||||
import { parse } from "acorn";
|
import { parse } from "acorn";
|
||||||
|
|
||||||
import { makeRuntimeRejectMsg } from "./NetscriptEvaluator";
|
import { helpers } from "./Netscript/NetscriptHelpers";
|
||||||
import { ScriptUrl } from "./Script/ScriptUrl";
|
import { ScriptUrl } from "./Script/ScriptUrl";
|
||||||
import { WorkerScript } from "./Netscript/WorkerScript";
|
import { WorkerScript } from "./Netscript/WorkerScript";
|
||||||
import { Script } from "./Script/Script";
|
import { Script } from "./Script/Script";
|
||||||
@ -74,18 +74,21 @@ export async function executeJSScript(
|
|||||||
const ns = workerScript.env.vars;
|
const ns = workerScript.env.vars;
|
||||||
|
|
||||||
if (!loadedModule) {
|
if (!loadedModule) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, `${script.filename} cannot be run because the script module won't load`);
|
throw helpers.makeRuntimeRejectMsg(
|
||||||
|
workerScript,
|
||||||
|
`${script.filename} cannot be run because the script module won't load`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// TODO: putting await in a non-async function yields unhelpful
|
// TODO: putting await in a non-async function yields unhelpful
|
||||||
// "SyntaxError: unexpected reserved word" with no line number information.
|
// "SyntaxError: unexpected reserved word" with no line number information.
|
||||||
if (!loadedModule.main) {
|
if (!loadedModule.main) {
|
||||||
throw makeRuntimeRejectMsg(
|
throw helpers.makeRuntimeRejectMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
`${script.filename} cannot be run because it does not have a main function.`,
|
`${script.filename} cannot be run because it does not have a main function.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!ns) {
|
if (!ns) {
|
||||||
throw makeRuntimeRejectMsg(
|
throw helpers.makeRuntimeRejectMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
`${script.filename} cannot be run because the NS object hasn't been constructed properly.`,
|
`${script.filename} cannot be run because the NS object hasn't been constructed properly.`,
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,6 @@ import { generateNextPid } from "./Netscript/Pid";
|
|||||||
|
|
||||||
import { CONSTANTS } from "./Constants";
|
import { CONSTANTS } from "./Constants";
|
||||||
import { Interpreter } from "./ThirdParty/JSInterpreter";
|
import { Interpreter } from "./ThirdParty/JSInterpreter";
|
||||||
import { isScriptErrorMessage, makeRuntimeRejectMsg } from "./NetscriptEvaluator";
|
|
||||||
import { NetscriptFunctions } from "./NetscriptFunctions";
|
import { NetscriptFunctions } from "./NetscriptFunctions";
|
||||||
import { executeJSScript, Node } from "./NetscriptJSEvaluator";
|
import { executeJSScript, Node } from "./NetscriptJSEvaluator";
|
||||||
import { NetscriptPort, IPort } from "./NetscriptPort";
|
import { NetscriptPort, IPort } from "./NetscriptPort";
|
||||||
@ -29,7 +28,6 @@ import { dialogBoxCreate } from "./ui/React/DialogBox";
|
|||||||
import { arrayToString } from "./utils/helpers/arrayToString";
|
import { arrayToString } from "./utils/helpers/arrayToString";
|
||||||
import { roundToTwo } from "./utils/helpers/roundToTwo";
|
import { roundToTwo } from "./utils/helpers/roundToTwo";
|
||||||
import { isString } from "./utils/helpers/isString";
|
import { isString } from "./utils/helpers/isString";
|
||||||
import { sprintf } from "sprintf-js";
|
|
||||||
|
|
||||||
import { parse } from "acorn";
|
import { parse } from "acorn";
|
||||||
import { simple as walksimple } from "acorn-walk";
|
import { simple as walksimple } from "acorn-walk";
|
||||||
@ -38,6 +36,8 @@ import { Player } from "./Player";
|
|||||||
import { Terminal } from "./Terminal";
|
import { Terminal } from "./Terminal";
|
||||||
import { IPlayer } from "./PersonObjects/IPlayer";
|
import { IPlayer } from "./PersonObjects/IPlayer";
|
||||||
import { ScriptArg } from "./Netscript/ScriptArg";
|
import { ScriptArg } from "./Netscript/ScriptArg";
|
||||||
|
import { helpers } from "./Netscript/NetscriptHelpers";
|
||||||
|
import { NS } from "./ScriptEditor/NetscriptDefinitions";
|
||||||
|
|
||||||
// Netscript Ports are instantiated here
|
// Netscript Ports are instantiated here
|
||||||
export const NetscriptPorts: IPort[] = [];
|
export const NetscriptPorts: IPort[] = [];
|
||||||
@ -63,83 +63,6 @@ export function prestigeWorkerScripts(): void {
|
|||||||
// that resolves or rejects when the corresponding worker script is done.
|
// that resolves or rejects when the corresponding worker script is done.
|
||||||
function startNetscript2Script(player: IPlayer, workerScript: WorkerScript): Promise<void> {
|
function startNetscript2Script(player: IPlayer, workerScript: WorkerScript): Promise<void> {
|
||||||
workerScript.running = true;
|
workerScript.running = true;
|
||||||
|
|
||||||
// The name of the currently running netscript function, to prevent concurrent
|
|
||||||
// calls to hack, grow, etc.
|
|
||||||
let runningFn: string | null = null;
|
|
||||||
|
|
||||||
// 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
|
|
||||||
// hack promises are outstanding, for example.
|
|
||||||
function wrap(propName: string, f: (...args: unknown[]) => Promise<void>): (...args: unknown[]) => Promise<void> {
|
|
||||||
// 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.
|
|
||||||
return function (...args: unknown[]) {
|
|
||||||
// Wrap every netscript function with a check for the stop flag.
|
|
||||||
// This prevents cases where we never stop because we are only calling
|
|
||||||
// netscript functions that don't check this.
|
|
||||||
// This is not a problem for legacy Netscript because it also checks the
|
|
||||||
// stop flag in the evaluator.
|
|
||||||
if (workerScript.env.stopFlag) {
|
|
||||||
throw new ScriptDeath(workerScript);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propName === "asleep") return f(...args); // OK for multiple simultaneous calls to sleep.
|
|
||||||
|
|
||||||
const msg =
|
|
||||||
"Concurrent calls to Netscript functions are not allowed! " +
|
|
||||||
"Did you forget to await hack(), grow(), or some other " +
|
|
||||||
"promise-returning function? (Currently running: %s tried to run: %s)";
|
|
||||||
if (runningFn) {
|
|
||||||
workerScript.errorMessage = makeRuntimeRejectMsg(workerScript, sprintf(msg, runningFn, propName));
|
|
||||||
throw new ScriptDeath(workerScript);
|
|
||||||
}
|
|
||||||
runningFn = propName;
|
|
||||||
|
|
||||||
// If the function throws an error, clear the runningFn flag first, and then re-throw it
|
|
||||||
// This allows people to properly catch errors thrown by NS functions without getting
|
|
||||||
// the concurrent call error above
|
|
||||||
let result;
|
|
||||||
try {
|
|
||||||
result = f(...args);
|
|
||||||
} catch (e: unknown) {
|
|
||||||
runningFn = null;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result && result.finally !== undefined) {
|
|
||||||
return result.finally(function () {
|
|
||||||
runningFn = null;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
runningFn = null;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function wrapObject(vars: unknown, ...tree: string[]): void {
|
|
||||||
const isObject = (x: unknown): x is { [key: string]: unknown } => typeof x === "object";
|
|
||||||
if (!isObject(vars)) throw new Error("wrong argument sent to wrapObject");
|
|
||||||
for (const prop of Object.keys(vars)) {
|
|
||||||
let e = vars[prop];
|
|
||||||
switch (typeof e) {
|
|
||||||
case "function": {
|
|
||||||
e = wrap([...tree, prop].join("."), e as any);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "object": {
|
|
||||||
if (Array.isArray(e)) continue;
|
|
||||||
wrapObject(e, ...tree, prop);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
wrapObject(workerScript.env.vars);
|
|
||||||
|
|
||||||
// Note: the environment that we pass to the JS script only needs to contain the functions visible
|
|
||||||
// to that script, which env.vars does at this point.
|
|
||||||
return new Promise<void>((resolve, reject) => {
|
return new Promise<void>((resolve, reject) => {
|
||||||
executeJSScript(player, workerScript.getServer().scripts, workerScript)
|
executeJSScript(player, workerScript.getServer().scripts, workerScript)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -149,15 +72,18 @@ function startNetscript2Script(player: IPlayer, workerScript: WorkerScript): Pro
|
|||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
if (e instanceof SyntaxError) {
|
if (e instanceof SyntaxError) {
|
||||||
workerScript.errorMessage = makeRuntimeRejectMsg(workerScript, e.message + " (sorry we can't be more helpful)");
|
workerScript.errorMessage = helpers.makeRuntimeRejectMsg(
|
||||||
|
workerScript,
|
||||||
|
e.message + " (sorry we can't be more helpful)",
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
workerScript.errorMessage = makeRuntimeRejectMsg(
|
workerScript.errorMessage = helpers.makeRuntimeRejectMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
e.message + ((e.stack && "\nstack:\n" + e.stack.toString()) || ""),
|
e.message + ((e.stack && "\nstack:\n" + e.stack.toString()) || ""),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
throw new ScriptDeath(workerScript);
|
throw new ScriptDeath(workerScript);
|
||||||
} else if (isScriptErrorMessage(e)) {
|
} else if (helpers.isScriptErrorMessage(e)) {
|
||||||
workerScript.errorMessage = e;
|
workerScript.errorMessage = e;
|
||||||
throw new ScriptDeath(workerScript);
|
throw new ScriptDeath(workerScript);
|
||||||
} else if (e instanceof ScriptDeath) {
|
} else if (e instanceof ScriptDeath) {
|
||||||
@ -165,7 +91,7 @@ function startNetscript2Script(player: IPlayer, workerScript: WorkerScript): Pro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't know what to do with it, let's try making an error message out of it
|
// Don't know what to do with it, let's try making an error message out of it
|
||||||
workerScript.errorMessage = makeRuntimeRejectMsg(workerScript, "" + e);
|
workerScript.errorMessage = helpers.makeRuntimeRejectMsg(workerScript, "" + e);
|
||||||
throw new ScriptDeath(workerScript);
|
throw new ScriptDeath(workerScript);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -189,8 +115,11 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const interpreterInitialization = function (int: Interpreter, scope: unknown): void {
|
const interpreterInitialization = function (int: Interpreter, scope: unknown): void {
|
||||||
|
interface NS1 extends NS {
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
//Add the Netscript environment
|
//Add the Netscript environment
|
||||||
const ns = NetscriptFunctions(workerScript);
|
const ns = NetscriptFunctions(workerScript) as NS1;
|
||||||
for (const name of Object.keys(ns)) {
|
for (const name of Object.keys(ns)) {
|
||||||
const entry = ns[name];
|
const entry = ns[name];
|
||||||
if (typeof entry === "function") {
|
if (typeof entry === "function") {
|
||||||
@ -242,7 +171,7 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
name === "vsprintf" ||
|
name === "vsprintf" ||
|
||||||
name === "scp" ||
|
name === "scp" ||
|
||||||
name == "write" ||
|
name == "write" ||
|
||||||
name === "tryWrite" ||
|
name === "tryWritePort" ||
|
||||||
name === "run" ||
|
name === "run" ||
|
||||||
name === "exec"
|
name === "exec"
|
||||||
) {
|
) {
|
||||||
@ -319,8 +248,8 @@ function startNetscript1Script(workerScript: WorkerScript): Promise<void> {
|
|||||||
}
|
}
|
||||||
} catch (_e: unknown) {
|
} catch (_e: unknown) {
|
||||||
let e = String(_e);
|
let e = String(_e);
|
||||||
if (!isScriptErrorMessage(e)) {
|
if (!helpers.isScriptErrorMessage(e)) {
|
||||||
e = makeRuntimeRejectMsg(workerScript, e);
|
e = helpers.makeRuntimeRejectMsg(workerScript, e);
|
||||||
}
|
}
|
||||||
workerScript.errorMessage = e;
|
workerScript.errorMessage = e;
|
||||||
return reject(new ScriptDeath(workerScript));
|
return reject(new ScriptDeath(workerScript));
|
||||||
@ -598,7 +527,7 @@ function createAndAddWorkerScript(
|
|||||||
console.error("Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + e.toString());
|
console.error("Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + e.toString());
|
||||||
return;
|
return;
|
||||||
} else if (e instanceof ScriptDeath) {
|
} else if (e instanceof ScriptDeath) {
|
||||||
if (isScriptErrorMessage(workerScript.errorMessage)) {
|
if (helpers.isScriptErrorMessage(workerScript.errorMessage)) {
|
||||||
const errorTextArray = workerScript.errorMessage.split("|DELIMITER|");
|
const errorTextArray = workerScript.errorMessage.split("|DELIMITER|");
|
||||||
if (errorTextArray.length != 4) {
|
if (errorTextArray.length != 4) {
|
||||||
console.error("ERROR: Something wrong with Error text in evaluator...");
|
console.error("ERROR: Something wrong with Error text in evaluator...");
|
||||||
@ -622,7 +551,7 @@ function createAndAddWorkerScript(
|
|||||||
workerScript.log("", () => "Script killed");
|
workerScript.log("", () => "Script killed");
|
||||||
return; // Already killed, so stop here
|
return; // Already killed, so stop here
|
||||||
}
|
}
|
||||||
} else if (isScriptErrorMessage(e)) {
|
} else if (helpers.isScriptErrorMessage(e)) {
|
||||||
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
|
||||||
console.error(
|
console.error(
|
||||||
"ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " +
|
"ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " +
|
||||||
|
27
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
27
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -4281,7 +4281,7 @@ export interface InfiltrationReward {
|
|||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
export interface ILocation {
|
export interface ILocation {
|
||||||
city: CityName | null;
|
city: string;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6920,6 +6920,31 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
|
|||||||
* @returns An offer of investment
|
* @returns An offer of investment
|
||||||
*/
|
*/
|
||||||
getInvestmentOffer(): InvestmentOffer;
|
getInvestmentOffer(): InvestmentOffer;
|
||||||
|
/**
|
||||||
|
* Get list of materials
|
||||||
|
* @returns material names
|
||||||
|
*/
|
||||||
|
getMaterialNames(): string[];
|
||||||
|
/**
|
||||||
|
* Get list of industry types
|
||||||
|
* @returns industry names
|
||||||
|
*/
|
||||||
|
getIndustryTypes(): string[];
|
||||||
|
/**
|
||||||
|
* Get list of one-time unlockable upgrades
|
||||||
|
* @returns unlockable upgrades names
|
||||||
|
*/
|
||||||
|
getUnlockables(): string[];
|
||||||
|
/**
|
||||||
|
* Get list of upgrade names
|
||||||
|
* @returns upgrade names
|
||||||
|
*/
|
||||||
|
getUpgradeNames(): string[];
|
||||||
|
/**
|
||||||
|
* Get list of research names
|
||||||
|
* @returns research names
|
||||||
|
*/
|
||||||
|
getResearchNames(): string[];
|
||||||
/**
|
/**
|
||||||
* Accept investment based on you companies current valuation
|
* Accept investment based on you companies current valuation
|
||||||
* @remarks
|
* @remarks
|
||||||
|
@ -309,7 +309,7 @@ export async function determineAllPossibilitiesForTabCompletion(
|
|||||||
return "--" + f[0];
|
return "--" + f[0];
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
return flagFunc()(schema);
|
return flagFunc(schema);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
import { ScriptDeath } from "./Netscript/ScriptDeath";
|
||||||
import { isScriptErrorMessage } from "./NetscriptEvaluator";
|
import { helpers } from "./Netscript/NetscriptHelpers";
|
||||||
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
import { dialogBoxCreate } from "./ui/React/DialogBox";
|
||||||
|
|
||||||
export function setupUncaughtPromiseHandler(): void {
|
export function setupUncaughtPromiseHandler(): void {
|
||||||
window.addEventListener("unhandledrejection", function (e) {
|
window.addEventListener("unhandledrejection", function (e) {
|
||||||
if (isScriptErrorMessage(e.reason)) {
|
if (helpers.isScriptErrorMessage(e.reason)) {
|
||||||
const errorTextArray = e.reason.split("|DELIMITER|");
|
const errorTextArray = e.reason.split("|DELIMITER|");
|
||||||
const hostname = errorTextArray[1];
|
const hostname = errorTextArray[1];
|
||||||
const scriptName = errorTextArray[2];
|
const scriptName = errorTextArray[2];
|
||||||
|
@ -381,7 +381,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
<Typography>
|
<Typography>
|
||||||
Scripts must end with the {tutorialScriptExtension} extension. Let's make a script now by entering{" "}
|
Scripts must end with the {tutorialScriptExtension} extension. Let's make a script now by entering{" "}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography classes={{ root: classes.textfield }}>{`[home ~/]> nano ${tutorialScriptName}`}</Typography>
|
<Typography classes={{ root: classes.textfield }}>{`[n00dles ~/]> nano ${tutorialScriptName}`}</Typography>
|
||||||
|
|
||||||
<Typography>
|
<Typography>
|
||||||
after the hack command finishes running (Sidenote: Pressing ctrl + c will end a command like hack early)
|
after the hack command finishes running (Sidenote: Pressing ctrl + c will end a command like hack early)
|
||||||
@ -439,7 +439,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
<br />
|
<br />
|
||||||
To check how much RAM is available on this machine, enter
|
To check how much RAM is available on this machine, enter
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography classes={{ root: classes.textfield }}>{"[home ~/]> free"}</Typography>
|
<Typography classes={{ root: classes.textfield }}>{"[n00dles ~/]> free"}</Typography>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
canNext: false,
|
canNext: false,
|
||||||
@ -448,9 +448,9 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
content: (
|
content: (
|
||||||
<>
|
<>
|
||||||
<Typography>
|
<Typography>
|
||||||
We have 8GB of free RAM on this machine, which is enough to run our script. Let's run our script using
|
We have 4GB of free RAM on this machine, which is enough to run our script. Let's run our script using
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography classes={{ root: classes.textfield }}>{`[home ~/]> run ${tutorialScriptName}`}</Typography>
|
<Typography classes={{ root: classes.textfield }}>{`[n00dles ~/]> run ${tutorialScriptName}`}</Typography>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
canNext: false,
|
canNext: false,
|
||||||
@ -497,7 +497,7 @@ export function InteractiveTutorialRoot(): React.ReactElement {
|
|||||||
One last thing about scripts, each active script contains logs that detail what it's doing. We can check
|
One last thing about scripts, each active script contains logs that detail what it's doing. We can check
|
||||||
these logs using the tail command. Do that now for the script we just ran by typing{" "}
|
these logs using the tail command. Do that now for the script we just ran by typing{" "}
|
||||||
</Typography>
|
</Typography>
|
||||||
<Typography classes={{ root: classes.textfield }}>{`[home ~/]> tail ${tutorialScriptName}`}</Typography>
|
<Typography classes={{ root: classes.textfield }}>{`[n00dles ~/]> tail ${tutorialScriptName}`}</Typography>
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
canNext: false,
|
canNext: false,
|
||||||
|
@ -139,6 +139,10 @@ function PromptMenuSelect({ prompt, resolve }: IContentProps): React.ReactElemen
|
|||||||
return content;
|
return content;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!Array.isArray(prompt?.options?.choices)) {
|
||||||
|
return <Typography>Error: Please provide an array of string choices</Typography>;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div style={{ display: "flex", alignItems: "center", paddingTop: "10px" }}>
|
<div style={{ display: "flex", alignItems: "center", paddingTop: "10px" }}>
|
||||||
|
@ -60,7 +60,7 @@ describe("tutorial", () => {
|
|||||||
cy.findByText(/now we'll run the script/i);
|
cy.findByText(/now we'll run the script/i);
|
||||||
cy.findByRole("textbox").type("free{enter}");
|
cy.findByRole("textbox").type("free{enter}");
|
||||||
|
|
||||||
cy.findByText(/We have 8GB of free RAM on this machine/i);
|
cy.findByText(/We have 4GB of free RAM on this machine/i);
|
||||||
cy.findByRole("textbox").type("run n00dles.script{enter}");
|
cy.findByRole("textbox").type("run n00dles.script{enter}");
|
||||||
|
|
||||||
cy.findByText(/Your script is now running/i);
|
cy.findByText(/Your script is now running/i);
|
||||||
|
Loading…
Reference in New Issue
Block a user