diff --git a/src/ActiveScriptsUI.js b/src/ActiveScriptsUI.js index 12903448b..12c70eb36 100644 --- a/src/ActiveScriptsUI.js +++ b/src/ActiveScriptsUI.js @@ -190,8 +190,7 @@ function createActiveScriptsText(workerscript, item) { var itemText = document.createElement("p"); //Server ip/hostname - var hostname = workerscript.getServer().hostname; - var serverIpHostname = "Server: " + hostname + "(" + workerscript.serverIp + ")"; + var serverIpHostname = "Threads: " + workerscript.scriptRef.threads; //Online var onlineTotalMoneyMade = "Total online production: $" + formatNumber(workerscript.scriptRef.onlineMoneyMade, 2); diff --git a/src/Augmentations.js b/src/Augmentations.js index e30a2c256..439db1d07 100644 --- a/src/Augmentations.js +++ b/src/Augmentations.js @@ -1476,7 +1476,6 @@ applyAugmentation = function(aug, reapply=false) { Player.defense_mult *= 1.8; break; case AugmentationNames.CombatRib1: - //Str and Defense 5% Player.strength_mult *= 1.15; Player.defense_mult *= 1.15; break; diff --git a/src/NetscriptEvaluator.js b/src/NetscriptEvaluator.js index 3a5429585..9d56b71e2 100644 --- a/src/NetscriptEvaluator.js +++ b/src/NetscriptEvaluator.js @@ -6,6 +6,8 @@ //wait for that promise to finish before continuing function evaluate(exp, workerScript) { return new Promise(function(resolve, reject) { + var threads = workerScript.scriptRef.threads; + if (isNaN(threads) || threads < 1) {threads = 1;} var env = workerScript.env; if (env.stopFlag) {return reject(workerScript);} if (exp == null) { @@ -48,7 +50,6 @@ function evaluate(exp, workerScript) { //Do array stuff here var iPromise = evaluate(exp.index.value, workerScript); iPromise.then(function(i) { - console.log("Index resolved with value: " + i); if (i >= res.length || i < 0) { return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator")); } else { diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 8af360425..4e186bd83 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -43,6 +43,8 @@ function netscriptBinary(exp, workerScript) { function netscriptHack(exp, workerScript) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} + var threads = workerScript.scriptRef.threads; + if (isNaN(threads) || threads < 1) {threads = 1;} if (exp.args.length != 1) { return Promise.reject(makeRuntimeRejectMsg(workerScript, "Hack() call has incorrect number of arguments. Takes 1 argument")); @@ -69,19 +71,19 @@ function netscriptHack(exp, workerScript) { return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because player's hacking skill is not high enough to hack " + server.hostname)); } - workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds"); + workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds (t=" + threads + ")"); return Promise.resolve([server, hackingTime]); }).then(function([server, hackingTime]) { - console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds."); + console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds (t=" + threads + ")"); return netscriptDelay(hackingTime* 1000).then(function() { if (env.stopFlag) {return Promise.reject(workerScript);} var hackChance = scriptCalculateHackingChance(server); var rand = Math.random(); - var expGainedOnSuccess = scriptCalculateExpGain(server); + var expGainedOnSuccess = scriptCalculateExpGain(server) * threads; var expGainedOnFailure = (expGainedOnSuccess / 4); if (rand < hackChance) { //Success! var moneyGained = scriptCalculatePercentMoneyHacked(server); - moneyGained = Math.floor(server.moneyAvailable * moneyGained); + moneyGained = Math.floor(server.moneyAvailable * moneyGained) * threads; //Safety check if (moneyGained <= 0) {moneyGained = 0;} @@ -89,21 +91,19 @@ function netscriptHack(exp, workerScript) { server.moneyAvailable -= moneyGained; Player.gainMoney(moneyGained); workerScript.scriptRef.onlineMoneyMade += moneyGained; - workerScript.scriptRef.recordHack(server.ip, moneyGained); - + workerScript.scriptRef.recordHack(server.ip, moneyGained, threads); Player.gainHackingExp(expGainedOnSuccess); workerScript.scriptRef.onlineExpGained += expGainedOnSuccess; console.log("Script successfully hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp"); - workerScript.scriptRef.log("Script SUCCESSFULLY hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp"); - server.fortify(CONSTANTS.ServerFortifyAmount); + workerScript.scriptRef.log("Script SUCCESSFULLY hacked " + server.hostname + " for $" + formatNumber(moneyGained, 2) + " and " + formatNumber(expGainedOnSuccess, 4) + " exp (t=" + threads + ")"); + server.fortify(CONSTANTS.ServerFortifyAmount * threads); return Promise.resolve(true); } else { //Player only gains 25% exp for failure? TODO Can change this later to balance Player.gainHackingExp(expGainedOnFailure); workerScript.scriptRef.onlineExpGained += expGainedOnFailure; - console.log("Script unsuccessful to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp"); - workerScript.scriptRef.log("Script FAILED to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp"); + workerScript.scriptRef.log("Script FAILED to hack " + server.hostname + ". Gained " + formatNumber(expGainedOnFailure, 4) + " exp (t=" + threads + ")"); return Promise.resolve(false); } }); @@ -117,6 +117,8 @@ function netscriptHack(exp, workerScript) { function netscriptGrow(exp, workerScript) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} + var threads = workerScript.scriptRef.threads; + if (isNaN(threads) || threads < 1) {threads = 1;} if (exp.args.length != 1) { return Promise.reject(makeRuntimeRejectMsg(workerScript, "grow() call has incorrect number of arguments. Takes 1 argument")); } @@ -137,20 +139,20 @@ function netscriptGrow(exp, workerScript) { var growTime = scriptCalculateGrowTime(server); console.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds") - workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds"); + workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds (t=" + threads + ")"); return Promise.resolve([server, growTime]); }).then(function([server, growTime]) { if (env.stopFlag) {return Promise.reject(workerScript);} return netscriptDelay(growTime).then(function() { if (env.stopFlag) {return Promise.reject(workerScript);} - server.moneyAvailable += 1; //It can be grown even if it has no money - var growthPercentage = processSingleServerGrowth(server, 450); - workerScript.scriptRef.recordGrow(server.ip); - var expGain = 0.5 * Player.hacking_exp_mult; + server.moneyAvailable += (1 * threads); //It can be grown even if it has no money + var growthPercentage = processSingleServerGrowth(server, 450 * threads); + workerScript.scriptRef.recordGrow(server.ip, threads); + var expGain = 0.5 * Player.hacking_exp_mult * threads; workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " + formatNumber(growthPercentage*100 - 100, 6) + "%. Gained " + - formatNumber(expGain, 4) + " hacking exp"); + formatNumber(expGain, 4) + " hacking exp (t=" + threads +")"); workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); return Promise.resolve(growthPercentage); @@ -165,6 +167,8 @@ function netscriptGrow(exp, workerScript) { function netscriptWeaken(exp, workerScript) { var env = workerScript.env; if (env.stopFlag) {return Promise.reject(workerScript);} + var threads = workerScript.scriptRef.threads; + if (isNaN(threads) || threads < 1) {threads = 1;} if (exp.args.length != 1) { return Promise.reject(makeRuntimeRejectMsg(workerScript, "weaken() call has incorrect number of arguments. Takes 1 argument")); } @@ -185,21 +189,22 @@ function netscriptWeaken(exp, workerScript) { var weakenTime = scriptCalculateWeakenTime(server); console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds") - workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds"); + workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " + + formatNumber(weakenTime/1000, 3) + " seconds (t=" + threads + ")"); return Promise.resolve([server, weakenTime]); }).then(function([server, weakenTime]) { if (env.stopFlag) {return Promise.reject(workerScript);} return netscriptDelay(weakenTime).then(function() { if (env.stopFlag) {return Promise.reject(workerScript);} - server.weaken(CONSTANTS.ServerWeakenAmount); - workerScript.scriptRef.recordWeaken(server.ip); - var expGain = 3 * Player.hacking_exp_mult; + server.weaken(CONSTANTS.ServerWeakenAmount * threads); + workerScript.scriptRef.recordWeaken(server.ip, threads); + var expGain = 3 * Player.hacking_exp_mult * threads; workerScript.scriptRef.log("Server security level on " + server.hostname + " weakened to " + server.hackDifficulty + - ". Gained " + formatNumber(expGain, 4) + " hacking exp"); + ". Gained " + formatNumber(expGain, 4) + " hacking exp (t=" + threads + ")"); workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); - return Promise.resolve(CONSTANTS.ServerWeakenAmount); + return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads); }); }).then(function(res) { return Promise.resolve(res); diff --git a/src/NetscriptWorker.js b/src/NetscriptWorker.js index 540c0cb3e..64a57dccb 100644 --- a/src/NetscriptWorker.js +++ b/src/NetscriptWorker.js @@ -165,14 +165,15 @@ function addWorkerScript(script, server) { var filename = script.filename; //Update server's ram usage - server.ramUsed += script.ramUsage; + var ramUsage = script.ramUsage * script.threads * Math.pow(1.02, script.threads-1); + server.ramUsed += ramUsage; //Create the WorkerScript var s = new WorkerScript(script); s.name = filename; s.code = script.code; s.serverIp = server.ip; - s.ramUsage = script.ramUsage; + s.ramUsage = ramUsage; //Add the WorkerScript to the Active Scripts list addActiveScriptsItem(s); diff --git a/src/Script.js b/src/Script.js index e25905e99..7c6c439e1 100644 --- a/src/Script.js +++ b/src/Script.js @@ -126,6 +126,8 @@ function Script() { this.numTimesHackMap = new AllServersMap(); this.numTimesGrowMap = new AllServersMap(); this.numTimesWeakenMap = new AllServersMap(); + + this.threads = 1; }; //Get the script data from the Script Editor and save it to the object @@ -291,7 +293,7 @@ Script.prototype.displayLog = function() { } //Update the moneyStolen and numTimesHack maps when hacking -Script.prototype.recordHack = function(serverIp, moneyGained) { +Script.prototype.recordHack = function(serverIp, moneyGained, n=1) { if (this.moneyStolenMap == null) { this.moneyStolenMap = new AllServersMap(); } @@ -299,23 +301,23 @@ Script.prototype.recordHack = function(serverIp, moneyGained) { this.numTimesHackMap = new AllServersMap(); } this.moneyStolenMap[serverIp] += moneyGained; - this.numTimesHackMap[serverIp] += 1; + this.numTimesHackMap[serverIp] += n; } //Update the grow map when calling grow() -Script.prototype.recordGrow = function(serverIp) { +Script.prototype.recordGrow = function(serverIp, n=1) { if (this.numTimesGrowMap == null) { this.numTimesGrowMap = new AllServersMap(); } - this.numTimesGrowMap[serverIp] += 1; + this.numTimesGrowMap[serverIp] += n; } //Update the weaken map when calling weaken() { -Script.prototype.recordWeaken = function(serverIp) { +Script.prototype.recordWeaken = function(serverIp, n=1) { if (this.numTimesWeakenMap == null) { this.numTimesWeakenMap = new AllServersMap(); } - this.numTimesWeakenMap[serverIp] += 1; + this.numTimesWeakenMap[serverIp] += n; } Script.prototype.toJSON = function() { diff --git a/src/Server.js b/src/Server.js index 5cc514a75..72ff91cd7 100644 --- a/src/Server.js +++ b/src/Server.js @@ -464,8 +464,8 @@ initForeignServers = function() { AddToAllServers(HongFangTeaHouseServer); var HaraKiriSushiBarServer = new Server(); - HaraKiriSushiBarServer.setHackingParameters(40, 3500000, 15, 40); HaraKiriSushiBarServer.init(createRandomIp(), "harakiri-sushi", "HaraKiri Sushi Bar Network", true, false, false, false, 4); + HaraKiriSushiBarServer.setHackingParameters(40, 3500000, 15, 40); HaraKiriSushiBarServer.setPortProperties(0); AddToAllServers(HaraKiriSushiBarServer); @@ -527,7 +527,7 @@ initForeignServers = function() { SpecialServerIps.addIp(SpecialServerNames.BitRunnersServer, BitRunnersServer.ip); var TheBlackHandServer = new Server(); - TheBlackHandServer.init(createRandomIp(), "I.I.I.I", "I.I.I.I", true, false, false, false, false, 0); + TheBlackHandServer.init(createRandomIp(), "I.I.I.I", "I.I.I.I", true, false, false, false, 0); TheBlackHandServer.setHackingParameters(getRandomInt(303, 325), 0, 0, 0); TheBlackHandServer.setPortProperties(3); AddToAllServers(TheBlackHandServer); diff --git a/src/Terminal.js b/src/Terminal.js index e9367f6cd..73d92ee38 100644 --- a/src/Terminal.js +++ b/src/Terminal.js @@ -733,10 +733,28 @@ var Terminal = { post("Incorrect usage of mem command. usage: mem [scriptname]"); return; } var scriptName = commandArray[1]; + var numThreads = 1; + if (scriptName.indexOf(" -t ") != -1) { + var results = scriptName.split(" "); + if (results.length != 3) { + post("Invalid use of run command. Usage: mem [script] [-t] [number threads]"); + return; + } + numThreads = Math.round(Number(results[2])); + if (isNaN(numThreads) || numThreads < 1) { + post("Invalid number of threads specified. Number of threads must be greater than 1"); + return; + } + scriptName = results[0]; + } + var currServ = Player.getCurrentServer(); for (var i = 0; i < currServ.scripts.length; ++i) { if (scriptName == currServ.scripts[i].filename) { - post("This script requires " + formatNumber(currServ.scripts[i].ramUsage, 2) + "GB of RAM to run"); + var scriptBaseRamUsage = currServ.scripts[i].ramUsage; + var ramUsage = scriptBaseRamUsage * numThreads * Math.pow(1.02, numThreads-1); + + post("This script requires " + formatNumber(ramUsage, 2) + "GB of RAM to run for " + numThreads + " thread(s)"); return; } } @@ -1143,23 +1161,41 @@ var Terminal = { } } + var numThreads = 1; + //Get the number of threads + if (scriptName.indexOf(" -t ") != -1) { + var results = scriptName.split(" "); + if (results.length != 3) { + post("Invalid use of run command. Usage: run [script] [-t] [number threads]"); + return; + } + numThreads = Math.round(Number(results[2])); + if (isNaN(numThreads) || numThreads < 1) { + post("Invalid number of threads specified. Number of threads must be greater than 0"); + return; + } + scriptName = results[0]; + } + //Check if the script exists and if it does run it for (var i = 0; i < server.scripts.length; i++) { if (server.scripts[i].filename == scriptName) { //Check for admin rights and that there is enough RAM availble to run - var ramUsage = server.scripts[i].ramUsage; + var script = server.scripts[i]; + script.threads = numThreads; + var ramUsage = script.ramUsage * numThreads * Math.pow(1.02, numThreads-1); var ramAvailable = server.maxRam - server.ramUsed; if (server.hasAdminRights == false) { post("Need root access to run script"); return; } else if (ramUsage > ramAvailable){ - post("This machine does not have enough RAM to run this script. Script requires " + ramUsage + "GB of RAM"); + post("This machine does not have enough RAM to run this script with " + + script.threads + " threads. Script requires " + ramUsage + "GB of RAM"); return; }else { //Able to run script - post("Running script. May take a few seconds to start up the process..."); - var script = server.scripts[i]; + post("Running script with " + script.threads + " thread(s). May take a few seconds to start up the process..."); server.runningScripts.push(script.filename); //Push onto runningScripts addWorkerScript(script, server); return;