Merge pull request #4236 from Snarling/typeFix

NETSCRIPT: Fix internal typechecking of functions
This commit is contained in:
hydroflame 2022-10-12 23:50:22 -04:00 committed by GitHub
commit 68e90b8e6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 3379 additions and 3841 deletions

@ -5,13 +5,15 @@ import { ScriptArg } from "./ScriptArg";
import { NSEnums } from "src/ScriptEditor/NetscriptDefinitions"; import { NSEnums } from "src/ScriptEditor/NetscriptDefinitions";
import { NSFull } from "src/NetscriptFunctions"; import { NSFull } from "src/NetscriptFunctions";
type ExternalFunction = (...args: unknown[]) => unknown; type ExternalFunction = (...args: any[]) => void;
export type ExternalAPILayer = { export type ExternalAPILayer = {
[key: string]: ExternalAPILayer | ExternalFunction | ScriptArg[]; [key: string]: ExternalAPILayer | ExternalFunction | ScriptArg[];
}; };
type InternalFunction<F extends (...args: unknown[]) => unknown> = (ctx: NetscriptContext) => F; type InternalFunction<F extends ExternalFunction> = (
ctx: NetscriptContext,
) => ((...args: unknown[]) => ReturnType<F>) & F;
export type InternalAPI<API> = { export type InternalAPI<API> = {
[Property in keyof API]: API[Property] extends ExternalFunction [Property in keyof API]: API[Property] extends ExternalFunction

@ -65,6 +65,39 @@ export const helpers = {
failOnHacknetServer, failOnHacknetServer,
}; };
export function assertObjectType<T extends object>(
ctx: NetscriptContext,
name: string,
obj: unknown,
desiredObject: T,
): asserts obj is T {
if (typeof obj !== "object" || obj === null) {
throw makeRuntimeErrorMsg(
ctx,
`Type ${obj === null ? "null" : typeof obj} provided for ${name}. Must be an object.`,
"TYPE",
);
}
const objHas = Object.prototype.hasOwnProperty.bind(obj);
for (const [key, val] of Object.entries(desiredObject)) {
if (!objHas(key)) {
throw makeRuntimeErrorMsg(
ctx,
`Object provided for argument ${name} is missing required property ${key}.`,
"TYPE",
);
}
const objVal = (obj as Record<string, unknown>)[key];
if (typeof val !== typeof objVal) {
throw makeRuntimeErrorMsg(
ctx,
`Incorrect type ${typeof objVal} provided for property ${key} on ${name} argument. Should be type ${typeof val}.`,
"TYPE",
);
}
}
}
const userFriendlyString = (v: unknown): string => { const userFriendlyString = (v: unknown): string => {
const clip = (s: string): string => { const clip = (s: string): string => {
if (s.length > 15) return s.slice(0, 12) + "..."; if (s.length > 15) return s.slice(0, 12) + "...";
@ -220,10 +253,7 @@ function resolveNetscriptRequestedThreads(ctx: NetscriptContext, requestedThread
} }
const requestedThreadsAsInt = requestedThreads | 0; const requestedThreadsAsInt = requestedThreads | 0;
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) { if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
throw makeRuntimeErrorMsg( throw makeRuntimeErrorMsg(ctx, `Invalid thread count: ${requestedThreads}. Threads must be a positive number.`);
ctx,
`Invalid thread count passed to ${ctx.function}: ${requestedThreads}. Threads must be a positive number.`,
);
} }
if (requestedThreadsAsInt > threads) { if (requestedThreadsAsInt > threads) {
throw makeRuntimeErrorMsg( throw makeRuntimeErrorMsg(

@ -546,6 +546,7 @@ export const RamCosts: RamCostTree<Omit<NSFull, "args" | "enums">> = {
// Easter egg function // Easter egg function
break: 0, break: 0,
}, },
iKnowWhatImDoing: 0,
formulas: { formulas: {
mockServer: 0, mockServer: 0,

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
import { Player } from "@player"; import { Player } from "@player";
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 } from "../ScriptEditor/NetscriptDefinitions";
import { Action } from "src/Bladeburner/Action"; import { Action } from "src/Bladeburner/Action";
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper"; import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
import { BlackOperation } from "../Bladeburner/BlackOperation"; import { BlackOperation } from "../Bladeburner/BlackOperation";
@ -47,38 +47,34 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
}; };
return { return {
getContractNames: (ctx: NetscriptContext) => (): string[] => { getContractNames: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.getContractNamesNetscriptFn(); return bladeburner.getContractNamesNetscriptFn();
}, },
getOperationNames: (ctx: NetscriptContext) => (): string[] => { getOperationNames: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.getOperationNamesNetscriptFn(); return bladeburner.getOperationNamesNetscriptFn();
}, },
getBlackOpNames: (ctx: NetscriptContext) => (): string[] => { getBlackOpNames: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.getBlackOpNamesNetscriptFn(); return bladeburner.getBlackOpNamesNetscriptFn();
}, },
getBlackOpRank: getBlackOpRank: (ctx) => (_blackOpName) => {
(ctx: NetscriptContext) =>
(_blackOpName: unknown): number => {
const blackOpName = helpers.string(ctx, "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");
return action.reqdRank; return action.reqdRank;
}, },
getGeneralActionNames: (ctx: NetscriptContext) => (): string[] => { getGeneralActionNames: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.getGeneralActionNamesNetscriptFn(); return bladeburner.getGeneralActionNamesNetscriptFn();
}, },
getSkillNames: (ctx: NetscriptContext) => (): string[] => { getSkillNames: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.getSkillNamesNetscriptFn(); return bladeburner.getSkillNamesNetscriptFn();
}, },
startAction: startAction: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): boolean => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -88,17 +84,15 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
stopBladeburnerAction: (ctx: NetscriptContext) => (): void => { stopBladeburnerAction: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.resetAction(); return bladeburner.resetAction();
}, },
getCurrentAction: (ctx: NetscriptContext) => (): BladeburnerCurAction => { getCurrentAction: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.getTypeAndNameFromActionId(bladeburner.action); return bladeburner.getTypeAndNameFromActionId(bladeburner.action);
}, },
getActionTime: getActionTime: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -115,7 +109,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
getActionCurrentTime: (ctx: NetscriptContext) => (): number => { getActionCurrentTime: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
try { try {
const timecomputed = const timecomputed =
@ -126,9 +120,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
getActionEstimatedSuccessChance: getActionEstimatedSuccessChance: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): [number, number] => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -145,9 +137,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
getActionRepGain: getActionRepGain: (ctx) => (_type, _name, _level) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown, _level: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const level = helpers.number(ctx, "level", _level); const level = helpers.number(ctx, "level", _level);
@ -162,9 +152,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank; return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank;
}, },
getActionCountRemaining: getActionCountRemaining: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -174,27 +162,21 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
getActionMaxLevel: getActionMaxLevel: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "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;
}, },
getActionCurrentLevel: getActionCurrentLevel: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "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;
}, },
getActionAutolevel: getActionAutolevel: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): boolean => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
checkBladeburnerAccess(ctx); checkBladeburnerAccess(ctx);
@ -202,8 +184,8 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
return action.autoLevel; return action.autoLevel;
}, },
setActionAutolevel: setActionAutolevel:
(ctx: NetscriptContext) => (ctx) =>
(_type: unknown, _name: unknown, _autoLevel: unknown = true): void => { (_type, _name, _autoLevel = true) => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const autoLevel = !!_autoLevel; const autoLevel = !!_autoLevel;
@ -212,8 +194,8 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
action.autoLevel = autoLevel; action.autoLevel = autoLevel;
}, },
setActionLevel: setActionLevel:
(ctx: NetscriptContext) => (ctx) =>
(_type: unknown, _name: unknown, _level: unknown = 1): void => { (_type, _name, _level = 1) => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const level = helpers.number(ctx, "level", _level); const level = helpers.number(ctx, "level", _level);
@ -224,17 +206,15 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
} }
action.level = level; action.level = level;
}, },
getRank: (ctx: NetscriptContext) => (): number => { getRank: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.rank; return bladeburner.rank;
}, },
getSkillPoints: (ctx: NetscriptContext) => (): number => { getSkillPoints: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.skillPoints; return bladeburner.skillPoints;
}, },
getSkillLevel: getSkillLevel: (ctx) => (_skillName) => {
(ctx: NetscriptContext) =>
(_skillName: unknown): number => {
const skillName = helpers.string(ctx, "skillName", _skillName); const skillName = helpers.string(ctx, "skillName", _skillName);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
try { try {
@ -244,8 +224,8 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
} }
}, },
getSkillUpgradeCost: getSkillUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_skillName: unknown, _count: unknown = 1): number => { (_skillName, _count = 1) => {
const skillName = helpers.string(ctx, "skillName", _skillName); const skillName = helpers.string(ctx, "skillName", _skillName);
const count = helpers.number(ctx, "count", _count); const count = helpers.number(ctx, "count", _count);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -256,8 +236,8 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
} }
}, },
upgradeSkill: upgradeSkill:
(ctx: NetscriptContext) => (ctx) =>
(_skillName: unknown, _count: unknown = 1): boolean => { (_skillName, _count = 1) => {
const skillName = helpers.string(ctx, "skillName", _skillName); const skillName = helpers.string(ctx, "skillName", _skillName);
const count = helpers.number(ctx, "count", _count); const count = helpers.number(ctx, "count", _count);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -267,9 +247,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
getTeamSize: getTeamSize: (ctx) => (_type, _name) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
@ -279,9 +257,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
setTeamSize: setTeamSize: (ctx) => (_type, _name, _size) => {
(ctx: NetscriptContext) =>
(_type: unknown, _name: unknown, _size: unknown): number => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
const name = helpers.string(ctx, "name", _name); const name = helpers.string(ctx, "name", _name);
const size = helpers.number(ctx, "size", _size); const size = helpers.number(ctx, "size", _size);
@ -292,9 +268,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
throw helpers.makeRuntimeErrorMsg(ctx, String(e)); throw helpers.makeRuntimeErrorMsg(ctx, String(e));
} }
}, },
getCityEstimatedPopulation: getCityEstimatedPopulation: (ctx) => (_cityName) => {
(ctx: NetscriptContext) =>
(_cityName: unknown): number => {
const cityName = helpers.string(ctx, "cityName", _cityName); const cityName = helpers.string(ctx, "cityName", _cityName);
checkBladeburnerAccess(ctx); checkBladeburnerAccess(ctx);
checkBladeburnerCity(ctx, cityName); checkBladeburnerCity(ctx, cityName);
@ -302,9 +276,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
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.cities[cityName].popEst; return bladeburner.cities[cityName].popEst;
}, },
getCityCommunities: getCityCommunities: (ctx) => (_cityName) => {
(ctx: NetscriptContext) =>
(_cityName: unknown): number => {
const cityName = helpers.string(ctx, "cityName", _cityName); const cityName = helpers.string(ctx, "cityName", _cityName);
checkBladeburnerAccess(ctx); checkBladeburnerAccess(ctx);
checkBladeburnerCity(ctx, cityName); checkBladeburnerCity(ctx, cityName);
@ -312,9 +284,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
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.cities[cityName].comms; return bladeburner.cities[cityName].comms;
}, },
getCityChaos: getCityChaos: (ctx) => (_cityName) => {
(ctx: NetscriptContext) =>
(_cityName: unknown): number => {
const cityName = helpers.string(ctx, "cityName", _cityName); const cityName = helpers.string(ctx, "cityName", _cityName);
checkBladeburnerAccess(ctx); checkBladeburnerAccess(ctx);
checkBladeburnerCity(ctx, cityName); checkBladeburnerCity(ctx, cityName);
@ -322,13 +292,11 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
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.cities[cityName].chaos; return bladeburner.cities[cityName].chaos;
}, },
getCity: (ctx: NetscriptContext) => (): string => { getCity: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.city; return bladeburner.city;
}, },
switchCity: switchCity: (ctx) => (_cityName) => {
(ctx: NetscriptContext) =>
(_cityName: unknown): boolean => {
const cityName = helpers.string(ctx, "cityName", _cityName); const cityName = helpers.string(ctx, "cityName", _cityName);
checkBladeburnerAccess(ctx); checkBladeburnerAccess(ctx);
checkBladeburnerCity(ctx, cityName); checkBladeburnerCity(ctx, cityName);
@ -337,15 +305,15 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
bladeburner.city = cityName; bladeburner.city = cityName;
return true; return true;
}, },
getStamina: (ctx: NetscriptContext) => (): [number, number] => { getStamina: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return [bladeburner.stamina, bladeburner.maxStamina]; return [bladeburner.stamina, bladeburner.maxStamina];
}, },
joinBladeburnerFaction: (ctx: NetscriptContext) => (): boolean => { joinBladeburnerFaction: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return bladeburner.joinBladeburnerFactionNetscriptFn(ctx.workerScript); return bladeburner.joinBladeburnerFactionNetscriptFn(ctx.workerScript);
}, },
joinBladeburnerDivision: (ctx: NetscriptContext) => (): boolean => { joinBladeburnerDivision: (ctx) => () => {
if (Player.bitNodeN === 7 || Player.sourceFileLvl(7) > 0) { if (Player.bitNodeN === 7 || Player.sourceFileLvl(7) > 0) {
if (BitNodeMultipliers.BladeburnerRank === 0) { if (BitNodeMultipliers.BladeburnerRank === 0) {
return false; // Disabled in this bitnode return false; // Disabled in this bitnode
@ -369,7 +337,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
} }
return false; return false;
}, },
getBonusTime: (ctx: NetscriptContext) => (): number => { getBonusTime: (ctx) => () => {
const bladeburner = getBladeburner(ctx); const bladeburner = getBladeburner(ctx);
return Math.round(bladeburner.storedCycles / 5) * 1000; return Math.round(bladeburner.storedCycles / 5) * 1000;
}, },

@ -2,17 +2,12 @@ import { Player as player } from "../Player";
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 "../Netscript/APIWrapper"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
import { helpers } from "../Netscript/NetscriptHelpers"; import { helpers, assertObjectType } from "../Netscript/NetscriptHelpers";
import { codingContractTypesMetadata } from "../data/codingcontracttypes"; import { codingContractTypesMetadata } from "../data/codingcontracttypes";
import { generateDummyContract } from "../CodingContractGenerator"; import { generateDummyContract } from "../CodingContractGenerator";
export function NetscriptCodingContract(): InternalAPI<ICodingContract> { export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
const getCodingContract = function ( const getCodingContract = function (ctx: NetscriptContext, hostname: string, filename: string): CodingContract {
ctx: NetscriptContext,
func: string,
hostname: string,
filename: string,
): CodingContract {
const server = helpers.getServer(ctx, hostname); const server = helpers.getServer(ctx, hostname);
const contract = server.getContract(filename); const contract = server.getContract(filename);
if (contract == null) { if (contract == null) {
@ -23,18 +18,14 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
}; };
return { return {
attempt: attempt: (ctx) => (answer, _filename, _hostname?, opts?) => {
(ctx: NetscriptContext) =>
(
answer: unknown,
_filename: unknown,
_hostname: unknown = ctx.workerScript.hostname,
{ returnReward }: CodingAttemptOptions = { returnReward: false },
): boolean | string => {
const filename = helpers.string(ctx, "filename", _filename); const filename = helpers.string(ctx, "filename", _filename);
const hostname = helpers.string(ctx, "hostname", _hostname); const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
const contract = getCodingContract(ctx, "attempt", hostname, filename); const contract = getCodingContract(ctx, hostname, filename);
const optsValidator: CodingAttemptOptions = { returnReward: true };
opts ??= optsValidator;
assertObjectType(ctx, "opts", opts, optsValidator);
if (typeof answer !== "number" && typeof answer !== "string" && !Array.isArray(answer)) if (typeof answer !== "number" && typeof answer !== "string" && !Array.isArray(answer))
throw new Error("The answer provided was not a number, string, or array"); throw new Error("The answer provided was not a number, string, or array");
@ -47,7 +38,7 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
const reward = player.gainCodingContractReward(creward, contract.getDifficulty()); const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
helpers.log(ctx, () => `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 opts.returnReward ? reward : true;
} else { } else {
++contract.tries; ++contract.tries;
if (contract.tries >= contract.getMaxNumTries()) { if (contract.tries >= contract.getMaxNumTries()) {
@ -63,23 +54,19 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
); );
} }
return returnReward ? "" : false; return opts.returnReward ? "" : false;
} }
}, },
getContractType: getContractType: (ctx) => (_filename, _hostname?) => {
(ctx: NetscriptContext) =>
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
const filename = helpers.string(ctx, "filename", _filename); const filename = helpers.string(ctx, "filename", _filename);
const hostname = helpers.string(ctx, "hostname", _hostname); const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
const contract = getCodingContract(ctx, "getContractType", hostname, filename); const contract = getCodingContract(ctx, hostname, filename);
return contract.getType(); return contract.getType();
}, },
getData: getData: (ctx) => (_filename, _hostname?) => {
(ctx: NetscriptContext) =>
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): unknown => {
const filename = helpers.string(ctx, "filename", _filename); const filename = helpers.string(ctx, "filename", _filename);
const hostname = helpers.string(ctx, "hostname", _hostname); const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
const contract = getCodingContract(ctx, "getData", hostname, filename); const contract = getCodingContract(ctx, hostname, filename);
const data = contract.getData(); const data = contract.getData();
if (Array.isArray(data)) { if (Array.isArray(data)) {
// For two dimensional arrays, we have to copy the internal arrays using // For two dimensional arrays, we have to copy the internal arrays using
@ -93,32 +80,24 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
} }
return copy; return copy;
} else { } else return data;
return data;
}
}, },
getDescription: getDescription: (ctx) => (_filename, _hostname?) => {
(ctx: NetscriptContext) =>
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
const filename = helpers.string(ctx, "filename", _filename); const filename = helpers.string(ctx, "filename", _filename);
const hostname = helpers.string(ctx, "hostname", _hostname); const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
const contract = getCodingContract(ctx, "getDescription", hostname, filename); const contract = getCodingContract(ctx, hostname, filename);
return contract.getDescription(); return contract.getDescription();
}, },
getNumTriesRemaining: getNumTriesRemaining: (ctx) => (_filename, _hostname?) => {
(ctx: NetscriptContext) =>
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): number => {
const filename = helpers.string(ctx, "filename", _filename); const filename = helpers.string(ctx, "filename", _filename);
const hostname = helpers.string(ctx, "hostname", _hostname); const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
const contract = getCodingContract(ctx, "getNumTriesRemaining", hostname, filename); const contract = getCodingContract(ctx, hostname, filename);
return contract.getMaxNumTries() - contract.tries; return contract.getMaxNumTries() - contract.tries;
}, },
createDummyContract: createDummyContract: (ctx) => (_type) => {
(ctx: NetscriptContext) =>
(_type: unknown): void => {
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
generateDummyContract(type); generateDummyContract(type);
}, },
getContractTypes: () => (): string[] => codingContractTypesMetadata.map((c) => c.name), getContractTypes: () => () => codingContractTypesMetadata.map((c) => c.name),
}; };
} }

@ -10,16 +10,10 @@ import { Corporation } from "../Corporation/Corporation";
import { import {
Corporation as NSCorporation, Corporation as NSCorporation,
CorporationInfo,
Employee as NSEmployee,
Product as NSProduct,
Material as NSMaterial,
Warehouse as NSWarehouse,
Division as NSDivision, Division as NSDivision,
WarehouseAPI, WarehouseAPI,
OfficeAPI, OfficeAPI,
InvestmentOffer, InvestmentOffer,
Office as NSOffice,
} from "../ScriptEditor/NetscriptDefinitions"; } from "../ScriptEditor/NetscriptDefinitions";
import { import {
@ -308,13 +302,13 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
} }
const warehouseAPI: InternalAPI<WarehouseAPI> = { const warehouseAPI: InternalAPI<WarehouseAPI> = {
getPurchaseWarehouseCost: (ctx: NetscriptContext) => (): number => { getPurchaseWarehouseCost: (ctx) => () => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
return CorporationConstants.WarehouseInitialCost; return CorporationConstants.WarehouseInitialCost;
}, },
getUpgradeWarehouseCost: getUpgradeWarehouseCost:
(ctx: NetscriptContext) => (ctx) =>
(_divisionName: unknown, _cityName: unknown, _amt: unknown = 1): number => { (_divisionName, _cityName, _amt = 1) => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -325,9 +319,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const warehouse = getWarehouse(divisionName, cityName); const warehouse = getWarehouse(divisionName, cityName);
return UpgradeWarehouseCost(warehouse, amt); return UpgradeWarehouseCost(warehouse, amt);
}, },
hasWarehouse: hasWarehouse: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): boolean => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -336,9 +328,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const warehouse = division.warehouses[cityName]; const warehouse = division.warehouses[cityName];
return warehouse !== 0; return warehouse !== 0;
}, },
getWarehouse: getWarehouse: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): NSWarehouse => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -351,9 +341,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
smartSupplyEnabled: warehouse.smartSupplyEnabled, smartSupplyEnabled: warehouse.smartSupplyEnabled,
}; };
}, },
getMaterial: getMaterial: (ctx) => (_divisionName, _cityName, _materialName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown): NSMaterial => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -376,9 +364,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
exp: exports, exp: exports,
}; };
}, },
getProduct: getProduct: (ctx) => (_divisionName, _productName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _productName: unknown): NSProduct => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName); const productName = helpers.string(ctx, "productName", _productName);
@ -403,9 +389,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
developmentProgress: product.prog, developmentProgress: product.prog,
}; };
}, },
purchaseWarehouse: purchaseWarehouse: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -413,8 +397,8 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
PurchaseWarehouse(corporation, getDivision(divisionName), cityName); PurchaseWarehouse(corporation, getDivision(divisionName), cityName);
}, },
upgradeWarehouse: upgradeWarehouse:
(ctx: NetscriptContext) => (ctx) =>
(_divisionName: unknown, _cityName: unknown, _amt: unknown = 1): void => { (_divisionName, _cityName, _amt = 1): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -425,9 +409,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
} }
UpgradeWarehouse(corporation, getDivision(divisionName), getWarehouse(divisionName, cityName), amt); UpgradeWarehouse(corporation, getDivision(divisionName), getWarehouse(divisionName, cityName), amt);
}, },
sellMaterial: sellMaterial: (ctx) => (_divisionName, _cityName, _materialName, _amt, _price) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown, _price: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -438,15 +420,8 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
SellMaterial(material, amt, price); SellMaterial(material, amt, price);
}, },
sellProduct: sellProduct:
(ctx: NetscriptContext) => (ctx) =>
( (_divisionName, _cityName, _productName, _amt, _price, _all): void => {
_divisionName: unknown,
_cityName: unknown,
_productName: unknown,
_amt: unknown,
_price: unknown,
_all: unknown,
): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -457,17 +432,13 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const product = getProduct(divisionName, productName); const product = getProduct(divisionName, productName);
SellProduct(product, cityName, amt, price, all); SellProduct(product, cityName, amt, price, all);
}, },
discontinueProduct: discontinueProduct: (ctx) => (_divisionName, _productName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _productName: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName); const productName = helpers.string(ctx, "productName", _productName);
getDivision(divisionName).discontinueProduct(getProduct(divisionName, productName)); getDivision(divisionName).discontinueProduct(getProduct(divisionName, productName));
}, },
setSmartSupply: setSmartSupply: (ctx) => (_divisionName, _cityName, _enabled) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _enabled: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -477,9 +448,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
throw helpers.makeRuntimeErrorMsg(ctx, `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) => (_divisionName, _cityName, _materialName, _enabled) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _enabled: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -491,9 +460,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
throw helpers.makeRuntimeErrorMsg(ctx, `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) => (_divisionName, _cityName, _materialName, _amt) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -503,9 +470,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const material = getMaterial(divisionName, cityName, materialName); const material = getMaterial(divisionName, cityName, materialName);
BuyMaterial(material, amt); BuyMaterial(material, amt);
}, },
bulkPurchase: bulkPurchase: (ctx) => (_divisionName, _cityName, _materialName, _amt) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _amt: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
if (!hasResearched(getDivision(divisionName), "Bulk Purchasing")) if (!hasResearched(getDivision(divisionName), "Bulk Purchasing"))
@ -519,14 +484,8 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
BulkPurchase(corporation, warehouse, material, amt); BulkPurchase(corporation, warehouse, material, amt);
}, },
makeProduct: makeProduct:
(ctx: NetscriptContext) => (ctx) =>
( (_divisionName, _cityName, _productName, _designInvest, _marketingInvest): void => {
_divisionName: unknown,
_cityName: unknown,
_productName: unknown,
_designInvest: unknown,
_marketingInvest: unknown,
): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -536,9 +495,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const corporation = getCorporation(); const corporation = getCorporation();
MakeProduct(corporation, getDivision(divisionName), cityName, productName, designInvest, marketingInvest); MakeProduct(corporation, getDivision(divisionName), cityName, productName, designInvest, marketingInvest);
}, },
limitProductProduction: limitProductProduction: (ctx) => (_divisionName, _cityName, _productName, _qty) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _productName: unknown, _qty: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -547,15 +504,8 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
LimitProductProduction(getProduct(divisionName, productName), cityName, qty); LimitProductProduction(getProduct(divisionName, productName), cityName, qty);
}, },
exportMaterial: exportMaterial:
(ctx: NetscriptContext) => (ctx) =>
( (_sourceDivision, _sourceCity, _targetDivision, _targetCity, _materialName, _amt): void => {
_sourceDivision: unknown,
_sourceCity: unknown,
_targetDivision: unknown,
_targetCity: unknown,
_materialName: unknown,
_amt: unknown,
): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision); const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision);
const sourceCity = helpers.string(ctx, "sourceCity", _sourceCity); const sourceCity = helpers.string(ctx, "sourceCity", _sourceCity);
@ -572,15 +522,8 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
); );
}, },
cancelExportMaterial: cancelExportMaterial:
(ctx: NetscriptContext) => (ctx) =>
( (_sourceDivision, _sourceCity, _targetDivision, _targetCity, _materialName, _amt): void => {
_sourceDivision: unknown,
_sourceCity: unknown,
_targetDivision: unknown,
_targetCity: unknown,
_materialName: unknown,
_amt: unknown,
): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision); const sourceDivision = helpers.string(ctx, "sourceDivision", _sourceDivision);
const sourceCity = helpers.string(ctx, "sourceCity", _sourceCity); const sourceCity = helpers.string(ctx, "sourceCity", _sourceCity);
@ -595,9 +538,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
amt + "", amt + "",
); );
}, },
limitMaterialProduction: limitMaterialProduction: (ctx) => (_divisionName, _cityName, _materialName, _qty) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _qty: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -605,9 +546,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const qty = helpers.number(ctx, "qty", _qty); const qty = helpers.number(ctx, "qty", _qty);
LimitMaterialProduction(getMaterial(divisionName, cityName, materialName), qty); LimitMaterialProduction(getMaterial(divisionName, cityName, materialName), qty);
}, },
setMaterialMarketTA1: setMaterialMarketTA1: (ctx) => (_divisionName, _cityName, _materialName, _on) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _on: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -617,9 +556,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
throw helpers.makeRuntimeErrorMsg(ctx, `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) => (_divisionName, _cityName, _materialName, _on) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _materialName: unknown, _on: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -629,9 +566,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
throw helpers.makeRuntimeErrorMsg(ctx, `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) => (_divisionName, _productName, _on) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _productName: unknown, _on: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName); const productName = helpers.string(ctx, "productName", _productName);
@ -640,9 +575,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
throw helpers.makeRuntimeErrorMsg(ctx, `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) => (_divisionName, _productName, _on) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _productName: unknown, _on: unknown): void => {
checkAccess(ctx, 7); checkAccess(ctx, 7);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const productName = helpers.string(ctx, "productName", _productName); const productName = helpers.string(ctx, "productName", _productName);
@ -654,41 +587,31 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
}; };
const officeAPI: InternalAPI<OfficeAPI> = { const officeAPI: InternalAPI<OfficeAPI> = {
getHireAdVertCost: getHireAdVertCost: (ctx) => (_divisionName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown): number => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
return division.getAdVertCost(); return division.getAdVertCost();
}, },
getHireAdVertCount: getHireAdVertCount: (ctx) => (_divisionName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown): number => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
return division.numAdVerts; return division.numAdVerts;
}, },
getResearchCost: getResearchCost: (ctx) => (_divisionName, _researchName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _researchName: unknown): number => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const researchName = helpers.string(ctx, "researchName", _researchName); const researchName = helpers.string(ctx, "researchName", _researchName);
return getResearchCost(getDivision(divisionName), researchName); return getResearchCost(getDivision(divisionName), researchName);
}, },
hasResearched: hasResearched: (ctx) => (_divisionName, _researchName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _researchName: unknown): boolean => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const researchName = helpers.string(ctx, "researchName", _researchName); const researchName = helpers.string(ctx, "researchName", _researchName);
return hasResearched(getDivision(divisionName), researchName); return hasResearched(getDivision(divisionName), researchName);
}, },
getOfficeSizeUpgradeCost: getOfficeSizeUpgradeCost: (ctx) => (_divisionName, _cityName, _size) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _size: unknown): number => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -703,9 +626,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
} }
return CorporationConstants.OfficeInitialCost * mult; return CorporationConstants.OfficeInitialCost * mult;
}, },
assignJob: assignJob: (ctx) => (_divisionName, _cityName, _employeeName, _job) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _employeeName: unknown, _job: unknown): void => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -717,9 +638,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
AssignJob(office, employeeName, job); AssignJob(office, employeeName, job);
}, },
setAutoJobAssignment: setAutoJobAssignment: (ctx) => (_divisionName, _cityName, _job, _amount) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _job: unknown, _amount: unknown): boolean => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -731,9 +650,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
return AutoAssignJob(office, job, amount); return AutoAssignJob(office, job, amount);
}, },
hireEmployee: hireEmployee: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): NSEmployee | undefined => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -755,9 +672,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
pos: employee.pos, pos: employee.pos,
}; };
}, },
upgradeOfficeSize: upgradeOfficeSize: (ctx) => (_divisionName, _cityName, _size) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _size: unknown): void => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -767,9 +682,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const corporation = getCorporation(); const corporation = getCorporation();
UpgradeOfficeSize(corporation, office, size); UpgradeOfficeSize(corporation, office, size);
}, },
throwParty: throwParty: (ctx) => (_divisionName, _cityName, _costPerEmployee) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _costPerEmployee: unknown): number => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -784,9 +697,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
return ThrowParty(corporation, office, costPerEmployee); return ThrowParty(corporation, office, costPerEmployee);
}, },
buyCoffee: buyCoffee: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): boolean => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -796,25 +707,19 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
return BuyCoffee(corporation, office); return BuyCoffee(corporation, office);
}, },
hireAdVert: hireAdVert: (ctx) => (_divisionName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown): void => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const corporation = getCorporation(); const corporation = getCorporation();
HireAdVert(corporation, getDivision(divisionName)); HireAdVert(corporation, getDivision(divisionName));
}, },
research: research: (ctx) => (_divisionName, _researchName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _researchName: unknown): void => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const researchName = helpers.string(ctx, "researchName", _researchName); const researchName = helpers.string(ctx, "researchName", _researchName);
Research(getDivision(divisionName), researchName); Research(getDivision(divisionName), researchName);
}, },
getOffice: getOffice: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): NSOffice => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -849,9 +754,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
}, },
}; };
}, },
getEmployee: getEmployee: (ctx) => (_divisionName, _cityName, _employeeName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown, _employeeName: unknown): NSEmployee => {
checkAccess(ctx, 8); checkAccess(ctx, 8);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -877,38 +780,34 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
return { return {
...warehouseAPI, ...warehouseAPI,
...officeAPI, ...officeAPI,
getMaterialNames: (ctx: NetscriptContext) => (): string[] => { getMaterialNames: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return [...CorporationConstants.AllMaterials]; return [...CorporationConstants.AllMaterials];
}, },
getIndustryTypes: (ctx: NetscriptContext) => (): string[] => { getIndustryTypes: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return [...CorporationConstants.AllIndustryTypes]; return [...CorporationConstants.AllIndustryTypes];
}, },
getUnlockables: (ctx: NetscriptContext) => (): string[] => { getUnlockables: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return [...CorporationConstants.AllUnlocks]; return [...CorporationConstants.AllUnlocks];
}, },
getUpgradeNames: (ctx: NetscriptContext) => (): string[] => { getUpgradeNames: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return [...CorporationConstants.AllUpgrades]; return [...CorporationConstants.AllUpgrades];
}, },
getResearchNames: (ctx: NetscriptContext) => (): string[] => { getResearchNames: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return [...CorporationConstants.AllResearch]; return [...CorporationConstants.AllResearch];
}, },
expandIndustry: expandIndustry: (ctx) => (_industryName, _divisionName) => {
(ctx: NetscriptContext) =>
(_industryName: unknown, _divisionName: unknown): void => {
checkAccess(ctx); checkAccess(ctx);
const industryName = helpers.string(ctx, "industryName", _industryName); const industryName = helpers.string(ctx, "industryName", _industryName);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const corporation = getCorporation(); const corporation = getCorporation();
NewIndustry(corporation, industryName, divisionName); NewIndustry(corporation, industryName, divisionName);
}, },
expandCity: expandCity: (ctx) => (_divisionName, _cityName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown, _cityName: unknown): void => {
checkAccess(ctx); checkAccess(ctx);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -917,9 +816,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
const division = getDivision(divisionName); const division = getDivision(divisionName);
NewCity(corporation, division, cityName); NewCity(corporation, division, cityName);
}, },
unlockUpgrade: unlockUpgrade: (ctx) => (_upgradeName) => {
(ctx: NetscriptContext) =>
(_upgradeName: unknown): void => {
checkAccess(ctx); checkAccess(ctx);
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName); const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
const corporation = getCorporation(); const corporation = getCorporation();
@ -927,9 +824,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`); if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
UnlockUpgrade(corporation, upgrade); UnlockUpgrade(corporation, upgrade);
}, },
levelUpgrade: levelUpgrade: (ctx) => (_upgradeName) => {
(ctx: NetscriptContext) =>
(_upgradeName: unknown): void => {
checkAccess(ctx); checkAccess(ctx);
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName); const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
const corporation = getCorporation(); const corporation = getCorporation();
@ -937,9 +832,7 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`); if (upgrade === undefined) throw new Error(`No upgrade named '${upgradeName}'`);
LevelUpgrade(corporation, upgrade); LevelUpgrade(corporation, upgrade);
}, },
issueDividends: issueDividends: (ctx) => (_rate) => {
(ctx: NetscriptContext) =>
(_rate: unknown): void => {
checkAccess(ctx); checkAccess(ctx);
const rate = helpers.number(ctx, "rate", _rate); const rate = helpers.number(ctx, "rate", _rate);
const max = CorporationConstants.DividendMaxRate; const max = CorporationConstants.DividendMaxRate;
@ -952,15 +845,13 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
// If you modify these objects you will affect them for real, it's not // If you modify these objects you will affect them for real, it's not
// copies. // copies.
getDivision: getDivision: (ctx) => (_divisionName) => {
(ctx: NetscriptContext) =>
(_divisionName: unknown): NSDivision => {
checkAccess(ctx); checkAccess(ctx);
const divisionName = helpers.string(ctx, "divisionName", _divisionName); const divisionName = helpers.string(ctx, "divisionName", _divisionName);
const division = getDivision(divisionName); const division = getDivision(divisionName);
return getSafeDivision(division); return getSafeDivision(division);
}, },
getCorporation: (ctx: NetscriptContext) => (): CorporationInfo => { getCorporation: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
const corporation = getCorporation(); const corporation = getCorporation();
return { return {
@ -982,89 +873,71 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
}; };
}, },
createCorporation: createCorporation:
(ctx: NetscriptContext) => (ctx) =>
(_corporationName: unknown, _selfFund: unknown = true): boolean => { (_corporationName, _selfFund = true): boolean => {
const corporationName = helpers.string(ctx, "corporationName", _corporationName); const corporationName = helpers.string(ctx, "corporationName", _corporationName);
const selfFund = !!_selfFund; const selfFund = !!_selfFund;
return createCorporation(corporationName, selfFund); return createCorporation(corporationName, selfFund);
}, },
hasUnlockUpgrade: hasUnlockUpgrade: (ctx) => (_upgradeName) => {
(ctx: NetscriptContext) =>
(_upgradeName: unknown): boolean => {
checkAccess(ctx); checkAccess(ctx);
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName); const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
return hasUnlockUpgrade(upgradeName); return hasUnlockUpgrade(upgradeName);
}, },
getUnlockUpgradeCost: getUnlockUpgradeCost: (ctx) => (_upgradeName) => {
(ctx: NetscriptContext) =>
(_upgradeName: unknown): number => {
checkAccess(ctx); checkAccess(ctx);
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName); const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
return getUnlockUpgradeCost(upgradeName); return getUnlockUpgradeCost(upgradeName);
}, },
getUpgradeLevel: getUpgradeLevel: (ctx) => (_upgradeName) => {
(ctx: NetscriptContext) =>
(_upgradeName: unknown): number => {
checkAccess(ctx); checkAccess(ctx);
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName); const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
return getUpgradeLevel(ctx, upgradeName); return getUpgradeLevel(ctx, upgradeName);
}, },
getUpgradeLevelCost: getUpgradeLevelCost: (ctx) => (_upgradeName) => {
(ctx: NetscriptContext) =>
(_upgradeName: unknown): number => {
checkAccess(ctx); checkAccess(ctx);
const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName); const upgradeName = helpers.string(ctx, "upgradeName", _upgradeName);
return getUpgradeLevelCost(ctx, upgradeName); return getUpgradeLevelCost(ctx, upgradeName);
}, },
getExpandIndustryCost: getExpandIndustryCost: (ctx) => (_industryName) => {
(ctx: NetscriptContext) =>
(_industryName: unknown): number => {
checkAccess(ctx); checkAccess(ctx);
const industryName = helpers.string(ctx, "industryName", _industryName); const industryName = helpers.string(ctx, "industryName", _industryName);
return getExpandIndustryCost(industryName); return getExpandIndustryCost(industryName);
}, },
getExpandCityCost: (ctx: NetscriptContext) => (): number => { getExpandCityCost: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return getExpandCityCost(); return getExpandCityCost();
}, },
getInvestmentOffer: (ctx: NetscriptContext) => (): InvestmentOffer => { getInvestmentOffer: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return getInvestmentOffer(); return getInvestmentOffer();
}, },
acceptInvestmentOffer: (ctx: NetscriptContext) => (): boolean => { acceptInvestmentOffer: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return acceptInvestmentOffer(); return acceptInvestmentOffer();
}, },
goPublic: goPublic: (ctx) => (_numShares) => {
(ctx: NetscriptContext) =>
(_numShares: unknown): boolean => {
checkAccess(ctx); checkAccess(ctx);
const numShares = helpers.number(ctx, "numShares", _numShares); const numShares = helpers.number(ctx, "numShares", _numShares);
return goPublic(numShares); return goPublic(numShares);
}, },
sellShares: sellShares: (ctx) => (_numShares) => {
(ctx: NetscriptContext) =>
(_numShares: unknown): number => {
checkAccess(ctx); checkAccess(ctx);
const numShares = helpers.number(ctx, "numShares", _numShares); const numShares = helpers.number(ctx, "numShares", _numShares);
return SellShares(getCorporation(), numShares); return SellShares(getCorporation(), numShares);
}, },
buyBackShares: buyBackShares: (ctx) => (_numShares) => {
(ctx: NetscriptContext) =>
(_numShares: unknown): boolean => {
checkAccess(ctx); checkAccess(ctx);
const numShares = helpers.number(ctx, "numShares", _numShares); const numShares = helpers.number(ctx, "numShares", _numShares);
return BuyBackShares(getCorporation(), numShares); return BuyBackShares(getCorporation(), numShares);
}, },
bribe: bribe: (ctx) => (_factionName, _amountCash) => {
(ctx: NetscriptContext) =>
(_factionName: unknown, _amountCash: unknown): boolean => {
checkAccess(ctx); checkAccess(ctx);
const factionName = helpers.string(ctx, "factionName", _factionName); const factionName = helpers.string(ctx, "factionName", _factionName);
const amountCash = helpers.number(ctx, "amountCash", _amountCash); const amountCash = helpers.number(ctx, "amountCash", _amountCash);
return bribe(factionName, amountCash); return bribe(factionName, amountCash);
}, },
getBonusTime: (ctx: NetscriptContext) => (): number => { getBonusTime: (ctx) => () => {
checkAccess(ctx); checkAccess(ctx);
return Math.round(getCorporation().storedCycles / 5) * 1000; return Math.round(getCorporation().storedCycles / 5) * 1000;
}, },

@ -1,9 +1,10 @@
import { Player as player } from "../Player"; import { 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 } from "../Netscript/APIWrapper";
import { helpers } from "../Netscript/NetscriptHelpers"; import { helpers } from "../Netscript/NetscriptHelpers";
import { Terminal } from "../Terminal";
export interface INetscriptExtra { export interface INetscriptExtra {
heart: { heart: {
@ -14,25 +15,24 @@ export interface INetscriptExtra {
bypass(doc: Document): void; bypass(doc: Document): void;
alterReality(): void; alterReality(): void;
rainbow(guess: string): void; rainbow(guess: string): void;
iKnowWhatImDoing(): void;
} }
export function NetscriptExtra(): InternalAPI<INetscriptExtra> { export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
return { return {
heart: { heart: {
// Easter egg function // Easter egg function
break: () => (): number => { break: () => () => {
return player.karma; return Player.karma;
}, },
}, },
openDevMenu: () => (): void => { openDevMenu: () => () => {
devMenu.emit(); devMenu.emit();
}, },
exploit: () => (): void => { exploit: () => () => {
player.giveExploit(Exploit.UndocumentedFunctionCall); Player.giveExploit(Exploit.UndocumentedFunctionCall);
}, },
bypass: bypass: (ctx) => (doc) => {
(ctx: NetscriptContext) =>
(doc: unknown): void => {
// reset both fields first // reset both fields first
type temporary = { completely_unused_field: unknown }; type temporary = { completely_unused_field: unknown };
const d = doc as temporary; const d = doc as temporary;
@ -42,12 +42,12 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
// set one to true and check that it affected the other. // set one to true and check that it affected the other.
real_document.completely_unused_field = true; real_document.completely_unused_field = true;
if (d.completely_unused_field && ctx.workerScript.ramUsage === 1.6) { if (d.completely_unused_field && ctx.workerScript.ramUsage === 1.6) {
player.giveExploit(Exploit.Bypass); Player.giveExploit(Exploit.Bypass);
} }
d.completely_unused_field = undefined; d.completely_unused_field = undefined;
real_document.completely_unused_field = undefined; real_document.completely_unused_field = undefined;
}, },
alterReality: () => (): void => { alterReality: () => () => {
// We need to trick webpack into not optimizing a variable that is guaranteed to be false (and doesn't use prototypes) // We need to trick webpack into not optimizing a variable that is guaranteed to be false (and doesn't use prototypes)
let x = false; let x = false;
const recur = function (depth: number): void { const recur = function (depth: number): void {
@ -59,12 +59,10 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
console.warn("I am sure that this variable is false."); console.warn("I am sure that this variable is false.");
if (x !== false) { if (x !== false) {
console.warn("Reality has been altered!"); console.warn("Reality has been altered!");
player.giveExploit(Exploit.RealityAlteration); Player.giveExploit(Exploit.RealityAlteration);
} }
}, },
rainbow: rainbow: (ctx) => (guess) => {
(ctx: NetscriptContext) =>
(guess: unknown): boolean => {
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(
@ -72,12 +70,17 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
"$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO", "$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO",
); );
if (verified) { if (verified) {
player.giveExploit(Exploit.INeedARainbow); Player.giveExploit(Exploit.INeedARainbow);
return true; return true;
} }
return false; return false;
} }
return tryGuess(); return tryGuess();
}, },
iKnowWhatImDoing: (ctx) => () => {
helpers.log(ctx, () => "Unlocking unsupported feature: window.tprintRaw");
// @ts-ignore window has no tprintRaw property defined
window.tprintRaw = Terminal.printRaw.bind(Terminal);
},
}; };
} }

@ -26,11 +26,7 @@ import {
calculateWeakenTime, calculateWeakenTime,
} from "../Hacking"; } from "../Hacking";
import { Programs } from "../Programs/Programs"; import { Programs } from "../Programs/Programs";
import { import { Formulas as IFormulas } from "../ScriptEditor/NetscriptDefinitions";
Formulas as IFormulas,
HacknetNodeConstants as DefHacknetNodeConstants,
HacknetServerConstants as DefHacknetServerConstants,
} from "../ScriptEditor/NetscriptDefinitions";
import { import {
calculateRespectGain, calculateRespectGain,
calculateWantedLevelGain, calculateWantedLevelGain,
@ -43,7 +39,6 @@ import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor }
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"; import { helpers } from "../Netscript/NetscriptHelpers";
import { WorkStats } from "../Work/WorkStats";
import { calculateCrimeWorkStats } from "../Work/formulas/Crime"; import { calculateCrimeWorkStats } from "../Work/formulas/Crime";
import { Crimes } from "../Crime/Crimes"; import { Crimes } from "../Crime/Crimes";
import { calculateClassEarnings } from "../Work/formulas/Class"; import { calculateClassEarnings } from "../Work/formulas/Class";
@ -52,7 +47,6 @@ import { LocationName } from "../Locations/data/LocationNames";
import { calculateFactionExp, calculateFactionRep } from "../Work/formulas/Faction"; import { calculateFactionExp, calculateFactionRep } from "../Work/formulas/Faction";
import { FactionWorkType } from "../Work/data/FactionWorkType"; import { FactionWorkType } from "../Work/data/FactionWorkType";
import { Player as INetscriptPlayer, Server as IServerDef } from "../ScriptEditor/NetscriptDefinitions";
import { defaultMultipliers } from "../PersonObjects/Multipliers"; import { defaultMultipliers } from "../PersonObjects/Multipliers";
export function NetscriptFormulas(): InternalAPI<IFormulas> { export function NetscriptFormulas(): InternalAPI<IFormulas> {
@ -62,7 +56,7 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
} }
}; };
return { return {
mockServer: () => (): IServerDef => ({ mockServer: () => () => ({
cpuCores: 0, cpuCores: 0,
ftpPortOpen: false, ftpPortOpen: false,
hasAdminRights: false, hasAdminRights: false,
@ -88,7 +82,7 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
requiredHackingSkill: 0, requiredHackingSkill: 0,
serverGrowth: 0, serverGrowth: 0,
}), }),
mockPlayer: () => (): INetscriptPlayer => ({ mockPlayer: () => () => ({
hp: { current: 0, max: 0 }, hp: { current: 0, max: 0 },
skills: { skills: {
hacking: 0, hacking: 0,
@ -125,23 +119,17 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
entropy: 0, entropy: 0,
}), }),
reputation: { reputation: {
calculateFavorToRep: calculateFavorToRep: (ctx) => (_favor) => {
(ctx: NetscriptContext) =>
(_favor: unknown): number => {
const favor = helpers.number(ctx, "favor", _favor); const favor = helpers.number(ctx, "favor", _favor);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateFavorToRep(favor); return calculateFavorToRep(favor);
}, },
calculateRepToFavor: calculateRepToFavor: (ctx) => (_rep) => {
(ctx: NetscriptContext) =>
(_rep: unknown): number => {
const rep = helpers.number(ctx, "rep", _rep); const rep = helpers.number(ctx, "rep", _rep);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateRepToFavor(rep); return calculateRepToFavor(rep);
}, },
repFromDonation: repFromDonation: (ctx) => (_amount, _player) => {
(ctx: NetscriptContext) =>
(_amount: unknown, _player: unknown): number => {
const amount = helpers.number(ctx, "amount", _amount); const amount = helpers.number(ctx, "amount", _amount);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
@ -150,16 +138,16 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
}, },
skills: { skills: {
calculateSkill: calculateSkill:
(ctx: NetscriptContext) => (ctx) =>
(_exp: unknown, _mult: unknown = 1): number => { (_exp, _mult = 1) => {
const exp = helpers.number(ctx, "exp", _exp); const exp = helpers.number(ctx, "exp", _exp);
const mult = helpers.number(ctx, "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) =>
(_skill: unknown, _mult: unknown = 1): number => { (_skill, _mult = 1) => {
const skill = helpers.number(ctx, "skill", _skill); const skill = helpers.number(ctx, "skill", _skill);
const mult = helpers.number(ctx, "mult", _mult); const mult = helpers.number(ctx, "mult", _mult);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
@ -167,33 +155,27 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
}, },
}, },
hacking: { hacking: {
hackChance: hackChance: (ctx) => (_server, _player) => {
(ctx: NetscriptContext) =>
(_server: unknown, _player: unknown): number => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateHackingChance(server, player); return calculateHackingChance(server, player);
}, },
hackExp: hackExp: (ctx) => (_server, _player) => {
(ctx: NetscriptContext) =>
(_server: unknown, _player: unknown): number => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateHackingExpGain(server, player); return calculateHackingExpGain(server, player);
}, },
hackPercent: hackPercent: (ctx) => (_server, _player) => {
(ctx: NetscriptContext) =>
(_server: unknown, _player: unknown): number => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculatePercentMoneyHacked(server, player); return calculatePercentMoneyHacked(server, player);
}, },
growPercent: growPercent:
(ctx: NetscriptContext) => (ctx) =>
(_server: unknown, _threads: unknown, _player: unknown, _cores: unknown = 1): number => { (_server, _threads, _player, _cores = 1) => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
const threads = helpers.number(ctx, "threads", _threads); const threads = helpers.number(ctx, "threads", _threads);
@ -201,25 +183,19 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateServerGrowth(server, threads, player, cores); return calculateServerGrowth(server, threads, player, cores);
}, },
hackTime: hackTime: (ctx) => (_server, _player) => {
(ctx: NetscriptContext) =>
(_server: unknown, _player: unknown): number => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateHackingTime(server, player) * 1000; return calculateHackingTime(server, player) * 1000;
}, },
growTime: growTime: (ctx) => (_server, _player) => {
(ctx: NetscriptContext) =>
(_server: unknown, _player: unknown): number => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateGrowTime(server, player) * 1000; return calculateGrowTime(server, player) * 1000;
}, },
weakenTime: weakenTime: (ctx) => (_server, _player) => {
(ctx: NetscriptContext) =>
(_server: unknown, _player: unknown): number => {
const server = helpers.server(ctx, _server); const server = helpers.server(ctx, _server);
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
@ -228,8 +204,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
}, },
hacknetNodes: { hacknetNodes: {
moneyGainRate: moneyGainRate:
(ctx: NetscriptContext) => (ctx) =>
(_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number => { (_level, _ram, _cores, _mult = 1) => {
const level = helpers.number(ctx, "level", _level); const level = helpers.number(ctx, "level", _level);
const ram = helpers.number(ctx, "ram", _ram); const ram = helpers.number(ctx, "ram", _ram);
const cores = helpers.number(ctx, "cores", _cores); const cores = helpers.number(ctx, "cores", _cores);
@ -238,8 +214,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return calculateMoneyGainRate(level, ram, cores, mult); return calculateMoneyGainRate(level, ram, cores, mult);
}, },
levelUpgradeCost: levelUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => { (_startingLevel, _extraLevels = 1, _costMult = 1) => {
const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel); const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel);
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels); const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
const costMult = helpers.number(ctx, "costMult", _costMult); const costMult = helpers.number(ctx, "costMult", _costMult);
@ -247,8 +223,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult); return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
}, },
ramUpgradeCost: ramUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => { (_startingRam, _extraLevels = 1, _costMult = 1) => {
const startingRam = helpers.number(ctx, "startingRam", _startingRam); const startingRam = helpers.number(ctx, "startingRam", _startingRam);
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels); const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
const costMult = helpers.number(ctx, "costMult", _costMult); const costMult = helpers.number(ctx, "costMult", _costMult);
@ -256,31 +232,29 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return calculateRamUpgradeCost(startingRam, extraLevels, costMult); return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
}, },
coreUpgradeCost: coreUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => { (_startingCore, _extraCores = 1, _costMult = 1) => {
const startingCore = helpers.number(ctx, "startingCore", _startingCore); const startingCore = helpers.number(ctx, "startingCore", _startingCore);
const extraCores = helpers.number(ctx, "extraCores", _extraCores); const extraCores = helpers.number(ctx, "extraCores", _extraCores);
const costMult = helpers.number(ctx, "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) => (_n, _mult) => {
(ctx: NetscriptContext) =>
(_n: unknown, _mult: unknown): number => {
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const mult = helpers.number(ctx, "mult", _mult); const mult = helpers.number(ctx, "mult", _mult);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateNodeCost(n, mult); return calculateNodeCost(n, mult);
}, },
constants: (ctx: NetscriptContext) => (): DefHacknetNodeConstants => { constants: (ctx) => () => {
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return Object.assign({}, HacknetNodeConstants); return Object.assign({}, HacknetNodeConstants);
}, },
}, },
hacknetServers: { hacknetServers: {
hashGainRate: hashGainRate:
(ctx: NetscriptContext) => (ctx) =>
(_level: unknown, _ramUsed: unknown, _maxRam: unknown, _cores: unknown, _mult: unknown = 1): number => { (_level, _ramUsed, _maxRam, _cores, _mult = 1) => {
const level = helpers.number(ctx, "level", _level); const level = helpers.number(ctx, "level", _level);
const ramUsed = helpers.number(ctx, "ramUsed", _ramUsed); const ramUsed = helpers.number(ctx, "ramUsed", _ramUsed);
const maxRam = helpers.number(ctx, "maxRam", _maxRam); const maxRam = helpers.number(ctx, "maxRam", _maxRam);
@ -290,8 +264,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult); return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
}, },
levelUpgradeCost: levelUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => { (_startingLevel, _extraLevels = 1, _costMult = 1) => {
const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel); const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel);
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels); const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
const costMult = helpers.number(ctx, "costMult", _costMult); const costMult = helpers.number(ctx, "costMult", _costMult);
@ -299,8 +273,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult); return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
}, },
ramUpgradeCost: ramUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => { (_startingRam, _extraLevels = 1, _costMult = 1) => {
const startingRam = helpers.number(ctx, "startingRam", _startingRam); const startingRam = helpers.number(ctx, "startingRam", _startingRam);
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels); const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
const costMult = helpers.number(ctx, "costMult", _costMult); const costMult = helpers.number(ctx, "costMult", _costMult);
@ -308,8 +282,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult); return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
}, },
coreUpgradeCost: coreUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => { (_startingCore, _extraCores = 1, _costMult = 1) => {
const startingCore = helpers.number(ctx, "startingCore", _startingCore); const startingCore = helpers.number(ctx, "startingCore", _startingCore);
const extraCores = helpers.number(ctx, "extraCores", _extraCores); const extraCores = helpers.number(ctx, "extraCores", _extraCores);
const costMult = helpers.number(ctx, "costMult", _costMult); const costMult = helpers.number(ctx, "costMult", _costMult);
@ -317,16 +291,14 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult); return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
}, },
cacheUpgradeCost: cacheUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_startingCache: unknown, _extraCache: unknown = 1): number => { (_startingCache, _extraCache = 1) => {
const startingCache = helpers.number(ctx, "startingCache", _startingCache); const startingCache = helpers.number(ctx, "startingCache", _startingCache);
const extraCache = helpers.number(ctx, "extraCache", _extraCache); const extraCache = helpers.number(ctx, "extraCache", _extraCache);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return HScalculateCacheUpgradeCost(startingCache, extraCache); return HScalculateCacheUpgradeCost(startingCache, extraCache);
}, },
hashUpgradeCost: hashUpgradeCost: (ctx) => (_upgName, _level) => {
(ctx: NetscriptContext) =>
(_upgName: unknown, _level: unknown): number => {
const upgName = helpers.string(ctx, "upgName", _upgName); const upgName = helpers.string(ctx, "upgName", _upgName);
const level = helpers.number(ctx, "level", _level); const level = helpers.number(ctx, "level", _level);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
@ -337,88 +309,70 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
return upg.getCost(level); return upg.getCost(level);
}, },
hacknetServerCost: hacknetServerCost:
(ctx: NetscriptContext) => (ctx) =>
(_n: unknown, _mult: unknown = 1): number => { (_n, _mult = 1) => {
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const mult = helpers.number(ctx, "mult", _mult); const mult = helpers.number(ctx, "mult", _mult);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return HScalculateServerCost(n, mult); return HScalculateServerCost(n, mult);
}, },
constants: (ctx: NetscriptContext) => (): DefHacknetServerConstants => { constants: (ctx) => () => {
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return Object.assign({}, HacknetServerConstants); return Object.assign({}, HacknetServerConstants);
}, },
}, },
gang: { gang: {
wantedPenalty: wantedPenalty: (ctx) => (_gang) => {
(ctx: NetscriptContext) =>
(_gang: unknown): number => {
const gang = helpers.gang(ctx, _gang); const gang = helpers.gang(ctx, _gang);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateWantedPenalty(gang); return calculateWantedPenalty(gang);
}, },
respectGain: respectGain: (ctx) => (_gang, _member, _task) => {
(ctx: NetscriptContext) =>
(_gang: unknown, _member: unknown, _task: unknown): number => {
const gang = helpers.gang(ctx, _gang); const gang = helpers.gang(ctx, _gang);
const member = helpers.gangMember(ctx, _member); const member = helpers.gangMember(ctx, _member);
const task = helpers.gangTask(ctx, _task); const task = helpers.gangTask(ctx, _task);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateRespectGain(gang, member, task); return calculateRespectGain(gang, member, task);
}, },
wantedLevelGain: wantedLevelGain: (ctx) => (_gang, _member, _task) => {
(ctx: NetscriptContext) =>
(_gang: unknown, _member: unknown, _task: unknown): number => {
const gang = helpers.gang(ctx, _gang); const gang = helpers.gang(ctx, _gang);
const member = helpers.gangMember(ctx, _member); const member = helpers.gangMember(ctx, _member);
const task = helpers.gangTask(ctx, _task); const task = helpers.gangTask(ctx, _task);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateWantedLevelGain(gang, member, task); return calculateWantedLevelGain(gang, member, task);
}, },
moneyGain: moneyGain: (ctx) => (_gang, _member, _task) => {
(ctx: NetscriptContext) =>
(_gang: unknown, _member: unknown, _task: unknown): number => {
const gang = helpers.gang(ctx, _gang); const gang = helpers.gang(ctx, _gang);
const member = helpers.gangMember(ctx, _member); const member = helpers.gangMember(ctx, _member);
const task = helpers.gangTask(ctx, _task); const task = helpers.gangTask(ctx, _task);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateMoneyGain(gang, member, task); return calculateMoneyGain(gang, member, task);
}, },
ascensionPointsGain: ascensionPointsGain: (ctx) => (_exp) => {
(ctx: NetscriptContext) =>
(_exp: unknown): number => {
const exp = helpers.number(ctx, "exp", _exp); const exp = helpers.number(ctx, "exp", _exp);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateAscensionPointsGain(exp); return calculateAscensionPointsGain(exp);
}, },
ascensionMultiplier: ascensionMultiplier: (ctx) => (_points) => {
(ctx: NetscriptContext) =>
(_points: unknown): number => {
const points = helpers.number(ctx, "points", _points); const points = helpers.number(ctx, "points", _points);
checkFormulasAccess(ctx); checkFormulasAccess(ctx);
return calculateAscensionMult(points); return calculateAscensionMult(points);
}, },
}, },
work: { work: {
crimeGains: crimeGains: (ctx) => (_crimeType) => {
(ctx: NetscriptContext) =>
(_crimeType: unknown): WorkStats => {
const crimeType = helpers.string(ctx, "crimeType", _crimeType); const crimeType = helpers.string(ctx, "crimeType", _crimeType);
const crime = Object.values(Crimes).find((c) => String(c.type) === crimeType); const crime = Object.values(Crimes).find((c) => String(c.type) === crimeType);
if (!crime) throw new Error(`Invalid crime type: ${crimeType}`); if (!crime) throw new Error(`Invalid crime type: ${crimeType}`);
return calculateCrimeWorkStats(crime); return calculateCrimeWorkStats(crime);
}, },
classGains: classGains: (ctx) => (_person, _classType, _locationName) => {
(ctx: NetscriptContext) =>
(_person: unknown, _classType: unknown, _locationName: unknown): WorkStats => {
const person = helpers.player(ctx, _person); const person = helpers.player(ctx, _person);
const classType = helpers.string(ctx, "classType", _classType); const classType = helpers.string(ctx, "classType", _classType);
const locationName = helpers.string(ctx, "locationName", _locationName); const locationName = helpers.string(ctx, "locationName", _locationName);
return calculateClassEarnings(person, classType as ClassType, locationName as LocationName); return calculateClassEarnings(person, classType as ClassType, locationName as LocationName);
}, },
factionGains: factionGains: (ctx) => (_player, _workType, _favor) => {
(ctx: NetscriptContext) =>
(_player: unknown, _workType: unknown, _favor: unknown): WorkStats => {
const player = helpers.player(ctx, _player); const player = helpers.player(ctx, _player);
const workType = helpers.string(ctx, "_workType", _workType) as FactionWorkType; const workType = helpers.string(ctx, "_workType", _workType) as FactionWorkType;
const favor = helpers.number(ctx, "favor", _favor); const favor = helpers.number(ctx, "favor", _favor);
@ -427,7 +381,7 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
exp.reputation = rep; exp.reputation = rep;
return exp; return exp;
}, },
// companyGains: (ctx: NetscriptContext) =>_player: unknown (): WorkStats { // companyGains: (ctx) => (_player) {
// const player = helpers.player(ctx, _player); // const player = helpers.player(ctx, _player);
// }, // },

@ -9,16 +9,7 @@ import { GangMember } from "../Gang/GangMember";
import { GangMemberTask } from "../Gang/GangMemberTask"; import { GangMemberTask } from "../Gang/GangMemberTask";
import { helpers } from "../Netscript/NetscriptHelpers"; import { helpers } from "../Netscript/NetscriptHelpers";
import { import { Gang as IGang, EquipmentStats, GangOtherInfoObject } from "../ScriptEditor/NetscriptDefinitions";
Gang as IGang,
GangGenInfo,
GangOtherInfo,
GangMemberInfo,
GangMemberAscension,
EquipmentStats,
GangTaskStats,
GangOtherInfoObject,
} from "../ScriptEditor/NetscriptDefinitions";
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
export function NetscriptGang(): InternalAPI<IGang> { export function NetscriptGang(): InternalAPI<IGang> {
@ -44,9 +35,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
}; };
return { return {
createGang: createGang: (ctx) => (_faction) => {
(ctx: NetscriptContext) =>
(_faction: unknown): boolean => {
const faction = helpers.string(ctx, "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
@ -58,14 +47,14 @@ export function NetscriptGang(): InternalAPI<IGang> {
Player.startGang(faction, isHacking); Player.startGang(faction, isHacking);
return true; return true;
}, },
inGang: () => (): boolean => { inGang: () => () => {
return Player.gang ? true : false; return Player.gang ? true : false;
}, },
getMemberNames: (ctx: NetscriptContext) => (): string[] => { getMemberNames: (ctx) => () => {
const gang = getGang(ctx); const gang = getGang(ctx);
return gang.members.map((member) => member.name); return gang.members.map((member) => member.name);
}, },
getGangInformation: (ctx: NetscriptContext) => (): GangGenInfo => { getGangInformation: (ctx) => () => {
const gang = getGang(ctx); const gang = getGang(ctx);
return { return {
faction: gang.facName, faction: gang.facName,
@ -82,7 +71,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
wantedPenalty: gang.getWantedPenalty(), wantedPenalty: gang.getWantedPenalty(),
}; };
}, },
getOtherGangInformation: (ctx: NetscriptContext) => (): GangOtherInfo => { getOtherGangInformation: (ctx) => () => {
getGang(ctx); getGang(ctx);
const cpy: Record<string, GangOtherInfoObject> = {}; const cpy: Record<string, GangOtherInfoObject> = {};
for (const gang of Object.keys(AllGangs)) { for (const gang of Object.keys(AllGangs)) {
@ -91,9 +80,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
return cpy; return cpy;
}, },
getMemberInformation: getMemberInformation: (ctx) => (_memberName) => {
(ctx: NetscriptContext) =>
(_memberName: unknown): GangMemberInfo => {
const memberName = helpers.string(ctx, "memberName", _memberName); const memberName = helpers.string(ctx, "memberName", _memberName);
const gang = getGang(ctx); const gang = getGang(ctx);
const member = getGangMember(ctx, memberName); const member = getGangMember(ctx, memberName);
@ -144,13 +131,11 @@ export function NetscriptGang(): InternalAPI<IGang> {
moneyGain: member.calculateMoneyGain(gang), moneyGain: member.calculateMoneyGain(gang),
}; };
}, },
canRecruitMember: (ctx: NetscriptContext) => (): boolean => { canRecruitMember: (ctx) => () => {
const gang = getGang(ctx); const gang = getGang(ctx);
return gang.canRecruitMember(); return gang.canRecruitMember();
}, },
recruitMember: recruitMember: (ctx) => (_memberName) => {
(ctx: NetscriptContext) =>
(_memberName: unknown): boolean => {
const memberName = helpers.string(ctx, "memberName", _memberName); const memberName = helpers.string(ctx, "memberName", _memberName);
const gang = getGang(ctx); const gang = getGang(ctx);
const recruited = gang.recruitMember(memberName); const recruited = gang.recruitMember(memberName);
@ -162,15 +147,13 @@ export function NetscriptGang(): InternalAPI<IGang> {
return recruited; return recruited;
}, },
getTaskNames: (ctx: NetscriptContext) => (): string[] => { getTaskNames: (ctx) => () => {
const gang = getGang(ctx); const gang = getGang(ctx);
const tasks = gang.getAllTaskNames(); const tasks = gang.getAllTaskNames();
tasks.unshift("Unassigned"); tasks.unshift("Unassigned");
return tasks; return tasks;
}, },
setMemberTask: setMemberTask: (ctx) => (_memberName, _taskName) => {
(ctx: NetscriptContext) =>
(_memberName: unknown, _taskName: unknown): boolean => {
const memberName = helpers.string(ctx, "memberName", _memberName); const memberName = helpers.string(ctx, "memberName", _memberName);
const taskName = helpers.string(ctx, "taskName", _taskName); const taskName = helpers.string(ctx, "taskName", _taskName);
const gang = getGang(ctx); const gang = getGang(ctx);
@ -192,16 +175,13 @@ export function NetscriptGang(): InternalAPI<IGang> {
} else { } else {
ctx.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`,
); );
} }
return success; return success;
}, },
getTaskStats: getTaskStats: (ctx) => (_taskName) => {
(ctx: NetscriptContext) =>
(_taskName: unknown): GangTaskStats => {
const taskName = helpers.string(ctx, "taskName", _taskName); const taskName = helpers.string(ctx, "taskName", _taskName);
getGang(ctx); getGang(ctx);
const task = getGangTask(ctx, taskName); const task = getGangTask(ctx, taskName);
@ -209,31 +189,25 @@ export function NetscriptGang(): InternalAPI<IGang> {
copy.territory = Object.assign({}, task.territory); copy.territory = Object.assign({}, task.territory);
return copy; return copy;
}, },
getEquipmentNames: (ctx: NetscriptContext) => (): string[] => { getEquipmentNames: (ctx) => () => {
getGang(ctx); getGang(ctx);
return Object.keys(GangMemberUpgrades); return Object.keys(GangMemberUpgrades);
}, },
getEquipmentCost: getEquipmentCost: (ctx) => (_equipName) => {
(ctx: NetscriptContext) =>
(_equipName: unknown): number => {
const equipName = helpers.string(ctx, "equipName", _equipName); const equipName = helpers.string(ctx, "equipName", _equipName);
const gang = getGang(ctx); const gang = getGang(ctx);
const upg = GangMemberUpgrades[equipName]; const upg = GangMemberUpgrades[equipName];
if (upg === null) return Infinity; if (upg === null) return Infinity;
return gang.getUpgradeCost(upg); return gang.getUpgradeCost(upg);
}, },
getEquipmentType: getEquipmentType: (ctx) => (_equipName) => {
(ctx: NetscriptContext) =>
(_equipName: unknown): string => {
const equipName = helpers.string(ctx, "equipName", _equipName); const equipName = helpers.string(ctx, "equipName", _equipName);
getGang(ctx); getGang(ctx);
const upg = GangMemberUpgrades[equipName]; const upg = GangMemberUpgrades[equipName];
if (upg == null) return ""; if (upg == null) return "";
return upg.getType(); return upg.getType();
}, },
getEquipmentStats: getEquipmentStats: (ctx) => (_equipName) => {
(ctx: NetscriptContext) =>
(_equipName: unknown): EquipmentStats => {
const equipName = helpers.string(ctx, "equipName", _equipName); const equipName = helpers.string(ctx, "equipName", _equipName);
getGang(ctx); getGang(ctx);
const equipment = GangMemberUpgrades[equipName]; const equipment = GangMemberUpgrades[equipName];
@ -241,11 +215,9 @@ export function NetscriptGang(): InternalAPI<IGang> {
throw helpers.makeRuntimeErrorMsg(ctx, `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);
}, },
purchaseEquipment: purchaseEquipment: (ctx) => (_memberName, _equipName) => {
(ctx: NetscriptContext) =>
(_memberName: unknown, _equipName: unknown): boolean => {
const memberName = helpers.string(ctx, "memberName", _memberName); const memberName = helpers.string(ctx, "memberName", _memberName);
const equipName = helpers.string(ctx, "equipName", _equipName); const equipName = helpers.string(ctx, "equipName", _equipName);
getGang(ctx); getGang(ctx);
@ -267,18 +239,14 @@ export function NetscriptGang(): InternalAPI<IGang> {
return res; return res;
}, },
ascendMember: ascendMember: (ctx) => (_memberName) => {
(ctx: NetscriptContext) =>
(_memberName: unknown): GangMemberAscension | undefined => {
const memberName = helpers.string(ctx, "memberName", _memberName); const memberName = helpers.string(ctx, "memberName", _memberName);
const gang = getGang(ctx); const gang = getGang(ctx);
const member = getGangMember(ctx, memberName); const member = getGangMember(ctx, memberName);
if (!member.canAscend()) return; if (!member.canAscend()) return;
return gang.ascendMember(member, ctx.workerScript); return gang.ascendMember(member, ctx.workerScript);
}, },
getAscensionResult: getAscensionResult: (ctx) => (_memberName) => {
(ctx: NetscriptContext) =>
(_memberName: unknown): GangMemberAscension | undefined => {
const memberName = helpers.string(ctx, "memberName", _memberName); const memberName = helpers.string(ctx, "memberName", _memberName);
getGang(ctx); getGang(ctx);
const member = getGangMember(ctx, memberName); const member = getGangMember(ctx, memberName);
@ -288,9 +256,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
...member.getAscensionResults(), ...member.getAscensionResults(),
}; };
}, },
setTerritoryWarfare: setTerritoryWarfare: (ctx) => (_engage) => {
(ctx: NetscriptContext) =>
(_engage: unknown): void => {
const engage = !!_engage; const engage = !!_engage;
const gang = getGang(ctx); const gang = getGang(ctx);
if (engage) { if (engage) {
@ -301,9 +267,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare"); ctx.workerScript.log("gang.setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
} }
}, },
getChanceToWinClash: getChanceToWinClash: (ctx) => (_otherGang) => {
(ctx: NetscriptContext) =>
(_otherGang: unknown): number => {
const otherGang = helpers.string(ctx, "otherGang", _otherGang); const otherGang = helpers.string(ctx, "otherGang", _otherGang);
const gang = getGang(ctx); const gang = getGang(ctx);
if (AllGangs[otherGang] == null) { if (AllGangs[otherGang] == null) {
@ -315,7 +279,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
return playerPower / (otherPower + playerPower); return playerPower / (otherPower + playerPower);
}, },
getBonusTime: (ctx: NetscriptContext) => (): number => { getBonusTime: (ctx) => () => {
const gang = getGang(ctx); const gang = getGang(ctx);
return Math.round(gang.storedCycles / 5) * 1000; return Math.round(gang.storedCycles / 5) * 1000;
}, },

@ -21,9 +21,7 @@ export function NetscriptGrafting(): InternalAPI<IGrafting> {
}; };
return { return {
getAugmentationGraftPrice: getAugmentationGraftPrice: (ctx) => (_augName) => {
(ctx: NetscriptContext) =>
(_augName: unknown): number => {
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
checkGraftingAPIAccess(ctx); checkGraftingAPIAccess(ctx);
if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) { if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
@ -33,9 +31,7 @@ export function NetscriptGrafting(): InternalAPI<IGrafting> {
return graftableAug.cost; return graftableAug.cost;
}, },
getAugmentationGraftTime: getAugmentationGraftTime: (ctx) => (_augName) => {
(ctx: NetscriptContext) =>
(_augName: string): number => {
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
checkGraftingAPIAccess(ctx); checkGraftingAPIAccess(ctx);
if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) { if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
@ -45,15 +41,15 @@ export function NetscriptGrafting(): InternalAPI<IGrafting> {
return calculateGraftingTimeWithBonus(graftableAug); return calculateGraftingTimeWithBonus(graftableAug);
}, },
getGraftableAugmentations: (ctx: NetscriptContext) => (): string[] => { getGraftableAugmentations: (ctx) => () => {
checkGraftingAPIAccess(ctx); checkGraftingAPIAccess(ctx);
const graftableAugs = getGraftingAvailableAugs(); const graftableAugs = getGraftingAvailableAugs();
return graftableAugs; return graftableAugs;
}, },
graftAugmentation: graftAugmentation:
(ctx: NetscriptContext) => (ctx) =>
(_augName: string, _focus: unknown = true): boolean => { (_augName, _focus = true) => {
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const focus = !!_focus; const focus = !!_focus;
checkGraftingAPIAccess(ctx); checkGraftingAPIAccess(ctx);

@ -50,28 +50,26 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
}; };
return { return {
numNodes: () => (): number => { numNodes: () => () => {
return player.hacknetNodes.length; return player.hacknetNodes.length;
}, },
maxNumNodes: () => (): number => { maxNumNodes: () => () => {
if (hasHacknetServers()) { if (hasHacknetServers()) {
return HacknetServerConstants.MaxServers; return HacknetServerConstants.MaxServers;
} }
return Infinity; return Infinity;
}, },
purchaseNode: () => (): number => { purchaseNode: () => () => {
return purchaseHacknet(); return purchaseHacknet();
}, },
getPurchaseNodeCost: () => (): number => { getPurchaseNodeCost: () => () => {
if (hasHacknetServers()) { if (hasHacknetServers()) {
return getCostOfNextHacknetServer(); return getCostOfNextHacknetServer();
} else { } else {
return getCostOfNextHacknetNode(); return getCostOfNextHacknetNode();
} }
}, },
getNodeStats: getNodeStats: (ctx) => (_i) => {
(ctx: NetscriptContext) =>
(_i: unknown): NodeStats => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
const hasUpgraded = hasHacknetServers(); const hasUpgraded = hasHacknetServers();
@ -94,32 +92,32 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
return res; return res;
}, },
upgradeLevel: upgradeLevel:
(ctx: NetscriptContext) => (ctx) =>
(_i: unknown, _n: unknown = 1): boolean => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return purchaseLevelUpgrade(node, n); return purchaseLevelUpgrade(node, n);
}, },
upgradeRam: upgradeRam:
(ctx: NetscriptContext) => (ctx) =>
(_i: unknown, _n: unknown = 1): boolean => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return purchaseRamUpgrade(node, n); return purchaseRamUpgrade(node, n);
}, },
upgradeCore: upgradeCore:
(ctx: NetscriptContext) => (ctx) =>
(_i: unknown, _n: unknown = 1): boolean => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return purchaseCoreUpgrade(node, n); return purchaseCoreUpgrade(node, n);
}, },
upgradeCache: upgradeCache:
(ctx: NetscriptContext) => (ctx) =>
(_i: unknown, _n: unknown = 1): boolean => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
@ -137,32 +135,32 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
return res; return res;
}, },
getLevelUpgradeCost: getLevelUpgradeCost:
(ctx: NetscriptContext) => (ctx) =>
(_i: unknown, _n: unknown = 1): number => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "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) =>
(_i: unknown, _n: unknown = 1): number => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "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) =>
(_i: unknown, _n: unknown = 1): number => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "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) =>
(_i: unknown, _n: unknown = 1): number => { (_i, _n = 1) => {
const i = helpers.number(ctx, "i", _i); const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n); const n = helpers.number(ctx, "n", _n);
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
@ -175,21 +173,21 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
} }
return node.calculateCacheUpgradeCost(n); return node.calculateCacheUpgradeCost(n);
}, },
numHashes: () => (): number => { numHashes: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 0; return 0;
} }
return player.hashManager.hashes; return player.hashManager.hashes;
}, },
hashCapacity: () => (): number => { hashCapacity: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 0; return 0;
} }
return player.hashManager.capacity; return player.hashManager.capacity;
}, },
hashCost: hashCost:
(ctx: NetscriptContext) => (ctx) =>
(_upgName: unknown, _count: unknown = 1): number => { (_upgName, _count = 1) => {
const upgName = helpers.string(ctx, "upgName", _upgName); const upgName = helpers.string(ctx, "upgName", _upgName);
const count = helpers.number(ctx, "count", _count); const count = helpers.number(ctx, "count", _count);
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
@ -199,8 +197,8 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
return player.hashManager.getUpgradeCost(upgName, count); return player.hashManager.getUpgradeCost(upgName, count);
}, },
spendHashes: spendHashes:
(ctx: NetscriptContext) => (ctx) =>
(_upgName: unknown, _upgTarget: unknown = "", _count: unknown = 1): boolean => { (_upgName, _upgTarget = "", _count = 1) => {
const upgName = helpers.string(ctx, "upgName", _upgName); const upgName = helpers.string(ctx, "upgName", _upgName);
const upgTarget = helpers.string(ctx, "upgTarget", _upgTarget); const upgTarget = helpers.string(ctx, "upgTarget", _upgTarget);
const count = helpers.number(ctx, "count", _count); const count = helpers.number(ctx, "count", _count);
@ -209,15 +207,13 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
} }
return purchaseHashUpgrade(upgName, upgTarget, count); return purchaseHashUpgrade(upgName, upgTarget, count);
}, },
getHashUpgrades: () => (): string[] => { getHashUpgrades: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return []; return [];
} }
return Object.values(HashUpgrades).map((upgrade: HashUpgrade) => upgrade.name); return Object.values(HashUpgrades).map((upgrade: HashUpgrade) => upgrade.name);
}, },
getHashUpgradeLevel: getHashUpgradeLevel: (ctx) => (_upgName) => {
(ctx: NetscriptContext) =>
(_upgName: unknown): number => {
const upgName = helpers.string(ctx, "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) {
@ -225,13 +221,13 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
} }
return level; return level;
}, },
getStudyMult: () => (): number => { getStudyMult: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 1; return 1;
} }
return player.hashManager.getStudyMult(); return player.hashManager.getStudyMult();
}, },
getTrainingMult: () => (): number => { getTrainingMult: () => () => {
if (!hasHacknetServers()) { if (!hasHacknetServers()) {
return 1; return 1;
} }

@ -1,8 +1,4 @@
import { import { Infiltration as IInfiltration, InfiltrationLocation } from "../ScriptEditor/NetscriptDefinitions";
Infiltration as IInfiltration,
InfiltrationLocation,
PossibleInfiltrationLocation,
} from "../ScriptEditor/NetscriptDefinitions";
import { Location } from "../Locations/Location"; import { Location } from "../Locations/Location";
import { Locations } from "../Locations/Locations"; import { Locations } from "../Locations/Locations";
import { calculateDifficulty, calculateReward } from "../Infiltration/formulas/game"; import { calculateDifficulty, calculateReward } from "../Infiltration/formulas/game";
@ -44,15 +40,13 @@ export function NetscriptInfiltration(): InternalAPI<IInfiltration> {
}; };
}; };
return { return {
getPossibleLocations: () => (): PossibleInfiltrationLocation[] => { getPossibleLocations: () => () => {
return getLocationsWithInfiltrations.map((l) => ({ return getLocationsWithInfiltrations.map((l) => ({
city: l.city ?? "", city: l.city ?? "",
name: String(l.name), name: String(l.name),
})); }));
}, },
getInfiltration: getInfiltration: (ctx) => (_location) => {
(ctx: NetscriptContext) =>
(_location: unknown): InfiltrationLocation => {
const location = helpers.string(ctx, "location", _location); const location = helpers.string(ctx, "location", _location);
return calculateInfiltrationData(ctx, location); return calculateInfiltrationData(ctx, location);
}, },

@ -11,12 +11,7 @@ import { isString } from "../utils/helpers/isString";
import { RunningScript } from "../Script/RunningScript"; import { RunningScript } from "../Script/RunningScript";
import { calculateAchievements } from "../Achievements/Achievements"; import { calculateAchievements } from "../Achievements/Achievements";
import { import { Singularity as ISingularity } from "../ScriptEditor/NetscriptDefinitions";
Multipliers,
CrimeStats,
Singularity as ISingularity,
SourceFileLvl,
} from "../ScriptEditor/NetscriptDefinitions";
import { findCrime } from "../Crime/CrimeHelpers"; import { findCrime } from "../Crime/CrimeHelpers";
import { CompanyPositions } from "../Company/CompanyPositions"; import { CompanyPositions } from "../Company/CompanyPositions";
@ -79,7 +74,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return company; return company;
}; };
const runAfterReset = function (cbScript: string | null = null): void { const runAfterReset = function (cbScript: string | null = null) {
//Run a script after reset //Run a script after reset
if (!cbScript) return; if (!cbScript) return;
const home = Player.getHomeComputer(); const home = Player.getHomeComputer();
@ -98,11 +93,10 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
}; };
return { return {
getOwnedAugmentations: (ctx: NetscriptContext) => getOwnedAugmentations: (ctx) => (_purchased) => {
function (_purchased: unknown = false): string[] {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const purchased = !!_purchased; const purchased = !!_purchased;
const res = []; const res: string[] = [];
for (let i = 0; i < Player.augmentations.length; ++i) { for (let i = 0; i < Player.augmentations.length; ++i) {
res.push(Player.augmentations[i].name); res.push(Player.augmentations[i].name);
} }
@ -113,69 +107,56 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
return res; return res;
}, },
getOwnedSourceFiles: () => (): SourceFileLvl[] => { getOwnedSourceFiles: () => () => {
const res: SourceFileLvl[] = []; return Player.sourceFiles.map((sf) => {
for (let i = 0; i < Player.sourceFiles.length; ++i) { return { n: sf.n, lvl: sf.lvl };
res.push({
n: Player.sourceFiles[i].n,
lvl: Player.sourceFiles[i].lvl,
}); });
}
return res;
}, },
getAugmentationsFromFaction: (ctx: NetscriptContext) => getAugmentationsFromFaction: (ctx) => (_facName) => {
function (_facName: unknown): string[] {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const faction = getFaction(ctx, facName); const faction = getFaction(ctx, facName);
return getFactionAugmentationsFiltered(faction); return getFactionAugmentationsFiltered(faction);
}, },
getAugmentationCost: (ctx: NetscriptContext) => getAugmentationCost: (ctx) => (_augName) => {
function (_augName: unknown): [number, number] {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug = getAugmentation(ctx, augName); const aug = getAugmentation(ctx, augName);
const costs = aug.getCost(); const costs = aug.getCost();
return [costs.repCost, costs.moneyCost]; return [costs.repCost, costs.moneyCost];
}, },
getAugmentationPrereq: (ctx: NetscriptContext) => getAugmentationPrereq: (ctx) => (_augName) => {
function (_augName: unknown): string[] {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug = getAugmentation(ctx, augName); const aug = getAugmentation(ctx, augName);
return aug.prereqs.slice(); return aug.prereqs.slice();
}, },
getAugmentationBasePrice: (ctx: NetscriptContext) => getAugmentationBasePrice: (ctx) => (_augName) => {
function (_augName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug = getAugmentation(ctx, augName); const aug = getAugmentation(ctx, augName);
return aug.baseCost * BitNodeMultipliers.AugmentationMoneyCost; return aug.baseCost * BitNodeMultipliers.AugmentationMoneyCost;
}, },
getAugmentationPrice: (ctx: NetscriptContext) => getAugmentationPrice: (ctx) => (_augName) => {
function (_augName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug = getAugmentation(ctx, augName); const aug = getAugmentation(ctx, augName);
return aug.getCost().moneyCost; return aug.getCost().moneyCost;
}, },
getAugmentationRepReq: (ctx: NetscriptContext) => getAugmentationRepReq: (ctx) => (_augName) => {
function (_augName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug = getAugmentation(ctx, augName); const aug = getAugmentation(ctx, augName);
return aug.getCost().repCost; return aug.getCost().repCost;
}, },
getAugmentationStats: (ctx: NetscriptContext) => getAugmentationStats: (ctx) => (_augName) => {
function (_augName: unknown): Multipliers {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug = getAugmentation(ctx, augName); const aug = getAugmentation(ctx, augName);
return Object.assign({}, aug.mults); return Object.assign({}, aug.mults);
}, },
purchaseAugmentation: (ctx: NetscriptContext) => purchaseAugmentation: (ctx) => (_facName, _augName) => {
function (_facName: unknown, _augName: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
@ -224,10 +205,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return false; return false;
} }
}, },
softReset: (ctx: NetscriptContext) => softReset: (ctx) => (_cbScript) => {
function (_cbScript: unknown = ""): void {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const cbScript = helpers.string(ctx, "cbScript", _cbScript); const cbScript = _cbScript ? helpers.string(ctx, "cbScript", _cbScript) : "";
helpers.log(ctx, () => "Soft resetting. This will cause this script to be killed"); helpers.log(ctx, () => "Soft resetting. This will cause this script to be killed");
setTimeout(() => { setTimeout(() => {
@ -237,10 +217,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
killWorkerScript(ctx.workerScript); killWorkerScript(ctx.workerScript);
}, },
installAugmentations: (ctx: NetscriptContext) => installAugmentations: (ctx) => (_cbScript) => {
function (_cbScript: unknown = ""): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const cbScript = helpers.string(ctx, "cbScript", _cbScript); const cbScript = _cbScript ? helpers.string(ctx, "cbScript", _cbScript) : "";
if (Player.queuedAugmentations.length === 0) { if (Player.queuedAugmentations.length === 0) {
helpers.log(ctx, () => "You do not have any Augmentations to be installed."); helpers.log(ctx, () => "You do not have any Augmentations to be installed.");
@ -257,8 +236,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return true; return true;
}, },
goToLocation: (ctx: NetscriptContext) => goToLocation: (ctx) => (_locationName) => {
function (_locationName: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const locationName = helpers.string(ctx, "locationName", _locationName); const locationName = helpers.string(ctx, "locationName", _locationName);
const location = Object.values(Locations).find((l) => l.name === locationName); const location = Object.values(Locations).find((l) => l.name === locationName);
@ -280,8 +258,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000); Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000);
return true; return true;
}, },
universityCourse: (ctx: NetscriptContext) => universityCourse:
function (_universityName: unknown, _className: unknown, _focus: unknown = true): boolean { (ctx) =>
(_universityName, _className, _focus = true) => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const universityName = helpers.string(ctx, "universityName", _universityName); const universityName = helpers.string(ctx, "universityName", _universityName);
const className = helpers.string(ctx, "className", _className); const className = helpers.string(ctx, "className", _className);
@ -366,8 +345,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return true; return true;
}, },
gymWorkout: (ctx: NetscriptContext) => gymWorkout:
function (_gymName: unknown, _stat: unknown, _focus: unknown = true): boolean { (ctx) =>
(_gymName, _stat, _focus = true) => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const gymName = helpers.string(ctx, "gymName", _gymName); const gymName = helpers.string(ctx, "gymName", _gymName);
const stat = helpers.string(ctx, "stat", _stat); const stat = helpers.string(ctx, "stat", _stat);
@ -475,8 +455,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return true; return true;
}, },
travelToCity: (ctx: NetscriptContext) => travelToCity: (ctx) => (_cityName) => {
function (_cityName: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const cityName = helpers.city(ctx, "cityName", _cityName); const cityName = helpers.city(ctx, "cityName", _cityName);
@ -501,8 +480,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
}, },
purchaseTor: (ctx: NetscriptContext) => purchaseTor: (ctx) => () => {
function (): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
if (Player.hasTorRouter()) { if (Player.hasTorRouter()) {
@ -525,8 +503,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
helpers.log(ctx, () => "You have purchased a Tor router!"); helpers.log(ctx, () => "You have purchased a Tor router!");
return true; return true;
}, },
purchaseProgram: (ctx: NetscriptContext) => purchaseProgram: (ctx) => (_programName) => {
function (_programName: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const programName = helpers.string(ctx, "programName", _programName).toLowerCase(); const programName = helpers.string(ctx, "programName", _programName).toLowerCase();
@ -568,13 +545,11 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 5000); Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 5000);
return true; return true;
}, },
getCurrentServer: (ctx: NetscriptContext) => getCurrentServer: (ctx) => () => {
function (): string {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
return Player.getCurrentServer().hostname; return Player.getCurrentServer().hostname;
}, },
connect: (ctx: NetscriptContext) => connect: (ctx) => (_hostname) => {
function (_hostname: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const hostname = helpers.string(ctx, "hostname", _hostname); const hostname = helpers.string(ctx, "hostname", _hostname);
if (!hostname) { if (!hostname) {
@ -622,13 +597,12 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
//Failure case //Failure case
return false; return false;
}, },
manualHack: (ctx: NetscriptContext) => manualHack: (ctx) => () => {
function (): Promise<number> {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const server = Player.getCurrentServer(); const server = Player.getCurrentServer();
return helpers.hack(ctx, server.hostname, true); return helpers.hack(ctx, server.hostname, true);
}, },
installBackdoor: (ctx: NetscriptContext) => async (): Promise<void> => { installBackdoor: (ctx) => async (): Promise<void> => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const baseserver = Player.getCurrentServer(); const baseserver = Player.getCurrentServer();
if (!(baseserver instanceof Server)) { if (!(baseserver instanceof Server)) {
@ -660,13 +634,11 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return Promise.resolve(); return Promise.resolve();
}); });
}, },
isFocused: (ctx: NetscriptContext) => isFocused: (ctx) => () => {
function (): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
return Player.focus; return Player.focus;
}, },
setFocus: (ctx: NetscriptContext) => setFocus: (ctx) => (_focus) => {
function (_focus: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const focus = !!_focus; const focus = !!_focus;
if (Player.currentWork === null) { if (Player.currentWork === null) {
@ -684,8 +656,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
return false; return false;
}, },
hospitalize: (ctx: NetscriptContext) => hospitalize: (ctx) => () => {
function (): void {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
if (Player.currentWork || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) { if (Player.currentWork || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
helpers.log(ctx, () => "Cannot go to the hospital because the player is busy."); helpers.log(ctx, () => "Cannot go to the hospital because the player is busy.");
@ -693,20 +664,17 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
Player.hospitalize(); Player.hospitalize();
}, },
isBusy: (ctx: NetscriptContext) => isBusy: (ctx) => () => {
function (): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
return Player.currentWork !== null || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse; return Player.currentWork !== null || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse;
}, },
stopAction: (ctx: NetscriptContext) => stopAction: (ctx) => () => {
function (): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const wasWorking = Player.currentWork !== null; const wasWorking = Player.currentWork !== null;
Player.finishWork(true); Player.finishWork(true);
return wasWorking; return wasWorking;
}, },
upgradeHomeCores: (ctx: NetscriptContext) => upgradeHomeCores: (ctx) => () => {
function (): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
// Check if we're at max cores // Check if we're at max cores
@ -732,14 +700,12 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
); );
return true; return true;
}, },
getUpgradeHomeCoresCost: (ctx: NetscriptContext) => getUpgradeHomeCoresCost: (ctx) => () => {
function (): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
return Player.getUpgradeHomeCoresCost(); return Player.getUpgradeHomeCoresCost();
}, },
upgradeHomeRam: (ctx: NetscriptContext) => upgradeHomeRam: (ctx) => () => {
function (): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
// Check if we're at max RAM // Check if we're at max RAM
@ -768,14 +734,14 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
); );
return true; return true;
}, },
getUpgradeHomeRamCost: (ctx: NetscriptContext) => getUpgradeHomeRamCost: (ctx) => () => {
function (): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
return Player.getUpgradeHomeRamCost(); return Player.getUpgradeHomeRamCost();
}, },
workForCompany: (ctx: NetscriptContext) => workForCompany:
function (_companyName: unknown, _focus: unknown = true): boolean { (ctx) =>
(_companyName, _focus = true) => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const companyName = helpers.string(ctx, "companyName", _companyName); const companyName = helpers.string(ctx, "companyName", _companyName);
const focus = !!_focus; const focus = !!_focus;
@ -818,8 +784,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
helpers.log(ctx, () => `Began working at '${companyName}' with position '${companyPositionName}'`); helpers.log(ctx, () => `Began working at '${companyName}' with position '${companyPositionName}'`);
return true; return true;
}, },
applyToCompany: (ctx: NetscriptContext) => applyToCompany: (ctx) => (_companyName, _field) => {
function (_companyName: unknown, _field: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const companyName = helpers.string(ctx, "companyName", _companyName); const companyName = helpers.string(ctx, "companyName", _companyName);
const field = helpers.string(ctx, "field", _field); const field = helpers.string(ctx, "field", _field);
@ -887,41 +852,35 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
return res; return res;
}, },
quitJob: (ctx: NetscriptContext) => quitJob: (ctx) => (_companyName) => {
function (_companyName: unknown): void {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const companyName = helpers.string(ctx, "companyName", _companyName); const companyName = helpers.string(ctx, "companyName", _companyName);
Player.quitJob(companyName); Player.quitJob(companyName);
}, },
getCompanyRep: (ctx: NetscriptContext) => getCompanyRep: (ctx) => (_companyName) => {
function (_companyName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const companyName = helpers.string(ctx, "companyName", _companyName); const companyName = helpers.string(ctx, "companyName", _companyName);
const company = getCompany(ctx, companyName); const company = getCompany(ctx, companyName);
return company.playerReputation; return company.playerReputation;
}, },
getCompanyFavor: (ctx: NetscriptContext) => getCompanyFavor: (ctx) => (_companyName) => {
function (_companyName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const companyName = helpers.string(ctx, "companyName", _companyName); const companyName = helpers.string(ctx, "companyName", _companyName);
const company = getCompany(ctx, companyName); const company = getCompany(ctx, companyName);
return company.favor; return company.favor;
}, },
getCompanyFavorGain: (ctx: NetscriptContext) => getCompanyFavorGain: (ctx) => (_companyName) => {
function (_companyName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const companyName = helpers.string(ctx, "companyName", _companyName); const companyName = helpers.string(ctx, "companyName", _companyName);
const company = getCompany(ctx, companyName); const company = getCompany(ctx, companyName);
return company.getFavorGain(); return company.getFavorGain();
}, },
checkFactionInvitations: (ctx: NetscriptContext) => checkFactionInvitations: (ctx) => () => {
function (): string[] {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
// Make a copy of player.factionInvitations // Make a copy of player.factionInvitations
return Player.factionInvitations.slice(); return Player.factionInvitations.slice();
}, },
joinFaction: (ctx: NetscriptContext) => joinFaction: (ctx) => (_facName) => {
function (_facName: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
getFaction(ctx, facName); getFaction(ctx, facName);
@ -944,8 +903,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
helpers.log(ctx, () => `Joined the '${facName}' faction.`); helpers.log(ctx, () => `Joined the '${facName}' faction.`);
return true; return true;
}, },
workForFaction: (ctx: NetscriptContext) => workForFaction:
function (_facName: unknown, _type: unknown, _focus: unknown = true): boolean { (ctx) =>
(_facName, _type, _focus = true) => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const type = helpers.string(ctx, "type", _type); const type = helpers.string(ctx, "type", _type);
@ -1040,29 +1000,25 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return false; return false;
} }
}, },
getFactionRep: (ctx: NetscriptContext) => getFactionRep: (ctx) => (_facName) => {
function (_facName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const faction = getFaction(ctx, facName); const faction = getFaction(ctx, facName);
return faction.playerReputation; return faction.playerReputation;
}, },
getFactionFavor: (ctx: NetscriptContext) => getFactionFavor: (ctx) => (_facName) => {
function (_facName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const faction = getFaction(ctx, facName); const faction = getFaction(ctx, facName);
return faction.favor; return faction.favor;
}, },
getFactionFavorGain: (ctx: NetscriptContext) => getFactionFavorGain: (ctx) => (_facName) => {
function (_facName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const faction = getFaction(ctx, facName); const faction = getFaction(ctx, facName);
return faction.getFavorGain(); return faction.getFavorGain();
}, },
donateToFaction: (ctx: NetscriptContext) => donateToFaction: (ctx) => (_facName, _amt) => {
function (_facName: unknown, _amt: unknown): boolean {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const facName = helpers.string(ctx, "facName", _facName); const facName = helpers.string(ctx, "facName", _facName);
const amt = helpers.number(ctx, "amt", _amt); const amt = helpers.number(ctx, "amt", _amt);
@ -1111,8 +1067,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
); );
return true; return true;
}, },
createProgram: (ctx: NetscriptContext) => createProgram:
function (_programName: unknown, _focus: unknown = true): boolean { (ctx) =>
(_programName, _focus = true) => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const programName = helpers.string(ctx, "programName", _programName).toLowerCase(); const programName = helpers.string(ctx, "programName", _programName).toLowerCase();
const focus = !!_focus; const focus = !!_focus;
@ -1158,8 +1115,9 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
helpers.log(ctx, () => `Began creating program: '${programName}'`); helpers.log(ctx, () => `Began creating program: '${programName}'`);
return true; return true;
}, },
commitCrime: (ctx: NetscriptContext) => commitCrime:
function (_crimeRoughName: unknown, _focus: unknown = true): number { (ctx) =>
(_crimeRoughName, _focus = true) => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName); const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
const focus = !!_focus; const focus = !!_focus;
@ -1188,8 +1146,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
return crimeTime; return crimeTime;
}, },
getCrimeChance: (ctx: NetscriptContext) => getCrimeChance: (ctx) => (_crimeRoughName) => {
function (_crimeRoughName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName); const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
@ -1200,8 +1157,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return crime.successRate(Player); return crime.successRate(Player);
}, },
getCrimeStats: (ctx: NetscriptContext) => getCrimeStats: (ctx) => (_crimeRoughName) => {
function (_crimeRoughName: unknown): CrimeStats {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName); const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
@ -1224,8 +1180,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
intelligence_exp: crimeStatsWithMultipliers.intExp, intelligence_exp: crimeStatsWithMultipliers.intExp,
}); });
}, },
getDarkwebPrograms: (ctx: NetscriptContext) => getDarkwebPrograms: (ctx) => () => {
function (): string[] {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
// If we don't have Tor, log it and return [] (empty list) // If we don't have Tor, log it and return [] (empty list)
@ -1235,8 +1190,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
} }
return Object.values(DarkWebItems).map((p) => p.program); return Object.values(DarkWebItems).map((p) => p.program);
}, },
getDarkwebProgramCost: (ctx: NetscriptContext) => getDarkwebProgramCost: (ctx) => (_programName) => {
function (_programName: unknown): number {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const programName = helpers.string(ctx, "programName", _programName).toLowerCase(); const programName = helpers.string(ctx, "programName", _programName).toLowerCase();
@ -1269,8 +1223,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
return item.price; return item.price;
}, },
b1tflum3: b1tflum3:
(ctx: NetscriptContext) => (ctx) =>
(_nextBN: unknown, _callbackScript: unknown = ""): void => { (_nextBN, _callbackScript = "") => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const nextBN = helpers.number(ctx, "nextBN", _nextBN); const nextBN = helpers.number(ctx, "nextBN", _nextBN);
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript); const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
@ -1282,20 +1236,20 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
}, 0); }, 0);
}, },
destroyW0r1dD43m0n: destroyW0r1dD43m0n:
(ctx: NetscriptContext) => (ctx) =>
(_nextBN: unknown, _callbackScript: unknown = ""): void => { (_nextBN, _callbackScript = "") => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
const nextBN = helpers.number(ctx, "nextBN", _nextBN); const nextBN = helpers.number(ctx, "nextBN", _nextBN);
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript); const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
const wd = GetServer(SpecialServers.WorldDaemon); const wd = GetServer(SpecialServers.WorldDaemon);
if (!(wd instanceof Server)) throw new Error("WorldDaemon was not a normal server. This is a bug contact dev."); if (!(wd instanceof Server)) throw new Error("WorldDaemon was not a normal server. This is a bug contact dev.");
const hackingRequirements = (): boolean => { const hackingRequirements = () => {
if (Player.skills.hacking < wd.requiredHackingSkill) return false; if (Player.skills.hacking < wd.requiredHackingSkill) return false;
if (!wd.hasAdminRights) return false; if (!wd.hasAdminRights) return false;
return true; return true;
}; };
const bladeburnerRequirements = (): boolean => { const bladeburnerRequirements = () => {
if (!Player.inBladeburner()) return false; if (!Player.inBladeburner()) return false;
if (!Player.bladeburner) return false; if (!Player.bladeburner) return false;
return Player.bladeburner.blackops[BlackOperationNames.OperationDaedalus]; return Player.bladeburner.blackops[BlackOperationNames.OperationDaedalus];
@ -1314,16 +1268,16 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
runAfterReset(callbackScript); runAfterReset(callbackScript);
}, 0); }, 0);
}, },
getCurrentWork: () => (): any | null => { getCurrentWork: () => () => {
if (!Player.currentWork) return null; if (!Player.currentWork) return null;
return Player.currentWork.APICopy(); return Player.currentWork.APICopy();
}, },
exportGame: (ctx: NetscriptContext) => (): void => { exportGame: (ctx) => () => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
onExport(); onExport();
return saveObject.exportGame(); return saveObject.exportGame();
}, },
exportGameBonus: (ctx: NetscriptContext) => (): boolean => { exportGameBonus: (ctx) => () => {
helpers.checkSingularityAccess(ctx); helpers.checkSingularityAccess(ctx);
return canGetBonus(); return canGetBonus();
}, },

@ -4,13 +4,7 @@ import { CityName } from "../Locations/data/CityNames";
import { findCrime } from "../Crime/CrimeHelpers"; import { findCrime } from "../Crime/CrimeHelpers";
import { Augmentation } from "../Augmentation/Augmentation"; import { Augmentation } from "../Augmentation/Augmentation";
import { import { Sleeve as ISleeve, SleeveSkills } from "../ScriptEditor/NetscriptDefinitions";
AugmentPair,
Sleeve as ISleeve,
SleeveInformation,
SleeveSkills,
SleeveTask,
} from "../ScriptEditor/NetscriptDefinitions";
import { checkEnum } from "../utils/helpers/checkEnum"; import { checkEnum } from "../utils/helpers/checkEnum";
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork"; import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork";
@ -19,7 +13,7 @@ import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyW
import { helpers } from "../Netscript/NetscriptHelpers"; import { helpers } from "../Netscript/NetscriptHelpers";
export function NetscriptSleeve(): InternalAPI<ISleeve> { export function NetscriptSleeve(): InternalAPI<ISleeve> {
const checkSleeveAPIAccess = function (ctx: NetscriptContext): void { const checkSleeveAPIAccess = function (ctx: NetscriptContext) {
if (Player.bitNodeN !== 10 && !Player.sourceFileLvl(10)) { if (Player.bitNodeN !== 10 && !Player.sourceFileLvl(10)) {
throw helpers.makeRuntimeErrorMsg( throw helpers.makeRuntimeErrorMsg(
ctx, ctx,
@ -28,7 +22,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
} }
}; };
const checkSleeveNumber = function (ctx: NetscriptContext, sleeveNumber: number): void { const checkSleeveNumber = function (ctx: NetscriptContext, sleeveNumber: number) {
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}`;
helpers.log(ctx, () => msg); helpers.log(ctx, () => msg);
@ -52,29 +46,23 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
}; };
return { return {
getNumSleeves: (ctx: NetscriptContext) => (): number => { getNumSleeves: (ctx) => () => {
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
return Player.sleeves.length; return Player.sleeves.length;
}, },
setToShockRecovery: setToShockRecovery: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
return Player.sleeves[sleeveNumber].shockRecovery(); return Player.sleeves[sleeveNumber].shockRecovery();
}, },
setToSynchronize: setToSynchronize: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
return Player.sleeves[sleeveNumber].synchronize(); return Player.sleeves[sleeveNumber].synchronize();
}, },
setToCommitCrime: setToCommitCrime: (ctx) => (_sleeveNumber, _crimeRoughName) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _crimeRoughName: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const crimeRoughName = helpers.string(ctx, "crimeName", _crimeRoughName); const crimeRoughName = helpers.string(ctx, "crimeName", _crimeRoughName);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
@ -85,9 +73,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
} }
return Player.sleeves[sleeveNumber].commitCrime(crime.name); return Player.sleeves[sleeveNumber].commitCrime(crime.name);
}, },
setToUniversityCourse: setToUniversityCourse: (ctx) => (_sleeveNumber, _universityName, _className) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _universityName: unknown, _className: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const universityName = helpers.string(ctx, "universityName", _universityName); const universityName = helpers.string(ctx, "universityName", _universityName);
const className = helpers.string(ctx, "className", _className); const className = helpers.string(ctx, "className", _className);
@ -95,9 +81,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
return Player.sleeves[sleeveNumber].takeUniversityCourse(universityName, className); return Player.sleeves[sleeveNumber].takeUniversityCourse(universityName, className);
}, },
travel: travel: (ctx) => (_sleeveNumber, _cityName) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _cityName: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const cityName = helpers.string(ctx, "cityName", _cityName); const cityName = helpers.string(ctx, "cityName", _cityName);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
@ -108,9 +92,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city name: '${cityName}'.`); throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city name: '${cityName}'.`);
} }
}, },
setToCompanyWork: setToCompanyWork: (ctx) => (_sleeveNumber, acompanyName) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, acompanyName: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const companyName = helpers.string(ctx, "companyName", acompanyName); const companyName = helpers.string(ctx, "companyName", acompanyName);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
@ -132,9 +114,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
return Player.sleeves[sleeveNumber].workForCompany(companyName); return Player.sleeves[sleeveNumber].workForCompany(companyName);
}, },
setToFactionWork: setToFactionWork: (ctx) => (_sleeveNumber, _factionName, _workType) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _factionName: unknown, _workType: unknown): boolean | undefined => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const factionName = helpers.string(ctx, "factionName", _factionName); const factionName = helpers.string(ctx, "factionName", _factionName);
const workType = helpers.string(ctx, "workType", _workType); const workType = helpers.string(ctx, "workType", _workType);
@ -164,9 +144,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
return Player.sleeves[sleeveNumber].workForFaction(factionName, workType); return Player.sleeves[sleeveNumber].workForFaction(factionName, workType);
}, },
setToGymWorkout: setToGymWorkout: (ctx) => (_sleeveNumber, _gymName, _stat) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _gymName: unknown, _stat: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const gymName = helpers.string(ctx, "gymName", _gymName); const gymName = helpers.string(ctx, "gymName", _gymName);
const stat = helpers.string(ctx, "stat", _stat); const stat = helpers.string(ctx, "stat", _stat);
@ -175,17 +153,13 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
return Player.sleeves[sleeveNumber].workoutAtGym(gymName, stat); return Player.sleeves[sleeveNumber].workoutAtGym(gymName, stat);
}, },
getSleeveStats: getSleeveStats: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): SleeveSkills => {
const sleeveNumber = helpers.number(ctx, "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);
}, },
getTask: getTask: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): SleeveTask | null => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
@ -194,9 +168,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
if (sl.currentWork === null) return null; if (sl.currentWork === null) return null;
return sl.currentWork.APICopy(); return sl.currentWork.APICopy();
}, },
getInformation: getInformation: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): SleeveInformation => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
@ -230,9 +202,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
}, },
}; };
}, },
getSleeveAugmentations: getSleeveAugmentations: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): string[] => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
@ -243,9 +213,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
} }
return augs; return augs;
}, },
getSleevePurchasableAugs: getSleevePurchasableAugs: (ctx) => (_sleeveNumber) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown): AugmentPair[] => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
checkSleeveNumber(ctx, sleeveNumber); checkSleeveNumber(ctx, sleeveNumber);
@ -262,9 +230,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
return augs; return augs;
}, },
purchaseSleeveAug: purchaseSleeveAug: (ctx) => (_sleeveNumber, _augName) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _augName: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
@ -281,25 +247,19 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
return Player.sleeves[sleeveNumber].tryBuyAugmentation(aug); return Player.sleeves[sleeveNumber].tryBuyAugmentation(aug);
}, },
getSleeveAugmentationPrice: getSleeveAugmentationPrice: (ctx) => (_augName) => {
(ctx: NetscriptContext) =>
(_augName: unknown): number => {
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
const augName = helpers.string(ctx, "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;
}, },
getSleeveAugmentationRepReq: getSleeveAugmentationRepReq: (ctx) => (_augName) => {
(ctx: NetscriptContext) =>
(_augName: unknown): number => {
checkSleeveAPIAccess(ctx); checkSleeveAPIAccess(ctx);
const augName = helpers.string(ctx, "augName", _augName); const augName = helpers.string(ctx, "augName", _augName);
const aug: Augmentation = StaticAugmentations[augName]; const aug: Augmentation = StaticAugmentations[augName];
return aug.getCost().repCost; return aug.getCost().repCost;
}, },
setToBladeburnerAction: setToBladeburnerAction: (ctx) => (_sleeveNumber, _action, _contract?) => {
(ctx: NetscriptContext) =>
(_sleeveNumber: unknown, _action: unknown, _contract?: unknown): boolean => {
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
const action = helpers.string(ctx, "action", _action); const action = helpers.string(ctx, "action", _action);
let contract: string; let contract: string;

@ -4,11 +4,7 @@ import { staneksGift } from "../CotMG/Helper";
import { Fragments, FragmentById } from "../CotMG/Fragment"; import { Fragments, FragmentById } from "../CotMG/Fragment";
import { FragmentType } from "../CotMG/FragmentType"; import { FragmentType } from "../CotMG/FragmentType";
import { import { Stanek as IStanek } from "../ScriptEditor/NetscriptDefinitions";
Fragment as IFragment,
ActiveFragment as IActiveFragment,
Stanek as IStanek,
} from "../ScriptEditor/NetscriptDefinitions";
import { AugmentationNames } from "../Augmentation/data/AugmentationNames"; import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
import { NetscriptContext, InternalAPI } from "../Netscript/APIWrapper"; import { NetscriptContext, InternalAPI } from "../Netscript/APIWrapper";
import { applyAugmentation } from "../Augmentation/AugmentationHelpers"; import { applyAugmentation } from "../Augmentation/AugmentationHelpers";
@ -25,18 +21,15 @@ export function NetscriptStanek(): InternalAPI<IStanek> {
} }
return { return {
giftWidth: (ctx: NetscriptContext) => giftWidth: (ctx) => () => {
function (): number {
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
return staneksGift.width(); return staneksGift.width();
}, },
giftHeight: (ctx: NetscriptContext) => giftHeight: (ctx) => () => {
function (): number {
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
return staneksGift.height(); return staneksGift.height();
}, },
chargeFragment: (ctx: NetscriptContext) => chargeFragment: (ctx) => (_rootX, _rootY) => {
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 = helpers.number(ctx, "rootX", _rootX); const rootX = helpers.number(ctx, "rootX", _rootX);
const rootY = helpers.number(ctx, "rootY", _rootY); const rootY = helpers.number(ctx, "rootY", _rootY);
@ -58,28 +51,24 @@ export function NetscriptStanek(): InternalAPI<IStanek> {
return Promise.resolve(); return Promise.resolve();
}); });
}, },
fragmentDefinitions: (ctx: NetscriptContext) => fragmentDefinitions: (ctx) => () => {
function (): IFragment[] {
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
helpers.log(ctx, () => `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) => () => {
function (): IActiveFragment[] {
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
helpers.log(ctx, () => `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) => () => {
function (): void {
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
helpers.log(ctx, () => `Cleared Stanek's Gift.`); helpers.log(ctx, () => `Cleared Stanek's Gift.`);
staneksGift.clear(); staneksGift.clear();
}, },
canPlaceFragment: (ctx: NetscriptContext) => canPlaceFragment: (ctx) => (_rootX, _rootY, _rotation, _fragmentId) => {
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
const rootX = helpers.number(ctx, "rootX", _rootX); const rootX = helpers.number(ctx, "rootX", _rootX);
const rootY = helpers.number(ctx, "rootY", _rootY); const rootY = helpers.number(ctx, "rootY", _rootY);
const rotation = helpers.number(ctx, "rotation", _rotation); const rotation = helpers.number(ctx, "rotation", _rotation);
@ -90,8 +79,7 @@ export function NetscriptStanek(): InternalAPI<IStanek> {
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) => (_rootX, _rootY, _rotation, _fragmentId) => {
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
const rootX = helpers.number(ctx, "rootX", _rootX); const rootX = helpers.number(ctx, "rootX", _rootX);
const rootY = helpers.number(ctx, "rootY", _rootY); const rootY = helpers.number(ctx, "rootY", _rootY);
const rotation = helpers.number(ctx, "rotation", _rotation); const rotation = helpers.number(ctx, "rotation", _rotation);
@ -101,8 +89,7 @@ export function NetscriptStanek(): InternalAPI<IStanek> {
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `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) => (_rootX, _rootY) => {
function (_rootX: unknown, _rootY: unknown): IActiveFragment | undefined {
const rootX = helpers.number(ctx, "rootX", _rootX); const rootX = helpers.number(ctx, "rootX", _rootX);
const rootY = helpers.number(ctx, "rootY", _rootY); const rootY = helpers.number(ctx, "rootY", _rootY);
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
@ -110,15 +97,13 @@ export function NetscriptStanek(): InternalAPI<IStanek> {
if (fragment !== undefined) return fragment.copy(); if (fragment !== undefined) return fragment.copy();
return undefined; return undefined;
}, },
removeFragment: (ctx: NetscriptContext) => removeFragment: (ctx) => (_rootX, _rootY) => {
function (_rootX: unknown, _rootY: unknown): boolean {
const rootX = helpers.number(ctx, "rootX", _rootX); const rootX = helpers.number(ctx, "rootX", _rootX);
const rootY = helpers.number(ctx, "rootY", _rootY); const rootY = helpers.number(ctx, "rootY", _rootY);
checkStanekAPIAccess(ctx); checkStanekAPIAccess(ctx);
return staneksGift.delete(rootX, rootY); return staneksGift.delete(rootX, rootY);
}, },
acceptGift: (ctx: NetscriptContext) => acceptGift: (ctx) => () => {
function (): boolean {
//Check if the player is eligible to join the church //Check if the player is eligible to join the church
if ( if (
player.canAccessCotMG() && player.canAccessCotMG() &&

@ -37,52 +37,44 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
}; };
return { return {
hasWSEAccount: () => (): boolean => { hasWSEAccount: () => () => {
return player.hasWseAccount; return player.hasWseAccount;
}, },
hasTIXAPIAccess: () => (): boolean => { hasTIXAPIAccess: () => () => {
return player.hasTixApiAccess; return player.hasTixApiAccess;
}, },
has4SData: () => (): boolean => { has4SData: () => () => {
return player.has4SData; return player.has4SData;
}, },
has4SDataTIXAPI: () => (): boolean => { has4SDataTIXAPI: () => () => {
return player.has4SDataTixApi; return player.has4SDataTixApi;
}, },
getSymbols: (ctx: NetscriptContext) => (): string[] => { getSymbols: (ctx) => () => {
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
return Object.values(StockSymbols); return Object.values(StockSymbols);
}, },
getPrice: getPrice: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
const stock = getStockFromSymbol(ctx, symbol); const stock = getStockFromSymbol(ctx, symbol);
return stock.price; return stock.price;
}, },
getAskPrice: getAskPrice: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
const stock = getStockFromSymbol(ctx, symbol); const stock = getStockFromSymbol(ctx, symbol);
return stock.getAskPrice(); return stock.getAskPrice();
}, },
getBidPrice: getBidPrice: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
const stock = getStockFromSymbol(ctx, symbol); const stock = getStockFromSymbol(ctx, symbol);
return stock.getBidPrice(); return stock.getBidPrice();
}, },
getPosition: getPosition: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): [number, number, number, number] => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
const stock = SymbolToStockMap[symbol]; const stock = SymbolToStockMap[symbol];
@ -91,18 +83,14 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
} }
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx]; return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
}, },
getMaxShares: getMaxShares: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
const stock = getStockFromSymbol(ctx, symbol); const stock = getStockFromSymbol(ctx, symbol);
return stock.maxShares; return stock.maxShares;
}, },
getPurchaseCost: getPurchaseCost: (ctx) => (_symbol, _shares, _posType) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
let shares = helpers.number(ctx, "shares", _shares); let shares = helpers.number(ctx, "shares", _shares);
const posType = helpers.string(ctx, "posType", _posType); const posType = helpers.string(ctx, "posType", _posType);
@ -127,9 +115,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return res; return res;
}, },
getSaleGain: getSaleGain: (ctx) => (_symbol, _shares, _posType) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
let shares = helpers.number(ctx, "shares", _shares); let shares = helpers.number(ctx, "shares", _shares);
const posType = helpers.string(ctx, "posType", _posType); const posType = helpers.string(ctx, "posType", _posType);
@ -154,9 +140,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return res; return res;
}, },
buyStock: buyStock: (ctx) => (_symbol, _shares) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
const shares = helpers.number(ctx, "shares", _shares); const shares = helpers.number(ctx, "shares", _shares);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
@ -164,9 +148,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
const res = buyStock(stock, shares, ctx, {}); const res = buyStock(stock, shares, ctx, {});
return res ? stock.getAskPrice() : 0; return res ? stock.getAskPrice() : 0;
}, },
sellStock: sellStock: (ctx) => (_symbol, _shares) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
const shares = helpers.number(ctx, "shares", _shares); const shares = helpers.number(ctx, "shares", _shares);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
@ -175,9 +157,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return res ? stock.getBidPrice() : 0; return res ? stock.getBidPrice() : 0;
}, },
buyShort: buyShort: (ctx) => (_symbol, _shares) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
const shares = helpers.number(ctx, "shares", _shares); const shares = helpers.number(ctx, "shares", _shares);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
@ -194,9 +174,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return res ? stock.getBidPrice() : 0; return res ? stock.getBidPrice() : 0;
}, },
sellShort: sellShort: (ctx) => (_symbol, _shares) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
const shares = helpers.number(ctx, "shares", _shares); const shares = helpers.number(ctx, "shares", _shares);
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
@ -213,9 +191,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return res ? stock.getAskPrice() : 0; return res ? stock.getAskPrice() : 0;
}, },
placeOrder: placeOrder: (ctx) => (_symbol, _shares, _price, _type, _pos) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
const shares = helpers.number(ctx, "shares", _shares); const shares = helpers.number(ctx, "shares", _shares);
const price = helpers.number(ctx, "price", _price); const price = helpers.number(ctx, "price", _price);
@ -258,9 +234,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return placeOrder(stock, shares, price, orderType, orderPos, ctx); return placeOrder(stock, shares, price, orderType, orderPos, ctx);
}, },
cancelOrder: cancelOrder: (ctx) => (_symbol, _shares, _price, _type, _pos) => {
(ctx: NetscriptContext) =>
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
const shares = helpers.number(ctx, "shares", _shares); const shares = helpers.number(ctx, "shares", _shares);
const price = helpers.number(ctx, "price", _price); const price = helpers.number(ctx, "price", _price);
@ -314,7 +288,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
}; };
return cancelOrder(params, ctx); return cancelOrder(params, ctx);
}, },
getOrders: (ctx: NetscriptContext) => (): StockOrder => { getOrders: (ctx) => () => {
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
if (player.bitNodeN !== 8) { if (player.bitNodeN !== 8) {
if (player.sourceFileLvl(8) <= 2) { if (player.sourceFileLvl(8) <= 2) {
@ -342,9 +316,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return orders; return orders;
}, },
getVolatility: getVolatility: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
if (!player.has4SDataTixApi) { if (!player.has4SDataTixApi) {
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!"); throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
@ -353,9 +325,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
return stock.mv / 100; // Convert from percentage to decimal return stock.mv / 100; // Convert from percentage to decimal
}, },
getForecast: getForecast: (ctx) => (_symbol) => {
(ctx: NetscriptContext) =>
(_symbol: unknown): number => {
const symbol = helpers.string(ctx, "symbol", _symbol); const symbol = helpers.string(ctx, "symbol", _symbol);
if (!player.has4SDataTixApi) { if (!player.has4SDataTixApi) {
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!"); throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
@ -366,7 +336,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag); stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag);
return forecast / 100; // Convert from percentage to decimal return forecast / 100; // Convert from percentage to decimal
}, },
purchase4SMarketData: (ctx: NetscriptContext) => (): boolean => { purchase4SMarketData: (ctx) => () => {
if (player.has4SData) { if (player.has4SData) {
helpers.log(ctx, () => "Already purchased 4S Market Data."); helpers.log(ctx, () => "Already purchased 4S Market Data.");
return true; return true;
@ -382,7 +352,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
helpers.log(ctx, () => "Purchased 4S Market Data"); helpers.log(ctx, () => "Purchased 4S Market Data");
return true; return true;
}, },
purchase4SMarketDataTixApi: (ctx: NetscriptContext) => (): boolean => { purchase4SMarketDataTixApi: (ctx) => () => {
checkTixApiAccess(ctx); checkTixApiAccess(ctx);
if (player.has4SDataTixApi) { if (player.has4SDataTixApi) {
@ -400,7 +370,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
helpers.log(ctx, () => "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) => () => {
if (player.hasWseAccount) { if (player.hasWseAccount) {
helpers.log(ctx, () => "Already purchased WSE Account"); helpers.log(ctx, () => "Already purchased WSE Account");
return true; return true;
@ -417,7 +387,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
helpers.log(ctx, () => "Purchased WSE Account Access"); helpers.log(ctx, () => "Purchased WSE Account Access");
return true; return true;
}, },
purchaseTixApi: (ctx: NetscriptContext) => (): boolean => { purchaseTixApi: (ctx) => () => {
if (player.hasTixApiAccess) { if (player.hasTixApiAccess) {
helpers.log(ctx, () => "Already purchased TIX API"); helpers.log(ctx, () => "Already purchased TIX API");
return true; return true;

@ -1,38 +1,34 @@
import { import { UserInterface as IUserInterface } from "../ScriptEditor/NetscriptDefinitions";
GameInfo,
IStyleSettings,
UserInterface as IUserInterface,
UserInterfaceTheme,
} from "../ScriptEditor/NetscriptDefinitions";
import { Settings } from "../Settings/Settings"; import { Settings } from "../Settings/Settings";
import { ThemeEvents } from "../Themes/ui/Theme"; import { ThemeEvents } from "../Themes/ui/Theme";
import { defaultTheme } from "../Themes/Themes"; 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 "../Netscript/APIWrapper"; import { InternalAPI } from "../Netscript/APIWrapper";
import { Terminal } from "../../src/Terminal"; import { Terminal } from "../../src/Terminal";
import { helpers } from "../Netscript/NetscriptHelpers"; import { helpers, assertObjectType } from "../Netscript/NetscriptHelpers";
export function NetscriptUserInterface(): InternalAPI<IUserInterface> { export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
return { return {
windowSize: () => (): [number, number] => { windowSize: () => () => {
return [window.innerWidth, window.innerHeight]; return [window.innerWidth, window.innerHeight];
}, },
getTheme: () => (): UserInterfaceTheme => { getTheme: () => () => {
return { ...Settings.theme }; return { ...Settings.theme };
}, },
getStyles: () => (): IStyleSettings => { getStyles: () => () => {
return { ...Settings.styles }; return { ...Settings.styles };
}, },
setTheme: setTheme: (ctx) => (newTheme) => {
(ctx: NetscriptContext) => const themeValidator: Record<string, string | undefined> = {};
(newTheme: UserInterfaceTheme): void => { assertObjectType(ctx, "newTheme", newTheme, themeValidator);
const hex = /^(#)((?:[A-Fa-f0-9]{2}){3,4}|(?:[A-Fa-f0-9]{3}))$/; const hex = /^(#)((?:[A-Fa-f0-9]{2}){3,4}|(?:[A-Fa-f0-9]{3}))$/;
const currentTheme = { ...Settings.theme }; const currentTheme = { ...Settings.theme };
const errors: string[] = []; const errors: string[] = [];
if (typeof newTheme !== "object")
for (const key of Object.keys(newTheme)) { for (const key of Object.keys(newTheme)) {
if (!currentTheme[key]) { if (!currentTheme[key]) {
// Invalid key // Invalid key
@ -53,9 +49,9 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
} }
}, },
setStyles: setStyles: (ctx) => (newStyles) => {
(ctx: NetscriptContext) => const styleValidator: Record<string, string | number | undefined> = {};
(newStyles: IStyleSettings): void => { assertObjectType(ctx, "newStyles", newStyles, styleValidator);
const currentStyles = { ...Settings.styles }; const currentStyles = { ...Settings.styles };
const errors: string[] = []; const errors: string[] = [];
for (const key of Object.keys(newStyles)) { for (const key of Object.keys(newStyles)) {
@ -63,7 +59,7 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
// Invalid key // Invalid key
errors.push(`Invalid key "${key}"`); errors.push(`Invalid key "${key}"`);
} else { } else {
(currentStyles as any)[key] = (newStyles as any)[key]; (currentStyles as any)[key] = newStyles[key];
} }
} }
@ -76,19 +72,19 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
} }
}, },
resetTheme: (ctx: NetscriptContext) => (): void => { resetTheme: (ctx) => () => {
Settings.theme = { ...defaultTheme }; Settings.theme = { ...defaultTheme };
ThemeEvents.emit(); ThemeEvents.emit();
helpers.log(ctx, () => `Reinitialized theme to default`); helpers.log(ctx, () => `Reinitialized theme to default`);
}, },
resetStyles: (ctx: NetscriptContext) => (): void => { resetStyles: (ctx) => () => {
Settings.styles = { ...defaultStyles }; Settings.styles = { ...defaultStyles };
ThemeEvents.emit(); ThemeEvents.emit();
helpers.log(ctx, () => `Reinitialized styles to default`); helpers.log(ctx, () => `Reinitialized styles to default`);
}, },
getGameInfo: () => (): GameInfo => { getGameInfo: () => () => {
const version = CONSTANTS.VersionString; const version = CONSTANTS.VersionString;
const commit = hash(); const commit = hash();
const platform = navigator.userAgent.toLowerCase().indexOf(" electron/") > -1 ? "Steam" : "Browser"; const platform = navigator.userAgent.toLowerCase().indexOf(" electron/") > -1 ? "Steam" : "Browser";
@ -102,7 +98,7 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
return gameInfo; return gameInfo;
}, },
clearTerminal: (ctx: NetscriptContext) => (): void => { clearTerminal: (ctx) => () => {
helpers.log(ctx, () => `Clearing terminal`); helpers.log(ctx, () => `Clearing terminal`);
Terminal.clear(); Terminal.clear();
}, },

@ -1,28 +1,39 @@
import { Settings } from "./Settings/Settings"; import { Settings } from "./Settings/Settings";
type PortData = string | number;
export interface IPort { export interface IPort {
write: (value: unknown) => unknown; write: (value: unknown) => PortData | null;
tryWrite: (value: unknown) => boolean; tryWrite: (value: unknown) => boolean;
read: () => unknown; read: () => PortData;
peek: () => unknown; peek: () => PortData;
full: () => boolean; full: () => boolean;
empty: () => boolean; empty: () => boolean;
clear: () => void; clear: () => void;
} }
export function NetscriptPort(): IPort { export function NetscriptPort(): IPort {
const data: unknown[] = []; const data: PortData[] = [];
return { return {
write: (value: unknown): unknown => { write: (value) => {
if (typeof value !== "number" && typeof value !== "string") {
throw new Error(
`port.write: Tried to write type ${typeof value}. Only string and number types may be written to ports.`,
);
}
data.push(value); data.push(value);
if (data.length > Settings.MaxPortCapacity) { if (data.length > Settings.MaxPortCapacity) {
return data.shift(); return data.shift() as PortData;
} }
return null; return null;
}, },
tryWrite: (value: unknown): boolean => { tryWrite: (value) => {
if (typeof value != "number" && typeof value != "string") {
throw new Error(
`port.write: Tried to write type ${typeof value}. Only string and number types may be written to ports.`,
);
}
if (data.length >= Settings.MaxPortCapacity) { if (data.length >= Settings.MaxPortCapacity) {
return false; return false;
} }
@ -30,31 +41,25 @@ export function NetscriptPort(): IPort {
return true; return true;
}, },
read: (): unknown => { read: () => {
if (data.length === 0) { if (data.length === 0) return "NULL PORT DATA";
return "NULL PORT DATA"; return data.shift() as PortData;
}
return data.shift();
}, },
peek: (): unknown => { peek: () => {
if (data.length === 0) { if (data.length === 0) return "NULL PORT DATA";
return "NULL PORT DATA"; return data[0];
} else {
const foo = data.slice();
return foo[0];
}
}, },
full: (): boolean => { full: () => {
return data.length == Settings.MaxPortCapacity; return data.length == Settings.MaxPortCapacity;
}, },
empty: (): boolean => { empty: () => {
return data.length === 0; return data.length === 0;
}, },
clear: (): void => { clear: () => {
data.length = 0; data.length = 0;
}, },
}; };

@ -961,7 +961,7 @@ export interface NetscriptPort {
* *
* @returns The data popped off the queue if it was full. * @returns The data popped off the queue if it was full.
*/ */
write(value: string | number): null | string | number; write(value: string | number): PortData | null;
/** /**
* Attempt to write data to the port. * Attempt to write data to the port.
@ -981,7 +981,7 @@ export interface NetscriptPort {
* If the port is empty, then the string NULL PORT DATA will be returned. * If the port is empty, then the string NULL PORT DATA will be returned.
* @returns the data read. * @returns the data read.
*/ */
read(): string | number; read(): PortData;
/** /**
* Retrieve the first element from the port without removing it. * Retrieve the first element from the port without removing it.
@ -993,7 +993,7 @@ export interface NetscriptPort {
* the port is empty, the string NULL PORT DATA will be returned. * the port is empty, the string NULL PORT DATA will be returned.
* @returns the data read * @returns the data read
*/ */
peek(): string | number; peek(): PortData;
/** /**
* Check if the port is full. * Check if the port is full.

@ -1,3 +1,2 @@
import { Terminal as TTerminal } from "./Terminal/Terminal"; import { Terminal as TTerminal } from "./Terminal/Terminal";
export const Terminal = new TTerminal(); export const Terminal = new TTerminal();

@ -1,4 +1,4 @@
// This works for both enums and regular objects. /** Verifies that a supplied value is a member of the provided object/enum. Works for enums as well as enum-like objects (const {} as const). */
export function checkEnum<T extends Record<string, unknown>>(obj: T, value: unknown): value is T[keyof T] { export function checkEnum<T extends Record<string, unknown>>(obj: T, value: unknown): value is T[keyof T] {
return Object.values(obj).includes(value); return Object.values(obj).includes(value);
} }