mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-18 13:43:49 +01:00
Merge pull request #358 from danielyxie/new-hacknetnode-api
New hacknetnode api
This commit is contained in:
commit
44e4325a5d
8224
dist/engine.bundle.js
vendored
8224
dist/engine.bundle.js
vendored
File diff suppressed because it is too large
Load Diff
517
dist/vendor.bundle.js
vendored
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
|
||||
|
||||
|
11
netscript.js
11
netscript.js
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user