Wrap Singularity API with wrapper

also refactored the RamCosts IMap as it didnt quite work properly due to
how the wrapper calculates function names
This commit is contained in:
TheMas3212 2022-04-12 16:51:10 +10:00
parent 2d74b493ee
commit b2689eaa5a
No known key found for this signature in database
GPG Key ID: 62A173A4FDA683CA
4 changed files with 1405 additions and 1380 deletions

@ -4,6 +4,7 @@ import type { BaseServer } from "../Server/BaseServer";
import type { WorkerScript } from "./WorkerScript"; import type { WorkerScript } from "./WorkerScript";
import { makeRuntimeRejectMsg } from "../NetscriptEvaluator"; import { makeRuntimeRejectMsg } from "../NetscriptEvaluator";
import { Player } from "../Player"; import { Player } from "../Player";
import { CityName } from "src/Locations/data/CityNames";
type ExternalFunction = (...args: any[]) => any; type ExternalFunction = (...args: any[]) => any;
type ExternalAPI = { type ExternalAPI = {
@ -37,6 +38,7 @@ type NetscriptHelpers = {
makeRuntimeErrorMsg: (caller: string, msg: string) => string; makeRuntimeErrorMsg: (caller: string, msg: string) => string;
string: (funcName: string, argName: string, v: unknown) => string; string: (funcName: string, argName: string, v: unknown) => string;
number: (funcName: string, argName: string, v: unknown) => number; number: (funcName: string, argName: string, v: unknown) => number;
city: (funcName: string, argName: string, v: unknown) => CityName;
boolean: (v: unknown) => boolean; boolean: (v: unknown) => boolean;
getServer: (hostname: string, callingFnName: string) => BaseServer; getServer: (hostname: string, callingFnName: string) => BaseServer;
checkSingularityAccess: (func: string) => void; checkSingularityAccess: (func: string) => void;
@ -48,6 +50,7 @@ type WrappedNetscriptHelpers = {
makeRuntimeErrorMsg: (msg: string) => string; makeRuntimeErrorMsg: (msg: string) => string;
string: (argName: string, v: unknown) => string; string: (argName: string, v: unknown) => string;
number: (argName: string, v: unknown) => number; number: (argName: string, v: unknown) => number;
city: (argName: string, v: unknown) => CityName;
boolean: (v: unknown) => boolean; boolean: (v: unknown) => boolean;
getServer: (hostname: string) => BaseServer; getServer: (hostname: string) => BaseServer;
checkSingularityAccess: () => void; checkSingularityAccess: () => void;
@ -80,6 +83,7 @@ function wrapFunction(
makeRuntimeErrorMsg: (msg: string) => helpers.makeRuntimeErrorMsg(functionPath, msg), makeRuntimeErrorMsg: (msg: string) => helpers.makeRuntimeErrorMsg(functionPath, msg),
string: (argName: string, v: unknown) => helpers.string(functionPath, argName, v), string: (argName: string, v: unknown) => helpers.string(functionPath, argName, v),
number: (argName: string, v: unknown) => helpers.number(functionPath, argName, v), number: (argName: string, v: unknown) => helpers.number(functionPath, argName, v),
city: (argName: string, v: unknown) => helpers.city(functionPath, argName, v),
boolean: helpers.boolean, boolean: helpers.boolean,
getServer: (hostname: string) => helpers.getServer(hostname, functionPath), getServer: (hostname: string) => helpers.getServer(hostname, functionPath),
checkSingularityAccess: () => helpers.checkSingularityAccess(functionName), checkSingularityAccess: () => helpers.checkSingularityAccess(functionName),

@ -81,8 +81,8 @@ function SF4Cost(cost: number): (player: IPlayer) => number {
}; };
} }
export const RamCosts: IMap<any> = { // Hacknet API
hacknet: { const hacknet: IMap<any> = {
numNodes: 0, numNodes: 0,
purchaseNode: 0, purchaseNode: 0,
getPurchaseNodeCost: 0, getPurchaseNodeCost: 0,
@ -98,7 +98,222 @@ export const RamCosts: IMap<any> = {
numHashes: 0, numHashes: 0,
hashCost: 0, hashCost: 0,
spendHashes: 0, spendHashes: 0,
}, };
// Stock API
const stock: IMap<any> = {
getSymbols: RamCostConstants.ScriptGetStockRamCost,
getPrice: RamCostConstants.ScriptGetStockRamCost,
getAskPrice: RamCostConstants.ScriptGetStockRamCost,
getBidPrice: RamCostConstants.ScriptGetStockRamCost,
getPosition: RamCostConstants.ScriptGetStockRamCost,
getMaxShares: RamCostConstants.ScriptGetStockRamCost,
getPurchaseCost: RamCostConstants.ScriptGetStockRamCost,
getSaleGain: RamCostConstants.ScriptGetStockRamCost,
buy: RamCostConstants.ScriptBuySellStockRamCost,
sell: RamCostConstants.ScriptBuySellStockRamCost,
short: RamCostConstants.ScriptBuySellStockRamCost,
sellShort: RamCostConstants.ScriptBuySellStockRamCost,
placeOrder: RamCostConstants.ScriptBuySellStockRamCost,
cancelOrder: RamCostConstants.ScriptBuySellStockRamCost,
getOrders: RamCostConstants.ScriptBuySellStockRamCost,
getVolatility: RamCostConstants.ScriptBuySellStockRamCost,
getForecast: RamCostConstants.ScriptBuySellStockRamCost,
purchase4SMarketData: RamCostConstants.ScriptBuySellStockRamCost,
purchase4SMarketDataTixApi: RamCostConstants.ScriptBuySellStockRamCost,
purchaseWseAccount: RamCostConstants.ScriptBuySellStockRamCost,
purchaseTixApi: RamCostConstants.ScriptBuySellStockRamCost,
};
// Singularity API
const singularity: IMap<any> = {
universityCourse: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
gymWorkout: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
travelToCity: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
goToLocation: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
purchaseTor: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
purchaseProgram: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
getCurrentServer: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
connect: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
manualHack: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
installBackdoor: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
getDarkwebProgramCost: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getDarkwebPrograms: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getStats: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getCharacterInformation: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
hospitalize: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
isBusy: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
stopAction: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 2),
upgradeHomeRam: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
upgradeHomeCores: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
getUpgradeHomeRamCost: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 2),
getUpgradeHomeCoresCost: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 2),
workForCompany: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
applyToCompany: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
getCompanyRep: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getCompanyFavor: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getCompanyFavorGain: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 4),
checkFactionInvitations: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
joinFaction: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
workForFaction: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
getFactionRep: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getFactionFavor: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getFactionFavorGain: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 4),
donateToFaction: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
createProgram: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
commitCrime: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getCrimeChance: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getCrimeStats: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getOwnedAugmentations: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationsFromFaction: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationCost: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationPrereq: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationPrice: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost / 2),
getAugmentationRepReq: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost / 2),
getAugmentationStats: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
purchaseAugmentation: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
softReset: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
installAugmentations: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
isFocused: SF4Cost(0.1),
setFocus: SF4Cost(0.1),
};
// Gang API
const gang: IMap<any> = {
createGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
inGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getMemberNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getGangInformation: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getOtherGangInformation: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getMemberInformation: RamCostConstants.ScriptGangApiBaseRamCost / 2,
canRecruitMember: RamCostConstants.ScriptGangApiBaseRamCost / 4,
recruitMember: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getTaskNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getTaskStats: RamCostConstants.ScriptGangApiBaseRamCost / 4,
setMemberTask: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getEquipmentNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getEquipmentCost: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getEquipmentType: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getEquipmentStats: RamCostConstants.ScriptGangApiBaseRamCost / 2,
purchaseEquipment: RamCostConstants.ScriptGangApiBaseRamCost,
ascendMember: RamCostConstants.ScriptGangApiBaseRamCost,
getAscensionResult: RamCostConstants.ScriptGangApiBaseRamCost / 2,
setTerritoryWarfare: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getChanceToWinClash: RamCostConstants.ScriptGangApiBaseRamCost,
getBonusTime: 0,
};
// Bladeburner API
const bladeburner: IMap<any> = {
getContractNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getOperationNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getBlackOpNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getBlackOpRank: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 2,
getGeneralActionNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getSkillNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
startAction: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
stopBladeburnerAction: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 2,
getCurrentAction: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 4,
getActionTime: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionEstimatedSuccessChance: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionRepGain: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionCountRemaining: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionMaxLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionCurrentLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionAutolevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
setActionAutolevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
setActionLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getRank: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getSkillPoints: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getSkillLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getSkillUpgradeCost: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
upgradeSkill: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getTeamSize: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
setTeamSize: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCityEstimatedPopulation: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCityCommunities: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCityChaos: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCity: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
switchCity: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getStamina: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
joinBladeburnerFaction: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
joinBladeburnerDivision: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getBonusTime: 0,
};
// Coding Contract API
const codingcontract: IMap<any> = {
attempt: RamCostConstants.ScriptCodingContractBaseRamCost,
getContractType: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getData: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getDescription: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getNumTriesRemaining: RamCostConstants.ScriptCodingContractBaseRamCost / 5,
};
// Duplicate Sleeve API
const sleeve: IMap<any> = {
getNumSleeves: RamCostConstants.ScriptSleeveBaseRamCost,
setToShockRecovery: RamCostConstants.ScriptSleeveBaseRamCost,
setToSynchronize: RamCostConstants.ScriptSleeveBaseRamCost,
setToCommitCrime: RamCostConstants.ScriptSleeveBaseRamCost,
setToUniversityCourse: RamCostConstants.ScriptSleeveBaseRamCost,
travel: RamCostConstants.ScriptSleeveBaseRamCost,
setToCompanyWork: RamCostConstants.ScriptSleeveBaseRamCost,
setToFactionWork: RamCostConstants.ScriptSleeveBaseRamCost,
setToGymWorkout: RamCostConstants.ScriptSleeveBaseRamCost,
getSleeveStats: RamCostConstants.ScriptSleeveBaseRamCost,
getTask: RamCostConstants.ScriptSleeveBaseRamCost,
getInformation: RamCostConstants.ScriptSleeveBaseRamCost,
getSleeveAugmentations: RamCostConstants.ScriptSleeveBaseRamCost,
getSleevePurchasableAugs: RamCostConstants.ScriptSleeveBaseRamCost,
purchaseSleeveAug: RamCostConstants.ScriptSleeveBaseRamCost,
};
// Stanek API
const stanek: IMap<any> = {
giftWidth: RamCostConstants.ScriptStanekWidth,
giftHeight: RamCostConstants.ScriptStanekHeight,
chargeFragment: RamCostConstants.ScriptStanekCharge,
fragmentDefinitions: RamCostConstants.ScriptStanekFragmentDefinitions,
activeFragments: RamCostConstants.ScriptStanekPlacedFragments,
clearGift: RamCostConstants.ScriptStanekClear,
canPlaceFragment: RamCostConstants.ScriptStanekCanPlace,
placeFragment: RamCostConstants.ScriptStanekPlace,
getFragment: RamCostConstants.ScriptStanekFragmentAt,
removeFragment: RamCostConstants.ScriptStanekDeleteAt,
};
// UI API
const ui: IMap<any> = {
getTheme: 0,
setTheme: 0,
resetTheme: 0,
getStyles: 0,
setStyles: 0,
resetStyles: 0,
getGameInfo: 0,
};
// Grafting API
const grafting: IMap<any> = {
getAugmentationGraftPrice: 3.75,
getAugmentationGraftTime: 3.75,
graftAugmentation: 7.5,
};
export const RamCosts: IMap<any> = {
hacknet,
stock,
singularity,
...singularity, // singularity is in namespace & toplevel
gang,
bladeburner,
codingcontract,
sleeve,
stanek,
ui,
grafting,
sprintf: 0, sprintf: 0,
vsprintf: 0, vsprintf: 0,
scan: RamCostConstants.ScriptScanRamCost, scan: RamCostConstants.ScriptScanRamCost,
@ -162,29 +377,6 @@ export const RamCosts: IMap<any> = {
serverExists: RamCostConstants.ScriptGetServerRamCost, serverExists: RamCostConstants.ScriptGetServerRamCost,
fileExists: RamCostConstants.ScriptFileExistsRamCost, fileExists: RamCostConstants.ScriptFileExistsRamCost,
isRunning: RamCostConstants.ScriptIsRunningRamCost, isRunning: RamCostConstants.ScriptIsRunningRamCost,
stock: {
getSymbols: RamCostConstants.ScriptGetStockRamCost,
getPrice: RamCostConstants.ScriptGetStockRamCost,
getAskPrice: RamCostConstants.ScriptGetStockRamCost,
getBidPrice: RamCostConstants.ScriptGetStockRamCost,
getPosition: RamCostConstants.ScriptGetStockRamCost,
getMaxShares: RamCostConstants.ScriptGetStockRamCost,
getPurchaseCost: RamCostConstants.ScriptGetStockRamCost,
getSaleGain: RamCostConstants.ScriptGetStockRamCost,
buy: RamCostConstants.ScriptBuySellStockRamCost,
sell: RamCostConstants.ScriptBuySellStockRamCost,
short: RamCostConstants.ScriptBuySellStockRamCost,
sellShort: RamCostConstants.ScriptBuySellStockRamCost,
placeOrder: RamCostConstants.ScriptBuySellStockRamCost,
cancelOrder: RamCostConstants.ScriptBuySellStockRamCost,
getOrders: RamCostConstants.ScriptBuySellStockRamCost,
getVolatility: RamCostConstants.ScriptBuySellStockRamCost,
getForecast: RamCostConstants.ScriptBuySellStockRamCost,
purchase4SMarketData: RamCostConstants.ScriptBuySellStockRamCost,
purchase4SMarketDataTixApi: RamCostConstants.ScriptBuySellStockRamCost,
purchaseWseAccount: RamCostConstants.ScriptBuySellStockRamCost,
purchaseTixApi: RamCostConstants.ScriptBuySellStockRamCost,
},
getPurchasedServerLimit: RamCostConstants.ScriptGetPurchasedServerLimit, getPurchasedServerLimit: RamCostConstants.ScriptGetPurchasedServerLimit,
getPurchasedServerMaxRam: RamCostConstants.ScriptGetPurchasedServerMaxRam, getPurchasedServerMaxRam: RamCostConstants.ScriptGetPurchasedServerMaxRam,
getPurchasedServerCost: RamCostConstants.ScriptGetPurchaseServerRamCost, getPurchasedServerCost: RamCostConstants.ScriptGetPurchaseServerRamCost,
@ -221,178 +413,6 @@ export const RamCosts: IMap<any> = {
getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles, getOwnedSourceFiles: RamCostConstants.ScriptGetOwnedSourceFiles,
tail: 0, tail: 0,
toast: 0, toast: 0,
// Singularity Functions
universityCourse: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
gymWorkout: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
travelToCity: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
goToLocation: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
purchaseTor: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
purchaseProgram: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
getCurrentServer: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
connect: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
manualHack: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
installBackdoor: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost),
getDarkwebProgramCost: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getDarkwebPrograms: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getStats: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
getCharacterInformation: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
hospitalize: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
isBusy: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 4),
stopAction: SF4Cost(RamCostConstants.ScriptSingularityFn1RamCost / 2),
upgradeHomeRam: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
upgradeHomeCores: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
getUpgradeHomeRamCost: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 2),
getUpgradeHomeCoresCost: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 2),
workForCompany: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
applyToCompany: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
getCompanyRep: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getCompanyFavor: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getCompanyFavorGain: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 4),
checkFactionInvitations: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
joinFaction: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
workForFaction: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost),
getFactionRep: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getFactionFavor: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 3),
getFactionFavorGain: SF4Cost(RamCostConstants.ScriptSingularityFn2RamCost / 4),
donateToFaction: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
createProgram: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
commitCrime: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getCrimeChance: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getCrimeStats: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getOwnedAugmentations: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationsFromFaction: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationCost: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationPrereq: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
getAugmentationPrice: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost / 2),
getAugmentationRepReq: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost / 2),
getAugmentationStats: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
purchaseAugmentation: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
softReset: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
installAugmentations: SF4Cost(RamCostConstants.ScriptSingularityFn3RamCost),
isFocused: SF4Cost(0.1),
setFocus: SF4Cost(0.1),
// Gang API
gang: {
createGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
inGang: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getMemberNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getGangInformation: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getOtherGangInformation: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getMemberInformation: RamCostConstants.ScriptGangApiBaseRamCost / 2,
canRecruitMember: RamCostConstants.ScriptGangApiBaseRamCost / 4,
recruitMember: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getTaskNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getTaskStats: RamCostConstants.ScriptGangApiBaseRamCost / 4,
setMemberTask: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getEquipmentNames: RamCostConstants.ScriptGangApiBaseRamCost / 4,
getEquipmentCost: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getEquipmentType: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getEquipmentStats: RamCostConstants.ScriptGangApiBaseRamCost / 2,
purchaseEquipment: RamCostConstants.ScriptGangApiBaseRamCost,
ascendMember: RamCostConstants.ScriptGangApiBaseRamCost,
getAscensionResult: RamCostConstants.ScriptGangApiBaseRamCost / 2,
setTerritoryWarfare: RamCostConstants.ScriptGangApiBaseRamCost / 2,
getChanceToWinClash: RamCostConstants.ScriptGangApiBaseRamCost,
getBonusTime: 0,
},
// Bladeburner API
bladeburner: {
getContractNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getOperationNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getBlackOpNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getBlackOpRank: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 2,
getGeneralActionNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
getSkillNames: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 10,
startAction: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
stopBladeburnerAction: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 2,
getCurrentAction: RamCostConstants.ScriptBladeburnerApiBaseRamCost / 4,
getActionTime: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionEstimatedSuccessChance: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionRepGain: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionCountRemaining: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionMaxLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionCurrentLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getActionAutolevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
setActionAutolevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
setActionLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getRank: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getSkillPoints: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getSkillLevel: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getSkillUpgradeCost: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
upgradeSkill: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getTeamSize: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
setTeamSize: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCityEstimatedPopulation: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCityCommunities: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCityChaos: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getCity: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
switchCity: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getStamina: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
joinBladeburnerFaction: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
joinBladeburnerDivision: RamCostConstants.ScriptBladeburnerApiBaseRamCost,
getBonusTime: 0,
},
// Coding Contract API
codingcontract: {
attempt: RamCostConstants.ScriptCodingContractBaseRamCost,
getContractType: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getData: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getDescription: RamCostConstants.ScriptCodingContractBaseRamCost / 2,
getNumTriesRemaining: RamCostConstants.ScriptCodingContractBaseRamCost / 5,
},
// Duplicate Sleeve API
sleeve: {
getNumSleeves: RamCostConstants.ScriptSleeveBaseRamCost,
setToShockRecovery: RamCostConstants.ScriptSleeveBaseRamCost,
setToSynchronize: RamCostConstants.ScriptSleeveBaseRamCost,
setToCommitCrime: RamCostConstants.ScriptSleeveBaseRamCost,
setToUniversityCourse: RamCostConstants.ScriptSleeveBaseRamCost,
travel: RamCostConstants.ScriptSleeveBaseRamCost,
setToCompanyWork: RamCostConstants.ScriptSleeveBaseRamCost,
setToFactionWork: RamCostConstants.ScriptSleeveBaseRamCost,
setToGymWorkout: RamCostConstants.ScriptSleeveBaseRamCost,
getSleeveStats: RamCostConstants.ScriptSleeveBaseRamCost,
getTask: RamCostConstants.ScriptSleeveBaseRamCost,
getInformation: RamCostConstants.ScriptSleeveBaseRamCost,
getSleeveAugmentations: RamCostConstants.ScriptSleeveBaseRamCost,
getSleevePurchasableAugs: RamCostConstants.ScriptSleeveBaseRamCost,
purchaseSleeveAug: RamCostConstants.ScriptSleeveBaseRamCost,
},
stanek: {
giftWidth: RamCostConstants.ScriptStanekWidth,
giftHeight: RamCostConstants.ScriptStanekHeight,
chargeFragment: RamCostConstants.ScriptStanekCharge,
fragmentDefinitions: RamCostConstants.ScriptStanekFragmentDefinitions,
activeFragments: RamCostConstants.ScriptStanekPlacedFragments,
clearGift: RamCostConstants.ScriptStanekClear,
canPlaceFragment: RamCostConstants.ScriptStanekCanPlace,
placeFragment: RamCostConstants.ScriptStanekPlace,
getFragment: RamCostConstants.ScriptStanekFragmentAt,
removeFragment: RamCostConstants.ScriptStanekDeleteAt,
},
ui: {
getTheme: 0,
setTheme: 0,
resetTheme: 0,
getStyles: 0,
setStyles: 0,
resetStyles: 0,
getGameInfo: 0,
},
grafting: {
getAugmentationGraftPrice: 3.75,
getAugmentationGraftTime: 3.75,
graftAugmentation: 7.5,
},
heart: { heart: {
// Easter egg function // Easter egg function
break: 0, break: 0,

@ -75,6 +75,7 @@ import { IPort } from "./NetscriptPort";
import { import {
NS as INS, NS as INS,
Singularity as ISingularity,
Player as INetscriptPlayer, Player as INetscriptPlayer,
Gang as IGang, Gang as IGang,
Bladeburner as IBladeburner, Bladeburner as IBladeburner,
@ -498,7 +499,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
const codingcontract = NetscriptCodingContract(Player, workerScript, helper); const codingcontract = NetscriptCodingContract(Player, workerScript, helper);
const corporation = NetscriptCorporation(Player, workerScript, helper); const corporation = NetscriptCorporation(Player, workerScript, helper);
const formulas = NetscriptFormulas(Player, workerScript, helper); const formulas = NetscriptFormulas(Player, workerScript, helper);
const singularity = NetscriptSingularity(Player, workerScript, helper); const singularity = wrapAPI(helper, {}, workerScript, NetscriptSingularity(Player, workerScript), "singularity")
.singularity as unknown as ISingularity;
const stockmarket = NetscriptStockMarket(Player, workerScript, helper); const stockmarket = NetscriptStockMarket(Player, workerScript, helper);
const ui = NetscriptUserInterface(Player, workerScript, helper); const ui = NetscriptUserInterface(Player, workerScript, helper);
const grafting = NetscriptGrafting(Player, workerScript, helper); const grafting = NetscriptGrafting(Player, workerScript, helper);

@ -1,4 +1,3 @@
import { INetscriptHelper } from "./INetscriptHelper";
import { WorkerScript } from "../Netscript/WorkerScript"; import { WorkerScript } from "../Netscript/WorkerScript";
import { IPlayer } from "../PersonObjects/IPlayer"; import { IPlayer } from "../PersonObjects/IPlayer";
import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers"; import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers";
@ -10,7 +9,6 @@ import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
import { killWorkerScript } from "../Netscript/killWorkerScript"; import { killWorkerScript } from "../Netscript/killWorkerScript";
import { CONSTANTS } from "../Constants"; import { CONSTANTS } from "../Constants";
import { isString } from "../utils/helpers/isString"; import { isString } from "../utils/helpers/isString";
import { getRamCost } from "../Netscript/RamCostGenerator";
import { RunningScript } from "../Script/RunningScript"; import { RunningScript } from "../Script/RunningScript";
import { import {
@ -48,32 +46,29 @@ import { calculateHackingTime } from "../Hacking";
import { Server } from "../Server/Server"; import { Server } from "../Server/Server";
import { netscriptCanHack } from "../Hacking/netscriptCanHack"; import { netscriptCanHack } from "../Hacking/netscriptCanHack";
import { FactionInfos } from "../Faction/FactionInfo"; import { FactionInfos } from "../Faction/FactionInfo";
import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
export function NetscriptSingularity( export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript): InternalAPI<ISingularity> {
player: IPlayer, const getAugmentation = function (_ctx: NetscriptContext, name: string): Augmentation {
workerScript: WorkerScript,
helper: INetscriptHelper,
): ISingularity {
const getAugmentation = function (func: string, name: string): Augmentation {
if (!augmentationExists(name)) { if (!augmentationExists(name)) {
throw helper.makeRuntimeErrorMsg(func, `Invalid augmentation: '${name}'`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid augmentation: '${name}'`);
} }
return Augmentations[name]; return Augmentations[name];
}; };
const getFaction = function (func: string, name: string): Faction { const getFaction = function (_ctx: NetscriptContext, name: string): Faction {
if (!factionExists(name)) { if (!factionExists(name)) {
throw helper.makeRuntimeErrorMsg(func, `Invalid faction name: '${name}`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid faction name: '${name}`);
} }
return Factions[name]; return Factions[name];
}; };
const getCompany = function (func: string, name: string): Company { const getCompany = function (_ctx: NetscriptContext, name: string): Company {
const company = Companies[name]; const company = Companies[name];
if (company == null || !(company instanceof Company)) { if (company == null || !(company instanceof Company)) {
throw helper.makeRuntimeErrorMsg(func, `Invalid company name: '${name}'`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid company name: '${name}'`);
} }
return company; return company;
}; };
@ -96,12 +91,11 @@ export function NetscriptSingularity(
} }
}; };
const updateRam = (funcName: string): void => helper.updateDynamicRam(funcName, getRamCost(player, funcName));
return { return {
getOwnedAugmentations: function (_purchased: unknown = false): string[] { getOwnedAugmentations: (_ctx: NetscriptContext) =>
updateRam("getOwnedAugmentations"); function (_purchased: unknown = false): string[] {
const purchased = helper.boolean(_purchased); const purchased = _ctx.helper.boolean(_purchased);
helper.checkSingularityAccess("getOwnedAugmentations"); _ctx.helper.checkSingularityAccess();
const res = []; const res = [];
for (let i = 0; i < player.augmentations.length; ++i) { for (let i = 0; i < player.augmentations.length; ++i) {
res.push(player.augmentations[i].name); res.push(player.augmentations[i].name);
@ -113,56 +107,56 @@ export function NetscriptSingularity(
} }
return res; return res;
}, },
getAugmentationsFromFaction: function (_facName: unknown): string[] { getAugmentationsFromFaction: (_ctx: NetscriptContext) =>
updateRam("getAugmentationsFromFaction"); function (_facName: unknown): string[] {
const facName = helper.string("getAugmentationsFromFaction", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
helper.checkSingularityAccess("getAugmentationsFromFaction"); _ctx.helper.checkSingularityAccess();
const faction = getFaction("getAugmentationsFromFaction", facName); const faction = getFaction(_ctx, facName);
return getFactionAugmentationsFiltered(player, faction); return getFactionAugmentationsFiltered(player, faction);
}, },
getAugmentationCost: function (_augName: unknown): [number, number] { getAugmentationCost: (_ctx: NetscriptContext) =>
updateRam("getAugmentationCost"); function (_augName: unknown): [number, number] {
const augName = helper.string("getAugmentationCost", "augName", _augName); const augName = _ctx.helper.string("augName", _augName);
helper.checkSingularityAccess("getAugmentationCost"); _ctx.helper.checkSingularityAccess();
const aug = getAugmentation("getAugmentationCost", augName); const aug = getAugmentation(_ctx, augName);
return [aug.baseRepRequirement, aug.baseCost]; return [aug.baseRepRequirement, aug.baseCost];
}, },
getAugmentationPrereq: function (_augName: unknown): string[] { getAugmentationPrereq: (_ctx: NetscriptContext) =>
updateRam("getAugmentationPrereq"); function (_augName: unknown): string[] {
const augName = helper.string("getAugmentationPrereq", "augName", _augName); const augName = _ctx.helper.string("augName", _augName);
helper.checkSingularityAccess("getAugmentationPrereq"); _ctx.helper.checkSingularityAccess();
const aug = getAugmentation("getAugmentationPrereq", augName); const aug = getAugmentation(_ctx, augName);
return aug.prereqs.slice(); return aug.prereqs.slice();
}, },
getAugmentationPrice: function (_augName: unknown): number { getAugmentationPrice: (_ctx: NetscriptContext) =>
updateRam("getAugmentationPrice"); function (_augName: unknown): number {
const augName = helper.string("getAugmentationPrice", "augName", _augName); const augName = _ctx.helper.string("augName", _augName);
helper.checkSingularityAccess("getAugmentationPrice"); _ctx.helper.checkSingularityAccess();
const aug = getAugmentation("getAugmentationPrice", augName); const aug = getAugmentation(_ctx, augName);
return aug.baseCost; return aug.baseCost;
}, },
getAugmentationRepReq: function (_augName: unknown): number { getAugmentationRepReq: (_ctx: NetscriptContext) =>
updateRam("getAugmentationRepReq"); function (_augName: unknown): number {
const augName = helper.string("getAugmentationRepReq", "augName", _augName); const augName = _ctx.helper.string("augName", _augName);
helper.checkSingularityAccess("getAugmentationRepReq"); _ctx.helper.checkSingularityAccess();
const aug = getAugmentation("getAugmentationRepReq", augName); const aug = getAugmentation(_ctx, augName);
return aug.baseRepRequirement; return aug.baseRepRequirement;
}, },
getAugmentationStats: function (_augName: unknown): AugmentationStats { getAugmentationStats: (_ctx: NetscriptContext) =>
updateRam("getAugmentationStats"); function (_augName: unknown): AugmentationStats {
const augName = helper.string("getAugmentationStats", "augName", _augName); const augName = _ctx.helper.string("augName", _augName);
helper.checkSingularityAccess("getAugmentationStats"); _ctx.helper.checkSingularityAccess();
const aug = getAugmentation("getAugmentationStats", augName); const aug = getAugmentation(_ctx, augName);
return Object.assign({}, aug.mults); return Object.assign({}, aug.mults);
}, },
purchaseAugmentation: function (_facName: unknown, _augName: unknown): boolean { purchaseAugmentation: (_ctx: NetscriptContext) =>
updateRam("purchaseAugmentation"); function (_facName: unknown, _augName: unknown): boolean {
const facName = helper.string("purchaseAugmentation", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
const augName = helper.string("purchaseAugmentation", "augName", _augName); const augName = _ctx.helper.string("augName", _augName);
helper.checkSingularityAccess("purchaseAugmentation"); _ctx.helper.checkSingularityAccess();
const fac = getFaction("purchaseAugmentation", facName); const fac = getFaction(_ctx, facName);
const aug = getAugmentation("purchaseAugmentation", augName); const aug = getAugmentation(_ctx, augName);
const augs = getFactionAugmentationsFiltered(player, fac); const augs = getFactionAugmentationsFiltered(player, fac);
@ -204,10 +198,10 @@ export function NetscriptSingularity(
return false; return false;
} }
}, },
softReset: function (_cbScript: unknown): void { softReset: (_ctx: NetscriptContext) =>
updateRam("softReset"); function (_cbScript: unknown = ""): void {
const cbScript = helper.string("softReset", "cbScript", _cbScript); const cbScript = _ctx.helper.string("cbScript", _cbScript);
helper.checkSingularityAccess("softReset"); _ctx.helper.checkSingularityAccess();
workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed"); workerScript.log("softReset", () => "Soft resetting. This will cause this script to be killed");
setTimeout(() => { setTimeout(() => {
@ -219,10 +213,10 @@ export function NetscriptSingularity(
workerScript.running = false; workerScript.running = false;
killWorkerScript(workerScript); killWorkerScript(workerScript);
}, },
installAugmentations: function (_cbScript: unknown = ""): boolean { installAugmentations: (_ctx: NetscriptContext) =>
updateRam("installAugmentations"); function (_cbScript: unknown = ""): boolean {
const cbScript = helper.string("installAugmentations", "cbScript", _cbScript); const cbScript = _ctx.helper.string("cbScript", _cbScript);
helper.checkSingularityAccess("installAugmentations"); _ctx.helper.checkSingularityAccess();
if (player.queuedAugmentations.length === 0) { if (player.queuedAugmentations.length === 0) {
workerScript.log("installAugmentations", () => "You do not have any Augmentations to be installed."); workerScript.log("installAugmentations", () => "You do not have any Augmentations to be installed.");
@ -243,10 +237,10 @@ export function NetscriptSingularity(
return true; return true;
}, },
goToLocation: function (_locationName: unknown): boolean { goToLocation: (_ctx: NetscriptContext) =>
updateRam("goToLocation"); function (_locationName: unknown): boolean {
const locationName = helper.string("goToLocation", "locationName", _locationName); const locationName = _ctx.helper.string("locationName", _locationName);
helper.checkSingularityAccess("goToLocation"); _ctx.helper.checkSingularityAccess();
const location = Object.values(Locations).find((l) => l.name === locationName); const location = Object.values(Locations).find((l) => l.name === locationName);
if (!location) { if (!location) {
workerScript.log("goToLocation", () => `No location named ${locationName}`); workerScript.log("goToLocation", () => `No location named ${locationName}`);
@ -260,12 +254,12 @@ export function NetscriptSingularity(
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000);
return true; return true;
}, },
universityCourse: function (_universityName: unknown, _className: unknown, _focus: unknown = true): boolean { universityCourse: (_ctx: NetscriptContext) =>
updateRam("universityCourse"); function (_universityName: unknown, _className: unknown, _focus: unknown = true): boolean {
const universityName = helper.string("universityCourse", "universityName", _universityName); const universityName = _ctx.helper.string("universityName", _universityName);
const className = helper.string("universityCourse", "className", _className); const className = _ctx.helper.string("className", _className);
const focus = helper.boolean(_focus); const focus = _ctx.helper.boolean(_focus);
helper.checkSingularityAccess("universityCourse"); _ctx.helper.checkSingularityAccess();
const wasFocusing = player.focus; const wasFocusing = player.focus;
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
@ -351,12 +345,12 @@ export function NetscriptSingularity(
return true; return true;
}, },
gymWorkout: function (_gymName: unknown, _stat: unknown, _focus: unknown = true): boolean { gymWorkout: (_ctx: NetscriptContext) =>
updateRam("gymWorkout"); function (_gymName: unknown, _stat: unknown, _focus: unknown = true): boolean {
const gymName = helper.string("gymWorkout", "gymName", _gymName); const gymName = _ctx.helper.string("gymName", _gymName);
const stat = helper.string("gymWorkout", "stat", _stat); const stat = _ctx.helper.string("stat", _stat);
const focus = helper.boolean(_focus); const focus = _ctx.helper.boolean(_focus);
helper.checkSingularityAccess("gymWorkout"); _ctx.helper.checkSingularityAccess();
const wasFocusing = player.focus; const wasFocusing = player.focus;
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
@ -466,10 +460,10 @@ export function NetscriptSingularity(
return true; return true;
}, },
travelToCity: function (_cityName: unknown): boolean { travelToCity: (_ctx: NetscriptContext) =>
updateRam("travelToCity"); function (_cityName: unknown): boolean {
const cityName = helper.city("travelToCity", "cityName", _cityName); const cityName = _ctx.helper.city("cityName", _cityName);
helper.checkSingularityAccess("travelToCity"); _ctx.helper.checkSingularityAccess();
switch (cityName) { switch (cityName) {
case CityName.Aevum: case CityName.Aevum:
@ -488,13 +482,13 @@ export function NetscriptSingularity(
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 50000);
return true; return true;
default: default:
throw helper.makeRuntimeErrorMsg("travelToCity", `Invalid city name: '${cityName}'.`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid city name: '${cityName}'.`);
} }
}, },
purchaseTor: function (): boolean { purchaseTor: (_ctx: NetscriptContext) =>
updateRam("purchaseTor"); function (): boolean {
helper.checkSingularityAccess("purchaseTor"); _ctx.helper.checkSingularityAccess();
if (player.hasTorRouter()) { if (player.hasTorRouter()) {
workerScript.log("purchaseTor", () => "You already have a TOR router!"); workerScript.log("purchaseTor", () => "You already have a TOR router!");
@ -524,10 +518,10 @@ export function NetscriptSingularity(
workerScript.log("purchaseTor", () => "You have purchased a Tor router!"); workerScript.log("purchaseTor", () => "You have purchased a Tor router!");
return true; return true;
}, },
purchaseProgram: function (_programName: unknown): boolean { purchaseProgram: (_ctx: NetscriptContext) =>
updateRam("purchaseProgram"); function (_programName: unknown): boolean {
const programName = helper.string("purchaseProgram", "programName", _programName).toLowerCase(); const programName = _ctx.helper.string("programName", _programName).toLowerCase();
helper.checkSingularityAccess("purchaseProgram"); _ctx.helper.checkSingularityAccess();
if (!player.hasTorRouter()) { if (!player.hasTorRouter()) {
workerScript.log("purchaseProgram", () => "You do not have the TOR router."); workerScript.log("purchaseProgram", () => "You do not have the TOR router.");
@ -562,22 +556,22 @@ export function NetscriptSingularity(
player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 5000); player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain / 5000);
return true; return true;
}, },
getCurrentServer: function (): string { getCurrentServer: (_ctx: NetscriptContext) =>
updateRam("getCurrentServer"); function (): string {
helper.checkSingularityAccess("getCurrentServer"); _ctx.helper.checkSingularityAccess();
return player.getCurrentServer().hostname; return player.getCurrentServer().hostname;
}, },
connect: function (_hostname: unknown): boolean { connect: (_ctx: NetscriptContext) =>
updateRam("connect"); function (_hostname: unknown): boolean {
const hostname = helper.string("purchaseProgram", "hostname", _hostname); const hostname = _ctx.helper.string("hostname", _hostname);
helper.checkSingularityAccess("connect"); _ctx.helper.checkSingularityAccess();
if (!hostname) { if (!hostname) {
throw helper.makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid hostname: '${hostname}'`);
} }
const target = GetServer(hostname); const target = GetServer(hostname);
if (target == null) { if (target == null) {
throw helper.makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid hostname: '${hostname}'`);
} }
if (hostname === "home") { if (hostname === "home") {
@ -603,15 +597,15 @@ export function NetscriptSingularity(
return false; return false;
}, },
manualHack: function (): Promise<number> { manualHack: (_ctx: NetscriptContext) =>
updateRam("manualHack"); function (): Promise<number> {
helper.checkSingularityAccess("manualHack"); _ctx.helper.checkSingularityAccess();
const server = player.getCurrentServer(); const server = player.getCurrentServer();
return helper.hack(server.hostname, true); return _ctx.helper.hack(server.hostname, true);
}, },
installBackdoor: function (): Promise<void> { installBackdoor: (_ctx: NetscriptContext) =>
updateRam("installBackdoor"); function (): Promise<void> {
helper.checkSingularityAccess("installBackdoor"); _ctx.helper.checkSingularityAccess();
const baseserver = player.getCurrentServer(); const baseserver = player.getCurrentServer();
if (!(baseserver instanceof Server)) { if (!(baseserver instanceof Server)) {
workerScript.log("installBackdoor", () => "cannot backdoor this kind of server"); workerScript.log("installBackdoor", () => "cannot backdoor this kind of server");
@ -623,7 +617,7 @@ export function NetscriptSingularity(
// No root access or skill level too low // No root access or skill level too low
const canHack = netscriptCanHack(server, player); const canHack = netscriptCanHack(server, player);
if (!canHack.res) { if (!canHack.res) {
throw helper.makeRuntimeErrorMsg("installBackdoor", canHack.msg || ""); throw _ctx.helper.makeRuntimeErrorMsg(canHack.msg || "");
} }
workerScript.log( workerScript.log(
@ -642,17 +636,17 @@ export function NetscriptSingularity(
return Promise.resolve(); return Promise.resolve();
}); });
}, },
isFocused: function (): boolean { isFocused: (_ctx: NetscriptContext) =>
updateRam("isFocused"); function (): boolean {
helper.checkSingularityAccess("isFocused"); _ctx.helper.checkSingularityAccess();
return player.focus; return player.focus;
}, },
setFocus: function (_focus: unknown): boolean { setFocus: (_ctx: NetscriptContext) =>
updateRam("setFocus"); function (_focus: unknown): boolean {
const focus = helper.boolean(_focus); const focus = _ctx.helper.boolean(_focus);
helper.checkSingularityAccess("setFocus"); _ctx.helper.checkSingularityAccess();
if (!player.isWorking) { if (!player.isWorking) {
throw helper.makeRuntimeErrorMsg("setFocus", "Not currently working"); throw _ctx.helper.makeRuntimeErrorMsg("Not currently working");
} }
if ( if (
!( !(
@ -663,7 +657,7 @@ export function NetscriptSingularity(
player.workType == CONSTANTS.WorkTypeStudyClass player.workType == CONSTANTS.WorkTypeStudyClass
) )
) { ) {
throw helper.makeRuntimeErrorMsg("setFocus", "Cannot change focus for current job"); throw _ctx.helper.makeRuntimeErrorMsg("Cannot change focus for current job");
} }
if (!player.focus && focus) { if (!player.focus && focus) {
player.startFocusing(); player.startFocusing();
@ -676,9 +670,9 @@ export function NetscriptSingularity(
} }
return false; return false;
}, },
getStats: function (): PlayerSkills { getStats: (_ctx: NetscriptContext) =>
updateRam("getStats"); function (): PlayerSkills {
helper.checkSingularityAccess("getStats"); _ctx.helper.checkSingularityAccess();
workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`); workerScript.log("getStats", () => `getStats is deprecated, please use getplayer`);
return { return {
@ -691,10 +685,13 @@ export function NetscriptSingularity(
intelligence: player.intelligence, intelligence: player.intelligence,
}; };
}, },
getCharacterInformation: function (): CharacterInfo { getCharacterInformation: (_ctx: NetscriptContext) =>
updateRam("getCharacterInformation"); function (): CharacterInfo {
helper.checkSingularityAccess("getCharacterInformation"); _ctx.helper.checkSingularityAccess();
workerScript.log("getCharacterInformation", () => `getCharacterInformation is deprecated, please use getplayer`); workerScript.log(
"getCharacterInformation",
() => `getCharacterInformation is deprecated, please use getplayer`,
);
return { return {
bitnode: player.bitNodeN, bitnode: player.bitNodeN,
@ -741,23 +738,23 @@ export function NetscriptSingularity(
charismaExp: player.charisma_exp, charismaExp: player.charisma_exp,
}; };
}, },
hospitalize: function (): void { hospitalize: (_ctx: NetscriptContext) =>
updateRam("hospitalize"); function (): void {
helper.checkSingularityAccess("hospitalize"); _ctx.helper.checkSingularityAccess();
if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) { if (player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy."); workerScript.log("hospitalize", () => "Cannot go to the hospital because the player is busy.");
return; return;
} }
player.hospitalize(); player.hospitalize();
}, },
isBusy: function (): boolean { isBusy: (_ctx: NetscriptContext) =>
updateRam("isBusy"); function (): boolean {
helper.checkSingularityAccess("isBusy"); _ctx.helper.checkSingularityAccess();
return player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse; return player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse;
}, },
stopAction: function (): boolean { stopAction: (_ctx: NetscriptContext) =>
updateRam("stopAction"); function (): boolean {
helper.checkSingularityAccess("stopAction"); _ctx.helper.checkSingularityAccess();
if (player.isWorking) { if (player.isWorking) {
if (player.focus) { if (player.focus) {
player.stopFocusing(); player.stopFocusing();
@ -769,9 +766,9 @@ export function NetscriptSingularity(
} }
return false; return false;
}, },
upgradeHomeCores: function (): boolean { upgradeHomeCores: (_ctx: NetscriptContext) =>
updateRam("upgradeHomeCores"); function (): boolean {
helper.checkSingularityAccess("upgradeHomeCores"); _ctx.helper.checkSingularityAccess();
// Check if we're at max cores // Check if we're at max cores
const homeComputer = player.getHomeComputer(); const homeComputer = player.getHomeComputer();
@ -799,15 +796,15 @@ export function NetscriptSingularity(
); );
return true; return true;
}, },
getUpgradeHomeCoresCost: function (): number { getUpgradeHomeCoresCost: (_ctx: NetscriptContext) =>
updateRam("getUpgradeHomeCoresCost"); function (): number {
helper.checkSingularityAccess("getUpgradeHomeCoresCost"); _ctx.helper.checkSingularityAccess();
return player.getUpgradeHomeCoresCost(); return player.getUpgradeHomeCoresCost();
}, },
upgradeHomeRam: function (): boolean { upgradeHomeRam: (_ctx: NetscriptContext) =>
updateRam("upgradeHomeRam"); function (): boolean {
helper.checkSingularityAccess("upgradeHomeRam"); _ctx.helper.checkSingularityAccess();
// Check if we're at max RAM // Check if we're at max RAM
const homeComputer = player.getHomeComputer(); const homeComputer = player.getHomeComputer();
@ -838,17 +835,17 @@ export function NetscriptSingularity(
); );
return true; return true;
}, },
getUpgradeHomeRamCost: function (): number { getUpgradeHomeRamCost: (_ctx: NetscriptContext) =>
updateRam("getUpgradeHomeRamCost"); function (): number {
helper.checkSingularityAccess("getUpgradeHomeRamCost"); _ctx.helper.checkSingularityAccess();
return player.getUpgradeHomeRamCost(); return player.getUpgradeHomeRamCost();
}, },
workForCompany: function (_companyName: unknown, _focus: unknown = true): boolean { workForCompany: (_ctx: NetscriptContext) =>
updateRam("workForCompany"); function (_companyName: unknown, _focus: unknown = true): boolean {
let companyName = helper.string("workForCompany", "companyName", _companyName); let companyName = _ctx.helper.string("companyName", _companyName);
const focus = helper.boolean(_focus); const focus = _ctx.helper.boolean(_focus);
helper.checkSingularityAccess("workForCompany"); _ctx.helper.checkSingularityAccess();
// Sanitize input // Sanitize input
if (companyName == null) { if (companyName == null) {
@ -900,12 +897,12 @@ export function NetscriptSingularity(
); );
return true; return true;
}, },
applyToCompany: function (_companyName: unknown, _field: unknown): boolean { applyToCompany: (_ctx: NetscriptContext) =>
updateRam("applyToCompany"); function (_companyName: unknown, _field: unknown): boolean {
const companyName = helper.string("applyToCompany", "companyName", _companyName); const companyName = _ctx.helper.string("companyName", _companyName);
const field = helper.string("applyToCompany", "field", _field); const field = _ctx.helper.string("field", _field);
helper.checkSingularityAccess("applyToCompany"); _ctx.helper.checkSingularityAccess();
getCompany("applyToCompany", companyName); getCompany(_ctx, companyName);
player.location = companyName as LocationName; player.location = companyName as LocationName;
let res; let res;
@ -972,38 +969,38 @@ export function NetscriptSingularity(
} }
return res; return res;
}, },
getCompanyRep: function (_companyName: unknown): number { getCompanyRep: (_ctx: NetscriptContext) =>
updateRam("getCompanyRep"); function (_companyName: unknown): number {
const companyName = helper.string("getCompanyRep", "companyName", _companyName); const companyName = _ctx.helper.string("companyName", _companyName);
helper.checkSingularityAccess("getCompanyRep"); _ctx.helper.checkSingularityAccess();
const company = getCompany("getCompanyRep", companyName); const company = getCompany(_ctx, companyName);
return company.playerReputation; return company.playerReputation;
}, },
getCompanyFavor: function (_companyName: unknown): number { getCompanyFavor: (_ctx: NetscriptContext) =>
updateRam("getCompanyFavor"); function (_companyName: unknown): number {
const companyName = helper.string("getCompanyFavor", "companyName", _companyName); const companyName = _ctx.helper.string("companyName", _companyName);
helper.checkSingularityAccess("getCompanyFavor"); _ctx.helper.checkSingularityAccess();
const company = getCompany("getCompanyFavor", companyName); const company = getCompany(_ctx, companyName);
return company.favor; return company.favor;
}, },
getCompanyFavorGain: function (_companyName: unknown): number { getCompanyFavorGain: (_ctx: NetscriptContext) =>
updateRam("getCompanyFavorGain"); function (_companyName: unknown): number {
const companyName = helper.string("getCompanyFavorGain", "companyName", _companyName); const companyName = _ctx.helper.string("companyName", _companyName);
helper.checkSingularityAccess("getCompanyFavorGain"); _ctx.helper.checkSingularityAccess();
const company = getCompany("getCompanyFavorGain", companyName); const company = getCompany(_ctx, companyName);
return company.getFavorGain(); return company.getFavorGain();
}, },
checkFactionInvitations: function (): string[] { checkFactionInvitations: (_ctx: NetscriptContext) =>
helper.updateDynamicRam("checkFactionInvitations", getRamCost(player, "checkFactionInvitations")); function (): string[] {
helper.checkSingularityAccess("checkFactionInvitations"); _ctx.helper.checkSingularityAccess();
// Make a copy of player.factionInvitations // Make a copy of player.factionInvitations
return player.factionInvitations.slice(); return player.factionInvitations.slice();
}, },
joinFaction: function (_facName: unknown): boolean { joinFaction: (_ctx: NetscriptContext) =>
updateRam("joinFaction"); function (_facName: unknown): boolean {
const facName = helper.string("joinFaction", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
helper.checkSingularityAccess("joinFaction"); _ctx.helper.checkSingularityAccess();
getFaction("joinFaction", facName); getFaction(_ctx, facName);
if (!player.factionInvitations.includes(facName)) { if (!player.factionInvitations.includes(facName)) {
workerScript.log("joinFaction", () => `You have not been invited by faction '${facName}'`); workerScript.log("joinFaction", () => `You have not been invited by faction '${facName}'`);
@ -1023,13 +1020,13 @@ export function NetscriptSingularity(
workerScript.log("joinFaction", () => `Joined the '${facName}' faction.`); workerScript.log("joinFaction", () => `Joined the '${facName}' faction.`);
return true; return true;
}, },
workForFaction: function (_facName: unknown, _type: unknown, _focus: unknown = true): boolean { workForFaction: (_ctx: NetscriptContext) =>
updateRam("workForFaction"); function (_facName: unknown, _type: unknown, _focus: unknown = true): boolean {
const facName = helper.string("workForFaction", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
const type = helper.string("workForFaction", "type", _type); const type = _ctx.helper.string("type", _type);
const focus = helper.boolean(_focus); const focus = _ctx.helper.boolean(_focus);
helper.checkSingularityAccess("workForFaction"); _ctx.helper.checkSingularityAccess();
getFaction("workForFaction", facName); getFaction(_ctx, facName);
// if the player is in a gang and the target faction is any of the gang faction, fail // if the player is in a gang and the target faction is any of the gang faction, fail
if (player.inGang() && AllGangs[facName] !== undefined) { if (player.inGang() && AllGangs[facName] !== undefined) {
@ -1056,7 +1053,10 @@ export function NetscriptSingularity(
case "hacking contracts": case "hacking contracts":
case "hackingcontracts": case "hackingcontracts":
if (!FactionInfos[fac.name].offerHackingWork) { if (!FactionInfos[fac.name].offerHackingWork) {
workerScript.log("workForFaction", () => `Faction '${fac.name}' do not need help with hacking contracts.`); workerScript.log(
"workForFaction",
() => `Faction '${fac.name}' do not need help with hacking contracts.`,
);
return false; return false;
} }
player.startFactionHackWork(fac); player.startFactionHackWork(fac);
@ -1109,33 +1109,33 @@ export function NetscriptSingularity(
} }
return true; return true;
}, },
getFactionRep: function (_facName: unknown): number { getFactionRep: (_ctx: NetscriptContext) =>
updateRam("getFactionRep"); function (_facName: unknown): number {
const facName = helper.string("getFactionRep", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
helper.checkSingularityAccess("getFactionRep"); _ctx.helper.checkSingularityAccess();
const faction = getFaction("getFactionRep", facName); const faction = getFaction(_ctx, facName);
return faction.playerReputation; return faction.playerReputation;
}, },
getFactionFavor: function (_facName: unknown): number { getFactionFavor: (_ctx: NetscriptContext) =>
updateRam("getFactionFavor"); function (_facName: unknown): number {
const facName = helper.string("getFactionRep", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
helper.checkSingularityAccess("getFactionFavor"); _ctx.helper.checkSingularityAccess();
const faction = getFaction("getFactionFavor", facName); const faction = getFaction(_ctx, facName);
return faction.favor; return faction.favor;
}, },
getFactionFavorGain: function (_facName: unknown): number { getFactionFavorGain: (_ctx: NetscriptContext) =>
updateRam("getFactionFavorGain"); function (_facName: unknown): number {
const facName = helper.string("getFactionFavorGain", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
helper.checkSingularityAccess("getFactionFavorGain"); _ctx.helper.checkSingularityAccess();
const faction = getFaction("getFactionFavorGain", facName); const faction = getFaction(_ctx, facName);
return faction.getFavorGain(); return faction.getFavorGain();
}, },
donateToFaction: function (_facName: unknown, _amt: unknown): boolean { donateToFaction: (_ctx: NetscriptContext) =>
updateRam("donateToFaction"); function (_facName: unknown, _amt: unknown): boolean {
const facName = helper.string("donateToFaction", "facName", _facName); const facName = _ctx.helper.string("facName", _facName);
const amt = helper.number("donateToFaction", "amt", _amt); const amt = _ctx.helper.number("amt", _amt);
helper.checkSingularityAccess("donateToFaction"); _ctx.helper.checkSingularityAccess();
const faction = getFaction("donateToFaction", facName); const faction = getFaction(_ctx, facName);
if (!player.factions.includes(faction.name)) { if (!player.factions.includes(faction.name)) {
workerScript.log("donateToFaction", () => `You can't donate to '${facName}' because you aren't a member`); workerScript.log("donateToFaction", () => `You can't donate to '${facName}' because you aren't a member`);
return false; return false;
@ -1179,11 +1179,11 @@ export function NetscriptSingularity(
); );
return true; return true;
}, },
createProgram: function (_programName: unknown, _focus: unknown = true): boolean { createProgram: (_ctx: NetscriptContext) =>
updateRam("createProgram"); function (_programName: unknown, _focus: unknown = true): boolean {
const programName = helper.string("createProgram", "programName", _programName).toLowerCase(); const programName = _ctx.helper.string("programName", _programName).toLowerCase();
const focus = helper.boolean(_focus); const focus = _ctx.helper.boolean(_focus);
helper.checkSingularityAccess("createProgram"); _ctx.helper.checkSingularityAccess();
const wasFocusing = player.focus; const wasFocusing = player.focus;
if (player.isWorking) { if (player.isWorking) {
@ -1228,10 +1228,10 @@ export function NetscriptSingularity(
workerScript.log("createProgram", () => `Began creating program: '${programName}'`); workerScript.log("createProgram", () => `Began creating program: '${programName}'`);
return true; return true;
}, },
commitCrime: function (_crimeRoughName: unknown): number { commitCrime: (_ctx: NetscriptContext) =>
updateRam("commitCrime"); function (_crimeRoughName: unknown): number {
const crimeRoughName = helper.string("commitCrime", "crimeRoughName", _crimeRoughName); const crimeRoughName = _ctx.helper.string("crimeRoughName", _crimeRoughName);
helper.checkSingularityAccess("commitCrime"); _ctx.helper.checkSingularityAccess();
if (player.isWorking) { if (player.isWorking) {
const txt = player.singularityStopWork(); const txt = player.singularityStopWork();
@ -1244,38 +1244,38 @@ export function NetscriptSingularity(
const crime = findCrime(crimeRoughName.toLowerCase()); const crime = findCrime(crimeRoughName.toLowerCase());
if (crime == null) { if (crime == null) {
// couldn't find crime // couldn't find crime
throw helper.makeRuntimeErrorMsg("commitCrime", `Invalid crime: '${crimeRoughName}'`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid crime: '${crimeRoughName}'`);
} }
workerScript.log("commitCrime", () => `Attempting to commit ${crime.name}...`); workerScript.log("commitCrime", () => `Attempting to commit ${crime.name}...`);
return crime.commit(Router, player, 1, workerScript); return crime.commit(Router, player, 1, workerScript);
}, },
getCrimeChance: function (_crimeRoughName: unknown): number { getCrimeChance: (_ctx: NetscriptContext) =>
updateRam("getCrimeChance"); function (_crimeRoughName: unknown): number {
const crimeRoughName = helper.string("getCrimeChance", "crimeRoughName", _crimeRoughName); const crimeRoughName = _ctx.helper.string("crimeRoughName", _crimeRoughName);
helper.checkSingularityAccess("getCrimeChance"); _ctx.helper.checkSingularityAccess();
const crime = findCrime(crimeRoughName.toLowerCase()); const crime = findCrime(crimeRoughName.toLowerCase());
if (crime == null) { if (crime == null) {
throw helper.makeRuntimeErrorMsg("getCrimeChance", `Invalid crime: ${crimeRoughName}`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid crime: ${crimeRoughName}`);
} }
return crime.successRate(player); return crime.successRate(player);
}, },
getCrimeStats: function (_crimeRoughName: unknown): CrimeStats { getCrimeStats: (_ctx: NetscriptContext) =>
updateRam("getCrimeStats"); function (_crimeRoughName: unknown): CrimeStats {
const crimeRoughName = helper.string("getCrimeStats", "crimeRoughName", _crimeRoughName); const crimeRoughName = _ctx.helper.string("crimeRoughName", _crimeRoughName);
helper.checkSingularityAccess("getCrimeStats"); _ctx.helper.checkSingularityAccess();
const crime = findCrime(crimeRoughName.toLowerCase()); const crime = findCrime(crimeRoughName.toLowerCase());
if (crime == null) { if (crime == null) {
throw helper.makeRuntimeErrorMsg("getCrimeStats", `Invalid crime: ${crimeRoughName}`); throw _ctx.helper.makeRuntimeErrorMsg(`Invalid crime: ${crimeRoughName}`);
} }
return Object.assign({}, crime); return Object.assign({}, crime);
}, },
getDarkwebPrograms: function (): string[] { getDarkwebPrograms: (_ctx: NetscriptContext) =>
updateRam("getDarkwebPrograms"); function (): string[] {
helper.checkSingularityAccess("getDarkwebPrograms"); _ctx.helper.checkSingularityAccess();
// If we don't have Tor, log it and return [] (empty list) // If we don't have Tor, log it and return [] (empty list)
if (!player.hasTorRouter()) { if (!player.hasTorRouter()) {
@ -1284,10 +1284,10 @@ export function NetscriptSingularity(
} }
return Object.values(DarkWebItems).map((p) => p.program); return Object.values(DarkWebItems).map((p) => p.program);
}, },
getDarkwebProgramCost: function (_programName: unknown): number { getDarkwebProgramCost: (_ctx: NetscriptContext) =>
updateRam("getDarkwebProgramCost"); function (_programName: unknown): number {
const programName = helper.string("getDarkwebProgramCost", "programName", _programName).toLowerCase(); const programName = _ctx.helper.string("programName", _programName).toLowerCase();
helper.checkSingularityAccess("getDarkwebProgramCost"); _ctx.helper.checkSingularityAccess();
// If we don't have Tor, log it and return -1 // If we don't have Tor, log it and return -1
if (!player.hasTorRouter()) { if (!player.hasTorRouter()) {
@ -1304,8 +1304,7 @@ export function NetscriptSingularity(
// doesn't exist, it's the first time they've run the script. So throw an error to let them know // doesn't exist, it's the first time they've run the script. So throw an error to let them know
// that they need to fix it. // that they need to fix it.
if (item == null) { if (item == null) {
throw helper.makeRuntimeErrorMsg( throw _ctx.helper.makeRuntimeErrorMsg(
"getDarkwebProgramCost",
`No such exploit ('${programName}') found on the darkweb! ` + `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?`,
); );