bitburner-src/src/Hacknet/HashManager.ts

172 lines
4.5 KiB
TypeScript
Raw Normal View History

2019-03-25 04:03:24 +01:00
/**
* This is a central class for storing and managing the player's hashes,
* which are generated by Hacknet Servers
*
* It is also used to keep track of what upgrades the player has bought with
* his hashes, and contains method for grabbing the data/multipliers from
* those upgrades
*/
import { HashUpgrades } from "./HashUpgrades";
import { HashUpgrade } from "./HashUpgrade";
2019-03-25 04:03:24 +01:00
import { IMap } from "../types";
2021-09-25 20:42:57 +02:00
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
2019-03-25 04:03:24 +01:00
export class HashManager {
2021-09-05 01:09:30 +02:00
// Max number of hashes this can hold. Equal to the sum of capacities of
// all Hacknet Servers
capacity = 0;
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
// Number of hashes currently in storage
hashes = 0;
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
// Map of Hash Upgrade Name -> levels in that upgrade
upgrades: IMap<number> = {};
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
constructor() {
for (const name in HashUpgrades) {
this.upgrades[name] = 0;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
}
/**
* Generic helper function for getting a multiplier from a HashUpgrade
*/
getMult(upgName: string): number {
const upg = HashUpgrades[upgName];
const currLevel = this.upgrades[upgName];
if (upg == null || currLevel == null) {
console.error(`Could not find Hash Study upgrade`);
return 1;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
return 1 + (upg.value * currLevel) / 100;
}
/**
* One of the Hash upgrades improves studying. This returns that multiplier
*/
getStudyMult(): number {
const upgName = "Improve Studying";
return this.getMult(upgName);
}
/**
* One of the Hash upgrades improves gym training. This returns that multiplier
*/
getTrainingMult(): number {
const upgName = "Improve Gym Training";
return this.getMult(upgName);
}
getUpgrade(upgName: string): HashUpgrade | null {
const upg = HashUpgrades[upgName];
if (!upg) {
2021-09-09 05:47:34 +02:00
console.error(`Invalid Upgrade Name given to HashManager.getUpgrade(): ${upgName}`);
2021-09-05 01:09:30 +02:00
return null;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
return upg;
}
/**
* Get the cost (in hashes) of an upgrade
*/
getUpgradeCost(upgName: string): number {
const upg = this.getUpgrade(upgName);
const currLevel = this.upgrades[upgName];
if (upg == null || currLevel == null) {
2021-09-09 05:47:34 +02:00
console.error(`Invalid Upgrade Name given to HashManager.getUpgradeCost(): ${upgName}`);
2021-09-05 01:09:30 +02:00
return Infinity;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
return upg.getCost(currLevel);
}
2021-09-05 01:09:30 +02:00
prestige(): void {
for (const name in HashUpgrades) {
this.upgrades[name] = 0;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
this.hashes = 0;
// When prestiging, player's hacknet nodes are always reset. So capacity = 0
this.updateCapacity(0);
}
/**
* Reverts an upgrade and refunds the hashes used to buy it
*/
refundUpgrade(upgName: string): void {
const upg = HashUpgrades[upgName];
// Reduce the level first, so we get the right cost
--this.upgrades[upgName];
const currLevel = this.upgrades[upgName];
if (upg == null || currLevel == null || currLevel < 0) {
2021-09-09 05:47:34 +02:00
console.error(`Invalid Upgrade Name given to HashManager.upgrade(): ${upgName}`);
2021-09-05 01:09:30 +02:00
return;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
const cost = upg.getCost(currLevel);
this.hashes += cost;
}
2022-01-08 12:30:22 +01:00
/**
* Stores the given hashes, capping at capacity
* @param numHashes The number of hashes to increment
* @returns The number of wasted hashes (over capacity)
*/
storeHashes(numHashes: number): number {
2021-09-05 01:09:30 +02:00
this.hashes += numHashes;
2022-01-08 12:30:22 +01:00
let wastedHashes = this.hashes;
2021-09-05 01:09:30 +02:00
this.hashes = Math.min(this.hashes, this.capacity);
2022-01-08 12:30:22 +01:00
wastedHashes -= this.hashes;
return wastedHashes;
2021-09-05 01:09:30 +02:00
}
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
updateCapacity(newCap: number): void {
if (newCap < 0) {
this.capacity = 0;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
this.capacity = Math.max(newCap, 0);
}
/**
* Returns boolean indicating whether or not the upgrade was successfully purchased
* Note that this does NOT actually implement the effect
*/
upgrade(upgName: string): boolean {
const upg = HashUpgrades[upgName];
if (upg == null) {
2021-09-09 05:47:34 +02:00
console.error(`Invalid Upgrade Name given to HashManager.upgrade(): ${upgName}`);
2021-09-05 01:09:30 +02:00
return false;
2019-03-25 04:03:24 +01:00
}
2021-09-05 01:09:30 +02:00
const cost = this.getUpgradeCost(upgName);
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
if (this.hashes < cost) {
return false;
}
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
this.hashes -= cost;
++this.upgrades[upgName];
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
return true;
}
2019-03-25 04:03:24 +01:00
2021-09-05 01:09:30 +02:00
//Serialize the current object to a JSON save state.
toJSON(): any {
return Generic_toJSON("HashManager", this);
}
2021-05-01 09:17:31 +02:00
2021-09-05 01:09:30 +02:00
// Initiatizes a HashManager object from a JSON save state.
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
static fromJSON(value: any): HashManager {
return Generic_fromJSON(HashManager, value.data);
}
2019-03-25 04:03:24 +01:00
}
Reviver.constructors.HashManager = HashManager;