mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-27 03:25:44 +02:00
v0.51.0 (#826)
* Hash upgrades and Bladeburner skills can now be clicked to copy to clipboard * Aug purchase confirmation popup displays money in 0.000a format * Character now displays hacknet server info properly * Character,Info now displays hacknet server info correctly. * Formulas (#825) Formulas API v0.1 * Make all money the same color, same for reputation, format all numbers consistently. * rename a lot of the formulas function to no longer contain calculate * added hacking related formulas * removed unused variable * v0.51.0
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
/**
|
||||
* Utility functions for calculating the maximum number of Hacknet upgrades the player
|
||||
* can purchase for a Node with his/her current money
|
||||
*/
|
||||
@@ -8,24 +8,11 @@
|
||||
*
|
||||
* TODO Should probably split the different types of functions into their own modules
|
||||
*/
|
||||
import {
|
||||
HacknetNode,
|
||||
BaseCostForHacknetNode,
|
||||
HacknetNodePurchaseNextMult,
|
||||
HacknetNodeMaxLevel,
|
||||
HacknetNodeMaxRam,
|
||||
HacknetNodeMaxCores
|
||||
} from "./HacknetNode";
|
||||
import {
|
||||
HacknetServer,
|
||||
BaseCostForHacknetServer,
|
||||
HacknetServerPurchaseMult,
|
||||
HacknetServerMaxLevel,
|
||||
HacknetServerMaxRam,
|
||||
HacknetServerMaxCores,
|
||||
HacknetServerMaxCache,
|
||||
MaxNumberHacknetServers
|
||||
} from "./HacknetServer";
|
||||
import { HacknetNode } from "./HacknetNode";
|
||||
import { calculateNodeCost } from "./formulas/HacknetNodes";
|
||||
import { calculateServerCost } from "./formulas/HacknetServers";
|
||||
import { HacknetNodeConstants, HacknetServerConstants } from "./data/Constants";
|
||||
import { HacknetServer } from "./HacknetServer";
|
||||
import { HashManager } from "./HashManager";
|
||||
import { HashUpgrades } from "./HashUpgrades";
|
||||
|
||||
@@ -105,24 +92,15 @@ export function purchaseHacknet() {
|
||||
}
|
||||
|
||||
export function hasMaxNumberHacknetServers() {
|
||||
return hasHacknetServers() && Player.hacknetNodes.length >= MaxNumberHacknetServers;
|
||||
return hasHacknetServers() && Player.hacknetNodes.length >= HacknetServerConstants.MaxServers;
|
||||
}
|
||||
|
||||
export function getCostOfNextHacknetNode() {
|
||||
// Cost increases exponentially based on how many you own
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const mult = HacknetNodePurchaseNextMult;
|
||||
|
||||
return BaseCostForHacknetNode * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
||||
return calculateNodeCost(Player.hacknetNodes.length+1, Player.hacknet_node_purchase_cost_mult);
|
||||
}
|
||||
|
||||
export function getCostOfNextHacknetServer() {
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const mult = HacknetServerPurchaseMult;
|
||||
|
||||
if (numOwned >= MaxNumberHacknetServers) { return Infinity; }
|
||||
|
||||
return BaseCostForHacknetServer * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
||||
return calculateServerCost(Player.hacknetNodes.length+1, Player.hacknet_node_purchase_cost_mult);
|
||||
}
|
||||
|
||||
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's level
|
||||
@@ -270,14 +248,14 @@ export function purchaseLevelUpgrade(node, levels=1) {
|
||||
const isServer = (node instanceof HacknetServer);
|
||||
|
||||
// If we're at max level, return false
|
||||
if (node.level >= (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
|
||||
if (node.level >= (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel)) {
|
||||
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);
|
||||
if (node.level + sanitizedLevels > (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel)) {
|
||||
const diff = Math.max(0, (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel) - node.level);
|
||||
return purchaseLevelUpgrade(node, diff);
|
||||
}
|
||||
|
||||
@@ -301,20 +279,20 @@ export function purchaseRamUpgrade(node, levels=1) {
|
||||
const isServer = (node instanceof HacknetServer);
|
||||
|
||||
// Fail if we're already at max
|
||||
if (node.ram >= (isServer ? HacknetServerMaxRam : HacknetNodeMaxRam)) {
|
||||
if (node.ram >= (isServer ? HacknetServerConstants.MaxRam : HacknetNodeConstants.MaxRam)) {
|
||||
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)));
|
||||
if (node.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerConstants.MaxRam) {
|
||||
const diff = Math.max(0, Math.log2(Math.round(HacknetServerConstants.MaxRam / 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)));
|
||||
if (node.ram * Math.pow(2, sanitizedLevels) > HacknetNodeConstants.MaxRam) {
|
||||
const diff = Math.max(0, Math.log2(Math.round(HacknetNodeConstants.MaxRam / node.ram)));
|
||||
return purchaseRamUpgrade(node, diff);
|
||||
}
|
||||
}
|
||||
@@ -340,14 +318,14 @@ export function purchaseCoreUpgrade(node, levels=1) {
|
||||
const isServer = (node instanceof HacknetServer);
|
||||
|
||||
// Fail if we're already at max
|
||||
if (node.cores >= (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
|
||||
if (node.cores >= (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores)) {
|
||||
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);
|
||||
if (node.cores + sanitizedLevels > (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores)) {
|
||||
const diff = Math.max(0, (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores) - node.cores);
|
||||
return purchaseCoreUpgrade(node, diff);
|
||||
}
|
||||
|
||||
@@ -374,8 +352,8 @@ export function purchaseCacheUpgrade(node, levels=1) {
|
||||
}
|
||||
|
||||
// Fail if we're already at max
|
||||
if (node.cache + sanitizedLevels > HacknetServerMaxCache) {
|
||||
const diff = Math.max(0, HacknetServerMaxCache - node.cache);
|
||||
if (node.cache + sanitizedLevels > HacknetServerConstants.MaxCache) {
|
||||
const diff = Math.max(0, HacknetServerConstants.MaxCache - node.cache);
|
||||
return purchaseCacheUpgrade(node, diff);
|
||||
}
|
||||
|
||||
|
||||
+13
-92
@@ -9,29 +9,19 @@ import { IHacknetNode } from "./IHacknetNode";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import {
|
||||
calculateMoneyGainRate,
|
||||
calculateLevelUpgradeCost,
|
||||
calculateCoreUpgradeCost,
|
||||
calculateRamUpgradeCost,
|
||||
} from "./formulas/HacknetNodes";
|
||||
import { HacknetNodeConstants } from "./data/Constants";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
import { Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
Reviver } from "../../utils/JSONReviver";
|
||||
|
||||
// Constants for Hacknet Node production
|
||||
export const HacknetNodeMoneyGainPerLevel: number = 1.6; // Base production per level
|
||||
|
||||
// Constants for Hacknet Node purchase/upgrade costs
|
||||
export const BaseCostForHacknetNode: number = 1000;
|
||||
export const BaseCostFor1GBOfRamHacknetNode: number = 30e3;
|
||||
export const BaseCostForHacknetNodeCore: number = 500e3;
|
||||
export const HacknetNodePurchaseNextMult: number = 1.85; // Multiplier when purchasing an additional hacknet node
|
||||
export const HacknetNodeUpgradeLevelMult: number = 1.04; // Multiplier for cost when upgrading level
|
||||
export const HacknetNodeUpgradeRamMult: number = 1.28; // Multiplier for cost when upgrading RAM
|
||||
export const HacknetNodeUpgradeCoreMult: number = 1.48; // Multiplier for cost when buying another core
|
||||
|
||||
// Constants for max upgrade levels for Hacknet Nodes
|
||||
export const HacknetNodeMaxLevel: number = 200;
|
||||
export const HacknetNodeMaxRam: number = 64;
|
||||
export const HacknetNodeMaxCores: number = 16;
|
||||
|
||||
export class HacknetNode implements IHacknetNode {
|
||||
/**
|
||||
* Initiatizes a HacknetNode object from a JSON save state.
|
||||
@@ -69,79 +59,17 @@ export class HacknetNode implements IHacknetNode {
|
||||
|
||||
// Get the cost to upgrade this Node's number of cores
|
||||
calculateCoreUpgradeCost(levels: number=1, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.cores >= HacknetNodeMaxCores) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const coreBaseCost = BaseCostForHacknetNodeCore;
|
||||
const mult = HacknetNodeUpgradeCoreMult;
|
||||
let totalCost = 0;
|
||||
let currentCores = this.cores;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalCost += (coreBaseCost * Math.pow(mult, currentCores-1));
|
||||
++currentCores;
|
||||
}
|
||||
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
return calculateCoreUpgradeCost(this.cores, levels, costMult);
|
||||
}
|
||||
|
||||
// Get the cost to upgrade this Node's level
|
||||
calculateLevelUpgradeCost(levels: number=1, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.level >= HacknetNodeMaxLevel) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetNodeUpgradeLevelMult;
|
||||
let totalMultiplier = 0;
|
||||
let currLevel = this.level;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalMultiplier += Math.pow(mult, currLevel);
|
||||
++currLevel;
|
||||
}
|
||||
|
||||
return BaseCostForHacknetNode / 2 * totalMultiplier * costMult;
|
||||
return calculateLevelUpgradeCost(this.level, levels, costMult);
|
||||
}
|
||||
|
||||
// Get the cost to upgrade this Node's RAM
|
||||
calculateRamUpgradeCost(levels: number=1, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.ram >= HacknetNodeMaxRam) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
let totalCost = 0;
|
||||
let numUpgrades = Math.round(Math.log2(this.ram));
|
||||
let currentRam = this.ram;
|
||||
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
let baseCost = currentRam * BaseCostFor1GBOfRamHacknetNode;
|
||||
let mult = Math.pow(HacknetNodeUpgradeRamMult, numUpgrades);
|
||||
|
||||
totalCost += (baseCost * mult);
|
||||
|
||||
currentRam *= 2;
|
||||
++numUpgrades;
|
||||
}
|
||||
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
return calculateRamUpgradeCost(this.ram, levels, costMult);
|
||||
}
|
||||
|
||||
// Process this Hacknet Node in the game loop.
|
||||
@@ -163,14 +91,14 @@ export class HacknetNode implements IHacknetNode {
|
||||
// Upgrade this Node's number of cores, if possible
|
||||
// Returns a boolean indicating whether new cores were successfully bought
|
||||
upgradeCore(levels: number=1, prodMult: number): void {
|
||||
this.cores = Math.min(HacknetNodeMaxCores, Math.round(this.cores + levels));
|
||||
this.cores = Math.min(HacknetNodeConstants.MaxCores, Math.round(this.cores + levels));
|
||||
this.updateMoneyGainRate(prodMult);
|
||||
}
|
||||
|
||||
// Upgrade this Node's level, if possible
|
||||
// Returns a boolean indicating whether the level was successfully updated
|
||||
upgradeLevel(levels: number=1, prodMult: number): void {
|
||||
this.level = Math.min(HacknetNodeMaxLevel, Math.round(this.level + levels));
|
||||
this.level = Math.min(HacknetNodeConstants.MaxLevel, Math.round(this.level + levels));
|
||||
this.updateMoneyGainRate(prodMult);
|
||||
}
|
||||
|
||||
@@ -186,14 +114,7 @@ export class HacknetNode implements IHacknetNode {
|
||||
|
||||
// Re-calculate this Node's production and update the moneyGainRatePerSecond prop
|
||||
updateMoneyGainRate(prodMult: number): void {
|
||||
//How much extra $/s is gained per level
|
||||
var gainPerLevel = HacknetNodeMoneyGainPerLevel;
|
||||
|
||||
this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
|
||||
Math.pow(1.035, this.ram - 1) *
|
||||
((this.cores + 5) / 6) *
|
||||
prodMult *
|
||||
BitNodeMultipliers.HacknetNodeMoney;
|
||||
this.moneyGainRatePerSecond = calculateMoneyGainRate(this.level, this.ram, this.cores, prodMult);
|
||||
if (isNaN(this.moneyGainRatePerSecond)) {
|
||||
this.moneyGainRatePerSecond = 0;
|
||||
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer", false);
|
||||
|
||||
+18
-117
@@ -8,6 +8,14 @@ import { IHacknetNode } from "./IHacknetNode";
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import { BaseServer } from "../Server/BaseServer";
|
||||
import { RunningScript } from "../Script/RunningScript";
|
||||
import { HacknetServerConstants } from "./data/Constants";
|
||||
import {
|
||||
calculateHashGainRate,
|
||||
calculateLevelUpgradeCost,
|
||||
calculateRamUpgradeCost,
|
||||
calculateCoreUpgradeCost,
|
||||
calculateCacheUpgradeCost,
|
||||
} from "./formulas/HacknetServers";
|
||||
|
||||
import { createRandomIp } from "../../utils/IPAddress";
|
||||
|
||||
@@ -17,29 +25,6 @@ import {
|
||||
Reviver
|
||||
} from "../../utils/JSONReviver";
|
||||
|
||||
// Constants for Hacknet Server stats/production
|
||||
export const HacknetServerHashesPerLevel: number = 0.001;
|
||||
|
||||
// Constants for Hacknet Server purchase/upgrade costs
|
||||
export const BaseCostForHacknetServer: number = 50e3;
|
||||
export const BaseCostFor1GBHacknetServerRam: number = 200e3;
|
||||
export const BaseCostForHacknetServerCore: number = 1e6;
|
||||
export const BaseCostForHacknetServerCache: number = 10e6;
|
||||
|
||||
export const HacknetServerPurchaseMult: number = 3.2; // Multiplier for puchasing an additional Hacknet Server
|
||||
export const HacknetServerUpgradeLevelMult: number = 1.1; // Multiplier for cost when upgrading level
|
||||
export const HacknetServerUpgradeRamMult: number = 1.4; // Multiplier for cost when upgrading RAM
|
||||
export const HacknetServerUpgradeCoreMult: number = 1.55; // Multiplier for cost when buying another core
|
||||
export const HacknetServerUpgradeCacheMult: number = 1.85; // Multiplier for cost when upgrading cache
|
||||
|
||||
export const MaxNumberHacknetServers: number = 20; // Max number of Hacknet Servers you can own
|
||||
|
||||
// Constants for max upgrade levels for Hacknet Server
|
||||
export const HacknetServerMaxLevel: number = 300;
|
||||
export const HacknetServerMaxRam: number = 8192;
|
||||
export const HacknetServerMaxCores: number = 128;
|
||||
export const HacknetServerMaxCache: number = 15;
|
||||
|
||||
interface IConstructorParams {
|
||||
adminRights?: boolean;
|
||||
hostname: string;
|
||||
@@ -73,7 +58,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
// How long this HacknetServer has existed, in seconds
|
||||
onlineTimeSeconds: number = 0;
|
||||
|
||||
// Total number of hashes earned by this
|
||||
// Total number of hashes earned by this server
|
||||
totalHashesGenerated: number = 0;
|
||||
|
||||
constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) {
|
||||
@@ -84,96 +69,19 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
}
|
||||
|
||||
calculateCacheUpgradeCost(levels: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.cache >= HacknetServerMaxCache) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetServerUpgradeCacheMult;
|
||||
let totalCost = 0;
|
||||
let currentCache = this.cache;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalCost += Math.pow(mult, currentCache - 1);
|
||||
++currentCache;
|
||||
}
|
||||
totalCost *= BaseCostForHacknetServerCache;
|
||||
|
||||
return totalCost;
|
||||
return calculateCacheUpgradeCost(this.cache, levels);
|
||||
}
|
||||
|
||||
calculateCoreUpgradeCost(levels: number, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.cores >= HacknetServerMaxCores) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetServerUpgradeCoreMult;
|
||||
let totalCost = 0;
|
||||
let currentCores = this.cores;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalCost += Math.pow(mult, currentCores-1);
|
||||
++currentCores;
|
||||
}
|
||||
totalCost *= BaseCostForHacknetServerCore;
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
return calculateCoreUpgradeCost(this.cores, levels, costMult);
|
||||
}
|
||||
|
||||
calculateLevelUpgradeCost(levels: number, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.level >= HacknetServerMaxLevel) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetServerUpgradeLevelMult;
|
||||
let totalMultiplier = 0;
|
||||
let currLevel = this.level;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalMultiplier += Math.pow(mult, currLevel);
|
||||
++currLevel;
|
||||
}
|
||||
|
||||
return 10 * BaseCostForHacknetServer * totalMultiplier * costMult;
|
||||
return calculateLevelUpgradeCost(this.level, levels, costMult);
|
||||
}
|
||||
|
||||
calculateRamUpgradeCost(levels: number, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (this.maxRam >= HacknetServerMaxRam) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
let totalCost = 0;
|
||||
let numUpgrades = Math.round(Math.log2(this.maxRam));
|
||||
let currentRam = this.maxRam;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
let baseCost = currentRam * BaseCostFor1GBHacknetServerRam;
|
||||
let mult = Math.pow(HacknetServerUpgradeRamMult, numUpgrades);
|
||||
|
||||
totalCost += (baseCost * mult);
|
||||
|
||||
currentRam *= 2;
|
||||
++numUpgrades;
|
||||
}
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
return calculateRamUpgradeCost(this.maxRam, levels, costMult);
|
||||
}
|
||||
|
||||
// Process this Hacknet Server in the game loop. Returns the number of hashes generated
|
||||
@@ -184,17 +92,17 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
}
|
||||
|
||||
upgradeCache(levels: number): void {
|
||||
this.cache = Math.min(HacknetServerMaxCache, Math.round(this.cache + levels));
|
||||
this.cache = Math.min(HacknetServerConstants.MaxCache, Math.round(this.cache + levels));
|
||||
this.updateHashCapacity();
|
||||
}
|
||||
|
||||
upgradeCore(levels: number, prodMult: number): void {
|
||||
this.cores = Math.min(HacknetServerMaxCores, Math.round(this.cores + levels));
|
||||
this.cores = Math.min(HacknetServerConstants.MaxCores, Math.round(this.cores + levels));
|
||||
this.updateHashRate(prodMult);
|
||||
}
|
||||
|
||||
upgradeLevel(levels: number, prodMult: number): void {
|
||||
this.level = Math.min(HacknetServerMaxLevel, Math.round(this.level + levels));
|
||||
this.level = Math.min(HacknetServerConstants.MaxLevel, Math.round(this.level + levels));
|
||||
this.updateHashRate(prodMult);
|
||||
}
|
||||
|
||||
@@ -202,7 +110,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
for (let i = 0; i < levels; ++i) {
|
||||
this.maxRam *= 2;
|
||||
}
|
||||
this.maxRam = Math.min(HacknetServerMaxRam, Math.round(this.maxRam));
|
||||
this.maxRam = Math.min(HacknetServerConstants.MaxRam, Math.round(this.maxRam));
|
||||
this.updateHashRate(prodMult);
|
||||
|
||||
return true;
|
||||
@@ -221,14 +129,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
}
|
||||
|
||||
updateHashRate(prodMult: number): void {
|
||||
const baseGain = HacknetServerHashesPerLevel * this.level;
|
||||
const ramMultiplier = Math.pow(1.07, Math.log2(this.maxRam));
|
||||
const coreMultiplier = 1 + (this.cores - 1) / 5;
|
||||
const ramRatio = (1 - this.ramUsed / this.maxRam);
|
||||
|
||||
const hashRate = baseGain * ramMultiplier * coreMultiplier * ramRatio;
|
||||
|
||||
this.hashRate = hashRate * prodMult * BitNodeMultipliers.HacknetNodeMoney;
|
||||
this.hashRate = calculateHashGainRate(this.level, this.ramUsed, this.maxRam, this.cores, prodMult)
|
||||
|
||||
if (isNaN(this.hashRate)) {
|
||||
this.hashRate = 0;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
* those upgrades
|
||||
*/
|
||||
import { HashUpgrades } from "./HashUpgrades";
|
||||
import { HashUpgrade } from "./HashUpgrade";
|
||||
|
||||
import { IMap } from "../types";
|
||||
import { Generic_fromJSON,
|
||||
@@ -67,11 +68,20 @@ export class HashManager {
|
||||
return this.getMult(upgName);
|
||||
}
|
||||
|
||||
getUpgrade(upgName: string): HashUpgrade | null {
|
||||
const upg = HashUpgrades[upgName];
|
||||
if (!upg) {
|
||||
console.error(`Invalid Upgrade Name given to HashManager.getUpgrade(): ${upgName}`);
|
||||
return null;
|
||||
}
|
||||
return upg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cost (in hashes) of an upgrade
|
||||
*/
|
||||
getUpgradeCost(upgName: string): number {
|
||||
const upg = HashUpgrades[upgName];
|
||||
const upg = this.getUpgrade(upgName);
|
||||
const currLevel = this.upgrades[upgName];
|
||||
if (upg == null || currLevel == null) {
|
||||
console.error(`Invalid Upgrade Name given to HashManager.getUpgradeCost(): ${upgName}`);
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
export const HacknetNodeConstants: {
|
||||
// Constants for Hacknet Node production
|
||||
MoneyGainPerLevel: number;
|
||||
|
||||
// Constants for Hacknet Node purchase/upgrade costs
|
||||
BaseCost: number;
|
||||
LevelBaseCost: number;
|
||||
RamBaseCost: number;
|
||||
CoreBaseCost: number;
|
||||
|
||||
PurchaseNextMult: number;
|
||||
UpgradeLevelMult: number;
|
||||
UpgradeRamMult: number;
|
||||
UpgradeCoreMult: number;
|
||||
|
||||
// Constants for max upgrade levels for Hacknet Nodes
|
||||
MaxLevel: number;
|
||||
MaxRam: number;
|
||||
MaxCores: number;
|
||||
} = {
|
||||
MoneyGainPerLevel: 1.6,
|
||||
|
||||
BaseCost: 1000,
|
||||
LevelBaseCost: 1,
|
||||
RamBaseCost: 30e3,
|
||||
CoreBaseCost: 500e3,
|
||||
|
||||
PurchaseNextMult: 1.85,
|
||||
UpgradeLevelMult: 1.04,
|
||||
UpgradeRamMult: 1.28,
|
||||
UpgradeCoreMult: 1.48,
|
||||
|
||||
MaxLevel: 200,
|
||||
MaxRam: 64,
|
||||
MaxCores: 16,
|
||||
}
|
||||
|
||||
export const HacknetServerConstants: {
|
||||
// Constants for Hacknet Server stats/production
|
||||
HashesPerLevel: number;
|
||||
|
||||
// Constants for Hacknet Server purchase/upgrade costs
|
||||
BaseCost: number;
|
||||
RamBaseCost: number;
|
||||
CoreBaseCost: number;
|
||||
CacheBaseCost: number;
|
||||
|
||||
PurchaseMult: number; // Multiplier for puchasing an additional Hacknet Server
|
||||
UpgradeLevelMult: number; // Multiplier for cost when upgrading level
|
||||
UpgradeRamMult: number; // Multiplier for cost when upgrading RAM
|
||||
UpgradeCoreMult: number; // Multiplier for cost when buying another core
|
||||
UpgradeCacheMult: number; // Multiplier for cost when upgrading cache
|
||||
MaxServers: number; // Max number of Hacknet Servers you can own
|
||||
|
||||
// Constants for max upgrade levels for Hacknet Server
|
||||
MaxLevel: number;
|
||||
MaxRam: number;
|
||||
MaxCores: number;
|
||||
MaxCache: number;
|
||||
} = {
|
||||
HashesPerLevel: 0.001,
|
||||
|
||||
BaseCost: 50e3,
|
||||
RamBaseCost: 200e3,
|
||||
CoreBaseCost: 1e6,
|
||||
CacheBaseCost: 10e6,
|
||||
|
||||
PurchaseMult: 3.20,
|
||||
UpgradeLevelMult: 1.10,
|
||||
UpgradeRamMult: 1.40,
|
||||
UpgradeCoreMult: 1.55,
|
||||
UpgradeCacheMult: 1.85,
|
||||
|
||||
MaxServers: 20,
|
||||
|
||||
MaxLevel: 300,
|
||||
MaxRam: 8192,
|
||||
MaxCores: 128,
|
||||
MaxCache: 15,
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { HacknetNodeConstants } from "../data/Constants";
|
||||
|
||||
export function calculateMoneyGainRate(level: number, ram: number, cores: number, mult: number): number {
|
||||
const gainPerLevel = HacknetNodeConstants.MoneyGainPerLevel;
|
||||
|
||||
const levelMult = (level * gainPerLevel);
|
||||
const ramMult = Math.pow(1.035, ram - 1);
|
||||
const coresMult = ((cores + 5) / 6);
|
||||
return levelMult *
|
||||
ramMult *
|
||||
coresMult *
|
||||
mult *
|
||||
BitNodeMultipliers.HacknetNodeMoney;
|
||||
}
|
||||
|
||||
export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: number=1, costMult: number=1): number {
|
||||
const sanitizedLevels = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingLevel >= HacknetNodeConstants.MaxLevel) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetNodeConstants.UpgradeLevelMult;
|
||||
let totalMultiplier = 0;
|
||||
let currLevel = startingLevel;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalMultiplier += (HacknetNodeConstants.LevelBaseCost * Math.pow(mult, currLevel));
|
||||
++currLevel;
|
||||
}
|
||||
|
||||
return HacknetNodeConstants.BaseCost / 2 * totalMultiplier * costMult;
|
||||
}
|
||||
|
||||
export function calculateRamUpgradeCost(startingRam: number, extraLevels: number=1, costMult: number=1): number {
|
||||
const sanitizedLevels = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingRam >= HacknetNodeConstants.MaxRam) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
let totalCost = 0;
|
||||
let numUpgrades = Math.round(Math.log2(startingRam));
|
||||
let currentRam = startingRam;
|
||||
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
const baseCost = currentRam * HacknetNodeConstants.RamBaseCost;
|
||||
const mult = Math.pow(HacknetNodeConstants.UpgradeRamMult, numUpgrades);
|
||||
|
||||
totalCost += (baseCost * mult);
|
||||
|
||||
currentRam *= 2;
|
||||
++numUpgrades;
|
||||
}
|
||||
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
export function calculateCoreUpgradeCost(startingCore: number, extraLevels: number=1, costMult: number=1): number {
|
||||
const sanitizedCores = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedCores) || sanitizedCores < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingCore >= HacknetNodeConstants.MaxCores) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const coreBaseCost = HacknetNodeConstants.CoreBaseCost;
|
||||
const mult = HacknetNodeConstants.UpgradeCoreMult;
|
||||
let totalCost = 0;
|
||||
let currentCores = startingCore;
|
||||
for (let i = 0; i < sanitizedCores; ++i) {
|
||||
totalCost += (coreBaseCost * Math.pow(mult, currentCores-1));
|
||||
++currentCores;
|
||||
}
|
||||
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
export function calculateNodeCost(n: number, mult: number=1): number {
|
||||
if(n <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return HacknetNodeConstants.BaseCost * Math.pow(HacknetNodeConstants.PurchaseNextMult, n-1) * mult;
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { HacknetServerConstants } from "../data/Constants";
|
||||
|
||||
export function calculateHashGainRate(level: number, ramUsed: number, maxRam: number, cores: number, mult: number): number {
|
||||
const baseGain = HacknetServerConstants.HashesPerLevel * level;
|
||||
const ramMultiplier = Math.pow(1.07, Math.log2(maxRam));
|
||||
const coreMultiplier = 1 + (cores - 1) / 5;
|
||||
const ramRatio = (1 - ramUsed / maxRam);
|
||||
|
||||
return baseGain *
|
||||
ramMultiplier *
|
||||
coreMultiplier *
|
||||
ramRatio *
|
||||
mult *
|
||||
BitNodeMultipliers.HacknetNodeMoney;
|
||||
}
|
||||
|
||||
export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: number=1, costMult: number=1): number {
|
||||
const sanitizedLevels = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingLevel >= HacknetServerConstants.MaxLevel) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetServerConstants.UpgradeLevelMult;
|
||||
let totalMultiplier = 0;
|
||||
let currLevel = startingLevel;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalMultiplier += Math.pow(mult, currLevel);
|
||||
++currLevel;
|
||||
}
|
||||
|
||||
return 10 * HacknetServerConstants.BaseCost * totalMultiplier * costMult;
|
||||
}
|
||||
|
||||
export function calculateRamUpgradeCost(startingRam: number, extraLevels: number=1, costMult: number=1): number {
|
||||
const sanitizedLevels = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingRam >= HacknetServerConstants.MaxRam) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
let totalCost = 0;
|
||||
let numUpgrades = Math.round(Math.log2(startingRam));
|
||||
let currentRam = startingRam;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
let baseCost = currentRam * HacknetServerConstants.RamBaseCost;
|
||||
let mult = Math.pow(HacknetServerConstants.UpgradeRamMult, numUpgrades);
|
||||
|
||||
totalCost += (baseCost * mult);
|
||||
|
||||
currentRam *= 2;
|
||||
++numUpgrades;
|
||||
}
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
export function calculateCoreUpgradeCost(startingCores: number, extraLevels: number=1, costMult: number=1): number {
|
||||
const sanitizedLevels = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingCores >= HacknetServerConstants.MaxCores) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetServerConstants.UpgradeCoreMult;
|
||||
let totalCost = 0;
|
||||
let currentCores = startingCores;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalCost += Math.pow(mult, currentCores-1);
|
||||
++currentCores;
|
||||
}
|
||||
totalCost *= HacknetServerConstants.CoreBaseCost;
|
||||
totalCost *= costMult;
|
||||
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
export function calculateCacheUpgradeCost(startingCache: number, extraLevels: number=1): number {
|
||||
const sanitizedLevels = Math.round(extraLevels);
|
||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (startingCache >= HacknetServerConstants.MaxCache) {
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
const mult = HacknetServerConstants.UpgradeCacheMult;
|
||||
let totalCost = 0;
|
||||
let currentCache = startingCache;
|
||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||
totalCost += Math.pow(mult, currentCache - 1);
|
||||
++currentCache;
|
||||
}
|
||||
totalCost *= HacknetServerConstants.CacheBaseCost;
|
||||
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
export function calculateServerCost(n: number, mult: number=1): number {
|
||||
if (n-1 >= HacknetServerConstants.MaxServers) { return Infinity; }
|
||||
|
||||
return HacknetServerConstants.BaseCost * Math.pow(HacknetServerConstants.PurchaseMult, n-1) * mult;
|
||||
}
|
||||
@@ -4,11 +4,7 @@
|
||||
*/
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
HacknetNodeMaxLevel,
|
||||
HacknetNodeMaxRam,
|
||||
HacknetNodeMaxCores
|
||||
} from "../HacknetNode";
|
||||
import { HacknetNodeConstants } from "../data/Constants";
|
||||
import {
|
||||
getMaxNumberLevelUpgrades,
|
||||
getMaxNumberRamUpgrades,
|
||||
@@ -21,6 +17,8 @@ import {
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
|
||||
export class HacknetNode extends React.Component {
|
||||
render() {
|
||||
@@ -29,21 +27,21 @@ export class HacknetNode extends React.Component {
|
||||
const recalculate = this.props.recalculate;
|
||||
|
||||
// Upgrade Level Button
|
||||
let upgradeLevelText, upgradeLevelClass;
|
||||
if (node.level >= HacknetNodeMaxLevel) {
|
||||
upgradeLevelText = "MAX LEVEL";
|
||||
let upgradeLevelContent, upgradeLevelClass;
|
||||
if (node.level >= HacknetNodeConstants.MaxLevel) {
|
||||
upgradeLevelContent = <>MAX LEVEL</>;
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel);
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetNodeMaxLevel - node.level;
|
||||
const levelsToMax = HacknetNodeConstants.MaxLevel - node.level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.hacknet_node_level_cost_mult);
|
||||
upgradeLevelText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeLevelCost)}`;
|
||||
upgradeLevelContent = <>Upgrade x{multiplier} - {Money(upgradeLevelCost)}</>;
|
||||
if (Player.money.lt(upgradeLevelCost)) {
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -53,28 +51,28 @@ export class HacknetNode extends React.Component {
|
||||
const upgradeLevelOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel);
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeConstants.MaxLevel);
|
||||
}
|
||||
purchaseLevelUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
return false;
|
||||
}
|
||||
|
||||
let upgradeRamText, upgradeRamClass;
|
||||
if (node.ram >= HacknetNodeMaxRam) {
|
||||
upgradeRamText = "MAX RAM";
|
||||
let upgradeRamContent, upgradeRamClass;
|
||||
if (node.ram >= HacknetNodeConstants.MaxRam) {
|
||||
upgradeRamContent = <>MAX RAM</>;
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam);
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetNodeConstants.MaxRam);
|
||||
} else {
|
||||
const levelsToMax = Math.round(Math.log2(HacknetNodeMaxRam / node.ram));
|
||||
const levelsToMax = Math.round(Math.log2(HacknetNodeConstants.MaxRam / node.ram));
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player.hacknet_node_ram_cost_mult);
|
||||
upgradeRamText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeRamCost)}`;
|
||||
upgradeRamContent = <>Upgrade x{multiplier} - {Money(upgradeRamCost)}</>;
|
||||
if (Player.money.lt(upgradeRamCost)) {
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -84,28 +82,28 @@ export class HacknetNode extends React.Component {
|
||||
const upgradeRamOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam);
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeConstants.MaxRam);
|
||||
}
|
||||
purchaseRamUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
return false;
|
||||
}
|
||||
|
||||
let upgradeCoresText, upgradeCoresClass;
|
||||
if (node.cores >= HacknetNodeMaxCores) {
|
||||
upgradeCoresText = "MAX CORES";
|
||||
let upgradeCoresContent, upgradeCoresClass;
|
||||
if (node.cores >= HacknetNodeConstants.MaxCores) {
|
||||
upgradeCoresContent = <>MAX CORES</>;
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores);
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeConstants.MaxCores);
|
||||
} else {
|
||||
const levelsToMax = HacknetNodeMaxCores - node.cores;
|
||||
const levelsToMax = HacknetNodeConstants.MaxCores - node.cores;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player.hacknet_node_core_cost_mult);
|
||||
upgradeCoresText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCoreCost)}`;
|
||||
upgradeCoresContent = <>Upgrade x{multiplier} - {Money(upgradeCoreCost)}</>;
|
||||
if (Player.money.lt(upgradeCoreCost)) {
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -115,7 +113,7 @@ export class HacknetNode extends React.Component {
|
||||
const upgradeCoresOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores);
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeConstants.MaxCores);
|
||||
}
|
||||
purchaseCoreUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@@ -132,25 +130,25 @@ export class HacknetNode extends React.Component {
|
||||
<div className={"row"}>
|
||||
<p>Production:</p>
|
||||
<span className={"text money-gold"}>
|
||||
{numeralWrapper.formatMoney(node.totalMoneyGenerated)} ({numeralWrapper.formatMoney(node.moneyGainRatePerSecond)} / sec)
|
||||
{Money(node.totalMoneyGenerated)} ({MoneyRate(node.moneyGainRatePerSecond)})
|
||||
</span>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
||||
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
||||
{upgradeLevelText}
|
||||
{upgradeLevelContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>RAM:</p><span className={"text upgradable-info"}>{node.ram}GB</span>
|
||||
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
||||
{upgradeRamText}
|
||||
{upgradeRamContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
||||
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
||||
{upgradeCoresText}
|
||||
{upgradeCoresContent}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,12 +4,7 @@
|
||||
*/
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
HacknetServerMaxLevel,
|
||||
HacknetServerMaxRam,
|
||||
HacknetServerMaxCores,
|
||||
HacknetServerMaxCache
|
||||
} from "../HacknetServer";
|
||||
import { HacknetServerConstants } from "../data/Constants";
|
||||
import {
|
||||
getMaxNumberLevelUpgrades,
|
||||
getMaxNumberRamUpgrades,
|
||||
@@ -25,6 +20,9 @@ import {
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { Hashes } from "../../ui/React/Hashes";
|
||||
import { HashRate } from "../../ui/React/HashRate";
|
||||
|
||||
export class HacknetServer extends React.Component {
|
||||
render() {
|
||||
@@ -33,21 +31,21 @@ export class HacknetServer extends React.Component {
|
||||
const recalculate = this.props.recalculate;
|
||||
|
||||
// Upgrade Level Button
|
||||
let upgradeLevelText, upgradeLevelClass;
|
||||
if (node.level >= HacknetServerMaxLevel) {
|
||||
upgradeLevelText = "MAX LEVEL";
|
||||
let upgradeLevelContent, upgradeLevelClass;
|
||||
if (node.level >= HacknetServerConstants.MaxLevel) {
|
||||
upgradeLevelContent = <>MAX LEVEL</>;
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel);
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerMaxLevel - node.level;
|
||||
const levelsToMax = HacknetServerConstants.MaxLevel - node.level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.hacknet_node_level_cost_mult);
|
||||
upgradeLevelText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeLevelCost)}`;
|
||||
upgradeLevelContent = <>Upgrade x{multiplier} - {Money(upgradeLevelCost)}</>;
|
||||
if (Player.money.lt(upgradeLevelCost)) {
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -57,7 +55,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeLevelOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel);
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
}
|
||||
purchaseLevelUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@@ -65,21 +63,21 @@ export class HacknetServer extends React.Component {
|
||||
}
|
||||
|
||||
// Upgrade RAM Button
|
||||
let upgradeRamText, upgradeRamClass;
|
||||
if (node.maxRam >= HacknetServerMaxRam) {
|
||||
upgradeRamText = "MAX RAM";
|
||||
let upgradeRamContent, upgradeRamClass;
|
||||
if (node.maxRam >= HacknetServerConstants.MaxRam) {
|
||||
upgradeRamContent = <>MAX RAM</>;
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetServerMaxRam);
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetServerConstants.MaxRam);
|
||||
} else {
|
||||
const levelsToMax = Math.round(Math.log2(HacknetServerMaxRam / node.maxRam));
|
||||
const levelsToMax = Math.round(Math.log2(HacknetServerConstants.MaxRam / node.maxRam));
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player.hacknet_node_ram_cost_mult);
|
||||
upgradeRamText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeRamCost)}`;
|
||||
upgradeRamContent = <>Upgrade x{multiplier} - {Money(upgradeRamCost)}</>;
|
||||
if (Player.money.lt(upgradeRamCost)) {
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -89,7 +87,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeRamOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerMaxRam);
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerConstants.MaxRam);
|
||||
}
|
||||
purchaseRamUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@@ -97,21 +95,21 @@ export class HacknetServer extends React.Component {
|
||||
}
|
||||
|
||||
// Upgrade Cores Button
|
||||
let upgradeCoresText, upgradeCoresClass;
|
||||
if (node.cores >= HacknetServerMaxCores) {
|
||||
upgradeCoresText = "MAX CORES";
|
||||
let upgradeCoresContent, upgradeCoresClass;
|
||||
if (node.cores >= HacknetServerConstants.MaxCores) {
|
||||
upgradeCoresContent = <>MAX CORES</>;
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores);
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetServerConstants.MaxCores);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerMaxCores - node.cores;
|
||||
const levelsToMax = HacknetServerConstants.MaxCores - node.cores;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player.hacknet_node_core_cost_mult);
|
||||
upgradeCoresText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCoreCost)}`;
|
||||
upgradeCoresContent = <>Upgrade x{multiplier} - {Money(upgradeCoreCost)}</>;
|
||||
if (Player.money.lt(upgradeCoreCost)) {
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -121,7 +119,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeCoresOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores);
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerConstants.MaxCores);
|
||||
}
|
||||
purchaseCoreUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@@ -129,21 +127,21 @@ export class HacknetServer extends React.Component {
|
||||
}
|
||||
|
||||
// Upgrade Cache button
|
||||
let upgradeCacheText, upgradeCacheClass;
|
||||
if (node.cache >= HacknetServerMaxCache) {
|
||||
upgradeCacheText = "MAX CACHE";
|
||||
let upgradeCacheContent, upgradeCacheClass;
|
||||
if (node.cache >= HacknetServerConstants.MaxCache) {
|
||||
upgradeCacheContent = <>MAX CACHE</>;
|
||||
upgradeCacheClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache);
|
||||
multiplier = getMaxNumberCacheUpgrades(node, HacknetServerConstants.MaxCache);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerMaxCache - node.cache;
|
||||
const levelsToMax = HacknetServerConstants.MaxCache - node.cache;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeCacheCost = node.calculateCacheUpgradeCost(multiplier);
|
||||
upgradeCacheText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCacheCost)}`;
|
||||
upgradeCacheContent = <>Upgrade x{multiplier} - {Money(upgradeCacheCost)}</>;
|
||||
if (Player.money.lt(upgradeCacheCost)) {
|
||||
upgradeCacheClass = "std-button-disabled";
|
||||
} else {
|
||||
@@ -153,7 +151,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeCacheOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache);
|
||||
numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerConstants.MaxCache);
|
||||
}
|
||||
purchaseCacheUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@@ -171,7 +169,7 @@ export class HacknetServer extends React.Component {
|
||||
<div className={"row"}>
|
||||
<p>Production:</p>
|
||||
<span className={"text money-gold"}>
|
||||
{numeralWrapper.formatBigNumber(node.totalHashesGenerated)} ({numeralWrapper.formatBigNumber(node.hashRate)} / sec)
|
||||
{Hashes(node.totalHashesGenerated)} ({HashRate(node.hashRate)})
|
||||
</span>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
@@ -181,25 +179,25 @@ export class HacknetServer extends React.Component {
|
||||
<div className={"row"}>
|
||||
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
||||
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
||||
{upgradeLevelText}
|
||||
{upgradeLevelContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>RAM:</p><span className={"text upgradable-info"}>{node.maxRam}GB</span>
|
||||
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
||||
{upgradeRamText}
|
||||
{upgradeRamContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
||||
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
||||
{upgradeCoresText}
|
||||
{upgradeCoresContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Cache Level:</p><span className={"text upgradable-info"}>{node.cache}</span>
|
||||
<button className={upgradeCacheClass} onClick={upgradeCacheOnClick}>
|
||||
{upgradeCacheText}
|
||||
{upgradeCacheContent}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,8 @@ import { ServerDropdown,
|
||||
ServerType } from "../../ui/React/ServerDropdown"
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import { CopyableText } from "../../ui/React/CopyableText";
|
||||
import { Hashes } from "../../ui/React/Hashes";
|
||||
|
||||
class HashUpgrade extends React.Component {
|
||||
constructor(props) {
|
||||
@@ -63,8 +65,8 @@ class HashUpgrade extends React.Component {
|
||||
// We'll reuse a Bladeburner css class
|
||||
return (
|
||||
<div className={"bladeburner-action"}>
|
||||
<h2>{upg.name}</h2>
|
||||
<p>Cost: {numeralWrapper.format(cost, "0.000a")}</p>
|
||||
<CopyableText value={upg.name} />
|
||||
<p>Cost: {Hashes(cost)}</p>
|
||||
<p>{upg.desc}</p>
|
||||
<button className={btnClass} onClick={this.purchase}>
|
||||
Purchase
|
||||
@@ -122,7 +124,7 @@ export class HashUpgradePopup extends React.Component {
|
||||
<div>
|
||||
<PopupCloseButton popup={this.props.popupId} text={"Close"} />
|
||||
<p>Spend your hashes on a variety of different upgrades</p>
|
||||
<p>Hashes: {numeralWrapper.formatBigNumber(this.state.totalHashes)}</p>
|
||||
<p>Hashes: {numeralWrapper.formatHashes(this.state.totalHashes)}</p>
|
||||
{upgradeElems}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -9,43 +9,33 @@ import React from "react";
|
||||
import { hasHacknetServers } from "../HacknetHelpers";
|
||||
import { Player } from "../../Player";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { HashRate } from "../../ui/React/HashRate";
|
||||
import { Hashes } from "../../ui/React/Hashes";
|
||||
|
||||
export function PlayerInfo(props) {
|
||||
const hasServers = hasHacknetServers();
|
||||
|
||||
let prod;
|
||||
if (hasServers) {
|
||||
prod = numeralWrapper.format(props.totalProduction, "0.000a") + " hashes / sec";
|
||||
prod = HashRate(props.totalProduction);
|
||||
} else {
|
||||
prod = numeralWrapper.formatMoney(props.totalProduction) + " / sec";
|
||||
}
|
||||
|
||||
let hashInfo;
|
||||
if (hasServers) {
|
||||
hashInfo = numeralWrapper.format(Player.hashManager.hashes, "0.000a") + " / " +
|
||||
numeralWrapper.format(Player.hashManager.capacity, "0.000a");
|
||||
prod = MoneyRate(props.totalProduction);
|
||||
}
|
||||
|
||||
return (
|
||||
<p id={"hacknet-nodes-money"}>
|
||||
<span>Money:</span>
|
||||
<span className={"money-gold"}>{numeralWrapper.formatMoney(Player.money.toNumber())}</span><br />
|
||||
<span>Money: </span>
|
||||
{Money(Player.money.toNumber())}<br />
|
||||
|
||||
{
|
||||
hasServers &&
|
||||
<span>Hashes:</span>
|
||||
}
|
||||
{
|
||||
hasServers &&
|
||||
<span className={"money-gold"}>{hashInfo}</span>
|
||||
}
|
||||
{
|
||||
hasServers &&
|
||||
<br />
|
||||
<><span>Hashes: {Hashes(Player.hashManager.hashes)} / {Hashes(Player.hashManager.capacity)}</span><br /></>
|
||||
}
|
||||
|
||||
<span>Total Hacknet Node Production:</span>
|
||||
<span className={"money-gold"}>{prod}</span>
|
||||
<span>Total Hacknet Node Production: </span>
|
||||
{prod}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { hasHacknetServers,
|
||||
hasMaxNumberHacknetServers } from "../HacknetHelpers";
|
||||
import { Player } from "../../Player";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
export function PurchaseButton(props) {
|
||||
if (props.multiplier == null || props.onClick == null) {
|
||||
@@ -20,13 +21,13 @@ export function PurchaseButton(props) {
|
||||
if (hasHacknetServers()) {
|
||||
if (hasMaxNumberHacknetServers()) {
|
||||
className = "std-button-disabled";
|
||||
text = "Hacknet Server limit reached";
|
||||
text = <>Hacknet Server limit reached</>;
|
||||
style = {color: "red"};
|
||||
} else {
|
||||
text = `Purchase Hacknet Server - ${numeralWrapper.formatMoney(cost)}`;
|
||||
text = <>Purchase Hacknet Server - {Money(cost)}</>;
|
||||
}
|
||||
} else {
|
||||
text = `Purchase Hacknet Node - ${numeralWrapper.formatMoney(cost)}`;
|
||||
text = <>Purchase Hacknet Node - {Money(cost)}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user