bitburner-src/src/NetscriptFunctions/Hacknet.ts

242 lines
7.9 KiB
TypeScript
Raw Normal View History

2022-08-09 21:41:47 +02:00
import { Player as player } from "../Player";
import { HacknetServerConstants } from "../Hacknet/data/Constants";
import {
getCostOfNextHacknetNode,
getCostOfNextHacknetServer,
hasHacknetServers,
purchaseHacknet,
purchaseLevelUpgrade,
purchaseRamUpgrade,
purchaseCoreUpgrade,
purchaseCacheUpgrade,
purchaseHashUpgrade,
updateHashManagerCapacity,
} from "../Hacknet/HacknetHelpers";
import { HacknetServer } from "../Hacknet/HacknetServer";
import { HacknetNode } from "../Hacknet/HacknetNode";
import { HashUpgrades } from "../Hacknet/HashUpgrades";
import { HashUpgrade } from "../Hacknet/HashUpgrade";
2021-10-07 22:56:01 +02:00
import { GetServer } from "../Server/AllServers";
import { Hacknet as IHacknet, NodeStats } from "@nsdefs";
2022-05-08 01:08:07 +02:00
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
2022-08-08 19:43:41 +02:00
import { helpers } from "../Netscript/NetscriptHelpers";
2022-08-09 21:41:47 +02:00
export function NetscriptHacknet(): InternalAPI<IHacknet> {
// Utility function to get Hacknet Node object
2022-05-08 01:08:07 +02:00
const getHacknetNode = function (ctx: NetscriptContext, i: number): HacknetNode | HacknetServer {
if (i < 0 || i >= player.hacknetNodes.length) {
throw helpers.errorMessage(ctx, "Index specified for Hacknet Node is out-of-bounds: " + i);
}
2022-09-06 15:07:12 +02:00
if (hasHacknetServers()) {
const hi = player.hacknetNodes[i];
if (typeof hi !== "string") throw new Error("hacknet node was not a string");
2021-10-07 22:56:01 +02:00
const hserver = GetServer(hi);
if (!(hserver instanceof HacknetServer)) throw new Error("hacknet server was not actually hacknet server");
if (hserver == null) {
throw helpers.errorMessage(
2022-08-08 19:43:41 +02:00
ctx,
`Could not get Hacknet Server for index ${i}. This is probably a bug, please report to game dev`,
);
}
return hserver;
} else {
const node = player.hacknetNodes[i];
if (!(node instanceof HacknetNode)) throw new Error("hacknet node was not node.");
return node;
}
};
return {
numNodes: () => () => {
return player.hacknetNodes.length;
},
maxNumNodes: () => () => {
2022-09-06 15:07:12 +02:00
if (hasHacknetServers()) {
return HacknetServerConstants.MaxServers;
}
return Infinity;
},
purchaseNode: () => () => {
2022-09-06 15:07:12 +02:00
return purchaseHacknet();
},
getPurchaseNodeCost: () => () => {
2022-09-06 15:07:12 +02:00
if (hasHacknetServers()) {
return getCostOfNextHacknetServer();
} else {
2022-09-06 15:07:12 +02:00
return getCostOfNextHacknetNode();
}
},
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;
}
return res;
},
2022-05-08 01:08:07 +02:00
upgradeLevel:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-05-08 01:08:07 +02:00
const node = getHacknetNode(ctx, i);
2022-09-06 15:07:12 +02:00
return purchaseLevelUpgrade(node, n);
2022-05-08 01:08:07 +02:00
},
upgradeRam:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-05-08 01:08:07 +02:00
const node = getHacknetNode(ctx, i);
2022-09-06 15:07:12 +02:00
return purchaseRamUpgrade(node, n);
2022-05-08 01:08:07 +02:00
},
upgradeCore:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-05-08 01:08:07 +02:00
const node = getHacknetNode(ctx, i);
2022-09-06 15:07:12 +02:00
return purchaseCoreUpgrade(node, n);
2022-05-08 01:08:07 +02:00
},
upgradeCache:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
2022-05-08 01:08:07 +02:00
return false;
}
const node = getHacknetNode(ctx, i);
if (!(node instanceof HacknetServer)) {
2022-08-09 21:41:47 +02:00
helpers.log(ctx, () => "Can only be called on hacknet servers");
2022-05-08 01:08:07 +02:00
return false;
}
2022-09-06 15:07:12 +02:00
const res = purchaseCacheUpgrade(node, n);
2022-05-08 01:08:07 +02:00
if (res) {
2022-09-06 15:07:12 +02:00
updateHashManagerCapacity();
2022-05-08 01:08:07 +02:00
}
return res;
},
getLevelUpgradeCost:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-05-08 01:08:07 +02:00
const node = getHacknetNode(ctx, i);
2022-07-15 00:43:33 +02:00
return node.calculateLevelUpgradeCost(n, player.mults.hacknet_node_level_cost);
2022-05-08 01:08:07 +02:00
},
getRamUpgradeCost:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-05-08 01:08:07 +02:00
const node = getHacknetNode(ctx, i);
2022-07-15 00:43:33 +02:00
return node.calculateRamUpgradeCost(n, player.mults.hacknet_node_ram_cost);
2022-05-08 01:08:07 +02:00
},
getCoreUpgradeCost:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-05-08 01:08:07 +02:00
const node = getHacknetNode(ctx, i);
2022-07-15 00:43:33 +02:00
return node.calculateCoreUpgradeCost(n, player.mults.hacknet_node_core_cost);
2022-05-08 01:08:07 +02:00
},
getCacheUpgradeCost:
(ctx) =>
(_i, _n = 1) => {
2022-08-08 19:43:41 +02:00
const i = helpers.number(ctx, "i", _i);
const n = helpers.number(ctx, "n", _n);
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
2022-05-08 01:08:07 +02:00
return Infinity;
}
const node = getHacknetNode(ctx, i);
if (!(node instanceof HacknetServer)) {
2022-08-09 21:41:47 +02:00
helpers.log(ctx, () => "Can only be called on hacknet servers");
2022-05-08 01:08:07 +02:00
return -1;
}
return node.calculateCacheUpgradeCost(n);
},
numHashes: () => () => {
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
return 0;
}
return player.hashManager.hashes;
},
hashCapacity: () => () => {
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
return 0;
}
return player.hashManager.capacity;
},
2022-05-08 01:08:07 +02:00
hashCost:
(ctx) =>
(_upgName, _count = 1) => {
2022-08-08 19:43:41 +02:00
const upgName = helpers.string(ctx, "upgName", _upgName);
const count = helpers.number(ctx, "count", _count);
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
2022-05-08 01:08:07 +02:00
return Infinity;
}
return player.hashManager.getUpgradeCost(upgName, count);
2022-05-08 01:08:07 +02:00
},
spendHashes:
(ctx) =>
(_upgName, _upgTarget = "", _count = 1) => {
2022-08-08 19:43:41 +02:00
const upgName = helpers.string(ctx, "upgName", _upgName);
const upgTarget = helpers.string(ctx, "upgTarget", _upgTarget);
const count = Math.floor(helpers.number(ctx, "count", _count));
// TODO (3.0.0): use helpers.positiveInteger
if (!(count >= 0)) {
throw helpers.errorMessage(ctx, "count may not be negative");
}
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
2022-05-08 01:08:07 +02:00
return false;
}
2022-09-06 15:07:12 +02:00
return purchaseHashUpgrade(upgName, upgTarget, count);
2022-05-08 01:08:07 +02:00
},
getHashUpgrades: () => () => {
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
return [];
}
return Object.values(HashUpgrades).map((upgrade: HashUpgrade) => upgrade.name);
},
getHashUpgradeLevel: (ctx) => (_upgName) => {
const upgName = helpers.string(ctx, "upgName", _upgName);
const level = player.hashManager.upgrades[upgName];
if (level === undefined) {
throw helpers.errorMessage(ctx, `Invalid Hash Upgrade: ${upgName}`);
}
return level;
},
getStudyMult: () => () => {
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
return 1;
}
return player.hashManager.getStudyMult();
},
getTrainingMult: () => () => {
2022-09-06 15:07:12 +02:00
if (!hasHacknetServers()) {
return 1;
}
return player.hashManager.getTrainingMult();
},
};
}