diff --git a/css/menupages.css b/css/menupages.css
index 92c9c96aa..b1e5c50af 100644
--- a/css/menupages.css
+++ b/css/menupages.css
@@ -29,9 +29,15 @@
}
#script-editor-filename-tag {
+ padding-top: 10px;
+ padding-bottom: 0px;
float: left;
}
+#script-editor-save-and-close-button {
+ float: right;
+ display: inline-block;
+}
#script-editor-filename {
float: left;
diff --git a/css/popupboxes.css b/css/popupboxes.css
index 0c10a2d50..03413a89a 100644
--- a/css/popupboxes.css
+++ b/css/popupboxes.css
@@ -66,7 +66,7 @@
#purchase-server-box-content {
background-color: black;
margin: 15% auto; /* 15% from the top and centered */
- padding: 1px;
+ padding: 12px;
border: 5px solid #FFFFFF;
width: 80%; /* Could be more or less, depending on screen size */
color: #66ff33;
@@ -121,7 +121,7 @@
#purchase-ram-for-home-box-content {
background-color: black;
margin: 15% auto; /* 15% from the top and centered */
- padding: 1px;
+ padding: 12px;
border: 5px solid #FFFFFF;
width: 80%; /* Could be more or less, depending on screen size */
color: #66ff33;
@@ -231,6 +231,7 @@
#faction-invitation-box-warning {
margin: 4px;
+ padding: 4px;
}
#faction-invitation-box-yes,
diff --git a/index.html b/index.html
index 07b05a8c6..20f7cebb3 100644
--- a/index.html
+++ b/index.html
@@ -23,6 +23,7 @@
+
@@ -128,10 +129,10 @@
-
+
Script name:
-
-
+ Save & Close (Ctrl + b)
+
@@ -585,7 +586,7 @@
Purchasing an Augmentation lets you start over with the perks and benefits granted by all
of the Augmentations you have ever purchased (purchasing an Augmentation does not reset the benefits
of Augmentations you have previously purchased).
-
+
Purchase Cancel
diff --git a/src/Company.js b/src/Company.js
index 2d6a3c202..ca22f3996 100644
--- a/src/Company.js
+++ b/src/Company.js
@@ -204,45 +204,45 @@ CompanyPositions = {
//Software
SoftwareIntern: new CompanyPosition("Software Engineering Intern", 1, 0, 0, 0, 0, 0, 0, 1.2),
- JuniorDev: new CompanyPosition("Junior Software Engineer", 50, 0, 0, 0, 0, 0, 9000, 6),
- SeniorDev: new CompanyPosition("Senior Software Engineer", 250, 0, 0, 0, 0, 50, 36000, 15),
- LeadDev: new CompanyPosition("Lead Software Developer", 400, 0, 0, 0, 0, 150, 144000, 20),
+ JuniorDev: new CompanyPosition("Junior Software Engineer", 51, 0, 0, 0, 0, 0, 9000, 6),
+ SeniorDev: new CompanyPosition("Senior Software Engineer", 251, 0, 0, 0, 0, 51, 36000, 15),
+ LeadDev: new CompanyPosition("Lead Software Developer", 401, 0, 0, 0, 0, 151, 144000, 20),
//IT
ITIntern: new CompanyPosition("IT Intern", 1, 0, 0, 0, 0, 0, 0, 1),
- ITAnalyst: new CompanyPosition("IT Analyst", 25, 0, 0, 0, 0, 0, 9000, 4),
- ITManager: new CompanyPosition("IT Manager", 150, 0, 0, 0, 0, 50, 36000, 14),
- SysAdmin: new CompanyPosition("Systems Administrator", 250, 0, 0, 0, 0, 75, 144000, 14),
- SecurityEngineer: new CompanyPosition("Security Engineer", 150, 0, 0, 0, 0, 25, 36000, 12),
- NetworkEngineer: new CompanyPosition("Network Engineer", 150, 0, 0, 0, 0, 25, 36000, 12),
- NetworkAdministrator: new CompanyPosition("Network Administrator", 250, 0, 0, 0, 0, 75, 144000, 15),
+ ITAnalyst: new CompanyPosition("IT Analyst", 26, 0, 0, 0, 0, 0, 9000, 4),
+ ITManager: new CompanyPosition("IT Manager", 151, 0, 0, 0, 0, 51, 36000, 14),
+ SysAdmin: new CompanyPosition("Systems Administrator", 251, 0, 0, 0, 0, 76, 144000, 14),
+ SecurityEngineer: new CompanyPosition("Security Engineer", 151, 0, 0, 0, 0, 26, 36000, 12),
+ NetworkEngineer: new CompanyPosition("Network Engineer", 151, 0, 0, 0, 0, 26, 36000, 12),
+ NetworkAdministrator: new CompanyPosition("Network Administrator", 251, 0, 0, 0, 0, 76, 144000, 15),
//Technology management
- HeadOfSoftware: new CompanyPosition("Head of Software", 500, 0, 0, 0, 0, 250, 288000, 35),
- HeadOfEngineering: new CompanyPosition("Head of Engineering", 500, 0, 0, 0, 0, 250, 576000, 40),
- VicePresident: new CompanyPosition("Vice President of Technology", 600, 0, 0, 0, 0, 400, 1152000, 45),
- CTO: new CompanyPosition("Chief Technology Officer", 750, 0, 0, 0, 0, 500, 4608000, 50),
+ HeadOfSoftware: new CompanyPosition("Head of Software", 501, 0, 0, 0, 0, 251, 288000, 35),
+ HeadOfEngineering: new CompanyPosition("Head of Engineering", 501, 0, 0, 0, 0, 251, 576000, 40),
+ VicePresident: new CompanyPosition("Vice President of Technology", 601, 0, 0, 0, 0, 401, 1152000, 45),
+ CTO: new CompanyPosition("Chief Technology Officer", 751, 0, 0, 0, 0, 501, 4608000, 50),
//Business
BusinessIntern: new CompanyPosition("Business Intern", 1, 0, 0, 0, 0, 1, 0, 1.2),
- BusinessAnalyst: new CompanyPosition("Business Analyst", 5, 0, 0, 0, 0, 50, 9000, 10),
- BusinessManager: new CompanyPosition("Business Manager", 50, 0, 0, 0, 0, 100, 36000, 18),
- OperationsManager: new CompanyPosition("Operations Manager", 50, 0, 0, 0, 0, 200, 144000, 22),
- CFO: new CompanyPosition("Chief Financial Officer", 75, 0, 0, 0, 0, 500, 576000, 50),
- CEO: new CompanyPosition("Chief Executive Officer", 100, 0, 0, 0, 0, 750, 4608000, 100),
+ BusinessAnalyst: new CompanyPosition("Business Analyst", 6, 0, 0, 0, 0, 51, 9000, 10),
+ BusinessManager: new CompanyPosition("Business Manager", 51, 0, 0, 0, 0, 101, 36000, 18),
+ OperationsManager: new CompanyPosition("Operations Manager", 51, 0, 0, 0, 0, 201, 144000, 22),
+ CFO: new CompanyPosition("Chief Financial Officer", 76, 0, 0, 0, 0, 501, 576000, 50),
+ CEO: new CompanyPosition("Chief Executive Officer", 101, 0, 0, 0, 0, 751, 4608000, 100),
//Non-tech/management jobs
Waiter: new CompanyPosition("Waiter", 0, 0, 0, 0, 0, 0, 0, .75),
Employee: new CompanyPosition("Employee", 0, 0, 0, 0, 0, 0, 0, .75),
- PoliceOfficer: new CompanyPosition("Police Officer", 10, 100, 100, 100, 100, 9000, 5),
- PoliceChief: new CompanyPosition("Police Chief", 100, 300, 300, 300, 300, 36000, 12),
- SecurityGuard: new CompanyPosition("Security Guard", 0, 50, 50, 50, 50, 0, 4),
- SecurityOfficer: new CompanyPosition("Security Officer", 25, 150, 150, 150, 150, 9000, 8),
- SecuritySupervisor: new CompanyPosition("Security Supervisor", 25, 250, 250, 250, 250, 36000, 15),
- HeadOfSecurity: new CompanyPosition("Head of Security", 50, 500, 500, 500, 500, 144000, 22),
- FieldAgent: new CompanyPosition("Field Agent", 100, 100, 100, 100, 100, 9000, 6),
- SecretAgent: new CompanyPosition("Secret Agent", 200, 250, 250, 250, 250, 36000, 15),
- SpecialOperative: new CompanyPosition("Special Operative", 250, 500, 500, 500, 500, 144000, 25),
+ PoliceOfficer: new CompanyPosition("Police Officer", 11, 101, 101, 101, 101, 51, 9000, 5),
+ PoliceChief: new CompanyPosition("Police Chief", 101, 301, 301, 301, 301, 151, 36000, 12),
+ SecurityGuard: new CompanyPosition("Security Guard", 0, 51, 51, 51, 51, 1, 0, 4),
+ SecurityOfficer: new CompanyPosition("Security Officer", 26, 151, 151, 151, 151, 51, 9000, 8),
+ SecuritySupervisor: new CompanyPosition("Security Supervisor", 26, 251, 251, 251, 251, 101, 36000, 15),
+ HeadOfSecurity: new CompanyPosition("Head of Security", 51, 501, 501, 501, 501, 151, 144000, 22),
+ FieldAgent: new CompanyPosition("Field Agent", 101, 101, 101, 101, 101, 101, 9000, 6),
+ SecretAgent: new CompanyPosition("Secret Agent", 201, 251, 251, 251, 251, 36000, 15),
+ SpecialOperative: new CompanyPosition("Special Operative", 251, 501, 501, 501, 501, 144000, 25),
init: function() {
//Argument order: hack, str, def, dex, agi, cha
diff --git a/src/HacknetNode.js b/src/HacknetNode.js
index 046ebf2cc..106a1144a 100644
--- a/src/HacknetNode.js
+++ b/src/HacknetNode.js
@@ -28,11 +28,12 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
HacknetNode.prototype.calculateLevelUpgradeCost = function() {
//Upgrade cost = Base cost * multiplier ^ level
var mult = CONSTANTS.HacknetNodeUpgradeLevelMult;
- return CONSTANTS.BaseCostForHacknetNode * Math.pow(mult, this.level);
+ return CONSTANTS.BaseCostForHacknetNode * Math.pow(mult, this.level) * Player.hacknet_node_level_cost_mult;
}
HacknetNode.prototype.purchaseLevelUpgrade = function() {
var cost = this.calculateLevelUpgradeCost();
+ if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
if (cost > Player.money) {return;}
Player.loseMoney(cost);
++this.level;
@@ -47,11 +48,12 @@ HacknetNode.prototype.calculateRamUpgradeCost = function() {
//the RAM has been upgraded
var cost = this.ram * CONSTANTS.BaseCostFor1GBOfRam;
var mult = Math.pow(CONSTANTS.HacknetNodeUpgradeRamMult, numUpgrades);
- return cost * mult;
+ return cost * mult * Player.hacknet_node_ram_cost_mult;
}
HacknetNode.prototype.purchaseRamUpgrade = function() {
var cost = this.calculateRamUpgradeCost();
+ if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
if (cost > Player.money) {return;}
Player.loseMoney(cost);
this.ram *= 2; //Ram is always doubled
@@ -61,11 +63,12 @@ HacknetNode.prototype.purchaseRamUpgrade = function() {
HacknetNode.prototype.calculateCoreUpgradeCost = function() {
var coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore;
var mult = CONSTANTS.HacknetNodeUpgradeCoreMult;
- return coreBaseCost * Math.pow(mult, this.numCores-1);
+ return coreBaseCost * Math.pow(mult, this.numCores-1) * Player.hacknet_node_core_cost_mult;
}
HacknetNode.prototype.purchaseCoreUpgrade = function() {
var cost = this.calculateCoreUpgradeCost();
+ if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
if (cost > Player.money) {return;}
Player.loseMoney(cost);
++this.numCores;
@@ -84,9 +87,9 @@ HacknetNode.fromJSON = function(value) {
Reviver.constructors.HacknetNode = HacknetNode;
-
purchaseHacknet = function() {
var cost = getCostOfNextHacknetNode();
+ if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
if (cost > Player.money) {
dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
return;
@@ -108,7 +111,7 @@ getCostOfNextHacknetNode = function() {
//Cost increases exponentially based on how many you own
var numOwned = Player.hacknetNodes.length;
var mult = CONSTANTS.HacknetNodePurchaseNextMult;
- return CONSTANTS.BaseCostForHacknetNode * Math.pow(mult, numOwned);
+ return CONSTANTS.BaseCostForHacknetNode * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
}
//Creates Hacknet Node DOM elements when the page is opened
diff --git a/src/Netscript/Evaluator.js b/src/Netscript/Evaluator.js
index 45e146016..f6280e81e 100644
--- a/src/Netscript/Evaluator.js
+++ b/src/Netscript/Evaluator.js
@@ -355,6 +355,7 @@ function evaluate(exp, workerScript) {
return;
}
+ workerScript.scriptRef.log("Calling grow() on server " + server.hostname + " in 120 seconds");
var p = new Promise(function(resolve, reject) {
if (env.stopFlag) {reject(workerScript);}
console.log("Executing grow on " + server.hostname + " in 2 minutes ");
@@ -366,7 +367,7 @@ function evaluate(exp, workerScript) {
p.then(function(growthPercentage) {
resolve("hackExecuted");
- workerScript.scriptRef.log("Using grow(), the money available on " + server.hostname + " was grown by " + growthPercentage + "%");
+ workerScript.scriptRef.log("Using grow(), the money available on " + server.hostname + " was grown by " + (growthPercentage*100 - 100).toFixed(6) + "%");
}, function(e) {
reject(e);
});
@@ -482,7 +483,6 @@ function evaluateWhile(exp, workerScript) {
setTimeout(function() {
var evaluatePromise = evaluate(exp.code, workerScript);
evaluatePromise.then(function(resCode) {
- console.log("Evaluated an iteration of while loop code");
resolve(resCode);
}, function(e) {
reject(e);
@@ -502,7 +502,6 @@ function evaluateWhile(exp, workerScript) {
reject(e);
});
} else {
- console.log("Cond is false, stopping while loop");
resolve("endWhileLoop"); //Doesn't need to resolve to any particular value
}
}, function(e) {
@@ -603,7 +602,7 @@ function scriptCalculateHackingChance(server) {
//The same as Player's calculateHackingTime() function but takes in the server as an argument
function scriptCalculateHackingTime(server) {
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
- var skillFactor = (2 * difficultyMult + 1000) / (Player.hacking_skill + 50);
+ var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50);
var hackingTime = skillFactor * Player.hacking_speed_mult; //This is in seconds
return hackingTime;
}
diff --git a/src/Player.js b/src/Player.js
index eda1a33d1..9348a66a5 100644
--- a/src/Player.js
+++ b/src/Player.js
@@ -198,12 +198,12 @@ PlayerObject.prototype.calculateHackingChance = function() {
//Calculate the time it takes to hack a server in seconds. Returns the time
//The formula is:
-// (requiredLevel * difficulty + 500)
+// (2.5 * requiredLevel * difficulty + 200)
// ----------------------------------- * hacking_speed_multiplier
// hacking_skill + 100
PlayerObject.prototype.calculateHackingTime = function() {
var difficultyMult = this.getCurrentServer().requiredHackingSkill * this.getCurrentServer().hackDifficulty;
- var skillFactor = (2 * difficultyMult + 300) / (this.hacking_skill + 100);
+ var skillFactor = (2.5 * difficultyMult + 200) / (this.hacking_skill + 100);
return skillFactor * this.hacking_speed_mult;
}
diff --git a/src/Script.js b/src/Script.js
index 17c02314a..97759bec7 100644
--- a/src/Script.js
+++ b/src/Script.js
@@ -2,46 +2,68 @@
* Script object
*/
-//Define key commands in script editor (ctrl x to close, etc.)
+//Initialize the 'save and close' button on script editor page
+function scriptEditorSaveCloseInit() {
+ var closeButton = document.getElementById("script-editor-save-and-close-button");
+
+ closeButton.addEventListener("click", function() {
+ saveAndCloseScriptEditor();
+ return false;
+ });
+};
+
+document.addEventListener("DOMContentLoaded", scriptEditorSaveCloseInit, false);
+
+//Define key commands in script editor (ctrl o to save + close, etc.)
$(document).keydown(function(e) {
if (Engine.currentPage == Engine.Page.ScriptEditor) {
//Ctrl + x
- if (e.keyCode == 88 && e.ctrlKey) {
- var filename = document.getElementById("script-editor-filename").value;
-
- if (checkValidFilename(filename) == false) {
- postScriptEditorStatus("Script filename can contain only alphanumerics, hyphens, and underscores");
- return;
- }
-
- filename += ".script";
-
- //If the current script matches one thats currently running, throw an error
- for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) {
- if (filename == Player.getCurrentServer().runningScripts[i].filename) {
- postScriptEditorStatus("Cannot write to script that is currently running!");
- return;
- }
- }
-
- //If the current script already exists on the server, overwrite it
- for (var i = 0; i < Player.getCurrentServer().scripts.length; i++) {
- if (filename == Player.getCurrentServer().scripts[i].filename) {
- Player.getCurrentServer().scripts[i].saveScript();
- Engine.loadTerminalContent();
- return;
- }
- }
-
- //If the current script does NOT exist, create a new one
- var script = new Script();
- script.saveScript();
- Player.getCurrentServer().scripts.push(script);
- Engine.loadTerminalContent();
+ if (e.keyCode == 66 && e.ctrlKey) {
+ saveAndCloseScriptEditor();
}
}
});
+function saveAndCloseScriptEditor() {
+ var filename = document.getElementById("script-editor-filename").value;
+
+ if (filename == "") {
+ //If no filename...just close and do nothing
+ Engine.loadTerminalContent();
+ return;
+ }
+
+ if (checkValidFilename(filename) == false) {
+ dialogBoxCreate("Script filename can contain only alphanumerics, hyphens, and underscores");
+ return;
+ }
+
+ filename += ".script";
+
+ //If the current script matches one thats currently running, throw an error
+ for (var i = 0; i < Player.getCurrentServer().runningScripts.length; i++) {
+ if (filename == Player.getCurrentServer().runningScripts[i].filename) {
+ dialogBoxCreate("Cannot write to script that is currently running!");
+ return;
+ }
+ }
+
+ //If the current script already exists on the server, overwrite it
+ for (var i = 0; i < Player.getCurrentServer().scripts.length; i++) {
+ if (filename == Player.getCurrentServer().scripts[i].filename) {
+ Player.getCurrentServer().scripts[i].saveScript();
+ Engine.loadTerminalContent();
+ return;
+ }
+ }
+
+ //If the current script does NOT exist, create a new one
+ var script = new Script();
+ script.saveScript();
+ Player.getCurrentServer().scripts.push(script);
+ Engine.loadTerminalContent();
+}
+
//Checks that the string contains only valid characters for a filename, which are alphanumeric,
// underscores and hyphens
function checkValidFilename(filename) {
@@ -53,16 +75,6 @@ function checkValidFilename(filename) {
return false;
}
-var ScriptEditorLastStatus = null;
-function postScriptEditorStatus(text) {
- document.getElementById("script-editor-status").innerHTML = text;
-
- clearTimeout(ScriptEditorLastStatus);
- ScriptEditorLastStatus = setTimeout(function() {
- document.getElementById("script-editor-status").innerHTML = "";
- }, 3000);
-}
-
function Script() {
this.filename = "";
this.code = "";
diff --git a/src/Terminal.js b/src/Terminal.js
index da2cd2fcf..c11af8830 100644
--- a/src/Terminal.js
+++ b/src/Terminal.js
@@ -32,7 +32,6 @@ $(document).keydown(function(event) {
//Terminal
if (Engine.currentPage == Engine.Page.Terminal) {
var terminalInput = document.getElementById("terminal-input-text-box");
- if (terminalInput == null) {return;}
//Enter
if (event.keyCode == 13) {
@@ -55,6 +54,7 @@ $(document).keydown(function(event) {
//Up key to cycle through past commands
if (event.keyCode == 38) {
+ if (terminalInput == null) {return;}
var i = Terminal.commandHistoryIndex;
var len = Terminal.commandHistory.length;
@@ -73,6 +73,7 @@ $(document).keydown(function(event) {
//Down key
if (event.keyCode == 40) {
+ if (terminalInput == null) {return;}
var i = Terminal.commandHistoryIndex;
var len = Terminal.commandHistory.length;
@@ -94,13 +95,13 @@ $(document).keydown(function(event) {
//Tab (autocomplete)
if (event.keyCode == 9) {
+ if (terminalInput == null) {return;}
var input = terminalInput.value;
if (input == "") {return;}
input = input.trim();
input = input.replace(/\s\s+/g, ' ');
var allPos = determineAllPossibilitiesForTabCompletion(input);
- console.log("allPos: " + allPos);
if (allPos.length == 0) {return;}
var commandArray = input.split(" ");
@@ -131,7 +132,11 @@ $(document).keydown(function(e) {
} else if (terminalCtrlPressed == true) {
//Don't focus
} else {
- document.getElementById("terminal-input-text-box").focus();
+ var inputTextBox = document.getElementById("terminal-input-text-box");
+ if (inputTextBox != null) {
+ inputTextBox.focus();
+ }
+
terminalCtrlPressed = false;
}
}
@@ -201,7 +206,7 @@ function determineAllPossibilitiesForTabCompletion(input) {
}
if (input.startsWith("kill ") || input.startsWith("nano ") ||
- input.startsWith("tail ")) {
+ input.startsWith("tail ") || input.startsWith("rm ")) {
//All Scripts
for (var i = 0; i < currServ.scripts.length; ++i) {
allPos.push(currServ.scripts[i].filename);
diff --git a/utils/PurchaseRamForHomeBox.js b/utils/PurchaseRamForHomeBox.js
index f63f42374..da3e1ca0f 100644
--- a/utils/PurchaseRamForHomeBox.js
+++ b/utils/PurchaseRamForHomeBox.js
@@ -18,7 +18,7 @@ purchaseRamForHomeBoxClose = function() {
purchaseRamForHomeBoxOpen = function() {
var purchaseRamForHomeBox = document.getElementById("purchase-ram-for-home-box-container");
- purchaseRamForHomeBox.style.display = "none";
+ purchaseRamForHomeBox.style.display = "block";
}
purchaseRamForHomeBoxSetText = function(txt) {
@@ -44,6 +44,8 @@ purchaseRamForHomeBoxCreate = function() {
"This will upgrade your RAM from " + currentRam + "GB to " + newRam + "GB.
" +
"This will cost $" + cost);
+ purchaseRamForHomeBoxOpen();
+
//Clear old event listeners from Confirm button
var confirmButton = document.getElementById("purchase-ram-for-home-box-confirm");
var newConfirmButton = confirmButton.cloneNode(true);