Refactored stock buying/selling code into its own file. Refactored WorkerScript & NetscriptEnvironment into their own Typescript classes. Refactored a ton of code to remove circular dependencies

This commit is contained in:
danielyxie
2019-05-04 21:03:40 -07:00
parent 585e1ac7aa
commit 8a5b6f6cbc
47 changed files with 2867 additions and 2773 deletions
+211 -48
View File
@@ -1,35 +1,41 @@
import { HacknetNode,
BaseCostForHacknetNode,
HacknetNodePurchaseNextMult,
HacknetNodeMaxLevel,
HacknetNodeMaxRam,
HacknetNodeMaxCores } from "./HacknetNode";
import { HacknetServer,
BaseCostForHacknetServer,
HacknetServerPurchaseMult,
HacknetServerMaxLevel,
HacknetServerMaxRam,
HacknetServerMaxCores,
HacknetServerMaxCache,
MaxNumberHacknetServers } from "./HacknetServer";
import { HashManager } from "./HashManager";
import { HashUpgrades } from "./HashUpgrades";
import {
HacknetNode,
BaseCostForHacknetNode,
HacknetNodePurchaseNextMult,
HacknetNodeMaxLevel,
HacknetNodeMaxRam,
HacknetNodeMaxCores
} from "./HacknetNode";
import {
HacknetServer,
BaseCostForHacknetServer,
HacknetServerPurchaseMult,
HacknetServerMaxLevel,
HacknetServerMaxRam,
HacknetServerMaxCores,
HacknetServerMaxCache,
MaxNumberHacknetServers
} from "./HacknetServer";
import { HashManager } from "./HashManager";
import { HashUpgrades } from "./HashUpgrades";
import { generateRandomContract } from "../CodingContractGenerator";
import { iTutorialSteps, iTutorialNextStep,
ITutorial} from "../InteractiveTutorial";
import { Player } from "../Player";
import { AddToAllServers,
AllServers } from "../Server/AllServers";
import { GetServerByHostname } from "../Server/ServerHelpers";
import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
import { Page, routing } from "../ui/navigationTracking";
import { generateRandomContract } from "../CodingContractGenerator";
import {
iTutorialSteps,
iTutorialNextStep,
ITutorial
} from "../InteractiveTutorial";
import { Player } from "../Player";
import { AddToAllServers, AllServers } from "../Server/AllServers";
import { GetServerByHostname } from "../Server/ServerHelpers";
import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
import { Page, routing } from "../ui/navigationTracking";
import {getElementById} from "../../utils/uiHelpers/getElementById";
import { getElementById } from "../../utils/uiHelpers/getElementById";
import React from "react";
import ReactDOM from "react-dom";
import { HacknetRoot } from "./ui/Root";
import React from "react";
import ReactDOM from "react-dom";
import { HacknetRoot } from "./ui/Root";
let hacknetNodesDiv;
function hacknetNodesInit() {
@@ -66,7 +72,7 @@ export function purchaseHacknet() {
if (!Player.canAfford(cost)) { return -1; }
Player.loseMoney(cost);
const server = Player.createHacknetServer();
Player.hashManager.updateCapacity(Player);
Player.hashManager.updateCapacity(Player.hacknetNodes);
return numOwned;
} else {
@@ -79,8 +85,7 @@ export function purchaseHacknet() {
// Auto generate a name for the Node
const name = "hacknet-node-" + numOwned;
const node = new HacknetNode(name);
node.updateMoneyGainRate(Player);
const node = new HacknetNode(name, Player.hacknet_node_money_mult);
Player.loseMoney(cost);
Player.hacknetNodes.push(node);
@@ -116,26 +121,26 @@ export function getMaxNumberLevelUpgrades(nodeObj, maxLevel) {
throw new Error(`getMaxNumberLevelUpgrades() called without maxLevel arg`);
}
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1, Player))) {
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1, Player.hacknet_node_level_cost_mult))) {
return 0;
}
let min = 1;
let max = maxLevel - 1;
let levelsToMax = maxLevel - nodeObj.level;
if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax, Player))) {
if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax, Player.hacknet_node_level_cost_mult))) {
return levelsToMax;
}
while (min <= max) {
var curr = (min + max) / 2 | 0;
if (curr !== maxLevel &&
Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, Player)) &&
Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1, Player))) {
Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, Player.hacknet_node_level_cost_mult)) &&
Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1, Player.hacknet_node_level_cost_mult))) {
return Math.min(levelsToMax, curr);
} else if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr, Player))) {
} else if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr, Player.hacknet_node_level_cost_mult))) {
max = curr - 1;
} else if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, Player))) {
} else if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr, Player.hacknet_node_level_cost_mult))) {
min = curr + 1;
} else {
return Math.min(levelsToMax, curr);
@@ -149,7 +154,7 @@ export function getMaxNumberRamUpgrades(nodeObj, maxLevel) {
throw new Error(`getMaxNumberRamUpgrades() called without maxLevel arg`);
}
if (Player.money.lt(nodeObj.calculateRamUpgradeCost(1, Player))) {
if (Player.money.lt(nodeObj.calculateRamUpgradeCost(1, Player.hacknet_node_ram_cost_mult))) {
return 0;
}
@@ -159,13 +164,13 @@ export function getMaxNumberRamUpgrades(nodeObj, maxLevel) {
} else {
levelsToMax = Math.round(Math.log2(maxLevel / nodeObj.ram));
}
if (Player.money.gt(nodeObj.calculateRamUpgradeCost(levelsToMax, Player))) {
if (Player.money.gt(nodeObj.calculateRamUpgradeCost(levelsToMax, Player.hacknet_node_ram_cost_mult))) {
return levelsToMax;
}
//We'll just loop until we find the max
for (let i = levelsToMax-1; i >= 0; --i) {
if (Player.money.gt(nodeObj.calculateRamUpgradeCost(i, Player))) {
if (Player.money.gt(nodeObj.calculateRamUpgradeCost(i, Player.hacknet_node_ram_cost_mult))) {
return i;
}
}
@@ -177,14 +182,14 @@ export function getMaxNumberCoreUpgrades(nodeObj, maxLevel) {
throw new Error(`getMaxNumberCoreUpgrades() called without maxLevel arg`);
}
if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(1, Player))) {
if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(1, Player.hacknet_node_core_cost_mult))) {
return 0;
}
let min = 1;
let max = maxLevel - 1;
const levelsToMax = maxLevel - nodeObj.cores;
if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax, Player))) {
if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax, Player.hacknet_node_core_cost_mult))) {
return levelsToMax;
}
@@ -192,12 +197,12 @@ export function getMaxNumberCoreUpgrades(nodeObj, maxLevel) {
while (min <= max) {
let curr = (min + max) / 2 | 0;
if (curr != maxLevel &&
Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, Player)) &&
Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1, Player))) {
Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, Player.hacknet_node_core_cost_mult)) &&
Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1, Player.hacknet_node_core_cost_mult))) {
return Math.min(levelsToMax, curr);
} else if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr, Player))) {
} else if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr, Player.hacknet_node_core_cost_mult))) {
max = curr - 1;
} else if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, Player))) {
} else if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr, Player.hacknet_node_core_cost_mult))) {
min = curr + 1;
} else {
return Math.min(levelsToMax, curr);
@@ -242,7 +247,134 @@ export function getMaxNumberCacheUpgrades(nodeObj, maxLevel) {
return 0;
}
// Initial construction of Hacknet Nodes UI
export function purchaseLevelUpgrade(node, levels=1) {
const sanitizedLevels = Math.round(levels);
const cost = node.calculateLevelUpgradeCost(sanitizedLevels, Player.hacknet_node_level_cost_mult);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false;
}
const isServer = (node instanceof HacknetServer);
// If we're at max level, return false
if (node.level >= (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
return false;
}
// If the number of specified upgrades would exceed the max level, calculate
// the maximum number of upgrades and use that
if (node.level + sanitizedLevels > (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
const diff = Math.max(0, (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel) - node.level);
return purchaseLevelUpgrade(node, diff);
}
if (!Player.canAfford(cost)) {
return false;
}
Player.loseMoney(cost);
node.upgradeLevel(sanitizedLevels, Player.hacknet_node_money_mult);
return true;
}
export function purchaseRamUpgrade(node, levels=1) {
const sanitizedLevels = Math.round(levels);
const cost = node.calculateRamUpgradeCost(sanitizedLevels, Player.hacknet_node_ram_cost_mult);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false;
}
const isServer = (node instanceof HacknetServer);
// Fail if we're already at max
if (node.ram >= (isServer ? HacknetServerMaxRam : HacknetNodeMaxRam)) {
return false;
}
// If the number of specified upgrades would exceed the max RAM, calculate the
// max possible number of upgrades and use that
if (isServer) {
if (node.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerMaxRam) {
const diff = Math.max(0, Math.log2(Math.round(HacknetServerMaxRam / node.maxRam)));
return purchaseRamUpgrade(node, diff);
}
} else {
if (node.ram * Math.pow(2, sanitizedLevels) > HacknetNodeMaxRam) {
const diff = Math.max(0, Math.log2(Math.round(HacknetNodeMaxRam / node.ram)));
return purchaseRamUpgrade(node, diff);
}
}
if (!Player.canAfford(cost)) {
return false;
}
Player.loseMoney(cost);
node.upgradeRam(sanitizedLevels, Player.hacknet_node_money_mult);
return true;
}
export function purchaseCoreUpgrade(node, levels=1) {
const sanitizedLevels = Math.round(levels);
const cost = node.calculateCoreUpgradeCost(sanitizedLevels, Player.hacknet_node_core_cost_mult);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false;
}
const isServer = (node instanceof HacknetServer);
// Fail if we're already at max
if (node.cores >= (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
return false;
}
// If the specified number of upgrades would exceed the max Cores, calculate
// the max possible number of upgrades and use that
if (node.cores + sanitizedLevels > (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
const diff = Math.max(0, (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores) - node.cores);
return purchaseCoreUpgrade(node, diff);
}
if (!Player.canAfford(cost)) {
return false;
}
Player.loseMoney(cost);
node.upgradeCore(sanitizedLevels, Player.hacknet_node_money_mult);
return true;
}
export function purchaseCacheUpgrade(node, levels=1) {
const sanitizedLevels = Math.round(levels);
const cost = node.calculateCoreUpgradeCost(sanitizedLevels);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false;
}
if (!(node instanceof HacknetServer)) {
console.warn(`purchaseCacheUpgrade() called for a non-HacknetNode`);
return false;
}
// Fail if we're already at max
if (node.cache + sanitizedLevels > HacknetServerMaxCache) {
const diff = Math.max(0, HacknetServerMaxCache - node.cache);
return purchaseCacheUpgrade(node, diff);
}
if (!Player.canAfford(cost)) {
return false;
}
Player.loseMoney(cost);
node.upgradeCache(sanitizedLevels);
}
// Create/Refresh Hacknet Nodes UI
export function renderHacknetNodesUI() {
if (!routing.isOn(Page.HacknetNodes)) { return; }
@@ -303,6 +435,37 @@ function processAllHacknetServerEarnings(numCycles) {
return hashes;
}
export function updateHashManagerCapacity() {
if (!(Player.hashManager instanceof HashManager)) {
console.error(`Player does not have a HashManager`);
return;
}
const nodes = Player.hacknetNodes;
if (nodes.length === 0) {
Player.hashManager.updateCapacity(0);
return;
}
let total = 0;
for (let i = 0; i < nodes.length; ++i) {
if (typeof nodes[i] !== "string") {
Player.hashManager.updateCapacity(0);
return;
}
const h = AllServers[nodes[i]];
if (!(h instanceof HacknetServer)) {
Player.hashManager.updateCapacity(0);
return;
}
total += h.hashCapacity;
}
Player.hashManager.updateCapacity(total);
}
export function purchaseHashUpgrade(upgName, upgTarget) {
if (!(Player.hashManager instanceof HashManager)) {
console.error(`Player does not have a HashManager`);