mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-19 04:35:46 +01:00
typefix netscriptFunctions (see desc)
* Types for InternalFunction and ExternalFunction have been modified to actually typecheck ns functions against docs. * Internal functions are required to use unknown for any params on the inner function. * Return types for internal function inner-function must match the respective external function. * Added new typecheck assertion function for asserting dynamic object types, to allow unknownifying params that were previously hardcoded objec structures. * Because type assertion for parameter types and return types is enforced by InternalAPI, removed all duplicate type declarations on NetscriptFunction params and returns.
This commit is contained in:
parent
41b6f0b87b
commit
7a384d53f4
@ -5,13 +5,15 @@ import { ScriptArg } from "./ScriptArg";
|
||||
import { NSEnums } from "src/ScriptEditor/NetscriptDefinitions";
|
||||
import { NSFull } from "src/NetscriptFunctions";
|
||||
|
||||
type ExternalFunction = (...args: unknown[]) => unknown;
|
||||
type ExternalFunction = (...args: any[]) => void;
|
||||
|
||||
export type ExternalAPILayer = {
|
||||
[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> = {
|
||||
[Property in keyof API]: API[Property] extends ExternalFunction
|
||||
|
@ -65,6 +65,39 @@ export const helpers = {
|
||||
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 clip = (s: string): string => {
|
||||
if (s.length > 15) return s.slice(0, 12) + "...";
|
||||
@ -220,10 +253,7 @@ function resolveNetscriptRequestedThreads(ctx: NetscriptContext, requestedThread
|
||||
}
|
||||
const requestedThreadsAsInt = requestedThreads | 0;
|
||||
if (isNaN(requestedThreads) || requestedThreadsAsInt < 1) {
|
||||
throw makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Invalid thread count passed to ${ctx.function}: ${requestedThreads}. Threads must be a positive number.`,
|
||||
);
|
||||
throw makeRuntimeErrorMsg(ctx, `Invalid thread count: ${requestedThreads}. Threads must be a positive number.`);
|
||||
}
|
||||
if (requestedThreadsAsInt > threads) {
|
||||
throw makeRuntimeErrorMsg(
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
import { Player } from "@player";
|
||||
import { Bladeburner } from "../Bladeburner/Bladeburner";
|
||||
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 { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
||||
import { BlackOperation } from "../Bladeburner/BlackOperation";
|
||||
@ -47,75 +47,69 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
};
|
||||
|
||||
return {
|
||||
getContractNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
getContractNames: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getContractNamesNetscriptFn();
|
||||
},
|
||||
getOperationNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
getOperationNames: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getOperationNamesNetscriptFn();
|
||||
},
|
||||
getBlackOpNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
getBlackOpNames: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getBlackOpNamesNetscriptFn();
|
||||
},
|
||||
getBlackOpRank:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_blackOpName: unknown): number => {
|
||||
const blackOpName = helpers.string(ctx, "blackOpName", _blackOpName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, "blackops", blackOpName);
|
||||
if (!(action instanceof BlackOperation)) throw new Error("action was not a black operation");
|
||||
return action.reqdRank;
|
||||
},
|
||||
getGeneralActionNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
getBlackOpRank: (ctx) => (_blackOpName) => {
|
||||
const blackOpName = helpers.string(ctx, "blackOpName", _blackOpName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, "blackops", blackOpName);
|
||||
if (!(action instanceof BlackOperation)) throw new Error("action was not a black operation");
|
||||
return action.reqdRank;
|
||||
},
|
||||
getGeneralActionNames: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getGeneralActionNamesNetscriptFn();
|
||||
},
|
||||
getSkillNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
getSkillNames: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getSkillNamesNetscriptFn();
|
||||
},
|
||||
startAction:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): boolean => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.startActionNetscriptFn(type, name, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
stopBladeburnerAction: (ctx: NetscriptContext) => (): void => {
|
||||
startAction: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.startActionNetscriptFn(type, name, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
stopBladeburnerAction: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.resetAction();
|
||||
},
|
||||
getCurrentAction: (ctx: NetscriptContext) => (): BladeburnerCurAction => {
|
||||
getCurrentAction: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.getTypeAndNameFromActionId(bladeburner.action);
|
||||
},
|
||||
getActionTime:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
const time = bladeburner.getActionTimeNetscriptFn(Player, type, name);
|
||||
if (typeof time === "string") {
|
||||
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
||||
helpers.log(ctx, () => errorLogText);
|
||||
return -1;
|
||||
} else {
|
||||
return time;
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
getActionTime: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
const time = bladeburner.getActionTimeNetscriptFn(Player, type, name);
|
||||
if (typeof time === "string") {
|
||||
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
||||
helpers.log(ctx, () => errorLogText);
|
||||
return -1;
|
||||
} else {
|
||||
return time;
|
||||
}
|
||||
},
|
||||
getActionCurrentTime: (ctx: NetscriptContext) => (): number => {
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getActionCurrentTime: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
const timecomputed =
|
||||
@ -126,84 +120,72 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getActionEstimatedSuccessChance:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): [number, number] => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
const chance = bladeburner.getActionEstimatedSuccessChanceNetscriptFn(Player, type, name);
|
||||
if (typeof chance === "string") {
|
||||
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
||||
helpers.log(ctx, () => errorLogText);
|
||||
return [-1, -1];
|
||||
} else {
|
||||
return chance;
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getActionRepGain:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown, _level: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
let rewardMultiplier;
|
||||
if (level == null || isNaN(level)) {
|
||||
rewardMultiplier = Math.pow(action.rewardFac, action.level - 1);
|
||||
getActionEstimatedSuccessChance: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
const chance = bladeburner.getActionEstimatedSuccessChanceNetscriptFn(Player, type, name);
|
||||
if (typeof chance === "string") {
|
||||
const errorLogText = `Invalid action: type='${type}' name='${name}'`;
|
||||
helpers.log(ctx, () => errorLogText);
|
||||
return [-1, -1];
|
||||
} else {
|
||||
rewardMultiplier = Math.pow(action.rewardFac, level - 1);
|
||||
return chance;
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getActionRepGain: (ctx) => (_type, _name, _level) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
let rewardMultiplier;
|
||||
if (level == null || isNaN(level)) {
|
||||
rewardMultiplier = Math.pow(action.rewardFac, action.level - 1);
|
||||
} else {
|
||||
rewardMultiplier = Math.pow(action.rewardFac, level - 1);
|
||||
}
|
||||
|
||||
return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank;
|
||||
},
|
||||
getActionCountRemaining:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.getActionCountRemainingNetscriptFn(type, name, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getActionMaxLevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
return action.maxLevel;
|
||||
},
|
||||
getActionCurrentLevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
return action.level;
|
||||
},
|
||||
getActionAutolevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): boolean => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
return action.autoLevel;
|
||||
},
|
||||
return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank;
|
||||
},
|
||||
getActionCountRemaining: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.getActionCountRemainingNetscriptFn(type, name, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getActionMaxLevel: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
return action.maxLevel;
|
||||
},
|
||||
getActionCurrentLevel: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
return action.level;
|
||||
},
|
||||
getActionAutolevel: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
checkBladeburnerAccess(ctx);
|
||||
const action = getBladeburnerActionObject(ctx, type, name);
|
||||
return action.autoLevel;
|
||||
},
|
||||
setActionAutolevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown, _autoLevel: unknown = true): void => {
|
||||
(ctx) =>
|
||||
(_type, _name, _autoLevel = true) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const autoLevel = !!_autoLevel;
|
||||
@ -212,8 +194,8 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
action.autoLevel = autoLevel;
|
||||
},
|
||||
setActionLevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown, _level: unknown = 1): void => {
|
||||
(ctx) =>
|
||||
(_type, _name, _level = 1) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
@ -224,28 +206,26 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
}
|
||||
action.level = level;
|
||||
},
|
||||
getRank: (ctx: NetscriptContext) => (): number => {
|
||||
getRank: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.rank;
|
||||
},
|
||||
getSkillPoints: (ctx: NetscriptContext) => (): number => {
|
||||
getSkillPoints: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.skillPoints;
|
||||
},
|
||||
getSkillLevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_skillName: unknown): number => {
|
||||
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.getSkillLevelNetscriptFn(skillName, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getSkillLevel: (ctx) => (_skillName) => {
|
||||
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.getSkillLevelNetscriptFn(skillName, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getSkillUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_skillName: unknown, _count: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_skillName, _count = 1) => {
|
||||
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||
const count = helpers.number(ctx, "count", _count);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
@ -256,8 +236,8 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
}
|
||||
},
|
||||
upgradeSkill:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_skillName: unknown, _count: unknown = 1): boolean => {
|
||||
(ctx) =>
|
||||
(_skillName, _count = 1) => {
|
||||
const skillName = helpers.string(ctx, "skillName", _skillName);
|
||||
const count = helpers.number(ctx, "count", _count);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
@ -267,85 +247,73 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getTeamSize:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.getTeamSizeNetscriptFn(type, name, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
setTeamSize:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown, _name: unknown, _size: unknown): number => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const size = helpers.number(ctx, "size", _size);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.setTeamSizeNetscriptFn(type, name, size, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getCityEstimatedPopulation:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_cityName: unknown): number => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].popEst;
|
||||
},
|
||||
getCityCommunities:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_cityName: unknown): number => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].comms;
|
||||
},
|
||||
getCityChaos:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_cityName: unknown): number => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].chaos;
|
||||
},
|
||||
getCity: (ctx: NetscriptContext) => (): string => {
|
||||
getTeamSize: (ctx) => (_type, _name) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.getTeamSizeNetscriptFn(type, name, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
setTeamSize: (ctx) => (_type, _name, _size) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const name = helpers.string(ctx, "name", _name);
|
||||
const size = helpers.number(ctx, "size", _size);
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
try {
|
||||
return bladeburner.setTeamSizeNetscriptFn(type, name, size, ctx.workerScript);
|
||||
} catch (e: unknown) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, String(e));
|
||||
}
|
||||
},
|
||||
getCityEstimatedPopulation: (ctx) => (_cityName) => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].popEst;
|
||||
},
|
||||
getCityCommunities: (ctx) => (_cityName) => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].comms;
|
||||
},
|
||||
getCityChaos: (ctx) => (_cityName) => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
return bladeburner.cities[cityName].chaos;
|
||||
},
|
||||
getCity: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.city;
|
||||
},
|
||||
switchCity:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_cityName: unknown): boolean => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
bladeburner.city = cityName;
|
||||
return true;
|
||||
},
|
||||
getStamina: (ctx: NetscriptContext) => (): [number, number] => {
|
||||
switchCity: (ctx) => (_cityName) => {
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkBladeburnerAccess(ctx);
|
||||
checkBladeburnerCity(ctx, cityName);
|
||||
const bladeburner = Player.bladeburner;
|
||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
||||
bladeburner.city = cityName;
|
||||
return true;
|
||||
},
|
||||
getStamina: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return [bladeburner.stamina, bladeburner.maxStamina];
|
||||
},
|
||||
joinBladeburnerFaction: (ctx: NetscriptContext) => (): boolean => {
|
||||
joinBladeburnerFaction: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return bladeburner.joinBladeburnerFactionNetscriptFn(ctx.workerScript);
|
||||
},
|
||||
joinBladeburnerDivision: (ctx: NetscriptContext) => (): boolean => {
|
||||
joinBladeburnerDivision: (ctx) => () => {
|
||||
if (Player.bitNodeN === 7 || Player.sourceFileLvl(7) > 0) {
|
||||
if (BitNodeMultipliers.BladeburnerRank === 0) {
|
||||
return false; // Disabled in this bitnode
|
||||
@ -369,7 +337,7 @@ export function NetscriptBladeburner(): InternalAPI<INetscriptBladeburner> {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getBonusTime: (ctx: NetscriptContext) => (): number => {
|
||||
getBonusTime: (ctx) => () => {
|
||||
const bladeburner = getBladeburner(ctx);
|
||||
return Math.round(bladeburner.storedCycles / 5) * 1000;
|
||||
},
|
||||
|
@ -2,17 +2,12 @@ import { Player as player } from "../Player";
|
||||
import { CodingContract } from "../CodingContracts";
|
||||
import { CodingAttemptOptions, CodingContract as ICodingContract } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { helpers, assertObjectType } from "../Netscript/NetscriptHelpers";
|
||||
import { codingContractTypesMetadata } from "../data/codingcontracttypes";
|
||||
import { generateDummyContract } from "../CodingContractGenerator";
|
||||
|
||||
export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||
const getCodingContract = function (
|
||||
ctx: NetscriptContext,
|
||||
func: string,
|
||||
hostname: string,
|
||||
filename: string,
|
||||
): CodingContract {
|
||||
const getCodingContract = function (ctx: NetscriptContext, hostname: string, filename: string): CodingContract {
|
||||
const server = helpers.getServer(ctx, hostname);
|
||||
const contract = server.getContract(filename);
|
||||
if (contract == null) {
|
||||
@ -23,102 +18,86 @@ export function NetscriptCodingContract(): InternalAPI<ICodingContract> {
|
||||
};
|
||||
|
||||
return {
|
||||
attempt:
|
||||
(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 hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
const contract = getCodingContract(ctx, "attempt", hostname, filename);
|
||||
attempt: (ctx) => (answer, _filename, _hostname?, opts?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
|
||||
if (typeof answer !== "number" && typeof answer !== "string" && !Array.isArray(answer))
|
||||
throw new Error("The answer provided was not a number, string, or array");
|
||||
const optsValidator: CodingAttemptOptions = { returnReward: true };
|
||||
opts ??= optsValidator;
|
||||
assertObjectType(ctx, "opts", opts, optsValidator);
|
||||
if (typeof answer !== "number" && typeof answer !== "string" && !Array.isArray(answer))
|
||||
throw new Error("The answer provided was not a number, string, or array");
|
||||
|
||||
// Convert answer to string.
|
||||
const answerStr = typeof answer === "string" ? answer : JSON.stringify(answer);
|
||||
const creward = contract.reward;
|
||||
// Convert answer to string.
|
||||
const answerStr = typeof answer === "string" ? answer : JSON.stringify(answer);
|
||||
const creward = contract.reward;
|
||||
|
||||
const serv = helpers.getServer(ctx, hostname);
|
||||
if (contract.isSolution(answerStr)) {
|
||||
const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
|
||||
helpers.log(ctx, () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
||||
const serv = helpers.getServer(ctx, hostname);
|
||||
if (contract.isSolution(answerStr)) {
|
||||
const reward = player.gainCodingContractReward(creward, contract.getDifficulty());
|
||||
helpers.log(ctx, () => `Successfully completed Coding Contract '${filename}'. Reward: ${reward}`);
|
||||
serv.removeContract(filename);
|
||||
return opts.returnReward ? reward : true;
|
||||
} else {
|
||||
++contract.tries;
|
||||
if (contract.tries >= contract.getMaxNumTries()) {
|
||||
helpers.log(ctx, () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
||||
serv.removeContract(filename);
|
||||
return returnReward ? reward : true;
|
||||
} else {
|
||||
++contract.tries;
|
||||
if (contract.tries >= contract.getMaxNumTries()) {
|
||||
helpers.log(ctx, () => `Coding Contract attempt '${filename}' failed. Contract is now self-destructing`);
|
||||
serv.removeContract(filename);
|
||||
} else {
|
||||
helpers.log(
|
||||
ctx,
|
||||
() =>
|
||||
`Coding Contract attempt '${filename}' failed. ${
|
||||
contract.getMaxNumTries() - contract.tries
|
||||
} attempts remaining.`,
|
||||
);
|
||||
}
|
||||
|
||||
return returnReward ? "" : false;
|
||||
helpers.log(
|
||||
ctx,
|
||||
() =>
|
||||
`Coding Contract attempt '${filename}' failed. ${
|
||||
contract.getMaxNumTries() - contract.tries
|
||||
} attempts remaining.`,
|
||||
);
|
||||
}
|
||||
},
|
||||
getContractType:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
const contract = getCodingContract(ctx, "getContractType", hostname, filename);
|
||||
return contract.getType();
|
||||
},
|
||||
getData:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): unknown => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
const contract = getCodingContract(ctx, "getData", hostname, filename);
|
||||
const data = contract.getData();
|
||||
if (Array.isArray(data)) {
|
||||
// For two dimensional arrays, we have to copy the internal arrays using
|
||||
// slice() as well. As of right now, no contract has arrays that have
|
||||
// more than two dimensions
|
||||
const copy = data.slice();
|
||||
for (let i = 0; i < copy.length; ++i) {
|
||||
if (data[i].constructor === Array) {
|
||||
copy[i] = data[i].slice();
|
||||
}
|
||||
}
|
||||
|
||||
return copy;
|
||||
} else {
|
||||
return data;
|
||||
return opts.returnReward ? "" : false;
|
||||
}
|
||||
},
|
||||
getContractType: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
return contract.getType();
|
||||
},
|
||||
getData: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
const data = contract.getData();
|
||||
if (Array.isArray(data)) {
|
||||
// For two dimensional arrays, we have to copy the internal arrays using
|
||||
// slice() as well. As of right now, no contract has arrays that have
|
||||
// more than two dimensions
|
||||
const copy = data.slice();
|
||||
for (let i = 0; i < copy.length; ++i) {
|
||||
if (data[i].constructor === Array) {
|
||||
copy[i] = data[i].slice();
|
||||
}
|
||||
}
|
||||
},
|
||||
getDescription:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): string => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
const contract = getCodingContract(ctx, "getDescription", hostname, filename);
|
||||
return contract.getDescription();
|
||||
},
|
||||
getNumTriesRemaining:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_filename: unknown, _hostname: unknown = ctx.workerScript.hostname): number => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
const contract = getCodingContract(ctx, "getNumTriesRemaining", hostname, filename);
|
||||
return contract.getMaxNumTries() - contract.tries;
|
||||
},
|
||||
createDummyContract:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_type: unknown): void => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
generateDummyContract(type);
|
||||
},
|
||||
getContractTypes: () => (): string[] => codingContractTypesMetadata.map((c) => c.name),
|
||||
|
||||
return copy;
|
||||
} else return data;
|
||||
},
|
||||
getDescription: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
return contract.getDescription();
|
||||
},
|
||||
getNumTriesRemaining: (ctx) => (_filename, _hostname?) => {
|
||||
const filename = helpers.string(ctx, "filename", _filename);
|
||||
const hostname = _hostname ? helpers.string(ctx, "hostname", _hostname) : ctx.workerScript.hostname;
|
||||
const contract = getCodingContract(ctx, hostname, filename);
|
||||
return contract.getMaxNumTries() - contract.tries;
|
||||
},
|
||||
createDummyContract: (ctx) => (_type) => {
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
generateDummyContract(type);
|
||||
},
|
||||
getContractTypes: () => () => codingContractTypesMetadata.map((c) => c.name),
|
||||
};
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,7 @@ import { Player } from "../Player";
|
||||
import { Exploit } from "../Exploits/Exploit";
|
||||
import * as bcrypt from "bcryptjs";
|
||||
import { Apr1Events as devMenu } from "../ui/Apr1";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { InternalAPI } from "../Netscript/APIWrapper";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { Terminal } from "../Terminal";
|
||||
|
||||
@ -32,7 +32,7 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
|
||||
exploit: () => () => {
|
||||
Player.giveExploit(Exploit.UndocumentedFunctionCall);
|
||||
},
|
||||
bypass: (ctx: NetscriptContext) => (doc: unknown) => {
|
||||
bypass: (ctx) => (doc) => {
|
||||
// reset both fields first
|
||||
type temporary = { completely_unused_field: unknown };
|
||||
const d = doc as temporary;
|
||||
@ -47,7 +47,7 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
|
||||
d.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)
|
||||
let x = false;
|
||||
const recur = function (depth: number): void {
|
||||
@ -62,7 +62,7 @@ export function NetscriptExtra(): InternalAPI<INetscriptExtra> {
|
||||
Player.giveExploit(Exploit.RealityAlteration);
|
||||
}
|
||||
},
|
||||
rainbow: (ctx: NetscriptContext) => (guess: unknown) => {
|
||||
rainbow: (ctx) => (guess) => {
|
||||
function tryGuess(): boolean {
|
||||
// eslint-disable-next-line no-sync
|
||||
const verified = bcrypt.compareSync(
|
||||
|
@ -26,11 +26,7 @@ import {
|
||||
calculateWeakenTime,
|
||||
} from "../Hacking";
|
||||
import { Programs } from "../Programs/Programs";
|
||||
import {
|
||||
Formulas as IFormulas,
|
||||
HacknetNodeConstants as DefHacknetNodeConstants,
|
||||
HacknetServerConstants as DefHacknetServerConstants,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Formulas as IFormulas } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import {
|
||||
calculateRespectGain,
|
||||
calculateWantedLevelGain,
|
||||
@ -43,7 +39,6 @@ import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor }
|
||||
import { repFromDonation } from "../Faction/formulas/donation";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { WorkStats } from "../Work/WorkStats";
|
||||
import { calculateCrimeWorkStats } from "../Work/formulas/Crime";
|
||||
import { Crimes } from "../Crime/Crimes";
|
||||
import { calculateClassEarnings } from "../Work/formulas/Class";
|
||||
@ -52,7 +47,6 @@ import { LocationName } from "../Locations/data/LocationNames";
|
||||
import { calculateFactionExp, calculateFactionRep } from "../Work/formulas/Faction";
|
||||
import { FactionWorkType } from "../Work/data/FactionWorkType";
|
||||
|
||||
import { Player as INetscriptPlayer, Server as IServerDef } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { defaultMultipliers } from "../PersonObjects/Multipliers";
|
||||
|
||||
export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
@ -62,7 +56,7 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
}
|
||||
};
|
||||
return {
|
||||
mockServer: () => (): IServerDef => ({
|
||||
mockServer: () => () => ({
|
||||
cpuCores: 0,
|
||||
ftpPortOpen: false,
|
||||
hasAdminRights: false,
|
||||
@ -88,7 +82,7 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
requiredHackingSkill: 0,
|
||||
serverGrowth: 0,
|
||||
}),
|
||||
mockPlayer: () => (): INetscriptPlayer => ({
|
||||
mockPlayer: () => () => ({
|
||||
hp: { current: 0, max: 0 },
|
||||
skills: {
|
||||
hacking: 0,
|
||||
@ -125,41 +119,35 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
entropy: 0,
|
||||
}),
|
||||
reputation: {
|
||||
calculateFavorToRep:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_favor: unknown): number => {
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateFavorToRep(favor);
|
||||
},
|
||||
calculateRepToFavor:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_rep: unknown): number => {
|
||||
const rep = helpers.number(ctx, "rep", _rep);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateRepToFavor(rep);
|
||||
},
|
||||
repFromDonation:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_amount: unknown, _player: unknown): number => {
|
||||
const amount = helpers.number(ctx, "amount", _amount);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return repFromDonation(amount, player);
|
||||
},
|
||||
calculateFavorToRep: (ctx) => (_favor) => {
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateFavorToRep(favor);
|
||||
},
|
||||
calculateRepToFavor: (ctx) => (_rep) => {
|
||||
const rep = helpers.number(ctx, "rep", _rep);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateRepToFavor(rep);
|
||||
},
|
||||
repFromDonation: (ctx) => (_amount, _player) => {
|
||||
const amount = helpers.number(ctx, "amount", _amount);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return repFromDonation(amount, player);
|
||||
},
|
||||
},
|
||||
skills: {
|
||||
calculateSkill:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_exp: unknown, _mult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_exp, _mult = 1) => {
|
||||
const exp = helpers.number(ctx, "exp", _exp);
|
||||
const mult = helpers.number(ctx, "mult", _mult);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateSkill(exp, mult);
|
||||
},
|
||||
calculateExp:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_skill: unknown, _mult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_skill, _mult = 1) => {
|
||||
const skill = helpers.number(ctx, "skill", _skill);
|
||||
const mult = helpers.number(ctx, "mult", _mult);
|
||||
checkFormulasAccess(ctx);
|
||||
@ -167,33 +155,27 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
},
|
||||
},
|
||||
hacking: {
|
||||
hackChance:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _player: unknown): number => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingChance(server, player);
|
||||
},
|
||||
hackExp:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _player: unknown): number => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingExpGain(server, player);
|
||||
},
|
||||
hackPercent:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _player: unknown): number => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculatePercentMoneyHacked(server, player);
|
||||
},
|
||||
hackChance: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingChance(server, player);
|
||||
},
|
||||
hackExp: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingExpGain(server, player);
|
||||
},
|
||||
hackPercent: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculatePercentMoneyHacked(server, player);
|
||||
},
|
||||
growPercent:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _threads: unknown, _player: unknown, _cores: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_server, _threads, _player, _cores = 1) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
const threads = helpers.number(ctx, "threads", _threads);
|
||||
@ -201,35 +183,29 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateServerGrowth(server, threads, player, cores);
|
||||
},
|
||||
hackTime:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _player: unknown): number => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingTime(server, player) * 1000;
|
||||
},
|
||||
growTime:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _player: unknown): number => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateGrowTime(server, player) * 1000;
|
||||
},
|
||||
weakenTime:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_server: unknown, _player: unknown): number => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWeakenTime(server, player) * 1000;
|
||||
},
|
||||
hackTime: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateHackingTime(server, player) * 1000;
|
||||
},
|
||||
growTime: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateGrowTime(server, player) * 1000;
|
||||
},
|
||||
weakenTime: (ctx) => (_server, _player) => {
|
||||
const server = helpers.server(ctx, _server);
|
||||
const player = helpers.player(ctx, _player);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWeakenTime(server, player) * 1000;
|
||||
},
|
||||
},
|
||||
hacknetNodes: {
|
||||
moneyGainRate:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_level, _ram, _cores, _mult = 1) => {
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
const ram = helpers.number(ctx, "ram", _ram);
|
||||
const cores = helpers.number(ctx, "cores", _cores);
|
||||
@ -238,8 +214,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return calculateMoneyGainRate(level, ram, cores, mult);
|
||||
},
|
||||
levelUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingLevel, _extraLevels = 1, _costMult = 1) => {
|
||||
const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel);
|
||||
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||
@ -247,8 +223,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||
},
|
||||
ramUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingRam, _extraLevels = 1, _costMult = 1) => {
|
||||
const startingRam = helpers.number(ctx, "startingRam", _startingRam);
|
||||
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||
@ -256,31 +232,29 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||
},
|
||||
coreUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingCore, _extraCores = 1, _costMult = 1) => {
|
||||
const startingCore = helpers.number(ctx, "startingCore", _startingCore);
|
||||
const extraCores = helpers.number(ctx, "extraCores", _extraCores);
|
||||
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||
},
|
||||
hacknetNodeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_n: unknown, _mult: unknown): number => {
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const mult = helpers.number(ctx, "mult", _mult);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateNodeCost(n, mult);
|
||||
},
|
||||
constants: (ctx: NetscriptContext) => (): DefHacknetNodeConstants => {
|
||||
hacknetNodeCost: (ctx) => (_n, _mult) => {
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const mult = helpers.number(ctx, "mult", _mult);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateNodeCost(n, mult);
|
||||
},
|
||||
constants: (ctx) => () => {
|
||||
checkFormulasAccess(ctx);
|
||||
return Object.assign({}, HacknetNodeConstants);
|
||||
},
|
||||
},
|
||||
hacknetServers: {
|
||||
hashGainRate:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_level: unknown, _ramUsed: unknown, _maxRam: unknown, _cores: unknown, _mult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_level, _ramUsed, _maxRam, _cores, _mult = 1) => {
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
const ramUsed = helpers.number(ctx, "ramUsed", _ramUsed);
|
||||
const maxRam = helpers.number(ctx, "maxRam", _maxRam);
|
||||
@ -290,8 +264,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
||||
},
|
||||
levelUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingLevel, _extraLevels = 1, _costMult = 1) => {
|
||||
const startingLevel = helpers.number(ctx, "startingLevel", _startingLevel);
|
||||
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||
@ -299,8 +273,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||
},
|
||||
ramUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingRam, _extraLevels = 1, _costMult = 1) => {
|
||||
const startingRam = helpers.number(ctx, "startingRam", _startingRam);
|
||||
const extraLevels = helpers.number(ctx, "extraLevels", _extraLevels);
|
||||
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||
@ -308,8 +282,8 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||
},
|
||||
coreUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingCore, _extraCores = 1, _costMult = 1) => {
|
||||
const startingCore = helpers.number(ctx, "startingCore", _startingCore);
|
||||
const extraCores = helpers.number(ctx, "extraCores", _extraCores);
|
||||
const costMult = helpers.number(ctx, "costMult", _costMult);
|
||||
@ -317,117 +291,97 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||
},
|
||||
cacheUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_startingCache: unknown, _extraCache: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_startingCache, _extraCache = 1) => {
|
||||
const startingCache = helpers.number(ctx, "startingCache", _startingCache);
|
||||
const extraCache = helpers.number(ctx, "extraCache", _extraCache);
|
||||
checkFormulasAccess(ctx);
|
||||
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
||||
},
|
||||
hashUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_upgName: unknown, _level: unknown): number => {
|
||||
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
checkFormulasAccess(ctx);
|
||||
const upg = player.hashManager.getUpgrade(upgName);
|
||||
if (!upg) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid Hash Upgrade: ${upgName}`);
|
||||
}
|
||||
return upg.getCost(level);
|
||||
},
|
||||
hashUpgradeCost: (ctx) => (_upgName, _level) => {
|
||||
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||
const level = helpers.number(ctx, "level", _level);
|
||||
checkFormulasAccess(ctx);
|
||||
const upg = player.hashManager.getUpgrade(upgName);
|
||||
if (!upg) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid Hash Upgrade: ${upgName}`);
|
||||
}
|
||||
return upg.getCost(level);
|
||||
},
|
||||
hacknetServerCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_n: unknown, _mult: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_n, _mult = 1) => {
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const mult = helpers.number(ctx, "mult", _mult);
|
||||
checkFormulasAccess(ctx);
|
||||
return HScalculateServerCost(n, mult);
|
||||
},
|
||||
constants: (ctx: NetscriptContext) => (): DefHacknetServerConstants => {
|
||||
constants: (ctx) => () => {
|
||||
checkFormulasAccess(ctx);
|
||||
return Object.assign({}, HacknetServerConstants);
|
||||
},
|
||||
},
|
||||
gang: {
|
||||
wantedPenalty:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_gang: unknown): number => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWantedPenalty(gang);
|
||||
},
|
||||
respectGain:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
const member = helpers.gangMember(ctx, _member);
|
||||
const task = helpers.gangTask(ctx, _task);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateRespectGain(gang, member, task);
|
||||
},
|
||||
wantedLevelGain:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
const member = helpers.gangMember(ctx, _member);
|
||||
const task = helpers.gangTask(ctx, _task);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWantedLevelGain(gang, member, task);
|
||||
},
|
||||
moneyGain:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_gang: unknown, _member: unknown, _task: unknown): number => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
const member = helpers.gangMember(ctx, _member);
|
||||
const task = helpers.gangTask(ctx, _task);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateMoneyGain(gang, member, task);
|
||||
},
|
||||
ascensionPointsGain:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_exp: unknown): number => {
|
||||
const exp = helpers.number(ctx, "exp", _exp);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateAscensionPointsGain(exp);
|
||||
},
|
||||
ascensionMultiplier:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_points: unknown): number => {
|
||||
const points = helpers.number(ctx, "points", _points);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateAscensionMult(points);
|
||||
},
|
||||
wantedPenalty: (ctx) => (_gang) => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWantedPenalty(gang);
|
||||
},
|
||||
respectGain: (ctx) => (_gang, _member, _task) => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
const member = helpers.gangMember(ctx, _member);
|
||||
const task = helpers.gangTask(ctx, _task);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateRespectGain(gang, member, task);
|
||||
},
|
||||
wantedLevelGain: (ctx) => (_gang, _member, _task) => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
const member = helpers.gangMember(ctx, _member);
|
||||
const task = helpers.gangTask(ctx, _task);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateWantedLevelGain(gang, member, task);
|
||||
},
|
||||
moneyGain: (ctx) => (_gang, _member, _task) => {
|
||||
const gang = helpers.gang(ctx, _gang);
|
||||
const member = helpers.gangMember(ctx, _member);
|
||||
const task = helpers.gangTask(ctx, _task);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateMoneyGain(gang, member, task);
|
||||
},
|
||||
ascensionPointsGain: (ctx) => (_exp) => {
|
||||
const exp = helpers.number(ctx, "exp", _exp);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateAscensionPointsGain(exp);
|
||||
},
|
||||
ascensionMultiplier: (ctx) => (_points) => {
|
||||
const points = helpers.number(ctx, "points", _points);
|
||||
checkFormulasAccess(ctx);
|
||||
return calculateAscensionMult(points);
|
||||
},
|
||||
},
|
||||
work: {
|
||||
crimeGains:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_crimeType: unknown): WorkStats => {
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
const crime = Object.values(Crimes).find((c) => String(c.type) === crimeType);
|
||||
if (!crime) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return calculateCrimeWorkStats(crime);
|
||||
},
|
||||
classGains:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_person: unknown, _classType: unknown, _locationName: unknown): WorkStats => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
const classType = helpers.string(ctx, "classType", _classType);
|
||||
const locationName = helpers.string(ctx, "locationName", _locationName);
|
||||
return calculateClassEarnings(person, classType as ClassType, locationName as LocationName);
|
||||
},
|
||||
factionGains:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_player: unknown, _workType: unknown, _favor: unknown): WorkStats => {
|
||||
const player = helpers.player(ctx, _player);
|
||||
const workType = helpers.string(ctx, "_workType", _workType) as FactionWorkType;
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
const exp = calculateFactionExp(player, workType);
|
||||
const rep = calculateFactionRep(player, workType, favor);
|
||||
exp.reputation = rep;
|
||||
return exp;
|
||||
},
|
||||
// companyGains: (ctx: NetscriptContext) =>_player: unknown (): WorkStats {
|
||||
crimeGains: (ctx) => (_crimeType) => {
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
const crime = Object.values(Crimes).find((c) => String(c.type) === crimeType);
|
||||
if (!crime) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return calculateCrimeWorkStats(crime);
|
||||
},
|
||||
classGains: (ctx) => (_person, _classType, _locationName) => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
const classType = helpers.string(ctx, "classType", _classType);
|
||||
const locationName = helpers.string(ctx, "locationName", _locationName);
|
||||
return calculateClassEarnings(person, classType as ClassType, locationName as LocationName);
|
||||
},
|
||||
factionGains: (ctx) => (_player, _workType, _favor) => {
|
||||
const player = helpers.player(ctx, _player);
|
||||
const workType = helpers.string(ctx, "_workType", _workType) as FactionWorkType;
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
const exp = calculateFactionExp(player, workType);
|
||||
const rep = calculateFactionRep(player, workType, favor);
|
||||
exp.reputation = rep;
|
||||
return exp;
|
||||
},
|
||||
// companyGains: (ctx) => (_player) {
|
||||
// const player = helpers.player(ctx, _player);
|
||||
|
||||
// },
|
||||
|
@ -9,16 +9,7 @@ import { GangMember } from "../Gang/GangMember";
|
||||
import { GangMemberTask } from "../Gang/GangMemberTask";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
|
||||
import {
|
||||
Gang as IGang,
|
||||
GangGenInfo,
|
||||
GangOtherInfo,
|
||||
GangMemberInfo,
|
||||
GangMemberAscension,
|
||||
EquipmentStats,
|
||||
GangTaskStats,
|
||||
GangOtherInfoObject,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Gang as IGang, EquipmentStats, GangOtherInfoObject } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
|
||||
export function NetscriptGang(): InternalAPI<IGang> {
|
||||
@ -44,28 +35,26 @@ export function NetscriptGang(): InternalAPI<IGang> {
|
||||
};
|
||||
|
||||
return {
|
||||
createGang:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_faction: unknown): boolean => {
|
||||
const faction = helpers.string(ctx, "faction", _faction);
|
||||
// this list is copied from Faction/ui/Root.tsx
|
||||
createGang: (ctx) => (_faction) => {
|
||||
const faction = helpers.string(ctx, "faction", _faction);
|
||||
// this list is copied from Faction/ui/Root.tsx
|
||||
|
||||
if (!Player.canAccessGang() || !GangConstants.Names.includes(faction)) return false;
|
||||
if (Player.gang) return false;
|
||||
if (!Player.factions.includes(faction)) return false;
|
||||
if (!Player.canAccessGang() || !GangConstants.Names.includes(faction)) return false;
|
||||
if (Player.gang) return false;
|
||||
if (!Player.factions.includes(faction)) return false;
|
||||
|
||||
const isHacking = faction === FactionNames.NiteSec || faction === FactionNames.TheBlackHand;
|
||||
Player.startGang(faction, isHacking);
|
||||
return true;
|
||||
},
|
||||
inGang: () => (): boolean => {
|
||||
const isHacking = faction === FactionNames.NiteSec || faction === FactionNames.TheBlackHand;
|
||||
Player.startGang(faction, isHacking);
|
||||
return true;
|
||||
},
|
||||
inGang: () => () => {
|
||||
return Player.gang ? true : false;
|
||||
},
|
||||
getMemberNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
getMemberNames: (ctx) => () => {
|
||||
const gang = getGang(ctx);
|
||||
return gang.members.map((member) => member.name);
|
||||
},
|
||||
getGangInformation: (ctx: NetscriptContext) => (): GangGenInfo => {
|
||||
getGangInformation: (ctx) => () => {
|
||||
const gang = getGang(ctx);
|
||||
return {
|
||||
faction: gang.facName,
|
||||
@ -82,7 +71,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
|
||||
wantedPenalty: gang.getWantedPenalty(),
|
||||
};
|
||||
},
|
||||
getOtherGangInformation: (ctx: NetscriptContext) => (): GangOtherInfo => {
|
||||
getOtherGangInformation: (ctx) => () => {
|
||||
getGang(ctx);
|
||||
const cpy: Record<string, GangOtherInfoObject> = {};
|
||||
for (const gang of Object.keys(AllGangs)) {
|
||||
@ -91,231 +80,206 @@ export function NetscriptGang(): InternalAPI<IGang> {
|
||||
|
||||
return cpy;
|
||||
},
|
||||
getMemberInformation:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_memberName: unknown): GangMemberInfo => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const gang = getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
return {
|
||||
name: member.name,
|
||||
task: member.task,
|
||||
earnedRespect: member.earnedRespect,
|
||||
hack: member.hack,
|
||||
str: member.str,
|
||||
def: member.def,
|
||||
dex: member.dex,
|
||||
agi: member.agi,
|
||||
cha: member.cha,
|
||||
getMemberInformation: (ctx) => (_memberName) => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const gang = getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
return {
|
||||
name: member.name,
|
||||
task: member.task,
|
||||
earnedRespect: member.earnedRespect,
|
||||
hack: member.hack,
|
||||
str: member.str,
|
||||
def: member.def,
|
||||
dex: member.dex,
|
||||
agi: member.agi,
|
||||
cha: member.cha,
|
||||
|
||||
hack_exp: member.hack_exp,
|
||||
str_exp: member.str_exp,
|
||||
def_exp: member.def_exp,
|
||||
dex_exp: member.dex_exp,
|
||||
agi_exp: member.agi_exp,
|
||||
cha_exp: member.cha_exp,
|
||||
hack_exp: member.hack_exp,
|
||||
str_exp: member.str_exp,
|
||||
def_exp: member.def_exp,
|
||||
dex_exp: member.dex_exp,
|
||||
agi_exp: member.agi_exp,
|
||||
cha_exp: member.cha_exp,
|
||||
|
||||
hack_mult: member.hack_mult,
|
||||
str_mult: member.str_mult,
|
||||
def_mult: member.def_mult,
|
||||
dex_mult: member.dex_mult,
|
||||
agi_mult: member.agi_mult,
|
||||
cha_mult: member.cha_mult,
|
||||
hack_mult: member.hack_mult,
|
||||
str_mult: member.str_mult,
|
||||
def_mult: member.def_mult,
|
||||
dex_mult: member.dex_mult,
|
||||
agi_mult: member.agi_mult,
|
||||
cha_mult: member.cha_mult,
|
||||
|
||||
hack_asc_mult: member.calculateAscensionMult(member.hack_asc_points),
|
||||
str_asc_mult: member.calculateAscensionMult(member.str_asc_points),
|
||||
def_asc_mult: member.calculateAscensionMult(member.def_asc_points),
|
||||
dex_asc_mult: member.calculateAscensionMult(member.dex_asc_points),
|
||||
agi_asc_mult: member.calculateAscensionMult(member.agi_asc_points),
|
||||
cha_asc_mult: member.calculateAscensionMult(member.cha_asc_points),
|
||||
hack_asc_mult: member.calculateAscensionMult(member.hack_asc_points),
|
||||
str_asc_mult: member.calculateAscensionMult(member.str_asc_points),
|
||||
def_asc_mult: member.calculateAscensionMult(member.def_asc_points),
|
||||
dex_asc_mult: member.calculateAscensionMult(member.dex_asc_points),
|
||||
agi_asc_mult: member.calculateAscensionMult(member.agi_asc_points),
|
||||
cha_asc_mult: member.calculateAscensionMult(member.cha_asc_points),
|
||||
|
||||
hack_asc_points: member.hack_asc_points,
|
||||
str_asc_points: member.str_asc_points,
|
||||
def_asc_points: member.def_asc_points,
|
||||
dex_asc_points: member.dex_asc_points,
|
||||
agi_asc_points: member.agi_asc_points,
|
||||
cha_asc_points: member.cha_asc_points,
|
||||
hack_asc_points: member.hack_asc_points,
|
||||
str_asc_points: member.str_asc_points,
|
||||
def_asc_points: member.def_asc_points,
|
||||
dex_asc_points: member.dex_asc_points,
|
||||
agi_asc_points: member.agi_asc_points,
|
||||
cha_asc_points: member.cha_asc_points,
|
||||
|
||||
upgrades: member.upgrades.slice(),
|
||||
augmentations: member.augmentations.slice(),
|
||||
upgrades: member.upgrades.slice(),
|
||||
augmentations: member.augmentations.slice(),
|
||||
|
||||
respectGain: member.calculateRespectGain(gang),
|
||||
wantedLevelGain: member.calculateWantedLevelGain(gang),
|
||||
moneyGain: member.calculateMoneyGain(gang),
|
||||
};
|
||||
},
|
||||
canRecruitMember: (ctx: NetscriptContext) => (): boolean => {
|
||||
respectGain: member.calculateRespectGain(gang),
|
||||
wantedLevelGain: member.calculateWantedLevelGain(gang),
|
||||
moneyGain: member.calculateMoneyGain(gang),
|
||||
};
|
||||
},
|
||||
canRecruitMember: (ctx) => () => {
|
||||
const gang = getGang(ctx);
|
||||
return gang.canRecruitMember();
|
||||
},
|
||||
recruitMember:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_memberName: unknown): boolean => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const gang = getGang(ctx);
|
||||
const recruited = gang.recruitMember(memberName);
|
||||
if (recruited) {
|
||||
ctx.workerScript.log("gang.recruitMember", () => `Successfully recruited Gang Member '${memberName}'`);
|
||||
} else {
|
||||
ctx.workerScript.log("gang.recruitMember", () => `Failed to recruit Gang Member '${memberName}'`);
|
||||
}
|
||||
recruitMember: (ctx) => (_memberName) => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const gang = getGang(ctx);
|
||||
const recruited = gang.recruitMember(memberName);
|
||||
if (recruited) {
|
||||
ctx.workerScript.log("gang.recruitMember", () => `Successfully recruited Gang Member '${memberName}'`);
|
||||
} else {
|
||||
ctx.workerScript.log("gang.recruitMember", () => `Failed to recruit Gang Member '${memberName}'`);
|
||||
}
|
||||
|
||||
return recruited;
|
||||
},
|
||||
getTaskNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
return recruited;
|
||||
},
|
||||
getTaskNames: (ctx) => () => {
|
||||
const gang = getGang(ctx);
|
||||
const tasks = gang.getAllTaskNames();
|
||||
tasks.unshift("Unassigned");
|
||||
return tasks;
|
||||
},
|
||||
setMemberTask:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_memberName: unknown, _taskName: unknown): boolean => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const taskName = helpers.string(ctx, "taskName", _taskName);
|
||||
const gang = getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
if (!gang.getAllTaskNames().includes(taskName)) {
|
||||
ctx.workerScript.log(
|
||||
"gang.setMemberTask",
|
||||
() =>
|
||||
`Failed to assign Gang Member '${memberName}' to Invalid task '${taskName}'. '${memberName}' is now Unassigned`,
|
||||
);
|
||||
return member.assignToTask("Unassigned");
|
||||
}
|
||||
const success = member.assignToTask(taskName);
|
||||
if (success) {
|
||||
ctx.workerScript.log(
|
||||
"gang.setMemberTask",
|
||||
() => `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`,
|
||||
);
|
||||
} else {
|
||||
ctx.workerScript.log(
|
||||
"gang.setMemberTask",
|
||||
() =>
|
||||
`Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
|
||||
);
|
||||
}
|
||||
setMemberTask: (ctx) => (_memberName, _taskName) => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const taskName = helpers.string(ctx, "taskName", _taskName);
|
||||
const gang = getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
if (!gang.getAllTaskNames().includes(taskName)) {
|
||||
ctx.workerScript.log(
|
||||
"gang.setMemberTask",
|
||||
() =>
|
||||
`Failed to assign Gang Member '${memberName}' to Invalid task '${taskName}'. '${memberName}' is now Unassigned`,
|
||||
);
|
||||
return member.assignToTask("Unassigned");
|
||||
}
|
||||
const success = member.assignToTask(taskName);
|
||||
if (success) {
|
||||
ctx.workerScript.log(
|
||||
"gang.setMemberTask",
|
||||
() => `Successfully assigned Gang Member '${memberName}' to '${taskName}' task`,
|
||||
);
|
||||
} else {
|
||||
ctx.workerScript.log(
|
||||
"gang.setMemberTask",
|
||||
() => `Failed to assign Gang Member '${memberName}' to '${taskName}' task. '${memberName}' is now Unassigned`,
|
||||
);
|
||||
}
|
||||
|
||||
return success;
|
||||
},
|
||||
getTaskStats:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_taskName: unknown): GangTaskStats => {
|
||||
const taskName = helpers.string(ctx, "taskName", _taskName);
|
||||
getGang(ctx);
|
||||
const task = getGangTask(ctx, taskName);
|
||||
const copy = Object.assign({}, task);
|
||||
copy.territory = Object.assign({}, task.territory);
|
||||
return copy;
|
||||
},
|
||||
getEquipmentNames: (ctx: NetscriptContext) => (): string[] => {
|
||||
return success;
|
||||
},
|
||||
getTaskStats: (ctx) => (_taskName) => {
|
||||
const taskName = helpers.string(ctx, "taskName", _taskName);
|
||||
getGang(ctx);
|
||||
const task = getGangTask(ctx, taskName);
|
||||
const copy = Object.assign({}, task);
|
||||
copy.territory = Object.assign({}, task.territory);
|
||||
return copy;
|
||||
},
|
||||
getEquipmentNames: (ctx) => () => {
|
||||
getGang(ctx);
|
||||
return Object.keys(GangMemberUpgrades);
|
||||
},
|
||||
getEquipmentCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_equipName: unknown): number => {
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
const gang = getGang(ctx);
|
||||
const upg = GangMemberUpgrades[equipName];
|
||||
if (upg === null) return Infinity;
|
||||
return gang.getUpgradeCost(upg);
|
||||
},
|
||||
getEquipmentType:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_equipName: unknown): string => {
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
getGang(ctx);
|
||||
const upg = GangMemberUpgrades[equipName];
|
||||
if (upg == null) return "";
|
||||
return upg.getType();
|
||||
},
|
||||
getEquipmentStats:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_equipName: unknown): EquipmentStats => {
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
getGang(ctx);
|
||||
const equipment = GangMemberUpgrades[equipName];
|
||||
if (!equipment) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid equipment: ${equipName}`);
|
||||
}
|
||||
const typecheck: EquipmentStats = equipment.mults;
|
||||
return Object.assign({}, typecheck) as any;
|
||||
},
|
||||
purchaseEquipment:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_memberName: unknown, _equipName: unknown): boolean => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
const equipment = GangMemberUpgrades[equipName];
|
||||
if (!equipment) return false;
|
||||
const res = member.buyUpgrade(equipment);
|
||||
if (res) {
|
||||
ctx.workerScript.log(
|
||||
"gang.purchaseEquipment",
|
||||
() => `Purchased '${equipName}' for Gang member '${memberName}'`,
|
||||
);
|
||||
} else {
|
||||
ctx.workerScript.log(
|
||||
"gang.purchaseEquipment",
|
||||
() => `Failed to purchase '${equipName}' for Gang member '${memberName}'`,
|
||||
);
|
||||
}
|
||||
getEquipmentCost: (ctx) => (_equipName) => {
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
const gang = getGang(ctx);
|
||||
const upg = GangMemberUpgrades[equipName];
|
||||
if (upg === null) return Infinity;
|
||||
return gang.getUpgradeCost(upg);
|
||||
},
|
||||
getEquipmentType: (ctx) => (_equipName) => {
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
getGang(ctx);
|
||||
const upg = GangMemberUpgrades[equipName];
|
||||
if (upg == null) return "";
|
||||
return upg.getType();
|
||||
},
|
||||
getEquipmentStats: (ctx) => (_equipName) => {
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
getGang(ctx);
|
||||
const equipment = GangMemberUpgrades[equipName];
|
||||
if (!equipment) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid equipment: ${equipName}`);
|
||||
}
|
||||
const typecheck: EquipmentStats = equipment.mults;
|
||||
return Object.assign({}, typecheck);
|
||||
},
|
||||
purchaseEquipment: (ctx) => (_memberName, _equipName) => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const equipName = helpers.string(ctx, "equipName", _equipName);
|
||||
getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
const equipment = GangMemberUpgrades[equipName];
|
||||
if (!equipment) return false;
|
||||
const res = member.buyUpgrade(equipment);
|
||||
if (res) {
|
||||
ctx.workerScript.log(
|
||||
"gang.purchaseEquipment",
|
||||
() => `Purchased '${equipName}' for Gang member '${memberName}'`,
|
||||
);
|
||||
} else {
|
||||
ctx.workerScript.log(
|
||||
"gang.purchaseEquipment",
|
||||
() => `Failed to purchase '${equipName}' for Gang member '${memberName}'`,
|
||||
);
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
ascendMember:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_memberName: unknown): GangMemberAscension | undefined => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const gang = getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
if (!member.canAscend()) return;
|
||||
return gang.ascendMember(member, ctx.workerScript);
|
||||
},
|
||||
getAscensionResult:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_memberName: unknown): GangMemberAscension | undefined => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
if (!member.canAscend()) return;
|
||||
return {
|
||||
respect: member.earnedRespect,
|
||||
...member.getAscensionResults(),
|
||||
};
|
||||
},
|
||||
setTerritoryWarfare:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_engage: unknown): void => {
|
||||
const engage = !!_engage;
|
||||
const gang = getGang(ctx);
|
||||
if (engage) {
|
||||
gang.territoryWarfareEngaged = true;
|
||||
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Engaging in Gang Territory Warfare");
|
||||
} else {
|
||||
gang.territoryWarfareEngaged = false;
|
||||
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
|
||||
}
|
||||
},
|
||||
getChanceToWinClash:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_otherGang: unknown): number => {
|
||||
const otherGang = helpers.string(ctx, "otherGang", _otherGang);
|
||||
const gang = getGang(ctx);
|
||||
if (AllGangs[otherGang] == null) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid gang: ${otherGang}`);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
ascendMember: (ctx) => (_memberName) => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
const gang = getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
if (!member.canAscend()) return;
|
||||
return gang.ascendMember(member, ctx.workerScript);
|
||||
},
|
||||
getAscensionResult: (ctx) => (_memberName) => {
|
||||
const memberName = helpers.string(ctx, "memberName", _memberName);
|
||||
getGang(ctx);
|
||||
const member = getGangMember(ctx, memberName);
|
||||
if (!member.canAscend()) return;
|
||||
return {
|
||||
respect: member.earnedRespect,
|
||||
...member.getAscensionResults(),
|
||||
};
|
||||
},
|
||||
setTerritoryWarfare: (ctx) => (_engage) => {
|
||||
const engage = !!_engage;
|
||||
const gang = getGang(ctx);
|
||||
if (engage) {
|
||||
gang.territoryWarfareEngaged = true;
|
||||
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Engaging in Gang Territory Warfare");
|
||||
} else {
|
||||
gang.territoryWarfareEngaged = false;
|
||||
ctx.workerScript.log("gang.setTerritoryWarfare", () => "Disengaging in Gang Territory Warfare");
|
||||
}
|
||||
},
|
||||
getChanceToWinClash: (ctx) => (_otherGang) => {
|
||||
const otherGang = helpers.string(ctx, "otherGang", _otherGang);
|
||||
const gang = getGang(ctx);
|
||||
if (AllGangs[otherGang] == null) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid gang: ${otherGang}`);
|
||||
}
|
||||
|
||||
const playerPower = AllGangs[gang.facName].power;
|
||||
const otherPower = AllGangs[otherGang].power;
|
||||
const playerPower = AllGangs[gang.facName].power;
|
||||
const otherPower = AllGangs[otherGang].power;
|
||||
|
||||
return playerPower / (otherPower + playerPower);
|
||||
},
|
||||
getBonusTime: (ctx: NetscriptContext) => (): number => {
|
||||
return playerPower / (otherPower + playerPower);
|
||||
},
|
||||
getBonusTime: (ctx) => () => {
|
||||
const gang = getGang(ctx);
|
||||
return Math.round(gang.storedCycles / 5) * 1000;
|
||||
},
|
||||
|
@ -21,39 +21,35 @@ export function NetscriptGrafting(): InternalAPI<IGrafting> {
|
||||
};
|
||||
|
||||
return {
|
||||
getAugmentationGraftPrice:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_augName: unknown): number => {
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
checkGraftingAPIAccess(ctx);
|
||||
if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||
}
|
||||
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||
return graftableAug.cost;
|
||||
},
|
||||
getAugmentationGraftPrice: (ctx) => (_augName) => {
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
checkGraftingAPIAccess(ctx);
|
||||
if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||
}
|
||||
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||
return graftableAug.cost;
|
||||
},
|
||||
|
||||
getAugmentationGraftTime:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_augName: string): number => {
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
checkGraftingAPIAccess(ctx);
|
||||
if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||
}
|
||||
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||
return calculateGraftingTimeWithBonus(graftableAug);
|
||||
},
|
||||
getAugmentationGraftTime: (ctx) => (_augName) => {
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
checkGraftingAPIAccess(ctx);
|
||||
if (!getGraftingAvailableAugs().includes(augName) || !StaticAugmentations.hasOwnProperty(augName)) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||
}
|
||||
const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]);
|
||||
return calculateGraftingTimeWithBonus(graftableAug);
|
||||
},
|
||||
|
||||
getGraftableAugmentations: (ctx: NetscriptContext) => (): string[] => {
|
||||
getGraftableAugmentations: (ctx) => () => {
|
||||
checkGraftingAPIAccess(ctx);
|
||||
const graftableAugs = getGraftingAvailableAugs();
|
||||
return graftableAugs;
|
||||
},
|
||||
|
||||
graftAugmentation:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_augName: string, _focus: unknown = true): boolean => {
|
||||
(ctx) =>
|
||||
(_augName, _focus = true) => {
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const focus = !!_focus;
|
||||
checkGraftingAPIAccess(ctx);
|
||||
|
@ -50,76 +50,74 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
|
||||
};
|
||||
|
||||
return {
|
||||
numNodes: () => (): number => {
|
||||
numNodes: () => () => {
|
||||
return player.hacknetNodes.length;
|
||||
},
|
||||
maxNumNodes: () => (): number => {
|
||||
maxNumNodes: () => () => {
|
||||
if (hasHacknetServers()) {
|
||||
return HacknetServerConstants.MaxServers;
|
||||
}
|
||||
return Infinity;
|
||||
},
|
||||
purchaseNode: () => (): number => {
|
||||
purchaseNode: () => () => {
|
||||
return purchaseHacknet();
|
||||
},
|
||||
getPurchaseNodeCost: () => (): number => {
|
||||
getPurchaseNodeCost: () => () => {
|
||||
if (hasHacknetServers()) {
|
||||
return getCostOfNextHacknetServer();
|
||||
} else {
|
||||
return getCostOfNextHacknetNode();
|
||||
}
|
||||
},
|
||||
getNodeStats:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown): NodeStats => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
const hasUpgraded = hasHacknetServers();
|
||||
const res: NodeStats = {
|
||||
name: node instanceof HacknetServer ? node.hostname : node.name,
|
||||
level: node.level,
|
||||
ram: node instanceof HacknetServer ? node.maxRam : node.ram,
|
||||
cores: node.cores,
|
||||
production: node instanceof HacknetServer ? node.hashRate : node.moneyGainRatePerSecond,
|
||||
timeOnline: node.onlineTimeSeconds,
|
||||
totalProduction: node instanceof HacknetServer ? node.totalHashesGenerated : node.totalMoneyGenerated,
|
||||
};
|
||||
getNodeStats: (ctx) => (_i) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
const hasUpgraded = hasHacknetServers();
|
||||
const res: NodeStats = {
|
||||
name: node instanceof HacknetServer ? node.hostname : node.name,
|
||||
level: node.level,
|
||||
ram: node instanceof HacknetServer ? node.maxRam : node.ram,
|
||||
cores: node.cores,
|
||||
production: node instanceof HacknetServer ? node.hashRate : node.moneyGainRatePerSecond,
|
||||
timeOnline: node.onlineTimeSeconds,
|
||||
totalProduction: node instanceof HacknetServer ? node.totalHashesGenerated : node.totalMoneyGenerated,
|
||||
};
|
||||
|
||||
if (hasUpgraded && node instanceof HacknetServer) {
|
||||
res.cache = node.cache;
|
||||
res.hashCapacity = node.hashCapacity;
|
||||
res.ramUsed = node.ramUsed;
|
||||
}
|
||||
if (hasUpgraded && node instanceof HacknetServer) {
|
||||
res.cache = node.cache;
|
||||
res.hashCapacity = node.hashCapacity;
|
||||
res.ramUsed = node.ramUsed;
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
return res;
|
||||
},
|
||||
upgradeLevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): boolean => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
return purchaseLevelUpgrade(node, n);
|
||||
},
|
||||
upgradeRam:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): boolean => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
return purchaseRamUpgrade(node, n);
|
||||
},
|
||||
upgradeCore:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): boolean => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
return purchaseCoreUpgrade(node, n);
|
||||
},
|
||||
upgradeCache:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): boolean => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
if (!hasHacknetServers()) {
|
||||
@ -137,32 +135,32 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
|
||||
return res;
|
||||
},
|
||||
getLevelUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
return node.calculateLevelUpgradeCost(n, player.mults.hacknet_node_level_cost);
|
||||
},
|
||||
getRamUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
return node.calculateRamUpgradeCost(n, player.mults.hacknet_node_ram_cost);
|
||||
},
|
||||
getCoreUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
const node = getHacknetNode(ctx, i);
|
||||
return node.calculateCoreUpgradeCost(n, player.mults.hacknet_node_core_cost);
|
||||
},
|
||||
getCacheUpgradeCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_i: unknown, _n: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_i, _n = 1) => {
|
||||
const i = helpers.number(ctx, "i", _i);
|
||||
const n = helpers.number(ctx, "n", _n);
|
||||
if (!hasHacknetServers()) {
|
||||
@ -175,21 +173,21 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
|
||||
}
|
||||
return node.calculateCacheUpgradeCost(n);
|
||||
},
|
||||
numHashes: () => (): number => {
|
||||
numHashes: () => () => {
|
||||
if (!hasHacknetServers()) {
|
||||
return 0;
|
||||
}
|
||||
return player.hashManager.hashes;
|
||||
},
|
||||
hashCapacity: () => (): number => {
|
||||
hashCapacity: () => () => {
|
||||
if (!hasHacknetServers()) {
|
||||
return 0;
|
||||
}
|
||||
return player.hashManager.capacity;
|
||||
},
|
||||
hashCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_upgName: unknown, _count: unknown = 1): number => {
|
||||
(ctx) =>
|
||||
(_upgName, _count = 1) => {
|
||||
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||
const count = helpers.number(ctx, "count", _count);
|
||||
if (!hasHacknetServers()) {
|
||||
@ -199,8 +197,8 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
|
||||
return player.hashManager.getUpgradeCost(upgName, count);
|
||||
},
|
||||
spendHashes:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_upgName: unknown, _upgTarget: unknown = "", _count: unknown = 1): boolean => {
|
||||
(ctx) =>
|
||||
(_upgName, _upgTarget = "", _count = 1) => {
|
||||
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||
const upgTarget = helpers.string(ctx, "upgTarget", _upgTarget);
|
||||
const count = helpers.number(ctx, "count", _count);
|
||||
@ -209,29 +207,27 @@ export function NetscriptHacknet(): InternalAPI<IHacknet> {
|
||||
}
|
||||
return purchaseHashUpgrade(upgName, upgTarget, count);
|
||||
},
|
||||
getHashUpgrades: () => (): string[] => {
|
||||
getHashUpgrades: () => () => {
|
||||
if (!hasHacknetServers()) {
|
||||
return [];
|
||||
}
|
||||
return Object.values(HashUpgrades).map((upgrade: HashUpgrade) => upgrade.name);
|
||||
},
|
||||
getHashUpgradeLevel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_upgName: unknown): number => {
|
||||
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||
const level = player.hashManager.upgrades[upgName];
|
||||
if (level === undefined) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid Hash Upgrade: ${upgName}`);
|
||||
}
|
||||
return level;
|
||||
},
|
||||
getStudyMult: () => (): number => {
|
||||
getHashUpgradeLevel: (ctx) => (_upgName) => {
|
||||
const upgName = helpers.string(ctx, "upgName", _upgName);
|
||||
const level = player.hashManager.upgrades[upgName];
|
||||
if (level === undefined) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid Hash Upgrade: ${upgName}`);
|
||||
}
|
||||
return level;
|
||||
},
|
||||
getStudyMult: () => () => {
|
||||
if (!hasHacknetServers()) {
|
||||
return 1;
|
||||
}
|
||||
return player.hashManager.getStudyMult();
|
||||
},
|
||||
getTrainingMult: () => (): number => {
|
||||
getTrainingMult: () => () => {
|
||||
if (!hasHacknetServers()) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -1,8 +1,4 @@
|
||||
import {
|
||||
Infiltration as IInfiltration,
|
||||
InfiltrationLocation,
|
||||
PossibleInfiltrationLocation,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Infiltration as IInfiltration, InfiltrationLocation } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Location } from "../Locations/Location";
|
||||
import { Locations } from "../Locations/Locations";
|
||||
import { calculateDifficulty, calculateReward } from "../Infiltration/formulas/game";
|
||||
@ -44,17 +40,15 @@ export function NetscriptInfiltration(): InternalAPI<IInfiltration> {
|
||||
};
|
||||
};
|
||||
return {
|
||||
getPossibleLocations: () => (): PossibleInfiltrationLocation[] => {
|
||||
getPossibleLocations: () => () => {
|
||||
return getLocationsWithInfiltrations.map((l) => ({
|
||||
city: l.city ?? "",
|
||||
name: String(l.name),
|
||||
}));
|
||||
},
|
||||
getInfiltration:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_location: unknown): InfiltrationLocation => {
|
||||
const location = helpers.string(ctx, "location", _location);
|
||||
return calculateInfiltrationData(ctx, location);
|
||||
},
|
||||
getInfiltration: (ctx) => (_location) => {
|
||||
const location = helpers.string(ctx, "location", _location);
|
||||
return calculateInfiltrationData(ctx, location);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
Multipliers,
|
||||
CrimeStats,
|
||||
Singularity as ISingularity,
|
||||
SourceFileLvl,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
|
||||
import { findCrime } from "../Crime/CrimeHelpers";
|
||||
@ -79,7 +78,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return company;
|
||||
};
|
||||
|
||||
const runAfterReset = function (cbScript: string | null = null): void {
|
||||
const runAfterReset = function (cbScript: string | null = null) {
|
||||
//Run a script after reset
|
||||
if (!cbScript) return;
|
||||
const home = Player.getHomeComputer();
|
||||
@ -98,11 +97,11 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
};
|
||||
|
||||
return {
|
||||
getOwnedAugmentations: (ctx: NetscriptContext) =>
|
||||
function (_purchased: unknown = false): string[] {
|
||||
getOwnedAugmentations: (ctx) =>
|
||||
function (_purchased = false) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const purchased = !!_purchased;
|
||||
const res = [];
|
||||
const res: string[] = [];
|
||||
for (let i = 0; i < Player.augmentations.length; ++i) {
|
||||
res.push(Player.augmentations[i].name);
|
||||
}
|
||||
@ -113,69 +112,64 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getOwnedSourceFiles: () => (): SourceFileLvl[] => {
|
||||
const res: SourceFileLvl[] = [];
|
||||
for (let i = 0; i < Player.sourceFiles.length; ++i) {
|
||||
res.push({
|
||||
n: Player.sourceFiles[i].n,
|
||||
lvl: Player.sourceFiles[i].lvl,
|
||||
});
|
||||
}
|
||||
return res;
|
||||
getOwnedSourceFiles: () => () => {
|
||||
return Player.sourceFiles.map((sf) => {
|
||||
return { n: sf.n, lvl: sf.lvl };
|
||||
});
|
||||
},
|
||||
getAugmentationsFromFaction: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown): string[] {
|
||||
getAugmentationsFromFaction: (ctx) =>
|
||||
function (_facName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const faction = getFaction(ctx, facName);
|
||||
|
||||
return getFactionAugmentationsFiltered(faction);
|
||||
},
|
||||
getAugmentationCost: (ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): [number, number] {
|
||||
getAugmentationCost: (ctx) =>
|
||||
function (_augName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug = getAugmentation(ctx, augName);
|
||||
const costs = aug.getCost();
|
||||
return [costs.repCost, costs.moneyCost];
|
||||
},
|
||||
getAugmentationPrereq: (ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): string[] {
|
||||
getAugmentationPrereq: (ctx) =>
|
||||
function (_augName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug = getAugmentation(ctx, augName);
|
||||
return aug.prereqs.slice();
|
||||
},
|
||||
getAugmentationBasePrice: (ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): number {
|
||||
getAugmentationBasePrice: (ctx) =>
|
||||
function (_augName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug = getAugmentation(ctx, augName);
|
||||
return aug.baseCost * BitNodeMultipliers.AugmentationMoneyCost;
|
||||
},
|
||||
getAugmentationPrice: (ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): number {
|
||||
getAugmentationPrice: (ctx) =>
|
||||
function (_augName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug = getAugmentation(ctx, augName);
|
||||
return aug.getCost().moneyCost;
|
||||
},
|
||||
getAugmentationRepReq: (ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): number {
|
||||
getAugmentationRepReq: (ctx) =>
|
||||
function (_augName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug = getAugmentation(ctx, augName);
|
||||
return aug.getCost().repCost;
|
||||
},
|
||||
getAugmentationStats: (ctx: NetscriptContext) =>
|
||||
function (_augName: unknown): Multipliers {
|
||||
getAugmentationStats: (ctx) =>
|
||||
function (_augName): Multipliers {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug = getAugmentation(ctx, augName);
|
||||
return Object.assign({}, aug.mults);
|
||||
},
|
||||
purchaseAugmentation: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown, _augName: unknown): boolean {
|
||||
purchaseAugmentation: (ctx) =>
|
||||
function (_facName, _augName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
@ -224,8 +218,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
softReset: (ctx: NetscriptContext) =>
|
||||
function (_cbScript: unknown = ""): void {
|
||||
softReset: (ctx) =>
|
||||
function (_cbScript = "") {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const cbScript = helpers.string(ctx, "cbScript", _cbScript);
|
||||
|
||||
@ -237,8 +231,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
|
||||
killWorkerScript(ctx.workerScript);
|
||||
},
|
||||
installAugmentations: (ctx: NetscriptContext) =>
|
||||
function (_cbScript: unknown = ""): boolean {
|
||||
installAugmentations: (ctx) =>
|
||||
function (_cbScript = "") {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const cbScript = helpers.string(ctx, "cbScript", _cbScript);
|
||||
|
||||
@ -257,8 +251,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return true;
|
||||
},
|
||||
|
||||
goToLocation: (ctx: NetscriptContext) =>
|
||||
function (_locationName: unknown): boolean {
|
||||
goToLocation: (ctx) =>
|
||||
function (_locationName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const locationName = helpers.string(ctx, "locationName", _locationName);
|
||||
const location = Object.values(Locations).find((l) => l.name === locationName);
|
||||
@ -280,8 +274,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000);
|
||||
return true;
|
||||
},
|
||||
universityCourse: (ctx: NetscriptContext) =>
|
||||
function (_universityName: unknown, _className: unknown, _focus: unknown = true): boolean {
|
||||
universityCourse: (ctx) =>
|
||||
function (_universityName, _className, _focus = true) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const universityName = helpers.string(ctx, "universityName", _universityName);
|
||||
const className = helpers.string(ctx, "className", _className);
|
||||
@ -366,8 +360,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return true;
|
||||
},
|
||||
|
||||
gymWorkout: (ctx: NetscriptContext) =>
|
||||
function (_gymName: unknown, _stat: unknown, _focus: unknown = true): boolean {
|
||||
gymWorkout: (ctx) =>
|
||||
function (_gymName, _stat, _focus = true) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const gymName = helpers.string(ctx, "gymName", _gymName);
|
||||
const stat = helpers.string(ctx, "stat", _stat);
|
||||
@ -475,8 +469,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return true;
|
||||
},
|
||||
|
||||
travelToCity: (ctx: NetscriptContext) =>
|
||||
function (_cityName: unknown): boolean {
|
||||
travelToCity: (ctx) =>
|
||||
function (_cityName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const cityName = helpers.city(ctx, "cityName", _cityName);
|
||||
|
||||
@ -501,8 +495,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
},
|
||||
|
||||
purchaseTor: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
purchaseTor: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
||||
if (Player.hasTorRouter()) {
|
||||
@ -525,8 +519,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
helpers.log(ctx, () => "You have purchased a Tor router!");
|
||||
return true;
|
||||
},
|
||||
purchaseProgram: (ctx: NetscriptContext) =>
|
||||
function (_programName: unknown): boolean {
|
||||
purchaseProgram: (ctx) =>
|
||||
function (_programName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const programName = helpers.string(ctx, "programName", _programName).toLowerCase();
|
||||
|
||||
@ -568,13 +562,13 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 5000);
|
||||
return true;
|
||||
},
|
||||
getCurrentServer: (ctx: NetscriptContext) =>
|
||||
getCurrentServer: (ctx) =>
|
||||
function (): string {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
return Player.getCurrentServer().hostname;
|
||||
},
|
||||
connect: (ctx: NetscriptContext) =>
|
||||
function (_hostname: unknown): boolean {
|
||||
connect: (ctx) =>
|
||||
function (_hostname) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const hostname = helpers.string(ctx, "hostname", _hostname);
|
||||
if (!hostname) {
|
||||
@ -622,13 +616,13 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
//Failure case
|
||||
return false;
|
||||
},
|
||||
manualHack: (ctx: NetscriptContext) =>
|
||||
manualHack: (ctx) =>
|
||||
function (): Promise<number> {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const server = Player.getCurrentServer();
|
||||
return helpers.hack(ctx, server.hostname, true);
|
||||
},
|
||||
installBackdoor: (ctx: NetscriptContext) => async (): Promise<void> => {
|
||||
installBackdoor: (ctx) => async (): Promise<void> => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const baseserver = Player.getCurrentServer();
|
||||
if (!(baseserver instanceof Server)) {
|
||||
@ -660,13 +654,13 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return Promise.resolve();
|
||||
});
|
||||
},
|
||||
isFocused: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
isFocused: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
return Player.focus;
|
||||
},
|
||||
setFocus: (ctx: NetscriptContext) =>
|
||||
function (_focus: unknown): boolean {
|
||||
setFocus: (ctx) =>
|
||||
function (_focus) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const focus = !!_focus;
|
||||
if (Player.currentWork === null) {
|
||||
@ -684,8 +678,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
hospitalize: (ctx: NetscriptContext) =>
|
||||
function (): void {
|
||||
hospitalize: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
if (Player.currentWork || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
|
||||
helpers.log(ctx, () => "Cannot go to the hospital because the player is busy.");
|
||||
@ -693,20 +687,20 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
Player.hospitalize();
|
||||
},
|
||||
isBusy: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
isBusy: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
return Player.currentWork !== null || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse;
|
||||
},
|
||||
stopAction: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
stopAction: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const wasWorking = Player.currentWork !== null;
|
||||
Player.finishWork(true);
|
||||
return wasWorking;
|
||||
},
|
||||
upgradeHomeCores: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
upgradeHomeCores: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
||||
// Check if we're at max cores
|
||||
@ -732,14 +726,14 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
);
|
||||
return true;
|
||||
},
|
||||
getUpgradeHomeCoresCost: (ctx: NetscriptContext) =>
|
||||
function (): number {
|
||||
getUpgradeHomeCoresCost: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
||||
return Player.getUpgradeHomeCoresCost();
|
||||
},
|
||||
upgradeHomeRam: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
upgradeHomeRam: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
||||
// Check if we're at max RAM
|
||||
@ -768,14 +762,14 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
);
|
||||
return true;
|
||||
},
|
||||
getUpgradeHomeRamCost: (ctx: NetscriptContext) =>
|
||||
function (): number {
|
||||
getUpgradeHomeRamCost: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
||||
return Player.getUpgradeHomeRamCost();
|
||||
},
|
||||
workForCompany: (ctx: NetscriptContext) =>
|
||||
function (_companyName: unknown, _focus: unknown = true): boolean {
|
||||
workForCompany: (ctx) =>
|
||||
function (_companyName, _focus = true) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const focus = !!_focus;
|
||||
@ -818,8 +812,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
helpers.log(ctx, () => `Began working at '${companyName}' with position '${companyPositionName}'`);
|
||||
return true;
|
||||
},
|
||||
applyToCompany: (ctx: NetscriptContext) =>
|
||||
function (_companyName: unknown, _field: unknown): boolean {
|
||||
applyToCompany: (ctx) =>
|
||||
function (_companyName, _field) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const field = helpers.string(ctx, "field", _field);
|
||||
@ -887,41 +881,41 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
quitJob: (ctx: NetscriptContext) =>
|
||||
function (_companyName: unknown): void {
|
||||
quitJob: (ctx) =>
|
||||
function (_companyName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
Player.quitJob(companyName);
|
||||
},
|
||||
getCompanyRep: (ctx: NetscriptContext) =>
|
||||
function (_companyName: unknown): number {
|
||||
getCompanyRep: (ctx) =>
|
||||
function (_companyName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const company = getCompany(ctx, companyName);
|
||||
return company.playerReputation;
|
||||
},
|
||||
getCompanyFavor: (ctx: NetscriptContext) =>
|
||||
function (_companyName: unknown): number {
|
||||
getCompanyFavor: (ctx) =>
|
||||
function (_companyName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const company = getCompany(ctx, companyName);
|
||||
return company.favor;
|
||||
},
|
||||
getCompanyFavorGain: (ctx: NetscriptContext) =>
|
||||
function (_companyName: unknown): number {
|
||||
getCompanyFavorGain: (ctx) =>
|
||||
function (_companyName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const companyName = helpers.string(ctx, "companyName", _companyName);
|
||||
const company = getCompany(ctx, companyName);
|
||||
return company.getFavorGain();
|
||||
},
|
||||
checkFactionInvitations: (ctx: NetscriptContext) =>
|
||||
function (): string[] {
|
||||
checkFactionInvitations: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
// Make a copy of player.factionInvitations
|
||||
return Player.factionInvitations.slice();
|
||||
},
|
||||
joinFaction: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown): boolean {
|
||||
joinFaction: (ctx) =>
|
||||
function (_facName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
getFaction(ctx, facName);
|
||||
@ -944,8 +938,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
helpers.log(ctx, () => `Joined the '${facName}' faction.`);
|
||||
return true;
|
||||
},
|
||||
workForFaction: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown, _type: unknown, _focus: unknown = true): boolean {
|
||||
workForFaction: (ctx) =>
|
||||
function (_facName, _type, _focus = true) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
@ -1040,29 +1034,29 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
getFactionRep: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown): number {
|
||||
getFactionRep: (ctx) =>
|
||||
function (_facName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const faction = getFaction(ctx, facName);
|
||||
return faction.playerReputation;
|
||||
},
|
||||
getFactionFavor: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown): number {
|
||||
getFactionFavor: (ctx) =>
|
||||
function (_facName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const faction = getFaction(ctx, facName);
|
||||
return faction.favor;
|
||||
},
|
||||
getFactionFavorGain: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown): number {
|
||||
getFactionFavorGain: (ctx) =>
|
||||
function (_facName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const faction = getFaction(ctx, facName);
|
||||
return faction.getFavorGain();
|
||||
},
|
||||
donateToFaction: (ctx: NetscriptContext) =>
|
||||
function (_facName: unknown, _amt: unknown): boolean {
|
||||
donateToFaction: (ctx) =>
|
||||
function (_facName, _amt) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const facName = helpers.string(ctx, "facName", _facName);
|
||||
const amt = helpers.number(ctx, "amt", _amt);
|
||||
@ -1111,8 +1105,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
);
|
||||
return true;
|
||||
},
|
||||
createProgram: (ctx: NetscriptContext) =>
|
||||
function (_programName: unknown, _focus: unknown = true): boolean {
|
||||
createProgram: (ctx) =>
|
||||
function (_programName, _focus = true) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const programName = helpers.string(ctx, "programName", _programName).toLowerCase();
|
||||
const focus = !!_focus;
|
||||
@ -1158,8 +1152,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
helpers.log(ctx, () => `Began creating program: '${programName}'`);
|
||||
return true;
|
||||
},
|
||||
commitCrime: (ctx: NetscriptContext) =>
|
||||
function (_crimeRoughName: unknown, _focus: unknown = true): number {
|
||||
commitCrime: (ctx) =>
|
||||
function (_crimeRoughName, _focus = true) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
|
||||
const focus = !!_focus;
|
||||
@ -1188,8 +1182,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
return crimeTime;
|
||||
},
|
||||
getCrimeChance: (ctx: NetscriptContext) =>
|
||||
function (_crimeRoughName: unknown): number {
|
||||
getCrimeChance: (ctx) =>
|
||||
function (_crimeRoughName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
|
||||
|
||||
@ -1200,8 +1194,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
|
||||
return crime.successRate(Player);
|
||||
},
|
||||
getCrimeStats: (ctx: NetscriptContext) =>
|
||||
function (_crimeRoughName: unknown): CrimeStats {
|
||||
getCrimeStats: (ctx) =>
|
||||
function (_crimeRoughName): CrimeStats {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeRoughName", _crimeRoughName);
|
||||
|
||||
@ -1224,8 +1218,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
intelligence_exp: crimeStatsWithMultipliers.intExp,
|
||||
});
|
||||
},
|
||||
getDarkwebPrograms: (ctx: NetscriptContext) =>
|
||||
function (): string[] {
|
||||
getDarkwebPrograms: (ctx) =>
|
||||
function () {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
|
||||
// If we don't have Tor, log it and return [] (empty list)
|
||||
@ -1235,8 +1229,8 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
}
|
||||
return Object.values(DarkWebItems).map((p) => p.program);
|
||||
},
|
||||
getDarkwebProgramCost: (ctx: NetscriptContext) =>
|
||||
function (_programName: unknown): number {
|
||||
getDarkwebProgramCost: (ctx) =>
|
||||
function (_programName) {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const programName = helpers.string(ctx, "programName", _programName).toLowerCase();
|
||||
|
||||
@ -1258,7 +1252,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`No such exploit ('${programName}') found on the darkweb! ` +
|
||||
`\nThis function is not case-sensitive. Did you perhaps forget .exe at the end?`,
|
||||
`\nThis function is not case-sensitive. Did you perhaps forget .exe at the end?`,
|
||||
);
|
||||
}
|
||||
|
||||
@ -1269,61 +1263,61 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
return item.price;
|
||||
},
|
||||
b1tflum3:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_nextBN: unknown, _callbackScript: unknown = ""): void => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const nextBN = helpers.number(ctx, "nextBN", _nextBN);
|
||||
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
enterBitNode(true, Player.bitNodeN, nextBN);
|
||||
if (callbackScript)
|
||||
setTimeout(() => {
|
||||
runAfterReset(callbackScript);
|
||||
}, 0);
|
||||
},
|
||||
(ctx) =>
|
||||
(_nextBN, _callbackScript = "") => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const nextBN = helpers.number(ctx, "nextBN", _nextBN);
|
||||
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
enterBitNode(true, Player.bitNodeN, nextBN);
|
||||
if (callbackScript)
|
||||
setTimeout(() => {
|
||||
runAfterReset(callbackScript);
|
||||
}, 0);
|
||||
},
|
||||
destroyW0r1dD43m0n:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_nextBN: unknown, _callbackScript: unknown = ""): void => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const nextBN = helpers.number(ctx, "nextBN", _nextBN);
|
||||
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
|
||||
(ctx) =>
|
||||
(_nextBN, _callbackScript = "") => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
const nextBN = helpers.number(ctx, "nextBN", _nextBN);
|
||||
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
|
||||
|
||||
const wd = GetServer(SpecialServers.WorldDaemon);
|
||||
if (!(wd instanceof Server)) throw new Error("WorldDaemon was not a normal server. This is a bug contact dev.");
|
||||
const hackingRequirements = (): boolean => {
|
||||
if (Player.skills.hacking < wd.requiredHackingSkill) return false;
|
||||
if (!wd.hasAdminRights) return false;
|
||||
return true;
|
||||
};
|
||||
const bladeburnerRequirements = (): boolean => {
|
||||
if (!Player.inBladeburner()) return false;
|
||||
if (!Player.bladeburner) return false;
|
||||
return Player.bladeburner.blackops[BlackOperationNames.OperationDaedalus];
|
||||
};
|
||||
const wd = GetServer(SpecialServers.WorldDaemon);
|
||||
if (!(wd instanceof Server)) throw new Error("WorldDaemon was not a normal server. This is a bug contact dev.");
|
||||
const hackingRequirements = () => {
|
||||
if (Player.skills.hacking < wd.requiredHackingSkill) return false;
|
||||
if (!wd.hasAdminRights) return false;
|
||||
return true;
|
||||
};
|
||||
const bladeburnerRequirements = () => {
|
||||
if (!Player.inBladeburner()) return false;
|
||||
if (!Player.bladeburner) return false;
|
||||
return Player.bladeburner.blackops[BlackOperationNames.OperationDaedalus];
|
||||
};
|
||||
|
||||
if (!hackingRequirements() && !bladeburnerRequirements()) {
|
||||
helpers.log(ctx, () => "Requirements not met to destroy the world daemon");
|
||||
return;
|
||||
}
|
||||
if (!hackingRequirements() && !bladeburnerRequirements()) {
|
||||
helpers.log(ctx, () => "Requirements not met to destroy the world daemon");
|
||||
return;
|
||||
}
|
||||
|
||||
wd.backdoorInstalled = true;
|
||||
calculateAchievements();
|
||||
enterBitNode(false, Player.bitNodeN, nextBN);
|
||||
if (callbackScript)
|
||||
setTimeout(() => {
|
||||
runAfterReset(callbackScript);
|
||||
}, 0);
|
||||
},
|
||||
getCurrentWork: () => (): any | null => {
|
||||
wd.backdoorInstalled = true;
|
||||
calculateAchievements();
|
||||
enterBitNode(false, Player.bitNodeN, nextBN);
|
||||
if (callbackScript)
|
||||
setTimeout(() => {
|
||||
runAfterReset(callbackScript);
|
||||
}, 0);
|
||||
},
|
||||
getCurrentWork: () => () => {
|
||||
if (!Player.currentWork) return null;
|
||||
return Player.currentWork.APICopy();
|
||||
},
|
||||
exportGame: (ctx: NetscriptContext) => (): void => {
|
||||
exportGame: (ctx) => () => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
onExport();
|
||||
return saveObject.exportGame();
|
||||
},
|
||||
exportGameBonus: (ctx: NetscriptContext) => (): boolean => {
|
||||
exportGameBonus: (ctx) => () => {
|
||||
helpers.checkSingularityAccess(ctx);
|
||||
return canGetBonus();
|
||||
},
|
||||
|
@ -4,13 +4,7 @@ import { CityName } from "../Locations/data/CityNames";
|
||||
import { findCrime } from "../Crime/CrimeHelpers";
|
||||
import { Augmentation } from "../Augmentation/Augmentation";
|
||||
|
||||
import {
|
||||
AugmentPair,
|
||||
Sleeve as ISleeve,
|
||||
SleeveInformation,
|
||||
SleeveSkills,
|
||||
SleeveTask,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Sleeve as ISleeve, SleeveSkills } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork";
|
||||
@ -19,7 +13,7 @@ import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyW
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
|
||||
export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext): void {
|
||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext) {
|
||||
if (Player.bitNodeN !== 10 && !Player.sourceFileLvl(10)) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
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) {
|
||||
const msg = `Invalid sleeve number: ${sleeveNumber}`;
|
||||
helpers.log(ctx, () => msg);
|
||||
@ -52,282 +46,248 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
};
|
||||
|
||||
return {
|
||||
getNumSleeves: (ctx: NetscriptContext) => (): number => {
|
||||
getNumSleeves: (ctx) => () => {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
return Player.sleeves.length;
|
||||
},
|
||||
setToShockRecovery:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].shockRecovery();
|
||||
},
|
||||
setToSynchronize:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].synchronize();
|
||||
},
|
||||
setToCommitCrime:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _crimeRoughName: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeName", _crimeRoughName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
const crime = findCrime(crimeRoughName);
|
||||
if (crime === null) {
|
||||
return false;
|
||||
}
|
||||
return Player.sleeves[sleeveNumber].commitCrime(crime.name);
|
||||
},
|
||||
setToUniversityCourse:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _universityName: unknown, _className: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const universityName = helpers.string(ctx, "universityName", _universityName);
|
||||
const className = helpers.string(ctx, "className", _className);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].takeUniversityCourse(universityName, className);
|
||||
},
|
||||
travel:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _cityName: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
if (checkEnum(CityName, cityName)) {
|
||||
return Player.sleeves[sleeveNumber].travel(cityName);
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city name: '${cityName}'.`);
|
||||
}
|
||||
},
|
||||
setToCompanyWork:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, acompanyName: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const companyName = helpers.string(ctx, "companyName", acompanyName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
setToShockRecovery: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].shockRecovery();
|
||||
},
|
||||
setToSynchronize: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].synchronize();
|
||||
},
|
||||
setToCommitCrime: (ctx) => (_sleeveNumber, _crimeRoughName) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const crimeRoughName = helpers.string(ctx, "crimeName", _crimeRoughName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
const crime = findCrime(crimeRoughName);
|
||||
if (crime === null) {
|
||||
return false;
|
||||
}
|
||||
return Player.sleeves[sleeveNumber].commitCrime(crime.name);
|
||||
},
|
||||
setToUniversityCourse: (ctx) => (_sleeveNumber, _universityName, _className) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const universityName = helpers.string(ctx, "universityName", _universityName);
|
||||
const className = helpers.string(ctx, "className", _className);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].takeUniversityCourse(universityName, className);
|
||||
},
|
||||
travel: (ctx) => (_sleeveNumber, _cityName) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const cityName = helpers.string(ctx, "cityName", _cityName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
if (checkEnum(CityName, cityName)) {
|
||||
return Player.sleeves[sleeveNumber].travel(cityName);
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid city name: '${cityName}'.`);
|
||||
}
|
||||
},
|
||||
setToCompanyWork: (ctx) => (_sleeveNumber, acompanyName) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const companyName = helpers.string(ctx, "companyName", acompanyName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
// Cannot work at the same company that another sleeve is working at
|
||||
for (let i = 0; i < Player.sleeves.length; ++i) {
|
||||
if (i === sleeveNumber) {
|
||||
continue;
|
||||
}
|
||||
const other = Player.sleeves[i];
|
||||
if (isSleeveCompanyWork(other.currentWork) && other.currentWork.companyName === companyName) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot work for company ${companyName} because Sleeve ${i} is already working for them.`,
|
||||
);
|
||||
}
|
||||
// Cannot work at the same company that another sleeve is working at
|
||||
for (let i = 0; i < Player.sleeves.length; ++i) {
|
||||
if (i === sleeveNumber) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return Player.sleeves[sleeveNumber].workForCompany(companyName);
|
||||
},
|
||||
setToFactionWork:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _factionName: unknown, _workType: unknown): boolean | undefined => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const factionName = helpers.string(ctx, "factionName", _factionName);
|
||||
const workType = helpers.string(ctx, "workType", _workType);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
// Cannot work at the same faction that another sleeve is working at
|
||||
for (let i = 0; i < Player.sleeves.length; ++i) {
|
||||
if (i === sleeveNumber) {
|
||||
continue;
|
||||
}
|
||||
const other = Player.sleeves[i];
|
||||
if (isSleeveFactionWork(other.currentWork) && other.currentWork.factionName === factionName) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because Sleeve ${i} is already working for them.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (Player.gang && Player.gang.facName == factionName) {
|
||||
const other = Player.sleeves[i];
|
||||
if (isSleeveCompanyWork(other.currentWork) && other.currentWork.companyName === companyName) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because you have started a gang with them.`,
|
||||
`Sleeve ${sleeveNumber} cannot work for company ${companyName} because Sleeve ${i} is already working for them.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Player.sleeves[sleeveNumber].workForFaction(factionName, workType);
|
||||
},
|
||||
setToGymWorkout:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _gymName: unknown, _stat: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const gymName = helpers.string(ctx, "gymName", _gymName);
|
||||
const stat = helpers.string(ctx, "stat", _stat);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return Player.sleeves[sleeveNumber].workForCompany(companyName);
|
||||
},
|
||||
setToFactionWork: (ctx) => (_sleeveNumber, _factionName, _workType) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const factionName = helpers.string(ctx, "factionName", _factionName);
|
||||
const workType = helpers.string(ctx, "workType", _workType);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
return Player.sleeves[sleeveNumber].workoutAtGym(gymName, stat);
|
||||
},
|
||||
getSleeveStats:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): SleeveSkills => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return getSleeveStats(sleeveNumber);
|
||||
},
|
||||
getTask:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): SleeveTask | null => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const sl = Player.sleeves[sleeveNumber];
|
||||
if (sl.currentWork === null) return null;
|
||||
return sl.currentWork.APICopy();
|
||||
},
|
||||
getInformation:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): SleeveInformation => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const sl = Player.sleeves[sleeveNumber];
|
||||
return {
|
||||
tor: false,
|
||||
city: sl.city,
|
||||
hp: sl.hp,
|
||||
jobs: Object.keys(Player.jobs), // technically sleeves have the same jobs as the player.
|
||||
jobTitle: Object.values(Player.jobs),
|
||||
|
||||
mult: {
|
||||
agility: sl.mults.agility,
|
||||
agilityExp: sl.mults.agility_exp,
|
||||
charisma: sl.mults.charisma,
|
||||
charismaExp: sl.mults.charisma_exp,
|
||||
companyRep: sl.mults.company_rep,
|
||||
crimeMoney: sl.mults.crime_money,
|
||||
crimeSuccess: sl.mults.crime_success,
|
||||
defense: sl.mults.defense,
|
||||
defenseExp: sl.mults.defense_exp,
|
||||
dexterity: sl.mults.dexterity,
|
||||
dexterityExp: sl.mults.dexterity_exp,
|
||||
factionRep: sl.mults.faction_rep,
|
||||
hacking: sl.mults.hacking,
|
||||
hackingExp: sl.mults.hacking_exp,
|
||||
strength: sl.mults.strength,
|
||||
strengthExp: sl.mults.strength_exp,
|
||||
workMoney: sl.mults.work_money,
|
||||
},
|
||||
};
|
||||
},
|
||||
getSleeveAugmentations:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): string[] => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const augs = [];
|
||||
for (let i = 0; i < Player.sleeves[sleeveNumber].augmentations.length; i++) {
|
||||
augs.push(Player.sleeves[sleeveNumber].augmentations[i].name);
|
||||
// Cannot work at the same faction that another sleeve is working at
|
||||
for (let i = 0; i < Player.sleeves.length; ++i) {
|
||||
if (i === sleeveNumber) {
|
||||
continue;
|
||||
}
|
||||
return augs;
|
||||
},
|
||||
getSleevePurchasableAugs:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown): AugmentPair[] => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const purchasableAugs = Player.sleeves[sleeveNumber].findPurchasableAugs();
|
||||
const augs = [];
|
||||
for (let i = 0; i < purchasableAugs.length; i++) {
|
||||
const aug = purchasableAugs[i];
|
||||
augs.push({
|
||||
name: aug.name,
|
||||
cost: aug.baseCost,
|
||||
});
|
||||
const other = Player.sleeves[i];
|
||||
if (isSleeveFactionWork(other.currentWork) && other.currentWork.factionName === factionName) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because Sleeve ${i} is already working for them.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return augs;
|
||||
},
|
||||
purchaseSleeveAug:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _augName: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
if (Player.gang && Player.gang.facName == factionName) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot work for faction ${factionName} because you have started a gang with them.`,
|
||||
);
|
||||
}
|
||||
|
||||
if (getSleeveStats(sleeveNumber).shock > 0) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
||||
}
|
||||
return Player.sleeves[sleeveNumber].workForFaction(factionName, workType);
|
||||
},
|
||||
setToGymWorkout: (ctx) => (_sleeveNumber, _gymName, _stat) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const gymName = helpers.string(ctx, "gymName", _gymName);
|
||||
const stat = helpers.string(ctx, "stat", _stat);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const aug = StaticAugmentations[augName];
|
||||
if (!aug) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||
}
|
||||
return Player.sleeves[sleeveNumber].workoutAtGym(gymName, stat);
|
||||
},
|
||||
getSleeveStats: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
return getSleeveStats(sleeveNumber);
|
||||
},
|
||||
getTask: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
return Player.sleeves[sleeveNumber].tryBuyAugmentation(aug);
|
||||
},
|
||||
getSleeveAugmentationPrice:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_augName: unknown): number => {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug: Augmentation = StaticAugmentations[augName];
|
||||
return aug.baseCost;
|
||||
},
|
||||
getSleeveAugmentationRepReq:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_augName: unknown): number => {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug: Augmentation = StaticAugmentations[augName];
|
||||
return aug.getCost().repCost;
|
||||
},
|
||||
setToBladeburnerAction:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_sleeveNumber: unknown, _action: unknown, _contract?: unknown): boolean => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const action = helpers.string(ctx, "action", _action);
|
||||
let contract: string;
|
||||
if (typeof _contract === "undefined") {
|
||||
contract = "------";
|
||||
} else {
|
||||
contract = helpers.string(ctx, "contract", _contract);
|
||||
}
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
const sl = Player.sleeves[sleeveNumber];
|
||||
if (sl.currentWork === null) return null;
|
||||
return sl.currentWork.APICopy();
|
||||
},
|
||||
getInformation: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
// Cannot Take on Contracts if another sleeve is performing that action
|
||||
if (action === "Take on contracts") {
|
||||
for (let i = 0; i < Player.sleeves.length; ++i) {
|
||||
if (i === sleeveNumber) {
|
||||
continue;
|
||||
}
|
||||
const other = Player.sleeves[i];
|
||||
if (isSleeveBladeburnerWork(other.currentWork) && other.currentWork.actionName === contract) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot take on contracts because Sleeve ${i} is already performing that action.`,
|
||||
);
|
||||
}
|
||||
const sl = Player.sleeves[sleeveNumber];
|
||||
return {
|
||||
tor: false,
|
||||
city: sl.city,
|
||||
hp: sl.hp,
|
||||
jobs: Object.keys(Player.jobs), // technically sleeves have the same jobs as the player.
|
||||
jobTitle: Object.values(Player.jobs),
|
||||
|
||||
mult: {
|
||||
agility: sl.mults.agility,
|
||||
agilityExp: sl.mults.agility_exp,
|
||||
charisma: sl.mults.charisma,
|
||||
charismaExp: sl.mults.charisma_exp,
|
||||
companyRep: sl.mults.company_rep,
|
||||
crimeMoney: sl.mults.crime_money,
|
||||
crimeSuccess: sl.mults.crime_success,
|
||||
defense: sl.mults.defense,
|
||||
defenseExp: sl.mults.defense_exp,
|
||||
dexterity: sl.mults.dexterity,
|
||||
dexterityExp: sl.mults.dexterity_exp,
|
||||
factionRep: sl.mults.faction_rep,
|
||||
hacking: sl.mults.hacking,
|
||||
hackingExp: sl.mults.hacking_exp,
|
||||
strength: sl.mults.strength,
|
||||
strengthExp: sl.mults.strength_exp,
|
||||
workMoney: sl.mults.work_money,
|
||||
},
|
||||
};
|
||||
},
|
||||
getSleeveAugmentations: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const augs = [];
|
||||
for (let i = 0; i < Player.sleeves[sleeveNumber].augmentations.length; i++) {
|
||||
augs.push(Player.sleeves[sleeveNumber].augmentations[i].name);
|
||||
}
|
||||
return augs;
|
||||
},
|
||||
getSleevePurchasableAugs: (ctx) => (_sleeveNumber) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
const purchasableAugs = Player.sleeves[sleeveNumber].findPurchasableAugs();
|
||||
const augs = [];
|
||||
for (let i = 0; i < purchasableAugs.length; i++) {
|
||||
const aug = purchasableAugs[i];
|
||||
augs.push({
|
||||
name: aug.name,
|
||||
cost: aug.baseCost,
|
||||
});
|
||||
}
|
||||
|
||||
return augs;
|
||||
},
|
||||
purchaseSleeveAug: (ctx) => (_sleeveNumber, _augName) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
if (getSleeveStats(sleeveNumber).shock > 0) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Sleeve shock too high: Sleeve ${sleeveNumber}`);
|
||||
}
|
||||
|
||||
const aug = StaticAugmentations[augName];
|
||||
if (!aug) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`);
|
||||
}
|
||||
|
||||
return Player.sleeves[sleeveNumber].tryBuyAugmentation(aug);
|
||||
},
|
||||
getSleeveAugmentationPrice: (ctx) => (_augName) => {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug: Augmentation = StaticAugmentations[augName];
|
||||
return aug.baseCost;
|
||||
},
|
||||
getSleeveAugmentationRepReq: (ctx) => (_augName) => {
|
||||
checkSleeveAPIAccess(ctx);
|
||||
const augName = helpers.string(ctx, "augName", _augName);
|
||||
const aug: Augmentation = StaticAugmentations[augName];
|
||||
return aug.getCost().repCost;
|
||||
},
|
||||
setToBladeburnerAction: (ctx) => (_sleeveNumber, _action, _contract?) => {
|
||||
const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber);
|
||||
const action = helpers.string(ctx, "action", _action);
|
||||
let contract: string;
|
||||
if (typeof _contract === "undefined") {
|
||||
contract = "------";
|
||||
} else {
|
||||
contract = helpers.string(ctx, "contract", _contract);
|
||||
}
|
||||
checkSleeveAPIAccess(ctx);
|
||||
checkSleeveNumber(ctx, sleeveNumber);
|
||||
|
||||
// Cannot Take on Contracts if another sleeve is performing that action
|
||||
if (action === "Take on contracts") {
|
||||
for (let i = 0; i < Player.sleeves.length; ++i) {
|
||||
if (i === sleeveNumber) {
|
||||
continue;
|
||||
}
|
||||
const other = Player.sleeves[i];
|
||||
if (isSleeveBladeburnerWork(other.currentWork) && other.currentWork.actionName === contract) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Sleeve ${sleeveNumber} cannot take on contracts because Sleeve ${i} is already performing that action.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Player.sleeves[sleeveNumber].bladeburner(action, contract);
|
||||
},
|
||||
return Player.sleeves[sleeveNumber].bladeburner(action, contract);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -4,11 +4,7 @@ import { staneksGift } from "../CotMG/Helper";
|
||||
import { Fragments, FragmentById } from "../CotMG/Fragment";
|
||||
import { FragmentType } from "../CotMG/FragmentType";
|
||||
|
||||
import {
|
||||
Fragment as IFragment,
|
||||
ActiveFragment as IActiveFragment,
|
||||
Stanek as IStanek,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Stanek as IStanek } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { NetscriptContext, InternalAPI } from "../Netscript/APIWrapper";
|
||||
import { applyAugmentation } from "../Augmentation/AugmentationHelpers";
|
||||
@ -25,125 +21,114 @@ export function NetscriptStanek(): InternalAPI<IStanek> {
|
||||
}
|
||||
|
||||
return {
|
||||
giftWidth: (ctx: NetscriptContext) =>
|
||||
function (): number {
|
||||
checkStanekAPIAccess(ctx);
|
||||
return staneksGift.width();
|
||||
},
|
||||
giftHeight: (ctx: NetscriptContext) =>
|
||||
function (): number {
|
||||
checkStanekAPIAccess(ctx);
|
||||
return staneksGift.height();
|
||||
},
|
||||
chargeFragment: (ctx: NetscriptContext) =>
|
||||
function (_rootX: unknown, _rootY: unknown): Promise<void> {
|
||||
//Get the fragment object using the given coordinates
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||
//Check whether the selected fragment can ge charged
|
||||
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `No fragment with root (${rootX}, ${rootY}).`);
|
||||
if (fragment.fragment().type == FragmentType.Booster) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
giftWidth: (ctx) => () => {
|
||||
checkStanekAPIAccess(ctx);
|
||||
return staneksGift.width();
|
||||
},
|
||||
giftHeight: (ctx) => () => {
|
||||
checkStanekAPIAccess(ctx);
|
||||
return staneksGift.height();
|
||||
},
|
||||
chargeFragment: (ctx) => (_rootX, _rootY) => {
|
||||
//Get the fragment object using the given coordinates
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||
//Check whether the selected fragment can ge charged
|
||||
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `No fragment with root (${rootX}, ${rootY}).`);
|
||||
if (fragment.fragment().type == FragmentType.Booster) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`The fragment with root (${rootX}, ${rootY}) is a Booster Fragment and thus cannot be charged.`,
|
||||
);
|
||||
}
|
||||
//Charge the fragment
|
||||
const time = staneksGift.inBonus() ? 200 : 1000;
|
||||
return helpers.netscriptDelay(ctx, time).then(function () {
|
||||
staneksGift.charge(fragment, ctx.workerScript.scriptRef.threads);
|
||||
helpers.log(ctx, () => `Charged fragment with ${ctx.workerScript.scriptRef.threads} threads.`);
|
||||
return Promise.resolve();
|
||||
});
|
||||
},
|
||||
fragmentDefinitions: (ctx) => () => {
|
||||
checkStanekAPIAccess(ctx);
|
||||
helpers.log(ctx, () => `Returned ${Fragments.length} fragments`);
|
||||
return Fragments.map((f) => f.copy());
|
||||
},
|
||||
activeFragments: (ctx) => () => {
|
||||
checkStanekAPIAccess(ctx);
|
||||
helpers.log(ctx, () => `Returned ${staneksGift.fragments.length} fragments`);
|
||||
return staneksGift.fragments.map((af) => {
|
||||
return { ...af.copy(), ...af.fragment().copy() };
|
||||
});
|
||||
},
|
||||
clearGift: (ctx) => () => {
|
||||
checkStanekAPIAccess(ctx);
|
||||
helpers.log(ctx, () => `Cleared Stanek's Gift.`);
|
||||
staneksGift.clear();
|
||||
},
|
||||
canPlaceFragment: (ctx) => (_rootX, _rootY, _rotation, _fragmentId) => {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
const rotation = helpers.number(ctx, "rotation", _rotation);
|
||||
const fragmentId = helpers.number(ctx, "fragmentId", _fragmentId);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = FragmentById(fragmentId);
|
||||
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid fragment id: ${fragmentId}`);
|
||||
const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
|
||||
return can;
|
||||
},
|
||||
placeFragment: (ctx) => (_rootX, _rootY, _rotation, _fragmentId) => {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
const rotation = helpers.number(ctx, "rotation", _rotation);
|
||||
const fragmentId = helpers.number(ctx, "fragmentId", _fragmentId);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = FragmentById(fragmentId);
|
||||
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid fragment id: ${fragmentId}`);
|
||||
return staneksGift.place(rootX, rootY, rotation, fragment);
|
||||
},
|
||||
getFragment: (ctx) => (_rootX, _rootY) => {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||
if (fragment !== undefined) return fragment.copy();
|
||||
return undefined;
|
||||
},
|
||||
removeFragment: (ctx) => (_rootX, _rootY) => {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
checkStanekAPIAccess(ctx);
|
||||
return staneksGift.delete(rootX, rootY);
|
||||
},
|
||||
acceptGift: (ctx) => () => {
|
||||
//Check if the player is eligible to join the church
|
||||
if (
|
||||
player.canAccessCotMG() &&
|
||||
player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length == 0 &&
|
||||
player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length == 0
|
||||
) {
|
||||
//Attempt to join CotMG
|
||||
joinFaction(Factions[FactionNames.ChurchOfTheMachineGod]);
|
||||
//Attempt to install the first Stanek aug
|
||||
if (
|
||||
!player.hasAugmentation(AugmentationNames.StaneksGift1) &&
|
||||
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
|
||||
) {
|
||||
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
|
||||
helpers.log(
|
||||
ctx,
|
||||
`The fragment with root (${rootX}, ${rootY}) is a Booster Fragment and thus cannot be charged.`,
|
||||
() => `'${FactionNames.ChurchOfTheMachineGod}' joined and '${AugmentationNames.StaneksGift1}' installed.`,
|
||||
);
|
||||
}
|
||||
//Charge the fragment
|
||||
const time = staneksGift.inBonus() ? 200 : 1000;
|
||||
return helpers.netscriptDelay(ctx, time).then(function () {
|
||||
staneksGift.charge(fragment, ctx.workerScript.scriptRef.threads);
|
||||
helpers.log(ctx, () => `Charged fragment with ${ctx.workerScript.scriptRef.threads} threads.`);
|
||||
return Promise.resolve();
|
||||
});
|
||||
},
|
||||
fragmentDefinitions: (ctx: NetscriptContext) =>
|
||||
function (): IFragment[] {
|
||||
checkStanekAPIAccess(ctx);
|
||||
helpers.log(ctx, () => `Returned ${Fragments.length} fragments`);
|
||||
return Fragments.map((f) => f.copy());
|
||||
},
|
||||
activeFragments: (ctx: NetscriptContext) =>
|
||||
function (): IActiveFragment[] {
|
||||
checkStanekAPIAccess(ctx);
|
||||
helpers.log(ctx, () => `Returned ${staneksGift.fragments.length} fragments`);
|
||||
return staneksGift.fragments.map((af) => {
|
||||
return { ...af.copy(), ...af.fragment().copy() };
|
||||
});
|
||||
},
|
||||
clearGift: (ctx: NetscriptContext) =>
|
||||
function (): void {
|
||||
checkStanekAPIAccess(ctx);
|
||||
helpers.log(ctx, () => `Cleared Stanek's Gift.`);
|
||||
staneksGift.clear();
|
||||
},
|
||||
canPlaceFragment: (ctx: NetscriptContext) =>
|
||||
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
const rotation = helpers.number(ctx, "rotation", _rotation);
|
||||
const fragmentId = helpers.number(ctx, "fragmentId", _fragmentId);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = FragmentById(fragmentId);
|
||||
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid fragment id: ${fragmentId}`);
|
||||
const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
|
||||
return can;
|
||||
},
|
||||
placeFragment: (ctx: NetscriptContext) =>
|
||||
function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
const rotation = helpers.number(ctx, "rotation", _rotation);
|
||||
const fragmentId = helpers.number(ctx, "fragmentId", _fragmentId);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = FragmentById(fragmentId);
|
||||
if (!fragment) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid fragment id: ${fragmentId}`);
|
||||
return staneksGift.place(rootX, rootY, rotation, fragment);
|
||||
},
|
||||
getFragment: (ctx: NetscriptContext) =>
|
||||
function (_rootX: unknown, _rootY: unknown): IActiveFragment | undefined {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
checkStanekAPIAccess(ctx);
|
||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||
if (fragment !== undefined) return fragment.copy();
|
||||
return undefined;
|
||||
},
|
||||
removeFragment: (ctx: NetscriptContext) =>
|
||||
function (_rootX: unknown, _rootY: unknown): boolean {
|
||||
const rootX = helpers.number(ctx, "rootX", _rootX);
|
||||
const rootY = helpers.number(ctx, "rootY", _rootY);
|
||||
checkStanekAPIAccess(ctx);
|
||||
return staneksGift.delete(rootX, rootY);
|
||||
},
|
||||
acceptGift: (ctx: NetscriptContext) =>
|
||||
function (): boolean {
|
||||
//Check if the player is eligible to join the church
|
||||
if (
|
||||
player.canAccessCotMG() &&
|
||||
player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length == 0 &&
|
||||
player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length == 0
|
||||
) {
|
||||
//Attempt to join CotMG
|
||||
joinFaction(Factions[FactionNames.ChurchOfTheMachineGod]);
|
||||
//Attempt to install the first Stanek aug
|
||||
if (
|
||||
!player.hasAugmentation(AugmentationNames.StaneksGift1) &&
|
||||
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
|
||||
) {
|
||||
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
|
||||
helpers.log(
|
||||
ctx,
|
||||
() => `'${FactionNames.ChurchOfTheMachineGod}' joined and '${AugmentationNames.StaneksGift1}' installed.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
//Return true iff the player is in CotMG and has the first Stanek aug installed
|
||||
return (
|
||||
Factions[FactionNames.ChurchOfTheMachineGod].isMember &&
|
||||
player.hasAugmentation(AugmentationNames.StaneksGift1, true)
|
||||
);
|
||||
},
|
||||
}
|
||||
//Return true iff the player is in CotMG and has the first Stanek aug installed
|
||||
return (
|
||||
Factions[FactionNames.ChurchOfTheMachineGod].isMember &&
|
||||
player.hasAugmentation(AugmentationNames.StaneksGift1, true)
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -37,284 +37,258 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
};
|
||||
|
||||
return {
|
||||
hasWSEAccount: () => (): boolean => {
|
||||
hasWSEAccount: () => () => {
|
||||
return player.hasWseAccount;
|
||||
},
|
||||
hasTIXAPIAccess: () => (): boolean => {
|
||||
hasTIXAPIAccess: () => () => {
|
||||
return player.hasTixApiAccess;
|
||||
},
|
||||
has4SData: () => (): boolean => {
|
||||
has4SData: () => () => {
|
||||
return player.has4SData;
|
||||
},
|
||||
has4SDataTIXAPI: () => (): boolean => {
|
||||
has4SDataTIXAPI: () => () => {
|
||||
return player.has4SDataTixApi;
|
||||
},
|
||||
getSymbols: (ctx: NetscriptContext) => (): string[] => {
|
||||
getSymbols: (ctx) => () => {
|
||||
checkTixApiAccess(ctx);
|
||||
return Object.values(StockSymbols);
|
||||
},
|
||||
getPrice:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
getPrice: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
return stock.price;
|
||||
},
|
||||
getAskPrice:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
return stock.price;
|
||||
},
|
||||
getAskPrice: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
return stock.getAskPrice();
|
||||
},
|
||||
getBidPrice:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
return stock.getAskPrice();
|
||||
},
|
||||
getBidPrice: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
return stock.getBidPrice();
|
||||
},
|
||||
getPosition:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): [number, number, number, number] => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid stock symbol: ${symbol}`);
|
||||
}
|
||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||
},
|
||||
getMaxShares:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
return stock.getBidPrice();
|
||||
},
|
||||
getPosition: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid stock symbol: ${symbol}`);
|
||||
}
|
||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||
},
|
||||
getMaxShares: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
return stock.maxShares;
|
||||
},
|
||||
getPurchaseCost:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
let shares = helpers.number(ctx, "shares", _shares);
|
||||
const posType = helpers.string(ctx, "posType", _posType);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
shares = Math.round(shares);
|
||||
return stock.maxShares;
|
||||
},
|
||||
getPurchaseCost: (ctx) => (_symbol, _shares, _posType) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
let shares = helpers.number(ctx, "shares", _shares);
|
||||
const posType = helpers.string(ctx, "posType", _posType);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
shares = Math.round(shares);
|
||||
|
||||
let pos;
|
||||
const sanitizedPosType = posType.toLowerCase();
|
||||
if (sanitizedPosType.includes("l")) {
|
||||
pos = PositionTypes.Long;
|
||||
} else if (sanitizedPosType.includes("s")) {
|
||||
pos = PositionTypes.Short;
|
||||
} else {
|
||||
return Infinity;
|
||||
}
|
||||
let pos;
|
||||
const sanitizedPosType = posType.toLowerCase();
|
||||
if (sanitizedPosType.includes("l")) {
|
||||
pos = PositionTypes.Long;
|
||||
} else if (sanitizedPosType.includes("s")) {
|
||||
pos = PositionTypes.Short;
|
||||
} else {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const res = getBuyTransactionCost(stock, shares, pos);
|
||||
if (res == null) {
|
||||
return Infinity;
|
||||
}
|
||||
const res = getBuyTransactionCost(stock, shares, pos);
|
||||
if (res == null) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
getSaleGain:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown, _posType: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
let shares = helpers.number(ctx, "shares", _shares);
|
||||
const posType = helpers.string(ctx, "posType", _posType);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
shares = Math.round(shares);
|
||||
return res;
|
||||
},
|
||||
getSaleGain: (ctx) => (_symbol, _shares, _posType) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
let shares = helpers.number(ctx, "shares", _shares);
|
||||
const posType = helpers.string(ctx, "posType", _posType);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
shares = Math.round(shares);
|
||||
|
||||
let pos;
|
||||
const sanitizedPosType = posType.toLowerCase();
|
||||
if (sanitizedPosType.includes("l")) {
|
||||
pos = PositionTypes.Long;
|
||||
} else if (sanitizedPosType.includes("s")) {
|
||||
pos = PositionTypes.Short;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
let pos;
|
||||
const sanitizedPosType = posType.toLowerCase();
|
||||
if (sanitizedPosType.includes("l")) {
|
||||
pos = PositionTypes.Long;
|
||||
} else if (sanitizedPosType.includes("s")) {
|
||||
pos = PositionTypes.Short;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const res = getSellTransactionGain(stock, shares, pos);
|
||||
if (res == null) {
|
||||
return 0;
|
||||
}
|
||||
const res = getSellTransactionGain(stock, shares, pos);
|
||||
if (res == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return res;
|
||||
},
|
||||
buyStock:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = buyStock(stock, shares, ctx, {});
|
||||
return res ? stock.getAskPrice() : 0;
|
||||
},
|
||||
sellStock:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = sellStock(stock, shares, ctx, {});
|
||||
return res;
|
||||
},
|
||||
buyStock: (ctx) => (_symbol, _shares) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = buyStock(stock, shares, ctx, {});
|
||||
return res ? stock.getAskPrice() : 0;
|
||||
},
|
||||
sellStock: (ctx) => (_symbol, _shares) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = sellStock(stock, shares, ctx, {});
|
||||
|
||||
return res ? stock.getBidPrice() : 0;
|
||||
},
|
||||
buyShort:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = shortStock(stock, shares, ctx, {});
|
||||
|
||||
return res ? stock.getBidPrice() : 0;
|
||||
},
|
||||
sellShort:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = sellShort(stock, shares, ctx, {});
|
||||
|
||||
return res ? stock.getAskPrice() : 0;
|
||||
},
|
||||
placeOrder:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
const price = helpers.number(ctx, "price", _price);
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const pos = helpers.string(ctx, "pos", _pos);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
let orderType;
|
||||
let orderPos;
|
||||
const ltype = type.toLowerCase();
|
||||
if (ltype.includes("limit") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (ltype.includes("limit") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (ltype.includes("stop") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid order type: ${type}`);
|
||||
}
|
||||
|
||||
const lpos = pos.toLowerCase();
|
||||
if (lpos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (lpos.includes("s")) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position type: ${pos}`);
|
||||
}
|
||||
|
||||
return placeOrder(stock, shares, price, orderType, orderPos, ctx);
|
||||
},
|
||||
cancelOrder:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
const price = helpers.number(ctx, "price", _price);
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const pos = helpers.string(ctx, "pos", _pos);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
if (isNaN(shares) || isNaN(price)) {
|
||||
return res ? stock.getBidPrice() : 0;
|
||||
},
|
||||
buyShort: (ctx) => (_symbol, _shares) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Invalid shares or price. Must be numeric. shares=${shares}, price=${price}`,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||
);
|
||||
}
|
||||
let orderType;
|
||||
let orderPos;
|
||||
const ltype = type.toLowerCase();
|
||||
if (ltype.includes("limit") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (ltype.includes("limit") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (ltype.includes("stop") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid order type: ${type}`);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = shortStock(stock, shares, ctx, {});
|
||||
|
||||
const lpos = pos.toLowerCase();
|
||||
if (lpos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (lpos.includes("s")) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position type: ${pos}`);
|
||||
return res ? stock.getBidPrice() : 0;
|
||||
},
|
||||
sellShort: (ctx) => (_symbol, _shares) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 1) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 2.",
|
||||
);
|
||||
}
|
||||
const params = {
|
||||
stock: stock,
|
||||
shares: shares,
|
||||
price: price,
|
||||
type: orderType,
|
||||
pos: orderPos,
|
||||
};
|
||||
return cancelOrder(params, ctx);
|
||||
},
|
||||
getOrders: (ctx: NetscriptContext) => (): StockOrder => {
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
const res = sellShort(stock, shares, ctx, {});
|
||||
|
||||
return res ? stock.getAskPrice() : 0;
|
||||
},
|
||||
placeOrder: (ctx) => (_symbol, _shares, _price, _type, _pos) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
const price = helpers.number(ctx, "price", _price);
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const pos = helpers.string(ctx, "pos", _pos);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
let orderType;
|
||||
let orderPos;
|
||||
const ltype = type.toLowerCase();
|
||||
if (ltype.includes("limit") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (ltype.includes("limit") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (ltype.includes("stop") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid order type: ${type}`);
|
||||
}
|
||||
|
||||
const lpos = pos.toLowerCase();
|
||||
if (lpos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (lpos.includes("s")) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position type: ${pos}`);
|
||||
}
|
||||
|
||||
return placeOrder(stock, shares, price, orderType, orderPos, ctx);
|
||||
},
|
||||
cancelOrder: (ctx) => (_symbol, _shares, _price, _type, _pos) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
const shares = helpers.number(ctx, "shares", _shares);
|
||||
const price = helpers.number(ctx, "price", _price);
|
||||
const type = helpers.string(ctx, "type", _type);
|
||||
const pos = helpers.string(ctx, "pos", _pos);
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
"You must either be in BitNode-8 or you must have Source-File 8 Level 3.",
|
||||
);
|
||||
}
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
if (isNaN(shares) || isNaN(price)) {
|
||||
throw helpers.makeRuntimeErrorMsg(
|
||||
ctx,
|
||||
`Invalid shares or price. Must be numeric. shares=${shares}, price=${price}`,
|
||||
);
|
||||
}
|
||||
let orderType;
|
||||
let orderPos;
|
||||
const ltype = type.toLowerCase();
|
||||
if (ltype.includes("limit") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (ltype.includes("limit") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (ltype.includes("stop") && ltype.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (ltype.includes("stop") && ltype.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid order type: ${type}`);
|
||||
}
|
||||
|
||||
const lpos = pos.toLowerCase();
|
||||
if (lpos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (lpos.includes("s")) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid position type: ${pos}`);
|
||||
}
|
||||
const params = {
|
||||
stock: stock,
|
||||
shares: shares,
|
||||
price: price,
|
||||
type: orderType,
|
||||
pos: orderPos,
|
||||
};
|
||||
return cancelOrder(params, ctx);
|
||||
},
|
||||
getOrders: (ctx) => () => {
|
||||
checkTixApiAccess(ctx);
|
||||
if (player.bitNodeN !== 8) {
|
||||
if (player.sourceFileLvl(8) <= 2) {
|
||||
@ -342,31 +316,27 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
|
||||
return orders;
|
||||
},
|
||||
getVolatility:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
getVolatility: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
return stock.mv / 100; // Convert from percentage to decimal
|
||||
},
|
||||
getForecast:
|
||||
(ctx: NetscriptContext) =>
|
||||
(_symbol: unknown): number => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
return stock.mv / 100; // Convert from percentage to decimal
|
||||
},
|
||||
getForecast: (ctx) => (_symbol) => {
|
||||
const symbol = helpers.string(ctx, "symbol", _symbol);
|
||||
if (!player.has4SDataTixApi) {
|
||||
throw helpers.makeRuntimeErrorMsg(ctx, "You don't have 4S Market Data TIX API Access!");
|
||||
}
|
||||
const stock = getStockFromSymbol(ctx, symbol);
|
||||
|
||||
let forecast = 50;
|
||||
stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag);
|
||||
return forecast / 100; // Convert from percentage to decimal
|
||||
},
|
||||
purchase4SMarketData: (ctx: NetscriptContext) => (): boolean => {
|
||||
let forecast = 50;
|
||||
stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag);
|
||||
return forecast / 100; // Convert from percentage to decimal
|
||||
},
|
||||
purchase4SMarketData: (ctx) => () => {
|
||||
if (player.has4SData) {
|
||||
helpers.log(ctx, () => "Already purchased 4S Market Data.");
|
||||
return true;
|
||||
@ -382,7 +352,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
helpers.log(ctx, () => "Purchased 4S Market Data");
|
||||
return true;
|
||||
},
|
||||
purchase4SMarketDataTixApi: (ctx: NetscriptContext) => (): boolean => {
|
||||
purchase4SMarketDataTixApi: (ctx) => () => {
|
||||
checkTixApiAccess(ctx);
|
||||
|
||||
if (player.has4SDataTixApi) {
|
||||
@ -400,7 +370,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
helpers.log(ctx, () => "Purchased 4S Market Data TIX API");
|
||||
return true;
|
||||
},
|
||||
purchaseWseAccount: (ctx: NetscriptContext) => (): boolean => {
|
||||
purchaseWseAccount: (ctx) => () => {
|
||||
if (player.hasWseAccount) {
|
||||
helpers.log(ctx, () => "Already purchased WSE Account");
|
||||
return true;
|
||||
@ -417,7 +387,7 @@ export function NetscriptStockMarket(): InternalAPI<TIX> {
|
||||
helpers.log(ctx, () => "Purchased WSE Account Access");
|
||||
return true;
|
||||
},
|
||||
purchaseTixApi: (ctx: NetscriptContext) => (): boolean => {
|
||||
purchaseTixApi: (ctx) => () => {
|
||||
if (player.hasTixApiAccess) {
|
||||
helpers.log(ctx, () => "Already purchased TIX API");
|
||||
return true;
|
||||
|
@ -1,38 +1,34 @@
|
||||
import {
|
||||
GameInfo,
|
||||
IStyleSettings,
|
||||
UserInterface as IUserInterface,
|
||||
UserInterfaceTheme,
|
||||
} from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { UserInterface as IUserInterface } from "../ScriptEditor/NetscriptDefinitions";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
import { ThemeEvents } from "../Themes/ui/Theme";
|
||||
import { defaultTheme } from "../Themes/Themes";
|
||||
import { defaultStyles } from "../Themes/Styles";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { hash } from "../hash/hash";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { InternalAPI } from "../Netscript/APIWrapper";
|
||||
import { Terminal } from "../../src/Terminal";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { helpers, assertObjectType } from "../Netscript/NetscriptHelpers";
|
||||
|
||||
export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
||||
return {
|
||||
windowSize: () => (): [number, number] => {
|
||||
windowSize: () => () => {
|
||||
return [window.innerWidth, window.innerHeight];
|
||||
},
|
||||
getTheme: () => (): UserInterfaceTheme => {
|
||||
getTheme: () => () => {
|
||||
return { ...Settings.theme };
|
||||
},
|
||||
|
||||
getStyles: () => (): IStyleSettings => {
|
||||
getStyles: () => () => {
|
||||
return { ...Settings.styles };
|
||||
},
|
||||
|
||||
setTheme:
|
||||
(ctx: NetscriptContext) =>
|
||||
(newTheme: UserInterfaceTheme): void => {
|
||||
const hex = /^(#)((?:[A-Fa-f0-9]{2}){3,4}|(?:[A-Fa-f0-9]{3}))$/;
|
||||
const currentTheme = { ...Settings.theme };
|
||||
const errors: string[] = [];
|
||||
setTheme: (ctx) => (newTheme) => {
|
||||
const themeValidator: Record<string, string | undefined> = {};
|
||||
assertObjectType(ctx, "newTheme", newTheme, themeValidator);
|
||||
const hex = /^(#)((?:[A-Fa-f0-9]{2}){3,4}|(?:[A-Fa-f0-9]{3}))$/;
|
||||
const currentTheme = { ...Settings.theme };
|
||||
const errors: string[] = [];
|
||||
if (typeof newTheme !== "object")
|
||||
for (const key of Object.keys(newTheme)) {
|
||||
if (!currentTheme[key]) {
|
||||
// Invalid key
|
||||
@ -44,51 +40,51 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length === 0) {
|
||||
Object.assign(Settings.theme, currentTheme);
|
||||
ThemeEvents.emit();
|
||||
helpers.log(ctx, () => `Successfully set theme`);
|
||||
if (errors.length === 0) {
|
||||
Object.assign(Settings.theme, currentTheme);
|
||||
ThemeEvents.emit();
|
||||
helpers.log(ctx, () => `Successfully set theme`);
|
||||
} else {
|
||||
helpers.log(ctx, () => `Failed to set theme. Errors: ${errors.join(", ")}`);
|
||||
}
|
||||
},
|
||||
|
||||
setStyles: (ctx) => (newStyles) => {
|
||||
const styleValidator: Record<string, string | number | undefined> = {};
|
||||
assertObjectType(ctx, "newStyles", newStyles, styleValidator);
|
||||
const currentStyles = { ...Settings.styles };
|
||||
const errors: string[] = [];
|
||||
for (const key of Object.keys(newStyles)) {
|
||||
if (!(currentStyles as any)[key]) {
|
||||
// Invalid key
|
||||
errors.push(`Invalid key "${key}"`);
|
||||
} else {
|
||||
helpers.log(ctx, () => `Failed to set theme. Errors: ${errors.join(", ")}`);
|
||||
(currentStyles as any)[key] = newStyles[key];
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
setStyles:
|
||||
(ctx: NetscriptContext) =>
|
||||
(newStyles: IStyleSettings): void => {
|
||||
const currentStyles = { ...Settings.styles };
|
||||
const errors: string[] = [];
|
||||
for (const key of Object.keys(newStyles)) {
|
||||
if (!(currentStyles as any)[key]) {
|
||||
// Invalid key
|
||||
errors.push(`Invalid key "${key}"`);
|
||||
} else {
|
||||
(currentStyles as any)[key] = (newStyles as any)[key];
|
||||
}
|
||||
}
|
||||
if (errors.length === 0) {
|
||||
Object.assign(Settings.styles, currentStyles);
|
||||
ThemeEvents.emit();
|
||||
helpers.log(ctx, () => `Successfully set styles`);
|
||||
} else {
|
||||
helpers.log(ctx, () => `Failed to set styles. Errors: ${errors.join(", ")}`);
|
||||
}
|
||||
},
|
||||
|
||||
if (errors.length === 0) {
|
||||
Object.assign(Settings.styles, currentStyles);
|
||||
ThemeEvents.emit();
|
||||
helpers.log(ctx, () => `Successfully set styles`);
|
||||
} else {
|
||||
helpers.log(ctx, () => `Failed to set styles. Errors: ${errors.join(", ")}`);
|
||||
}
|
||||
},
|
||||
|
||||
resetTheme: (ctx: NetscriptContext) => (): void => {
|
||||
resetTheme: (ctx) => () => {
|
||||
Settings.theme = { ...defaultTheme };
|
||||
ThemeEvents.emit();
|
||||
helpers.log(ctx, () => `Reinitialized theme to default`);
|
||||
},
|
||||
|
||||
resetStyles: (ctx: NetscriptContext) => (): void => {
|
||||
resetStyles: (ctx) => () => {
|
||||
Settings.styles = { ...defaultStyles };
|
||||
ThemeEvents.emit();
|
||||
helpers.log(ctx, () => `Reinitialized styles to default`);
|
||||
},
|
||||
|
||||
getGameInfo: () => (): GameInfo => {
|
||||
getGameInfo: () => () => {
|
||||
const version = CONSTANTS.VersionString;
|
||||
const commit = hash();
|
||||
const platform = navigator.userAgent.toLowerCase().indexOf(" electron/") > -1 ? "Steam" : "Browser";
|
||||
@ -102,7 +98,7 @@ export function NetscriptUserInterface(): InternalAPI<IUserInterface> {
|
||||
return gameInfo;
|
||||
},
|
||||
|
||||
clearTerminal: (ctx: NetscriptContext) => (): void => {
|
||||
clearTerminal: (ctx) => () => {
|
||||
helpers.log(ctx, () => `Clearing terminal`);
|
||||
Terminal.clear();
|
||||
},
|
||||
|
@ -1,28 +1,39 @@
|
||||
import { Settings } from "./Settings/Settings";
|
||||
|
||||
type PortData = string | number;
|
||||
export interface IPort {
|
||||
write: (value: unknown) => unknown;
|
||||
write: (value: unknown) => PortData | null;
|
||||
tryWrite: (value: unknown) => boolean;
|
||||
read: () => unknown;
|
||||
peek: () => unknown;
|
||||
read: () => PortData;
|
||||
peek: () => PortData;
|
||||
full: () => boolean;
|
||||
empty: () => boolean;
|
||||
clear: () => void;
|
||||
}
|
||||
|
||||
export function NetscriptPort(): IPort {
|
||||
const data: unknown[] = [];
|
||||
const data: PortData[] = [];
|
||||
|
||||
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);
|
||||
if (data.length > Settings.MaxPortCapacity) {
|
||||
return data.shift();
|
||||
return data.shift() as PortData;
|
||||
}
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
@ -30,31 +41,25 @@ export function NetscriptPort(): IPort {
|
||||
return true;
|
||||
},
|
||||
|
||||
read: (): unknown => {
|
||||
if (data.length === 0) {
|
||||
return "NULL PORT DATA";
|
||||
}
|
||||
return data.shift();
|
||||
read: () => {
|
||||
if (data.length === 0) return "NULL PORT DATA";
|
||||
return data.shift() as PortData;
|
||||
},
|
||||
|
||||
peek: (): unknown => {
|
||||
if (data.length === 0) {
|
||||
return "NULL PORT DATA";
|
||||
} else {
|
||||
const foo = data.slice();
|
||||
return foo[0];
|
||||
}
|
||||
peek: () => {
|
||||
if (data.length === 0) return "NULL PORT DATA";
|
||||
return data[0];
|
||||
},
|
||||
|
||||
full: (): boolean => {
|
||||
full: () => {
|
||||
return data.length == Settings.MaxPortCapacity;
|
||||
},
|
||||
|
||||
empty: (): boolean => {
|
||||
empty: () => {
|
||||
return data.length === 0;
|
||||
},
|
||||
|
||||
clear: (): void => {
|
||||
clear: () => {
|
||||
data.length = 0;
|
||||
},
|
||||
};
|
||||
|
6
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
6
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -961,7 +961,7 @@ export interface NetscriptPort {
|
||||
*
|
||||
* @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.
|
||||
@ -981,7 +981,7 @@ export interface NetscriptPort {
|
||||
* If the port is empty, then the string “NULL PORT DATA” will be returned.
|
||||
* @returns the data read.
|
||||
*/
|
||||
read(): string | number;
|
||||
read(): PortData;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @returns the data read
|
||||
*/
|
||||
peek(): string | number;
|
||||
peek(): PortData;
|
||||
|
||||
/**
|
||||
* Check if the port is full.
|
||||
|
@ -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] {
|
||||
return Object.values(obj).includes(value);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user