mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-20 05:05:47 +01:00
Fixed documentation typos in v0.47.0
This commit is contained in:
parent
95c928afc9
commit
a2551f98c2
@ -16,8 +16,6 @@ You can use the Singularity Functions in other BitNodes if and only if you have
|
||||
Source-File 4 will open up additional Singularity Functions that you can use in other BitNodes. If your Source-File 4 is upgraded all the way to
|
||||
level 3, then you will be able to access all of the Singularity Functions.
|
||||
|
||||
Note that Singularity Functions require twice as much RAM outside of BitNode-4
|
||||
|
||||
.. toctree::
|
||||
:caption: Functions:
|
||||
|
||||
|
@ -4,7 +4,7 @@ getStockSaleGain() Netscript Function
|
||||
.. js:function:: getStockSaleGain(sym, shares, posType)
|
||||
|
||||
:param string sym: Stock symbol
|
||||
:param number shares: Number of shares to purchase
|
||||
:param number shares: Number of shares to sell
|
||||
:param string posType: Specifies whether the order is a "Long" or "Short" position.
|
||||
The values "L" or "S" can also be used.
|
||||
:RAM cost: 2 GB
|
||||
|
@ -1,3 +1,13 @@
|
||||
/**
|
||||
* Generic helper/utility functions for the Hacknet mechanic:
|
||||
* - Purchase nodes/upgrades
|
||||
* - Calculating maximum number of upgrades
|
||||
* - Processing Hacknet earnings
|
||||
* - Updating Hash Manager capacity
|
||||
* - Purchasing hash upgrades
|
||||
*
|
||||
* TODO Should probably split the different types of functions into their own modules
|
||||
*/
|
||||
import {
|
||||
HacknetNode,
|
||||
BaseCostForHacknetNode,
|
||||
@ -26,7 +36,7 @@ import {
|
||||
ITutorial
|
||||
} from "../InteractiveTutorial";
|
||||
import { Player } from "../Player";
|
||||
import { AddToAllServers, AllServers } from "../Server/AllServers";
|
||||
import { AllServers } from "../Server/AllServers";
|
||||
import { GetServerByHostname } from "../Server/ServerHelpers";
|
||||
import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
|
||||
import { Page, routing } from "../ui/navigationTracking";
|
||||
@ -115,7 +125,7 @@ export function getCostOfNextHacknetServer() {
|
||||
return BaseCostForHacknetServer * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
||||
}
|
||||
|
||||
//Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node
|
||||
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's level
|
||||
export function getMaxNumberLevelUpgrades(nodeObj, maxLevel) {
|
||||
if (maxLevel == null) {
|
||||
throw new Error(`getMaxNumberLevelUpgrades() called without maxLevel arg`);
|
||||
@ -149,6 +159,7 @@ export function getMaxNumberLevelUpgrades(nodeObj, maxLevel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's RAM
|
||||
export function getMaxNumberRamUpgrades(nodeObj, maxLevel) {
|
||||
if (maxLevel == null) {
|
||||
throw new Error(`getMaxNumberRamUpgrades() called without maxLevel arg`);
|
||||
@ -177,6 +188,7 @@ export function getMaxNumberRamUpgrades(nodeObj, maxLevel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's cores
|
||||
export function getMaxNumberCoreUpgrades(nodeObj, maxLevel) {
|
||||
if (maxLevel == null) {
|
||||
throw new Error(`getMaxNumberCoreUpgrades() called without maxLevel arg`);
|
||||
@ -193,7 +205,7 @@ export function getMaxNumberCoreUpgrades(nodeObj, maxLevel) {
|
||||
return levelsToMax;
|
||||
}
|
||||
|
||||
//Use a binary search to find the max possible number of upgrades
|
||||
// Use a binary search to find the max possible number of upgrades
|
||||
while (min <= max) {
|
||||
let curr = (min + max) / 2 | 0;
|
||||
if (curr != maxLevel &&
|
||||
@ -212,6 +224,7 @@ export function getMaxNumberCoreUpgrades(nodeObj, maxLevel) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's cache
|
||||
export function getMaxNumberCacheUpgrades(nodeObj, maxLevel) {
|
||||
if (maxLevel == null) {
|
||||
throw new Error(`getMaxNumberCacheUpgrades() called without maxLevel arg`);
|
||||
|
@ -176,33 +176,28 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
return totalCost;
|
||||
}
|
||||
|
||||
// Process this Hacknet Server in the game loop.
|
||||
// Returns the number of hashes generated
|
||||
// Process this Hacknet Server in the game loop. Returns the number of hashes generated
|
||||
process(numCycles: number=1): number {
|
||||
const seconds = numCycles * CONSTANTS.MilliPerCycle / 1000;
|
||||
|
||||
return this.hashRate * seconds;
|
||||
}
|
||||
|
||||
// Returns a boolean indicating whether the cache was successfully upgraded
|
||||
upgradeCache(levels: number): void {
|
||||
this.cache = Math.min(HacknetServerMaxCache, Math.round(this.cache + levels));
|
||||
this.updateHashCapacity();
|
||||
}
|
||||
|
||||
// Returns a boolean indicating whether the number of cores was successfully upgraded
|
||||
upgradeCore(levels: number, prodMult: number): void {
|
||||
this.cores = Math.min(HacknetServerMaxCores, Math.round(this.cores + levels));
|
||||
this.updateHashRate(prodMult);
|
||||
}
|
||||
|
||||
// Returns a boolean indicating whether the level was successfully upgraded
|
||||
upgradeLevel(levels: number, prodMult: number): void {
|
||||
this.level = Math.min(HacknetServerMaxLevel, Math.round(this.level + levels));
|
||||
this.updateHashRate(prodMult);
|
||||
}
|
||||
|
||||
// Returns a boolean indicating whether the RAM was successfully upgraded
|
||||
upgradeRam(levels: number, prodMult: number): boolean {
|
||||
for (let i = 0; i < levels; ++i) {
|
||||
this.maxRam *= 2;
|
||||
@ -212,10 +207,8 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever a script is run, we must update this server's hash rate
|
||||
*/
|
||||
|
||||
// Whenever a script is run, we must update this server's hash rate
|
||||
runScript(script: RunningScript, prodMult?: number): void {
|
||||
super.runScript(script);
|
||||
if (prodMult != null && typeof prodMult === "number") {
|
||||
|
@ -40,13 +40,15 @@ import { createPopupCloseButton } from "../../utils/uiHelpers/createPopupCloseBu
|
||||
import { removeElementById } from "../../utils/uiHelpers/removeElementById";
|
||||
|
||||
/**
|
||||
* Create a pop-up box that lets the player confirm traveling to a different city
|
||||
* If settings are configured to suppress this popup, just instantly travel
|
||||
* Create a pop-up box that lets the player confirm traveling to a different city.
|
||||
* If settings are configured to suppress this popup, just instantly travel.
|
||||
* The actual "Travel" implementation is implemented in the UI, and is passed in
|
||||
* as an argument
|
||||
* as an argument.
|
||||
* @param {CityName} destination - City that the player is traveling to
|
||||
* @param {Function} travelFn - Function that changes the player's state for traveling
|
||||
*/
|
||||
type TravelFunction = (to: CityName) => void;
|
||||
export function createTravelPopup(destination: CityName, travelFn: TravelFunction) {
|
||||
export function createTravelPopup(destination: CityName, travelFn: TravelFunction): void {
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
|
||||
if (Settings.SuppressTravelConfirmation) {
|
||||
@ -80,10 +82,10 @@ export function createTravelPopup(destination: CityName, travelFn: TravelFunctio
|
||||
|
||||
/**
|
||||
* Create a pop-up box that lets the player purchase a server.
|
||||
* @param ram - Amount of RAM (GB) on server
|
||||
* @param p - Player object
|
||||
* @param {number} ram - Amount of RAM (GB) on server
|
||||
* @param {IPlayer} p - Player object
|
||||
*/
|
||||
export function createPurchaseServerPopup(ram: number, p: IPlayer) {
|
||||
export function createPurchaseServerPopup(ram: number, p: IPlayer): void {
|
||||
const cost = getPurchaseServerCost(ram);
|
||||
if (cost === Infinity) {
|
||||
dialogBoxCreate("Something went wrong when trying to purchase this server. Please contact developer");
|
||||
@ -111,6 +113,7 @@ export function createPurchaseServerPopup(ram: number, p: IPlayer) {
|
||||
|
||||
/**
|
||||
* Create a popup that lets the player start a Corporation
|
||||
* @param {IPlayer} p - Player object
|
||||
*/
|
||||
export function createStartCorporationPopup(p: IPlayer) {
|
||||
if (!p.canAccessCorporation() || p.hasCorporation()) { return; }
|
||||
@ -172,8 +175,10 @@ export function createStartCorporationPopup(p: IPlayer) {
|
||||
if (worldHeader instanceof HTMLElement) {
|
||||
worldHeader.click(); worldHeader.click();
|
||||
}
|
||||
dialogBoxCreate("Congratulations! You just started your own corporation with government seed money. " +
|
||||
"You can visit and manage your company in the City");
|
||||
dialogBoxCreate(
|
||||
"Congratulations! You just started your own corporation with government seed money. " +
|
||||
"You can visit and manage your company in the City"
|
||||
);
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
}
|
||||
@ -187,21 +192,23 @@ export function createStartCorporationPopup(p: IPlayer) {
|
||||
|
||||
/**
|
||||
* Create a popup that lets the player upgrade the cores on his/her home computer
|
||||
* @param p - Player object
|
||||
* @param {IPlayer} p - Player object
|
||||
*/
|
||||
export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
||||
const currentCores = p.getHomeComputer().cpuCores;
|
||||
if (currentCores >= 8) { return; } // Max of 8 cores
|
||||
|
||||
//Cost of purchasing another cost is found by indexing this array with number of current cores
|
||||
const allCosts = [0,
|
||||
10e9, // 1->2 Cores - 10 bn
|
||||
250e9, // 2->3 Cores - 250 bn
|
||||
5e12, // 3->4 Cores - 5 trillion
|
||||
100e12, // 4->5 Cores - 100 trillion
|
||||
1e15, // 5->6 Cores - 1 quadrillion
|
||||
20e15, // 6->7 Cores - 20 quadrillion
|
||||
200e15]; // 7->8 Cores - 200 quadrillion
|
||||
// Cost of purchasing another cost is found by indexing this array with number of current cores
|
||||
const allCosts = [
|
||||
0,
|
||||
10e9,
|
||||
250e9,
|
||||
5e12,
|
||||
100e12,
|
||||
1e15,
|
||||
20e15,
|
||||
200e15
|
||||
];
|
||||
const cost: number = allCosts[currentCores];
|
||||
|
||||
const yesBtn = yesNoBoxGetYesButton();
|
||||
@ -215,8 +222,10 @@ export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
||||
} else {
|
||||
p.loseMoney(cost);
|
||||
p.getHomeComputer().cpuCores++;
|
||||
dialogBoxCreate("You purchased an additional CPU Core for your home computer! It now has " +
|
||||
p.getHomeComputer().cpuCores + " cores.");
|
||||
dialogBoxCreate(
|
||||
"You purchased an additional CPU Core for your home computer! It now has " +
|
||||
p.getHomeComputer().cpuCores + " cores."
|
||||
);
|
||||
}
|
||||
yesNoBoxClose();
|
||||
});
|
||||
@ -226,15 +235,17 @@ export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
yesNoBoxCreate("Would you like to purchase an additional CPU Core for your home computer? Each CPU Core " +
|
||||
"lets you start with an additional Core Node in Hacking Missions.<br><br>" +
|
||||
"Purchasing an additional core (for a total of " + (p.getHomeComputer().cpuCores + 1) + ") will " +
|
||||
"cost " + numeralWrapper.formatMoney(cost));
|
||||
yesNoBoxCreate(
|
||||
"Would you like to purchase an additional CPU Core for your home computer? Each CPU Core " +
|
||||
"lets you start with an additional Core Node in Hacking Missions.<br><br>" +
|
||||
"Purchasing an additional core (for a total of " + (p.getHomeComputer().cpuCores + 1) + ") will " +
|
||||
"cost " + numeralWrapper.formatMoney(cost)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a popup that lets the player upgrade the RAM on his/her home computer
|
||||
* @param p - Player object
|
||||
* @param {IPlayer} p - Player object
|
||||
*/
|
||||
export function createUpgradeHomeRamPopup(p: IPlayer) {
|
||||
const cost: number = p.getUpgradeHomeRamCost();
|
||||
@ -255,15 +266,17 @@ export function createUpgradeHomeRamPopup(p: IPlayer) {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
yesNoBoxCreate("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
"This will upgrade your RAM from " + ram + "GB to " + ram*2 + "GB. <br><br>" +
|
||||
"This will cost " + numeralWrapper.format(cost, '$0.000a'));
|
||||
yesNoBoxCreate(
|
||||
"Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
"This will upgrade your RAM from " + ram + "GB to " + ram*2 + "GB. <br><br>" +
|
||||
"This will cost " + numeralWrapper.format(cost, '$0.000a')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to purchase a TOR router
|
||||
* @param p - Player object
|
||||
* @param {IPlayer} p - Player object
|
||||
*/
|
||||
export function purchaseTorRouter(p: IPlayer) {
|
||||
if (p.hasTorRouter()) {
|
||||
@ -285,7 +298,9 @@ export function purchaseTorRouter(p: IPlayer) {
|
||||
|
||||
p.getHomeComputer().serversOnNetwork.push(darkweb.ip);
|
||||
darkweb.serversOnNetwork.push(p.getHomeComputer().ip);
|
||||
dialogBoxCreate("You have purchased a Tor router!<br>" +
|
||||
"You now have access to the dark web from your home computer<br>" +
|
||||
"Use the scan/scan-analyze commands to search for the dark web connection.");
|
||||
dialogBoxCreate(
|
||||
"You have purchased a Tor router!<br>" +
|
||||
"You now have access to the dark web from your home computer<br>" +
|
||||
"Use the scan/scan-analyze commands to search for the dark web connection."
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,10 @@
|
||||
// Calculate a script's RAM usage
|
||||
/**
|
||||
* Implements RAM Calculation functionality.
|
||||
*
|
||||
* Uses the acorn.js library to parse a script's code into an AST and
|
||||
* recursively walk through that AST, calculating RAM usage along
|
||||
* the way
|
||||
*/
|
||||
import * as walk from "acorn-walk";
|
||||
|
||||
import { RamCalculationErrorCode } from "./RamCalculationErrorCodes";
|
||||
@ -15,19 +21,26 @@ const specialReferenceWHILE = "__SPECIAL_referenceWhile";
|
||||
// The global scope of a script is registered under this key during parsing.
|
||||
const memCheckGlobalKey = ".__GLOBAL__";
|
||||
|
||||
// Calcluates the amount of RAM a script uses. Uses parsing and AST walking only,
|
||||
// rather than NetscriptEvaluator. This is useful because NetscriptJS code does
|
||||
// not work under NetscriptEvaluator.
|
||||
/**
|
||||
* Parses code into an AST and walks through it recursively to calculate
|
||||
* RAM usage. Also accounts for imported modules.
|
||||
* @param {Script[]} otherScripts - All other scripts on the server. Used to account for imported scripts
|
||||
* @param {string} codeCopy - The code being parsed
|
||||
* @param {WorkerScript} workerScript - Object containing RAM costs of Netscript functions. Also used to
|
||||
* keep track of what functions have/havent been accounted for
|
||||
*/
|
||||
async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
try {
|
||||
// Maps dependent identifiers to their dependencies.
|
||||
//
|
||||
// The initial identifier is __SPECIAL_INITIAL_MODULE__.__GLOBAL__.
|
||||
// It depends on all the functions declared in the module, all the global scopes
|
||||
// of its imports, and any identifiers referenced in this global scope. Each
|
||||
// function depends on all the identifiers referenced internally.
|
||||
// We walk the dependency graph to calculate RAM usage, given that some identifiers
|
||||
// reference Netscript functions which have a RAM cost.
|
||||
/**
|
||||
* Maps dependent identifiers to their dependencies.
|
||||
*
|
||||
* The initial identifier is __SPECIAL_INITIAL_MODULE__.__GLOBAL__.
|
||||
* It depends on all the functions declared in the module, all the global scopes
|
||||
* of its imports, and any identifiers referenced in this global scope. Each
|
||||
* function depends on all the identifiers referenced internally.
|
||||
* We walk the dependency graph to calculate RAM usage, given that some identifiers
|
||||
* reference Netscript functions which have a RAM cost.
|
||||
*/
|
||||
let dependencyMap = {};
|
||||
|
||||
// Scripts we've parsed.
|
||||
@ -48,19 +61,20 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
}
|
||||
}
|
||||
|
||||
// Splice all the references in.
|
||||
//Spread syntax not supported in edge, use Object.assign instead
|
||||
//dependencyMap = {...dependencyMap, ...result.dependencyMap};
|
||||
// Splice all the references in
|
||||
dependencyMap = Object.assign(dependencyMap, result.dependencyMap);
|
||||
}
|
||||
|
||||
// Parse the initial module, which is the "main" script that is being run
|
||||
const initialModule = "__SPECIAL_INITIAL_MODULE__";
|
||||
parseCode(code, initialModule);
|
||||
|
||||
// Process additional modules, which occurs if the "main" script has any imports
|
||||
while (parseQueue.length > 0) {
|
||||
// Get the code from the server.
|
||||
const nextModule = parseQueue.shift();
|
||||
|
||||
// Additional modules can either be imported from the web (in which case we use
|
||||
// a dynamic import), or from other in-game scripts
|
||||
let code;
|
||||
if (nextModule.startsWith("https://") || nextModule.startsWith("http://")) {
|
||||
try {
|
||||
@ -91,7 +105,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
}
|
||||
|
||||
if (script == null) {
|
||||
return RamCalculationErrorCode.ImportError; // No such script on the server
|
||||
return RamCalculationErrorCode.ImportError; // No such script on the server
|
||||
}
|
||||
|
||||
code = script.code;
|
||||
@ -136,10 +150,8 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this identifier is a function in the workerscript env.
|
||||
// Check if this identifier is a function in the workerScript environment.
|
||||
// If it is, then we need to get its RAM cost.
|
||||
//
|
||||
// TODO it would be simpler to just reference a dictionary.
|
||||
try {
|
||||
function applyFuncRam(func) {
|
||||
if (typeof func === "function") {
|
||||
@ -170,7 +182,7 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
workerScript.loadedFns[ref] = true;
|
||||
}
|
||||
|
||||
// This accounts for namespaces (Bladeburner, CodingCOntract)
|
||||
// This accounts for namespaces (Bladeburner, CodingCpntract, etc.)
|
||||
let func;
|
||||
if (ref in workerScript.env.vars.bladeburner) {
|
||||
func = workerScript.env.vars.bladeburner[ref];
|
||||
@ -196,9 +208,12 @@ async function parseOnlyRamCalculate(otherScripts, code, workerScript) {
|
||||
}
|
||||
}
|
||||
|
||||
// Parses one script and calculates its ram usage, for the global scope and each function.
|
||||
// Returns a cost map and a dependencyMap for the module. Returns a reference map to be joined
|
||||
// onto the main reference map, and a list of modules that need to be parsed.
|
||||
/**
|
||||
* Helper function that parses a single script. It returns a map of all dependencies,
|
||||
* which are items in the code's AST that potentially need to be evaluated
|
||||
* for RAM usage calculations. It also returns an array of additional modules
|
||||
* that need to be parsed (i.e. are 'import'ed scripts).
|
||||
*/
|
||||
function parseOnlyCalculateDeps(code, currentModule) {
|
||||
const ast = parse(code, {sourceType:"module", ecmaVersion: 8});
|
||||
|
||||
@ -296,6 +311,12 @@ function parseOnlyCalculateDeps(code, currentModule) {
|
||||
return {dependencyMap: dependencyMap, additionalModules: additionalModules};
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate's a scripts RAM Usage
|
||||
* @param {string} codeCopy - The script's code
|
||||
* @param {Script[]} otherScripts - All other scripts on the server.
|
||||
* Used to account for imported scripts
|
||||
*/
|
||||
export async function calculateRamUsage(codeCopy, otherScripts) {
|
||||
// We don't need a real WorkerScript for this. Just an object that keeps
|
||||
// track of whatever's needed for RAM calculations
|
||||
|
@ -69,22 +69,20 @@ export class RunningScript {
|
||||
if (script == null) { return; }
|
||||
this.filename = script.filename;
|
||||
this.args = args;
|
||||
|
||||
this.server = script.server; //IP Address only
|
||||
this.server = script.server;
|
||||
this.ramUsage = script.ramUsage;
|
||||
}
|
||||
|
||||
log(txt: string): void {
|
||||
if (this.logs.length > Settings.MaxLogCapacity) {
|
||||
//Delete first element and add new log entry to the end.
|
||||
//TODO Eventually it might be better to replace this with circular array
|
||||
//to improve performance
|
||||
this.logs.shift();
|
||||
}
|
||||
|
||||
let logEntry = txt;
|
||||
if (FconfSettings.ENABLE_TIMESTAMPS) {
|
||||
logEntry = "[" + getTimestamp() + "] " + logEntry;
|
||||
}
|
||||
|
||||
this.logs.push(logEntry);
|
||||
this.logUpd = true;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ export function buyStock(stock: Stock, shares: number, workerScript: WorkerScrip
|
||||
if (totalPrice == null) { return false; }
|
||||
if (Player.money.lt(totalPrice)) {
|
||||
if (tixApi) {
|
||||
workerScript!.log(`ERROR: buyStock() failed because you do not have enough money to purchase this potiion. You need ${numeralWrapper.formatMoney(totalPrice)}`);
|
||||
workerScript!.log(`ERROR: buyStock() failed because you do not have enough money to purchase this position. You need ${numeralWrapper.formatMoney(totalPrice)}`);
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate(`You do not have enough money to purchase this. You need ${numeralWrapper.formatMoney(totalPrice)}`);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user