Merge pull request #358 from danielyxie/new-hacknetnode-api

New hacknetnode api
This commit is contained in:
danielyxie 2018-07-15 20:43:04 -05:00 committed by GitHub
commit 44e4325a5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 4723 additions and 4525 deletions

8224
dist/engine.bundle.js vendored

File diff suppressed because it is too large Load Diff

517
dist/vendor.bundle.js vendored

File diff suppressed because it is too large Load Diff

@ -110,6 +110,21 @@ stopBladeburnerAction
Stops the current Bladeburner action
getCurrentAction
----------------
.. js:function:: getCurrentAction()
Returns an object that represents the player's current Bladeburner action::
{
type: Type of Action
name: Name of Action
}
If the player is not performing an action, the function will return an object
with the 'type' property set to "Idle".
getActionTime
-------------
@ -162,21 +177,9 @@ getSkillLevel
.. js:function:: getSkillLevel(skillName="")
:param string skillName: Optional name of Skill. Empty string by default
:param string skillName: Name of skill
If no argument or an empty string is passed in, this function returns
an object with your level for all Bladeburner Skills (only for skills that
have at least one level). In the object, the name of the Bladeburner Skills
are the keys and your skill levels are the values. For example::
{
"Blade's Intuition": 10,
"Cloak": 5,
"Evasive System": 6
}
If the name of a skill is passed in as an argument, then this function
returns your level in the specified skill.
This function returns your level in the specified skill.
The function returns -1 if an invalid skill name is passed in

@ -69,8 +69,8 @@ let NetscriptFunctions =
"getServerGrowth|getServerSecurityLevel|getServerBaseSecurityLevel|" +
"getServerMinSecurityLevel|" +
"getServerRequiredHackingLevel|getServerNumPortsRequired|getServerRam|" +
"serverExists|fileExists|isRunning|getNextHacknetNodeCost|" +
"purchaseHacknetNode|deleteServer|getPurchasedServers|" +
"serverExists|fileExists|isRunning|" +
"deleteServer|getPurchasedServers|" +
"purchaseServer|round|write|read|peek|clear|rm|getPortHandle|" +
"scriptRunning|scriptKill|getScriptName|getScriptRam|" +
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
@ -83,10 +83,13 @@ let NetscriptFunctions =
"createProgram|commitCrime|getCrimeChance|getOwnedAugmentations|" +
"getAugmentationsFromFaction|" +
"getAugmentationCost|purchaseAugmentation|" +
"installAugmentations|hacknetnodes|upgradeLevel|upgradeRam|upgradeCore|" +
"getLevelUpgradeCost|getRamUpgradeCost|getCoreUpgradeCost|" +
"installAugmentations|" +
"getStockPrice|getStockPosition|buyStock|sellStock|shortStock|sellShort|" +
"placeOrder|cancelOrder|" +
//Hacknet Node API
"hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" +
"upgradeLevel|upgradeRam|upgradeCore|getLevelUpgradeCost|" +
"getRamUpgradeCost|getCoreUpgradeCost|" +
//Bladeburner functions
"bladeburner|getContractNames|getOperationNames|getBlackOpNames|" +

@ -3259,14 +3259,17 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
switch (convertedName) {
case "training":
action.type = ActionTypes["Training"];
action.name = "Training";
break;
case "recruitment":
case "recruit":
action.type = ActionTypes["Recruitment"];
action.name = "Recruitment";
break;
case "field analysis":
case "fieldanalysis":
action.type = ActionTypes["Field Analysis"];
action.name = "Field Analysis";
break;
default:
return null;
@ -3275,6 +3278,21 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
}
}
Bladeburner.prototype.getTypeAndNameFromActionId = function(actionId) {
var res = {};
let types = Object.keys(ActionTypes);
for (let i = 0; i < types.length; ++i) {
if (actionId.type === ActionTypes[types[i]]) {
res.type = types[i];
break;
}
}
if (res.type == null) {res.type = "Idle";}
res.name = actionId.name != null ? actionId.name : "Idle";
return res;
}
Bladeburner.prototype.getContractNamesNetscriptFn = function() {
return Object.keys(this.contracts);
}
@ -3424,9 +3442,7 @@ Bladeburner.prototype.getSkillLevelNetscriptFn = function(skillName, workerScrip
skillName + ". Note that the name of the skill is case-sensitive";
if (skillName === "") {
//If skill name isn't specified, return an object with all of the player's skill levels
let copy = Object.assign({}, this.Skills);
return copy;
return -1;
}
if (!Skills.hasOwnProperty(skillName)) {

@ -64,8 +64,7 @@ let CONSTANTS = {
ScriptGetServerRamCost: 0.1,
ScriptFileExistsRamCost: 0.1,
ScriptIsRunningRamCost: 0.1,
ScriptPurchaseHacknetRamCost: 1.5,
ScriptHacknetNodesRamCost: 4.0, //Base cost for accessing hacknet nodes array
ScriptHacknetNodesRamCost: 4.0, //Base cost for accessing Hacknet Node API
ScriptHNUpgLevelRamCost: 0.4,
ScriptHNUpgRamRamCost: 0.6,
ScriptHNUpgCoreRamCost: 0.8,
@ -488,8 +487,10 @@ let CONSTANTS = {
LatestUpdate:
"v0.40.0<br>" +
"* Added getCurrentAction() to Bladeburner API<br>" +
"* getSkillLevel() in Bladeburner API now returns an error if no argument is passed in (as opposed to an object with all skill levels). This may break scripts<br>" +
"* Minimum Netscript execution time reduced from 15ms to 10ms (configurable in Options)<br>" +
"* HP is now reset (restored) when Augmenting<br>" +
"* HP is now reset (restored) when Augmenting<br>" +
"* Bug Fix: Infiltration buttons can no longer be clicked through NetscriptJS<br>"
}

@ -63,7 +63,6 @@ function HacknetNode(name) {
this.moneyGainRatePerSecond = 0;
}
HacknetNode.prototype.updateMoneyGainRate = function() {
//How much extra $/s is gained per level
var gainPerLevel = CONSTANTS.HacknetNodeMoneyGainPerLevel;
@ -98,11 +97,6 @@ HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
return CONSTANTS.BaseCostForHacknetNode / 2 * totalMultiplier * Player.hacknet_node_level_cost_mult;
}
//Wrapper function for Netscript
HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
return this.calculateLevelUpgradeCost(levels);
}
HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
levels = Math.round(levels);
var cost = this.calculateLevelUpgradeCost(levels);
@ -110,6 +104,13 @@ HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
return false;
}
//If we're at max level, return false
if (this.level >= CONSTANTS.HacknetNodeMaxLevel) {
return false;
}
//If the number of specified upgrades would exceed the max level, calculate
//the maximum number of upgrades and use that
if (this.level + levels > CONSTANTS.HacknetNodeMaxLevel) {
var diff = Math.max(0, CONSTANTS.HacknetNodeMaxLevel - this.level);
return this.purchaseLevelUpgrade(diff);
@ -120,96 +121,114 @@ HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
}
Player.loseMoney(cost);
this.level += levels;
this.level = Math.round(this.level + levels); //Just in case of floating point imprecision
this.updateMoneyGainRate();
return true;
}
//Wrapper function for Netscript
HacknetNode.prototype.upgradeLevel = function(levels=1) {
let res = this.purchaseLevelUpgrade(levels);
createPlayerHacknetNodeWrappers();
return res;
HacknetNode.prototype.calculateRamUpgradeCost = function(levels=1) {
levels = Math.round(levels);
if (isNaN(levels) || levels < 1) {
return 0;
}
let totalCost = 0;
let numUpgrades = Math.round(Math.log2(this.ram));
let currentRam = this.ram;
for (let i = 0; i < levels; ++i) {
let baseCost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHacknetNode;
let mult = Math.pow(CONSTANTS.HacknetNodeUpgradeRamMult, numUpgrades);
totalCost += (baseCost * mult);
currentRam *= 2;
++numUpgrades;
}
totalCost *= Player.hacknet_node_ram_cost_mult
return totalCost;
}
HacknetNode.prototype.calculateRamUpgradeCost = function() {
var numUpgrades = Math.log2(this.ram);
//Calculate cost
//Base cost of RAM is 50k per 1GB, increased by some multiplier for each time RAM is upgraded
var baseCost = this.ram * CONSTANTS.BaseCostFor1GBOfRamHacknetNode;
var mult = Math.pow(CONSTANTS.HacknetNodeUpgradeRamMult, numUpgrades);
return baseCost * mult * Player.hacknet_node_ram_cost_mult;
}
//Wrapper function for Netscript
HacknetNode.prototype.getRamUpgradeCost = function() {
return this.calculateRamUpgradeCost();
}
HacknetNode.prototype.purchaseRamUpgrade = function() {
var cost = this.calculateRamUpgradeCost();
if (isNaN(cost)) {
return false;
}
if (Player.money.lt(cost)) {
HacknetNode.prototype.purchaseRamUpgrade = function(levels=1) {
levels = Math.round(levels);
var cost = this.calculateRamUpgradeCost(levels);
if (isNaN(cost) || levels < 0) {
return false;
}
//Fail if we're already at max
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {
return false;
}
Player.loseMoney(cost);
this.ram *= 2; //Ram is always doubled
this.updateMoneyGainRate();
return true;
}
//Wrapper function for Netscript
HacknetNode.prototype.upgradeRam = function() {
let res = this.purchaseRamUpgrade();
createPlayerHacknetNodeWrappers();
return res;
}
HacknetNode.prototype.calculateCoreUpgradeCost = function() {
var coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore;
var mult = CONSTANTS.HacknetNodeUpgradeCoreMult;
return coreBaseCost * Math.pow(mult, this.cores - 1) * Player.hacknet_node_core_cost_mult;
}
//Wrapper function for Netscript
HacknetNode.prototype.getCoreUpgradeCost = function() {
let res = this.calculateCoreUpgradeCost();
createPlayerHacknetNodeWrappers();
return res;
}
HacknetNode.prototype.purchaseCoreUpgrade = function() {
var cost = this.calculateCoreUpgradeCost();
if (isNaN(cost)) {
return false;
//If the number of specified upgrades would exceed the max RAM, calculate the
//max possible number of upgrades and use that
if (this.ram * Math.pow(2, levels) > CONSTANTS.HacknetNodeMaxRam) {
var diff = Math.max(0, Math.log2(Math.round(CONSTANTS.HacknetNodeMaxRam / this.ram)));
return this.purchaseRamUpgrade(diff);
}
if (Player.money.lt(cost)) {
return false;
}
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {
return false;
}
Player.loseMoney(cost);
++this.cores;
for (let i = 0; i < levels; ++i) {
this.ram *= 2; //Ram is always doubled
}
this.ram = Math.round(this.ram); //Handle any floating point precision issues
this.updateMoneyGainRate();
return true;
}
//Wrapper function for Netscript
HacknetNode.prototype.upgradeCore = function() {
return this.purchaseCoreUpgrade();
HacknetNode.prototype.calculateCoreUpgradeCost = function(levels=1) {
levels = Math.round(levels);
if (isNaN(levels) || levels < 1) {
return 0;
}
const coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore;
const mult = CONSTANTS.HacknetNodeUpgradeCoreMult;
let totalCost = 0;
let currentCores = this.cores;
for (let i = 0; i < levels; ++i) {
totalCost += (coreBaseCost * Math.pow(mult, currentCores-1));
++currentCores;
}
totalCost *= Player.hacknet_node_core_cost_mult;
return totalCost;
}
HacknetNode.prototype.purchaseCoreUpgrade = function(levels=1) {
levels = Math.round(levels);
var cost = this.calculateCoreUpgradeCost(levels);
if (isNaN(cost) || levels < 0) {
return false;
}
//Fail if we're already at max
if (this.cores >= CONSTANTS.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 (this.cores + levels > CONSTANTS.HacknetNodeMaxCores) {
var diff = Math.max(0, CONSTANTS.HacknetNodeMaxCores - this.cores);
return this.purchaseCoreUpgrade(diff);
}
if (Player.money.lt(cost)) {
return false;
}
Player.loseMoney(cost);
this.cores = Math.round(this.cores + levels); //Just in case of floating point imprecision
this.updateMoneyGainRate();
return true;
}
/* Saving and loading HackNets */
@ -223,37 +242,6 @@ HacknetNode.fromJSON = function(value) {
Reviver.constructors.HacknetNode = HacknetNode;
var HacknetNodeWrapper = function(hacknetNodeObj) {
var _node = hacknetNodeObj;
return {
name : _node.name,
level : _node.level,
ram : _node.ram,
cores : _node.cores,
totalMoneyGenerated : _node.totalMoneyGenerated,
onlineTimeSeconds : _node.onlineTimeSeconds,
moneyGainRatePerSecond : _node.moneyGainRatePerSecond,
upgradeLevel : function(n) {
return _node.upgradeLevel(n);
},
upgradeRam : function() {
return _node.upgradeRam();
},
upgradeCore : function() {
return _node.upgradeCore();
},
getLevelUpgradeCost : function(n) {
return _node.getLevelUpgradeCost(n);
},
getRamUpgradeCost : function() {
return _node.getRamUpgradeCost();
},
getCoreUpgradeCost : function() {
return _node.getCoreUpgradeCost();
}
}
}
function purchaseHacknet() {
/* INTERACTIVE TUTORIAL */
if (iTutorialIsRunning) {
@ -288,7 +276,6 @@ function purchaseHacknet() {
if (Engine.currentPage === Engine.Page.HacknetNodes) {
displayHacknetNodesContent();
}
createPlayerHacknetNodeWrappers();
updateTotalHacknetProduction();
return numOwned;
}
@ -335,8 +322,7 @@ function updateHacknetNodesMultiplierButtons() {
}
}
//Calculate the maximum number of times the Player can afford to upgrade
//a Hacknet Node's level"
//Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node
function getMaxNumberLevelUpgrades(nodeObj) {
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {
return 0;
@ -363,6 +349,56 @@ function getMaxNumberLevelUpgrades(nodeObj) {
return Math.min(levelsToMax, curr);
}
}
return 0;
}
function getMaxNumberRamUpgrades(nodeObj) {
if (Player.money.lt(nodeObj.calculateRamUpgradeCost(1))) {
return 0;
}
const levelsToMax = Math.round(Math.log2(CONSTANTS.HacknetNodeMaxRam / nodeObj.ram));
if (Player.money.gt(nodeObj.calculateRamUpgradeCost(levelsToMax))) {
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))) {
return i;
}
}
return 0;
}
function getMaxNumberCoreUpgrades(nodeObj) {
if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(1))) {
return 0;
}
var min = 1;
var max = CONSTANTS.HacknetNodeMaxCores - 1;
const levelsToMax = CONSTANTS.HacknetNodeMaxCores - nodeObj.cores;
if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(levelsToMax))) {
return levelsToMax;
}
//Use a binary search to find the max possible number of upgrades
while (min <= max) {
let curr = (min + max) / 2 | 0;
if (curr != CONSTANTS.HacknetNodeMaxCores &&
Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr)) &&
Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr + 1))) {
return Math.min(levelsToMax, curr);
} else if (Player.money.lt(nodeObj.calculateCoreUpgradeCost(curr))) {
max = curr - 1;
} else if (Player.money.gt(nodeObj.calculateCoreUpgradeCost(curr))) {
min = curr + 1;
} else {
return Math.min(levelsToMax, curr);
}
}
return 0;
}
//Creates Hacknet Node DOM elements when the page is opened
@ -440,7 +476,7 @@ function createHacknetNodeDomElement(nodeObj) {
innerHTML: "<div class=\"hacknet-node-name-container row\">" +
"<p>Node name:</p>" +
"<span class=\"text\" id=\"hacknet-node-name-" + nodeName + "\"></span>" +
"</div>" +
"</div>" +
"<div class=\"hacknet-node-production-container row\">" +
"<p>Production:</p>" +
"<span class=\"text\" id=\"hacknet-node-total-production-" + nodeName + "\"></span>" +
@ -461,7 +497,7 @@ function createHacknetNodeDomElement(nodeObj) {
id: "hacknet-node-upgrade-level-" + nodeName,
class: "a-link-button-inactive",
clickListener: function() {
var numUpgrades = hacknetNodePurchaseMultiplier;
let numUpgrades = hacknetNodePurchaseMultiplier;
if (hacknetNodePurchaseMultiplier == 0) {
numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
}
@ -475,7 +511,11 @@ function createHacknetNodeDomElement(nodeObj) {
id: "hacknet-node-upgrade-ram-" + nodeName,
class: "a-link-button-inactive",
clickListener: function() {
nodeObj.purchaseRamUpgrade();
let numUpgrades = hacknetNodePurchaseMultiplier;
if (hacknetNodePurchaseMultiplier == 0) {
numUpgrades = getMaxNumberRamUpgrades(nodeObj);
}
nodeObj.purchaseRamUpgrade(numUpgrades);
updateHacknetNodesContent();
return false;
}
@ -485,7 +525,11 @@ function createHacknetNodeDomElement(nodeObj) {
id: "hacknet-node-upgrade-core-" + nodeName,
class: "a-link-button-inactive",
clickListener: function() {
nodeObj.purchaseCoreUpgrade();
let numUpgrades = hacknetNodePurchaseMultiplier;
if (hacknetNodePurchaseMultiplier == 0) {
numUpgrades = getMaxNumberCoreUpgrades(nodeObj);
}
nodeObj.purchaseCoreUpgrade(numUpgrades);
updateHacknetNodesContent();
return false;
}
@ -515,7 +559,7 @@ function updateHacknetNodeDomElement(nodeObj) {
updateText("hacknet-node-upgrade-level-" + nodeName, "MAX LEVEL");
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
} else {
var multiplier = 0;
let multiplier = 0;
if (hacknetNodePurchaseMultiplier == 0) {
//Max
multiplier = getMaxNumberLevelUpgrades(nodeObj);
@ -540,8 +584,16 @@ function updateHacknetNodeDomElement(nodeObj) {
updateText("hacknet-node-upgrade-ram-" + nodeName, "MAX RAM");
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
} else {
var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
updateText("hacknet-node-upgrade-ram-" + nodeName, "Upgrade - $" + formatNumber(upgradeRamCost, 2));
let multiplier = 0;
if (hacknetNodePurchaseMultiplier == 0) {
multiplier = getMaxNumberRamUpgrades(nodeObj);
} else {
var levelsToMax = Math.round(Math.log2(CONSTANTS.HacknetNodeMaxRam / nodeObj.ram));
multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier);
}
var upgradeRamCost = nodeObj.calculateRamUpgradeCost(multiplier);
updateText("hacknet-node-upgrade-ram-" + nodeName, "Upgrade x" + multiplier + " - $" + formatNumber(upgradeRamCost, 2));
if (Player.money.lt(upgradeRamCost)) {
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
} else {
@ -556,8 +608,15 @@ function updateHacknetNodeDomElement(nodeObj) {
updateText("hacknet-node-upgrade-core-" + nodeName, "MAX CORES");
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
} else {
var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost();
updateText("hacknet-node-upgrade-core-" + nodeName, "Upgrade - $" + formatNumber(upgradeCoreCost, 2));
let multiplier = 0;
if (hacknetNodePurchaseMultiplier == 0) {
multiplier = getMaxNumberCoreUpgrades(nodeObj);
} else {
var levelsToMax = CONSTANTS.HacknetNodeMaxCores - nodeObj.cores;
multiplier = Math.min(levelsToMax, hacknetNodePurchaseMultiplier);
}
var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost(multiplier);
updateText("hacknet-node-upgrade-core-" + nodeName, "Upgrade x" + multiplier + " - $" + formatNumber(upgradeCoreCost, 2));
if (Player.money.lt(upgradeCoreCost)) {
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
} else {
@ -566,35 +625,9 @@ function updateHacknetNodeDomElement(nodeObj) {
}
}
function createPlayerHacknetNodeWrappers() {
Player.hacknetNodeWrappers.length = Player.hacknetNodes.length;
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
Player.hacknetNodeWrappers[i] = new HacknetNodeWrapper(Player.hacknetNodes[i]);
}
}
function updatePlayerHacknetNodeWrappers() {
if (Player.hacknetNodeWrappers.length !== Player.hacknetNodes.length) {
return createPlayerHacknetNodeWrappers();
}
for (var i = 0; i < Player.hacknetNodeWrappers.length; ++i) {
if (!(Player.hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {
return createPlayerHacknetNodeWrappers();
}
Player.hacknetNodeWrappers[i].level = Player.hacknetNodes[i].level;
Player.hacknetNodeWrappers[i].ram = Player.hacknetNodes[i].ram;
Player.hacknetNodeWrappers[i].cores = Player.hacknetNodes[i].cores;
Player.hacknetNodeWrappers[i].totalMoneyGenerated = Player.hacknetNodes[i].totalMoneyGenerated;
Player.hacknetNodeWrappers[i].onlineTimeSeconds = Player.hacknetNodes[i].onlineTimeSeconds;
Player.hacknetNodeWrappers[i].moneyGainRatePerSecond = Player.hacknetNodes[i].moneyGainRatePerSecond;
}
}
function processAllHacknetNodeEarnings(numCycles) {
var total = 0;
updatePlayerHacknetNodeWrappers();
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]);
}
@ -629,7 +662,6 @@ function getHacknetNode(name) {
export {
HacknetNode,
createPlayerHacknetNodeWrappers,
displayHacknetNodesContent,
getCostOfNextHacknetNode,
getHacknetNode,

@ -166,9 +166,64 @@ function NetscriptFunctions(workerScript) {
}
};
//Utility function to get Hacknet Node object
var getHacknetNode = function(i) {
if (isNaN(i)) {
throw makeRuntimeRejectMsg(workerScript, "Invalid index specified for Hacknet Node: " + i);
}
if (i < 0 || i >= Player.hacknetNodes.length) {
throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i);
}
return Player.hacknetNodes[i];
}
return {
hacknetnodes : function() {
return Player.hacknetNodeWrappers;
hacknet : {
numNodes : function() {
return Player.hacknetNodes.length;
},
purchaseNode : function() {
return purchaseHacknet();
},
getPurchaseNodeCost : function() {
return getCostOfNextHacknetNode();
},
getNodeStats : function(i) {
var node = getHacknetNode(i);
return {
name: node.name,
level: node.level,
ram: node.ram,
cores: node.cores,
production: node.moneyGainRatePerSecond,
timeOnline: node.onlineTimeSeconds,
totalProduction: node.totalMoneyGenerated,
};
},
upgradeLevel : function(i, n) {
var node = getHacknetNode(i);
return node.purchaseLevelUpgrade(n);
},
upgradeRam : function(i, n) {
var node = getHacknetNode(i);
return node.purchaseRamUpgrade(n);
},
upgradeCore : function(i, n) {
var node = getHacknetNode(i);
return node.purchaseCoreUpgrade(n);
},
getLevelUpgradeCost : function(i, n) {
var node = getHacknetNode(i);
return node.calculateLevelUpgradeCost(n);
},
getRamUpgradeCost : function(i, n) {
var node = getHacknetNode(i);
return node.calculateRamUpgradeCost(n);
},
getCoreUpgradeCost : function(i, n) {
var node = getHacknetNode(i);
return node.calculateCoreUpgradeCost(n);
}
},
sprintf : sprintf,
vsprintf: vsprintf,
@ -1273,21 +1328,6 @@ function NetscriptFunctions(workerScript) {
}
return (findRunningScript(filename, argsForTargetScript, server) != null);
},
getNextHacknetNodeCost : function() {
if (workerScript.checkingRam) {
return updateStaticRam("getNextHacknetNodeCost", CONSTANTS.ScriptPurchaseHacknetRamCost);
}
updateDynamicRam("getNextHacknetNodeCost", CONSTANTS.ScriptPurchaseHacknetRamCost);
return getCostOfNextHacknetNode();
},
purchaseHacknetNode : function() {
if (workerScript.checkingRam) {
return updateStaticRam("purchaseHacknetNode", CONSTANTS.ScriptPurchaseHacknetRamCost);
}
updateDynamicRam("purchaseHacknetNode", CONSTANTS.ScriptPurchaseHacknetRamCost);
return purchaseHacknet();
},
getStockPrice : function(symbol) {
if (workerScript.checkingRam) {
return updateStaticRam("getStockPrice", CONSTANTS.ScriptGetStockRamCost);
@ -3259,9 +3299,9 @@ function NetscriptFunctions(workerScript) {
if (workerScript.checkingRam) {
return updateStaticRam("getCurrentAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 4);
}
updateDynamicRam("getCurrentAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 2);
updateDynamicRam("getCurrentAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 4);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.resetAction();
return Player.bladeburner.getTypeAndNameFromActionId(Player.bladeburner.action);
}
throw makeRuntimeRejectMsg(workerScript, "getCurrentAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");

@ -99,7 +99,6 @@ function PlayerObject() {
this.currentServer = ""; //IP address of Server currently being accessed through terminal
this.purchasedServers = []; //IP Addresses of purchased servers
this.hacknetNodes = [];
this.hacknetNodeWrappers = [];
this.totalHacknetNodeProduction = 0;
//Factions

@ -8,8 +8,7 @@ import {loadFactions, Factions,
processPassiveFactionRepGain} from "./Faction";
import {FconfSettings, loadFconf} from "./Fconf";
import {loadAllGangs, AllGangs} from "./Gang";
import {processAllHacknetNodeEarnings,
createPlayerHacknetNodeWrappers} from "./HacknetNode";
import {processAllHacknetNodeEarnings} from "./HacknetNode";
import {loadMessages, initMessages, Messages} from "./Message";
import {Player, loadPlayer} from "./Player";
import {loadAllRunningScripts} from "./Script";
@ -230,8 +229,6 @@ function loadGame(saveString) {
}
}
//Re-initialize Hacknet Node Wrappers
createPlayerHacknetNodeWrappers();
return true;
}
@ -448,9 +445,6 @@ function loadImportedGame(saveObj, saveString) {
}
}
//Re-initialize Hacknet Node Wrappers
createPlayerHacknetNodeWrappers();
var popupId = "import-game-restart-game-notice";
var txt = createElement("p", {
innerText:"Imported game! I would suggest saving the game and then reloading the page " +

@ -211,12 +211,25 @@ function scriptEditorInit() {
if (prefix.length === 0) {callback(null, []); return;}
var words = [];
var fns = NetscriptFunctions(null);
for (var name in fns) {
for (let name in fns) {
if (fns.hasOwnProperty(name)) {
words.push({
name: name,
value: name,
});
name: name,
value: name,
});
//Get functions from namespaces
if (name === "bladeburner" || name === "hacknet") {
let namespace = fns[name];
if (typeof namespace !== "object") {continue;}
let namespaceFns = Object.keys(namespace);
for (let i = 0; i < namespaceFns.length; ++i) {
words.push({
name: namespaceFns[i],
value: namespaceFns[i],
});
}
}
}
}
callback(null, words);
@ -465,11 +478,11 @@ function parseOnlyRamCalculate(server, code, workerScript) {
}
// Check if this is one of the special keys, and add the appropriate ram cost if so.
if (ref == specialReferenceIF) ram += CONSTANTS.ScriptIfRamCost;
if (ref == specialReferenceFOR) ram += CONSTANTS.ScriptForRamCost;
if (ref == specialReferenceWHILE) ram += CONSTANTS.ScriptWhileRamCost;
if (ref == "hacknetnodes") ram += CONSTANTS.ScriptHacknetNodesRamCost;
if (ref == "document" || ref == "window") ram += CONSTANTS.ScriptDomRamCost;
if (ref == specialReferenceIF) ram += CONSTANTS.ScriptIfRamCost;
if (ref == specialReferenceFOR) ram += CONSTANTS.ScriptForRamCost;
if (ref == specialReferenceWHILE) ram += CONSTANTS.ScriptWhileRamCost;
if (ref == "hacknet") ram += CONSTANTS.ScriptHacknetNodesRamCost;
if (ref == "document" || ref == "window") ram += CONSTANTS.ScriptDomRamCost;
// Check if this ident is a function in the workerscript env. If it is, then we need to
// get its RAM cost. We do this by calling it, which works because the running script
@ -739,7 +752,7 @@ function calculateRamUsage(codeCopy) {
}
//Special case: hacknetnodes array
if (codeCopy.includes("hacknetnodes")) {
if (codeCopy.includes("hacknet")) {
ramUsage += CONSTANTS.ScriptHacknetNodesRamCost;
}
return ramUsage;