Merge pull request #273 from kopelli/hacknet-streamline

Shrunk the UI of Hacknet Nodes to view more at a time on screen.
This commit is contained in:
danielyxie 2018-06-06 11:12:58 -05:00 committed by GitHub
commit 7389db7295
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 264 additions and 140 deletions

@ -288,30 +288,44 @@
}
#hacknet-nodes-text,
#hacknet-nodes-money,
#hacknet-nodes-container li {
width: 70%;
margin: 10px;
padding: 10px;
}
#hacknet-nodes-purchase-button {
display: inline-block;
#hacknet-nodes-container li {
float: left;
overflow: hidden;
white-space: nowrap;
}
#hacknet-nodes-list {
list-style: none;
width: 82vw;
}
#hacknet-nodes-money {
margin: 10px;
float: left;
}
#hacknet-nodes-money-multipliers-div {
display: inline-block;
width: 70%;
width: 70vw;
}
#hacknet-nodes-multipliers {
float: right;
}
#hacknet-nodes-purchase-button {
display: inline-block;
}
.hacknet-node {
margin: 6px;
padding: 6px;
width: 85%;
width: 34vw;
border: 2px solid var(--my-highlight-color);
-webkit-box-shadow:
inset 0 0 8px rgba(0,0,0,0.1),
@ -324,12 +338,28 @@
0 0 16px rgba(0,0,0,0.1);
}
.hacknet-node-button-div a {
display: block;
.hacknet-node-container {
display: inline-table;
}
.hacknet-node-button-div:not(:last-child) {
border-bottom: none;
.hacknet-node-container .row {
display: table-row;
height: 30px;
}
.hacknet-node-container .row p {
display: table-cell;
}
.hacknet-node-container .upgradable-info {
display: inline-block;
margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */
padding: 0 4px;
width: 48px; /* Four times font-size */
}
.menu-page-text {
width: 70vw;
}
/* World */

@ -15,7 +15,10 @@ body {
background-color: var(--my-background-color);
}
p, pre, h2 {
p,
pre,
h2,
.text {
color: var(--my-font-color);
}

@ -185,7 +185,7 @@
<!-- Hacknet Nodes -->
<div id="hacknet-nodes-container" class="generic-menupage-container">
<h1 id="hacknet-nodes-title"> Hacknet Nodes </h1>
<p id="hacknet-nodes-text">
<p id="hacknet-nodes-text" class="menu-page-text">
The Hacknet is a global, decentralized network of machines. It is used by hackers all around
the world to anonymously share computing power and perform distributed cyberattacks without the
fear of being traced.
@ -199,8 +199,11 @@
</p>
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
<br>
<div id="hacknet-nodes-money-multipliers-div">"
<p id="hacknet-nodes-money"> </p>
<div id="hacknet-nodes-money-multipliers-div">
<p id="hacknet-nodes-money">
<span>Money:</span><span id="hacknet-nodes-player-money" ></span><br />
<span>Total Hacknet Node Prodution:</span><span id="hacknet-nodes-total-production"></span>
</p>
<span id="hacknet-nodes-multipliers">
<a id="hacknet-nodes-1x-multiplier" class="a-link-button-inactive"> x1 </a>
<a id="hacknet-nodes-5x-multiplier" class="a-link-button"> x5 </a>
@ -208,7 +211,7 @@
<a id="hacknet-nodes-max-multiplier" class="a-link-button"> MAX </a>
</span>
</div>
<ul id="hacknet-nodes-list" style="list-style : none;">
<ul id="hacknet-nodes-list">
</ul>
</div>

@ -5,42 +5,48 @@ import {iTutorialSteps, iTutorialNextStep,
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
import {Player} from "./Player.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {clearEventListeners, createElement,
getElementById} from "../utils/HelperFunctions.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
/**
* Overwrites the inner text of the specified HTML element if it is different from what currently exists.
* @param {string} elementId The HTML ID to find the first instance of.
* @param {string} text The inner text that should be set.
*/
function updateText(elementId, text) {
var el = getElementById(elementId);
if (el.innerText != text) {
el.innerText = text;
}
};
/* HacknetNode.js */
function hacknetNodesInit() {
var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
mult1x.addEventListener("click", function() {
hacknetNodePurchaseMultiplier = 1;
updateHacknetNodesMultiplierButtons();
updateHacknetNodesContent();
return false;
});
var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
mult5x.addEventListener("click", function() {
hacknetNodePurchaseMultiplier = 5;
updateHacknetNodesMultiplierButtons();
updateHacknetNodesContent();
return false;
});
var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
mult10x.addEventListener("click", function() {
hacknetNodePurchaseMultiplier = 10;
updateHacknetNodesMultiplierButtons();
updateHacknetNodesContent();
return false;
});
var multMax = document.getElementById("hacknet-nodes-max-multiplier");
multMax.addEventListener("click", function() {
hacknetNodePurchaseMultiplier = 0;
updateHacknetNodesMultiplierButtons();
updateHacknetNodesContent();
return false;
});
var performMapping = function(x) {
getElementById("hacknet-nodes-" + x.id + "-multiplier")
.addEventListener("click", function() {
hacknetNodePurchaseMultiplier = x.multiplier;
updateHacknetNodesMultiplierButtons();
updateHacknetNodesContent();
return false;
});
};
var mappings = [
{ id: "1x", multiplier: 1 },
{ id: "5x", multiplier: 5 },
{ id: "10x", multiplier: 10 },
{ id: "max", multiplier: 0 }
];
for (var elem of mappings) {
// Encapsulate in a function so that the appropriate scope is kept in the click handler.
performMapping(elem);
}
}
document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
function HacknetNode(name) {
@ -76,7 +82,10 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
levels = Math.round(levels);
if (isNaN(levels) || levels < 1) {return 0;}
if (isNaN(levels) || levels < 1) {
return 0;
}
var mult = CONSTANTS.HacknetNodeUpgradeLevelMult;
var totalMultiplier = 0; //Summed
var currLevel = this.level;
@ -84,6 +93,7 @@ HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
totalMultiplier += Math.pow(mult, currLevel);
++currLevel;
}
return CONSTANTS.BaseCostForHacknetNode / 2 * totalMultiplier * Player.hacknet_node_level_cost_mult;
}
@ -95,12 +105,19 @@ HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
levels = Math.round(levels);
var cost = this.calculateLevelUpgradeCost(levels);
if (isNaN(cost) || levels < 0) {return false;}
if (isNaN(cost) || levels < 0) {
return false;
}
if (this.level + levels > CONSTANTS.HacknetNodeMaxLevel) {
var diff = Math.max(0, CONSTANTS.HacknetNodeMaxLevel - this.level);
return this.purchaseLevelUpgrade(diff);
}
if (Player.money.lt(cost)) {return false;}
if (Player.money.lt(cost)) {
return false;
}
Player.loseMoney(cost);
this.level += levels;
this.updateMoneyGainRate();
@ -129,9 +146,18 @@ HacknetNode.prototype.getRamUpgradeCost = function() {
HacknetNode.prototype.purchaseRamUpgrade = function() {
var cost = this.calculateRamUpgradeCost();
if (isNaN(cost)) {return false;}
if (Player.money.lt(cost)) {return false;}
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {return false;}
if (isNaN(cost)) {
return false;
}
if (Player.money.lt(cost)) {
return false;
}
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {
return false;
}
Player.loseMoney(cost);
this.ram *= 2; //Ram is always doubled
this.updateMoneyGainRate();
@ -146,7 +172,7 @@ HacknetNode.prototype.upgradeRam = function() {
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;
return coreBaseCost * Math.pow(mult, this.cores - 1) * Player.hacknet_node_core_cost_mult;
}
//Wrapper function for Netscript
@ -156,9 +182,18 @@ HacknetNode.prototype.getCoreUpgradeCost = function() {
HacknetNode.prototype.purchaseCoreUpgrade = function() {
var cost = this.calculateCoreUpgradeCost();
if (isNaN(cost)) {return false;}
if (Player.money.lt(cost)) {return false;}
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {return false;}
if (isNaN(cost)) {
return false;
}
if (Player.money.lt(cost)) {
return false;
}
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {
return false;
}
Player.loseMoney(cost);
++this.cores;
this.updateMoneyGainRate();
@ -225,7 +260,10 @@ function purchaseHacknet() {
/* END INTERACTIVE TUTORIAL */
var cost = getCostOfNextHacknetNode();
if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
if (isNaN(cost)) {
throw new Error("Cost is NaN");
}
if (Player.money.lt(cost)) {
//dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
return false;
@ -290,9 +328,12 @@ function updateHacknetNodesMultiplierButtons() {
//Calculate the maximum number of times the Player can afford to upgrade
//a Hacknet Node's level"
function getMaxNumberLevelUpgrades(nodeObj) {
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;}
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {
return 0;
}
var min = 1;
var max = CONSTANTS.HacknetNodeMaxLevel-1;
var max = CONSTANTS.HacknetNodeMaxLevel - 1;
var levelsToMax = CONSTANTS.HacknetNodeMaxLevel - nodeObj.level;
if (Player.money.gt(nodeObj.calculateLevelUpgradeCost(levelsToMax))) {
return levelsToMax;
@ -302,7 +343,7 @@ function getMaxNumberLevelUpgrades(nodeObj) {
var curr = (min + max) / 2 | 0;
if (curr != CONSTANTS.HacknetNodeMaxLevel &&
Player.money.gt(nodeObj.calculateLevelUpgradeCost(curr)) &&
Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr+1))) {
Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr + 1))) {
return Math.min(levelsToMax, curr);
} else if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(curr))) {
max = curr - 1;
@ -329,7 +370,7 @@ function displayHacknetNodesContent() {
//Remove all old hacknet Node DOM elements
var hacknetNodesList = document.getElementById("hacknet-nodes-list");
while (hacknetNodesList.firstChild) {
while (hacknetNodesList.firstChild) {
hacknetNodesList.removeChild(hacknetNodesList.firstChild);
}
@ -337,6 +378,7 @@ function displayHacknetNodesContent() {
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
createHacknetNodeDomElement(Player.hacknetNodes[i]);
}
updateHacknetNodesContent();
}
@ -344,8 +386,11 @@ function displayHacknetNodesContent() {
function updateHacknetNodesContent() {
//Set purchase button to inactive if not enough money, and update its price display
var cost = getCostOfNextHacknetNode();
var purchaseButton = document.getElementById("hacknet-nodes-purchase-button");
purchaseButton.innerHTML = "Purchase Hacknet Node - $" + formatNumber(cost, 2);
var purchaseButton = getElementById("hacknet-nodes-purchase-button");
var formattedCost = formatNumber(cost, 2);
updateText("hacknet-nodes-purchase-button", "Purchase Hacknet Node - $" + formattedCost);
if (Player.money.lt(cost)) {
purchaseButton.setAttribute("class", "a-link-button-inactive");
} else {
@ -353,9 +398,8 @@ function updateHacknetNodesContent() {
}
//Update player's money
var moneyElem = document.getElementById("hacknet-nodes-money");
moneyElem.innerHTML = "Money: $" + formatNumber(Player.money.toNumber(), 2) + "<br>" +
"Total production from all Hacknet Nodes: $" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second";
updateText("hacknet-nodes-player-money", "$" + formatNumber(Player.money.toNumber(), 2));
updateText("hacknet-nodes-total-production", "$" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second");
//Update information in each owned hacknet node
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
@ -367,61 +411,75 @@ function updateHacknetNodesContent() {
function createHacknetNodeDomElement(nodeObj) {
var nodeName = nodeObj.name;
var listItem = document.createElement("li");
listItem.setAttribute("class", "hacknet-node");
var nodeLevelContainer = createElement("div", {
class: "hacknet-node-level-container row",
innerHTML: "<p>Level:</p><span class=\"text upgradable-info\" id=\"hacknet-node-level-" + nodeName + "\"></span>"
});
var span = document.createElement("span");
span.style.display = "inline";
var nodeRamContainer = createElement("div", {
class: "hacknet-node-ram-container row",
innerHTML: "<p>RAM:</p><span class=\"text upgradable-info\" id=\"hacknet-node-ram-" + nodeName + "\"></span>"
});
var buttonDiv = document.createElement("div");
buttonDiv.setAttribute("class", "hacknet-node-button-div");
var nodeCoresContainer = createElement("div", {
class: "hacknet-node-cores-container row",
innerHTML: "<p>Cores:</p><span class=\"text upgradable-info\" id=\"hacknet-node-cores-" + nodeName + "\"><span>"
})
var containingDiv = createElement("div", {
class: "hacknet-node-container",
innerHTML: "<div class=\"hacknet-node-name-container row\">" +
"<p>Node name:</p>" +
"<span class=\"text\" id=\"hacknet-node-name-" + nodeName + "\"></span>" +
"</div>" +
"<div class=\"hacknet-node-production-container row\">" +
"<p>Production:</p>" +
"<span class=\"text\" id=\"hacknet-node-total-production-" + nodeName + "\"></span>" +
"<span class=\"text\" id=\"hacknet-node-production-rate-" + nodeName + "\"></span>" +
"</div>"
});
containingDiv.appendChild(nodeLevelContainer);
containingDiv.appendChild(nodeRamContainer);
containingDiv.appendChild(nodeCoresContainer);
//Text
var txt = document.createElement("p");
//txt.setAttribute("id", "hacknet-node-text-" + nodeName);
txt.id = "hacknet-node-text-" + nodeName;
var listItem = createElement("li", {
class: "hacknet-node"
});
listItem.appendChild(containingDiv);
//Upgrade buttons
var upgradeLevelButton = document.createElement("a");
var upgradeRamButton = document.createElement("a");
var upgradeCoreButton = document.createElement("a");
//upgradeLevelButton.setAttribute("id", "hacknet-node-upgrade-level-" + nodeName);
upgradeLevelButton.id = "hacknet-node-upgrade-level-" + nodeName;
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
upgradeLevelButton.addEventListener("click", function() {
var numUpgrades = hacknetNodePurchaseMultiplier;
if (hacknetNodePurchaseMultiplier == 0) {
numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
nodeLevelContainer.appendChild(createElement("a", {
id: "hacknet-node-upgrade-level-" + nodeName,
class: "a-link-button-inactive",
clickListener: function() {
var numUpgrades = hacknetNodePurchaseMultiplier;
if (hacknetNodePurchaseMultiplier == 0) {
numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
}
nodeObj.purchaseLevelUpgrade(numUpgrades);
updateHacknetNodesContent();
return false;
}
nodeObj.purchaseLevelUpgrade(numUpgrades);
updateHacknetNodesContent();
return false;
});
//upgradeRamButton.setAttribute("id", "hacknet-node-upgrade-ram-" + nodeName);
upgradeRamButton.id = "hacknet-node-upgrade-ram-" + nodeName;
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
upgradeRamButton.addEventListener("click", function() {
nodeObj.purchaseRamUpgrade();
updateHacknetNodesContent();
return false;
});
//upgradeCoreButton.setAttribute("id", "hacknet-node-upgrade-core-" + nodeName);
upgradeCoreButton.id = "hacknet-node-upgrade-core-" + nodeName;
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
upgradeCoreButton.addEventListener("click", function() {
nodeObj.purchaseCoreUpgrade();
updateHacknetNodesContent();
return false;
});
}));
//Put all the components together in the li element
span.appendChild(txt);
buttonDiv.appendChild(upgradeLevelButton);
buttonDiv.appendChild(upgradeRamButton);
buttonDiv.appendChild(upgradeCoreButton);
span.appendChild(buttonDiv);
listItem.appendChild(span);
nodeRamContainer.appendChild(createElement("a", {
id: "hacknet-node-upgrade-ram-" + nodeName,
class: "a-link-button-inactive",
clickListener: function() {
nodeObj.purchaseRamUpgrade();
updateHacknetNodesContent();
return false;
}
}));
nodeCoresContainer.appendChild(createElement("a", {
id: "hacknet-node-upgrade-core-" + nodeName,
class: "a-link-button-inactive",
clickListener: function() {
nodeObj.purchaseCoreUpgrade();
updateHacknetNodesContent();
return false;
}
}));
document.getElementById("hacknet-nodes-list").appendChild(listItem);
@ -432,20 +490,19 @@ function createHacknetNodeDomElement(nodeObj) {
//Updates information on a single hacknet node DOM element
function updateHacknetNodeDomElement(nodeObj) {
var nodeName = nodeObj.name;
var txt = document.getElementById("hacknet-node-text-" + nodeName);
if (txt == null) {throw new Error("Cannot find text element");}
txt.innerHTML = "Node name: " + nodeName + "<br>" +
"Production: $" + formatNumber(nodeObj.totalMoneyGenerated, 2) +
" ($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
"Level: " + nodeObj.level + "<br>" +
"RAM: " + nodeObj.ram + "GB<br>" +
"Cores: " + nodeObj.cores;
updateText("hacknet-node-name-" + nodeName, nodeName);
updateText("hacknet-node-total-production-" + nodeName, "$" + formatNumber(nodeObj.totalMoneyGenerated, 2));
updateText("hacknet-node-production-rate-" + nodeName, "($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second)");
updateText("hacknet-node-level-" + nodeName, nodeObj.level);
updateText("hacknet-node-ram-" + nodeName, nodeObj.ram + "GB");
updateText("hacknet-node-cores-" + nodeName, nodeObj.cores);
//Upgrade level
var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
if (upgradeLevelButton == null) {throw new Error("Cannot find upgrade level button element");}
var upgradeLevelButton = getElementById("hacknet-node-upgrade-level-" + nodeName);
if (nodeObj.level >= CONSTANTS.HacknetNodeMaxLevel) {
upgradeLevelButton.innerHTML = "MAX LEVEL";
updateText("hacknet-node-upgrade-level-" + nodeName, "MAX LEVEL");
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
} else {
var multiplier = 0;
@ -458,8 +515,7 @@ function updateHacknetNodeDomElement(nodeObj) {
}
var upgradeLevelCost = nodeObj.calculateLevelUpgradeCost(multiplier);
upgradeLevelButton.innerHTML = "Upgrade Hacknet Node Level x" + multiplier +
" - $" + formatNumber(upgradeLevelCost, 2);
updateText("hacknet-node-upgrade-level-" + nodeName, "Upgrade x" + multiplier + " - $" + formatNumber(upgradeLevelCost, 2))
if (Player.money.lt(upgradeLevelCost)) {
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
} else {
@ -468,14 +524,14 @@ function updateHacknetNodeDomElement(nodeObj) {
}
//Upgrade RAM
var upgradeRamButton = document.getElementById("hacknet-node-upgrade-ram-" + nodeName);
if (upgradeRamButton == null) {throw new Error("Cannot find upgrade ram button element");}
var upgradeRamButton = getElementById("hacknet-node-upgrade-ram-" + nodeName);
if (nodeObj.ram >= CONSTANTS.HacknetNodeMaxRam) {
upgradeRamButton.innerHTML = "MAX RAM";
updateText("hacknet-node-upgrade-ram-" + nodeName, "MAX RAM");
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
} else {
var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM - $" + formatNumber(upgradeRamCost, 2);
updateText("hacknet-node-upgrade-ram-" + nodeName, "Upgrade - $" + formatNumber(upgradeRamCost, 2));
if (Player.money.lt(upgradeRamCost)) {
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
} else {
@ -484,14 +540,14 @@ function updateHacknetNodeDomElement(nodeObj) {
}
//Upgrade Cores
var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");}
var upgradeCoreButton = getElementById("hacknet-node-upgrade-core-" + nodeName);
if (nodeObj.cores >= CONSTANTS.HacknetNodeMaxCores) {
upgradeCoreButton.innerHTML = "MAX CORES";
updateText("hacknet-node-upgrade-core-" + nodeName, "MAX CORES");
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
} else {
var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost();
upgradeCoreButton.innerHTML = "Purchase additional CPU Core - $" + formatNumber(upgradeCoreCost, 2);
updateText("hacknet-node-upgrade-core-" + nodeName, "Upgrade - $" + formatNumber(upgradeCoreCost, 2));
if (Player.money.lt(upgradeCoreCost)) {
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
} else {
@ -511,8 +567,12 @@ 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();}
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;
@ -528,6 +588,7 @@ function processAllHacknetNodeEarnings(numCycles) {
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]);
}
return total;
}
@ -535,9 +596,10 @@ function processSingleHacknetNodeEarnings(numCycles, nodeObj) {
var cyclesPerSecond = 1000 / Engine._idleSpeed;
var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond;
if (isNaN(earningPerCycle)) {
console.log("ERROR: Hacknet Node Calculated earnings is NaN");
console.error("Hacknet Node '" + nodeObj.name + "' Calculated earnings is NaN");
earningPerCycle = 0;
}
var totalEarnings = numCycles * earningPerCycle;
nodeObj.totalMoneyGenerated += totalEarnings;
nodeObj.onlineTimeSeconds += (numCycles * (Engine._idleSpeed / 1000));
@ -551,10 +613,21 @@ function getHacknetNode(name) {
return Player.hacknetNodes[i];
}
}
return null;
}
export {hacknetNodesInit, HacknetNode, purchaseHacknet, updateTotalHacknetProduction,
getCostOfNextHacknetNode, updateHacknetNodesMultiplierButtons, getMaxNumberLevelUpgrades,
displayHacknetNodesContent, updateHacknetNodesContent, processAllHacknetNodeEarnings,
getHacknetNode, createPlayerHacknetNodeWrappers};
export {
HacknetNode,
createPlayerHacknetNodeWrappers,
displayHacknetNodesContent,
getCostOfNextHacknetNode,
getHacknetNode,
getMaxNumberLevelUpgrades,
hacknetNodesInit,
processAllHacknetNodeEarnings,
purchaseHacknet,
updateHacknetNodesContent,
updateHacknetNodesMultiplierButtons,
updateTotalHacknetProduction
};

@ -74,6 +74,21 @@ function removeChildrenFromElement(el) {
}
}
/**
* Returns a reference to the first object with the specified value of the ID or NAME attribute, throwing an error if it is unable to find it.
* @param {string} elementId The HTML ID to retrieve the element by.
* @returns {HTMLElement} The single element.
* @throws {Error} When the 'idString' cannot be found.
*/
function getElementById(elementId) {
var el = document.getElementById(elementId);
if (el == null) {
throw new Error("Unable to find element with id '" + elementId + "'");
}
return el;
}
function createElement(type, params={}) {
var el = document.createElement(type);
if (params.id) {el.id = params.id;}
@ -260,4 +275,4 @@ export {sizeOfObject, clearObject, addOffset, clearEventListeners, getRandomInt,
removeElementById, removeElement, createElement, createAccordionElement,
appendLineBreaks,
removeChildrenFromElement, createPopup, clearSelector, exceptionAlert,
createProgressBarText};
createProgressBarText, getElementById};