diff --git a/doc/source/netscriptfunctions.rst b/doc/source/netscriptfunctions.rst index 2662d41dd..e7af06a6a 100644 --- a/doc/source/netscriptfunctions.rst +++ b/doc/source/netscriptfunctions.rst @@ -670,6 +670,21 @@ purchaseHacknetNode end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase a new Hacknet Node then the function will return false. +getPurchasedServerCost +^^^^^^^^^^^^^^^^^^^^^^ + +.. js:function:: getPurchasedServerCost(ram) + + :param number ram: Amount of RAM of a potential purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20) + + Returns the cost to purchase a server with the specified amount of *ram*. + + Examples:: + + for (i = 1; i <= 20; i++) { + tprint(i + " -- " + getPurchasedServerCost(Math.pow(2, i))); + } + purchaseServer ^^^^^^^^^^^^^^ diff --git a/netscript.js b/netscript.js index befc1cac6..e57f9eb04 100644 --- a/netscript.js +++ b/netscript.js @@ -72,6 +72,7 @@ let NetscriptFunctions = "serverExists|fileExists|isRunning|" + "deleteServer|getPurchasedServers|" + "getPurchasedServerLimit|getPurchasedServerMaxRam|" + + "getPurchasedServerCost|" + "purchaseServer|round|write|read|peek|clear|rm|getPortHandle|" + "scriptRunning|scriptKill|getScriptName|getScriptRam|" + "getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" + diff --git a/src/Constants.js b/src/Constants.js index 4c54f8045..2b31b504d 100644 --- a/src/Constants.js +++ b/src/Constants.js @@ -70,6 +70,7 @@ let CONSTANTS = { ScriptHNUpgCoreRamCost: 0.8, ScriptGetStockRamCost: 2.0, ScriptBuySellStockRamCost: 2.5, + ScriptGetPurchaseServerRamCost: 0.25, ScriptPurchaseServerRamCost: 2.25, ScriptGetPurchasedServerLimit: 0.05, ScriptGetPurchasedServerMaxRam: 0.05, diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 3022f942d..147802db9 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -178,7 +178,25 @@ function NetscriptFunctions(workerScript) { throw makeRuntimeRejectMsg(workerScript, "Index specified for Hacknet Node is out-of-bounds: " + i); } return Player.hacknetNodes[i]; - } + }; + + /** + * @param {number} ram The amount of server RAM to calculate cost of. + * @exception {Error} If the value passed in is not numeric, out of range, or too large of a value. + * @returns {number} The cost of + */ + const getPurchaseServerRamCostGuard = (ram) => { + const guardedRam = Math.round(ram); + if (isNaN(guardedRam) || !powerOfTwo(guardedRam)) { + throw Error("failed due to invalid ram argument. Must be numeric and a power of 2"); + } + + if (guardedRam > CONSTANTS.PurchasedServerMaxRam) { + throw Error("failed because specified RAM was too high. Maximum RAM on a purchased server is " + CONSTANTS.PurchasedServerMaxRam + "GB"); + } + + return guardedRam * CONSTANTS.BaseCostFor1GBOfRamServer; + }; return { hacknet : { @@ -1597,6 +1615,22 @@ function NetscriptFunctions(workerScript) { return CONSTANTS.PurchasedServerMaxRam; }, + getPurchasedServerCost: function(ram) { + if (workerScript.checkingRam) { + return updateStaticRam("getPurchasedServerCost", CONSTANTS.ScriptGetPurchaseServerRamCost); + } + updateDynamicRam("getPurchasedServerCost", CONSTANTS.ScriptGetPurchaseServerRamCost); + + let cost = 0; + try { + cost = getPurchaseServerRamCostGuard(ram); + } catch (e) { + workerScript.scriptRef.log("ERROR: 'getPurchasedServerCost()' " + e.message); + return ""; + } + + return cost; + }, purchaseServer : function(hostname, ram) { if (workerScript.checkingRam) { return updateStaticRam("purchaseServer", CONSTANTS.ScriptPurchaseServerRamCost); @@ -1615,18 +1649,14 @@ function NetscriptFunctions(workerScript) { return ""; } - ram = Math.round(ram); - if (isNaN(ram) || !isPowerOfTwo(ram)) { - workerScript.scriptRef.log("ERROR: purchaseServer() failed due to invalid ram argument. Must be numeric and a power of 2"); + let cost = 0; + try { + cost = getPurchaseServerRamCostGuard(ram); + } catch (e) { + workerScript.scriptRef.log("ERROR: 'purchaseServer()' " + e.message); return ""; } - if (ram > CONSTANTS.PurchasedServerMaxRam) { - workerScript.scriptRef.log("ERROR: purchasedServer() failed because specified RAM was too high. Maximum RAM on a purchased server is " + CONSTANTS.PurchasedServerMaxRam + "GB"); - return ""; - } - - var cost = ram * CONSTANTS.BaseCostFor1GBOfRamServer; if (Player.money.lt(cost)) { workerScript.scriptRef.log("ERROR: Not enough money to purchase server. Need $" + formatNumber(cost, 2)); return "";