From 2ce6ff2041e72bf8e37be331adc93137967ce65e Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 02:51:56 -0500 Subject: [PATCH 01/13] work to make documentation unified. --- .../getBitNodeMultipliers.rst | 21 ++- .../netscript/basicfunctions/brutessh.rst | 12 +- doc/source/netscript/basicfunctions/clear.rst | 11 +- .../netscript/basicfunctions/clearLog.rst | 11 +- .../netscript/basicfunctions/deleteServer.rst | 12 +- .../netscript/basicfunctions/disableLog.rst | 9 +- .../netscript/basicfunctions/enableLog.rst | 10 +- doc/source/netscript/basicfunctions/exec.rst | 42 ++--- doc/source/netscript/basicfunctions/exit.rst | 2 +- .../netscript/basicfunctions/fileExists.rst | 34 ++-- .../netscript/basicfunctions/ftpcrack.rst | 13 +- .../basicfunctions/getFavorToDonate.rst | 7 +- .../netscript/basicfunctions/getGrowTime.rst | 24 ++- .../netscript/basicfunctions/getHackTime.rst | 18 +- .../basicfunctions/getHackingLevel.rst | 7 +- .../basicfunctions/getHackingMultipliers.rst | 10 +- .../basicfunctions/getHacknetMultipliers.rst | 10 +- .../netscript/basicfunctions/getHostname.rst | 8 +- .../basicfunctions/getPortHandle.rst | 4 +- .../basicfunctions/getPurchasedServerCost.rst | 9 +- .../getPurchasedServerLimit.rst | 7 +- .../getPurchasedServerMaxRam.rst | 7 +- .../basicfunctions/getPurchasedServers.rst | 12 +- .../basicfunctions/getScriptExpGain.rst | 18 +- .../basicfunctions/getScriptIncome.rst | 19 ++- .../basicfunctions/getScriptLogs.rst | 28 +-- .../basicfunctions/getScriptName.rst | 7 +- .../netscript/basicfunctions/getScriptRam.rst | 15 +- .../getServerBaseSecurityLevel.rst | 28 ++- .../basicfunctions/getServerGrowth.rst | 19 ++- .../basicfunctions/getServerMaxMoney.rst | 11 +- .../getServerMinSecurityLevel.rst | 11 +- .../getServerMoneyAvailable.rst | 18 +- .../getServerNumPortsRequired.rst | 12 +- .../netscript/basicfunctions/getServerRam.rst | 12 +- .../getServerRequiredHackingLevel.rst | 11 +- .../basicfunctions/getServerSecurityLevel.rst | 12 +- .../basicfunctions/getTimeSinceLastAug.rst | 7 +- .../basicfunctions/getWeakenTime.rst | 17 +- doc/source/netscript/basicfunctions/grow.rst | 34 ++-- .../basicfunctions/growthAnalyze.rst | 25 ++- doc/source/netscript/basicfunctions/hack.rst | 28 +-- .../basicfunctions/hackAnalyzePercent.rst | 20 ++- .../basicfunctions/hackAnalyzeThreads.rst | 22 ++- .../netscript/basicfunctions/hackChance.rst | 15 +- .../basicfunctions/hasRootAccess.rst | 9 +- .../netscript/basicfunctions/httpworm.rst | 11 +- .../netscript/basicfunctions/isLogEnabled.rst | 12 +- .../netscript/basicfunctions/isRunning.rst | 41 +++-- doc/source/netscript/basicfunctions/kill.rst | 48 +++--- .../netscript/basicfunctions/killall.rst | 15 +- doc/source/netscript/basicfunctions/ls.rst | 14 +- .../netscript/basicfunctions/nFormat.rst | 22 +-- doc/source/netscript/basicfunctions/nuke.rst | 9 +- doc/source/netscript/basicfunctions/peek.rst | 8 +- doc/source/netscript/basicfunctions/print.rst | 8 +- .../netscript/basicfunctions/prompt.rst | 19 ++- doc/source/netscript/basicfunctions/ps.rst | 33 ++-- .../basicfunctions/purchaseServer.rst | 26 +-- doc/source/netscript/basicfunctions/read.rst | 21 ++- .../netscript/basicfunctions/relaysmtp.rst | 12 +- doc/source/netscript/basicfunctions/rm.rst | 12 +- doc/source/netscript/basicfunctions/run.rst | 48 +++--- doc/source/netscript/basicfunctions/scan.rst | 14 +- doc/source/netscript/basicfunctions/scp.rst | 34 ++-- .../netscript/basicfunctions/scriptKill.rst | 17 +- .../basicfunctions/scriptRunning.rst | 26 +-- .../netscript/basicfunctions/serverExists.rst | 11 +- doc/source/netscript/basicfunctions/sleep.rst | 9 +- doc/source/netscript/basicfunctions/spawn.rst | 22 ++- .../netscript/basicfunctions/sqlinject.rst | 11 +- doc/source/netscript/basicfunctions/tail.rst | 18 +- .../netscript/basicfunctions/tprint.rst | 10 +- .../netscript/basicfunctions/tryWrite.rst | 10 +- .../netscript/basicfunctions/weaken.rst | 27 +-- doc/source/netscript/basicfunctions/wget.rst | 14 +- doc/source/netscript/basicfunctions/write.rst | 27 +-- .../bladeburnerapi/getActionAutolevel.rst | 8 +- .../getActionCountRemaining.rst | 16 +- .../bladeburnerapi/getActionCurrentLevel.rst | 10 +- .../getActionEstimatedSuccessChance.rst | 10 +- .../bladeburnerapi/getActionMaxLevel.rst | 8 +- .../bladeburnerapi/getActionRepGain.rst | 14 +- .../bladeburnerapi/getActionTime.rst | 9 +- .../bladeburnerapi/getBlackOpNames.rst | 7 +- .../bladeburnerapi/getBlackOpRank.rst | 8 +- .../netscript/bladeburnerapi/getBonusTime.rst | 9 +- .../netscript/bladeburnerapi/getCity.rst | 7 +- .../netscript/bladeburnerapi/getCityChaos.rst | 8 +- .../getCityEstimatedCommunities.rst | 10 +- .../getCityEstimatedPopulation.rst | 10 +- .../bladeburnerapi/getContractNames.rst | 7 +- .../bladeburnerapi/getCurrentAction.rst | 11 +- .../bladeburnerapi/getGeneralActionNames.rst | 7 +- .../bladeburnerapi/getOperationNames.rst | 7 +- .../netscript/bladeburnerapi/getRank.rst | 7 +- .../bladeburnerapi/getSkillLevel.rst | 10 +- .../bladeburnerapi/getSkillNames.rst | 7 +- .../bladeburnerapi/getSkillPoints.rst | 7 +- .../bladeburnerapi/getSkillUpgradeCost.rst | 11 +- .../netscript/bladeburnerapi/getStamina.rst | 13 +- .../netscript/bladeburnerapi/getTeamSize.rst | 12 +- .../joinBladeburnerDivision.rst | 9 +- .../bladeburnerapi/joinBladeburnerFaction.rst | 9 +- .../bladeburnerapi/setActionAutolevel.rst | 7 +- .../bladeburnerapi/setActionLevel.rst | 7 +- .../netscript/bladeburnerapi/setTeamSize.rst | 8 +- .../netscript/bladeburnerapi/startAction.rst | 11 +- .../bladeburnerapi/stopBladeburnerAction.rst | 6 + .../netscript/bladeburnerapi/switchCity.rst | 8 +- .../netscript/bladeburnerapi/upgradeSkill.rst | 11 +- .../netscript/codingcontractapi/attempt.rst | 21 ++- .../codingcontractapi/getContractType.rst | 24 +-- .../netscript/codingcontractapi/getData.rst | 18 +- .../codingcontractapi/getDescription.rst | 22 ++- .../getNumTriesRemaining.rst | 16 +- doc/source/netscript/gangapi/ascendMember.rst | 6 +- .../netscript/gangapi/canRecruitMember.rst | 3 +- doc/source/netscript/gangapi/getBonusTime.rst | 4 +- .../netscript/gangapi/getChanceToWinClash.rst | 6 +- .../netscript/gangapi/getEquipmentCost.rst | 8 +- .../netscript/gangapi/getEquipmentNames.rst | 2 +- .../netscript/gangapi/getEquipmentStats.rst | 14 +- .../netscript/gangapi/getEquipmentType.rst | 4 +- .../netscript/gangapi/getGangInformation.rst | 5 +- .../gangapi/getMemberInformation.rst | 6 +- .../netscript/gangapi/getMemberNames.rst | 5 +- .../gangapi/getOtherGangInformation.rst | 5 +- doc/source/netscript/gangapi/getTaskNames.rst | 5 +- doc/source/netscript/gangapi/getTaskStats.rst | 52 +++--- .../netscript/gangapi/purchaseEquipment.rst | 4 +- .../netscript/gangapi/recruitMember.rst | 4 +- .../netscript/gangapi/setMemberTask.rst | 3 +- .../netscript/gangapi/setTerritoryWarfare.rst | 1 - .../hacknetnodeapi/getCacheUpgradeCost.rst | 12 +- .../hacknetnodeapi/getCoreUpgradeCost.rst | 10 +- .../hacknetnodeapi/getLevelUpgradeCost.rst | 10 +- .../netscript/hacknetnodeapi/getNodeStats.rst | 10 +- .../hacknetnodeapi/getPurchaseNodeCost.rst | 3 +- .../hacknetnodeapi/getRamUpgradeCost.rst | 12 +- .../netscript/hacknetnodeapi/hashCost.rst | 8 +- .../netscript/hacknetnodeapi/maxNumNodes.rst | 5 +- .../netscript/hacknetnodeapi/numHashes.rst | 2 +- .../netscript/hacknetnodeapi/numNodes.rst | 3 +- .../netscript/hacknetnodeapi/purchaseNode.rst | 6 +- .../netscript/hacknetnodeapi/spendHashes.rst | 12 +- .../netscript/hacknetnodeapi/upgradeCache.rst | 11 +- .../netscript/hacknetnodeapi/upgradeCore.rst | 11 +- .../netscript/hacknetnodeapi/upgradeLevel.rst | 9 +- .../netscript/hacknetnodeapi/upgradeRam.rst | 17 +- doc/source/netscript/netscriptgangapi.rst | 2 + .../netscript/netscripthacknetnodeapi.rst | 1 + .../netscriptsingularityfunctions.rst | 3 + .../singularityfunctions/applyToCompany.rst | 7 +- .../checkFactionInvitations.rst | 2 +- .../singularityfunctions/commitCrime.rst | 5 +- .../singularityfunctions/createProgram.rst | 4 +- .../singularityfunctions/donateToFaction.rst | 5 +- .../getAugmentationCost.rst | 5 +- doc/source/netscript/tixapi/buyStock.rst | 3 +- doc/source/netscript/tixapi/cancelOrder.rst | 2 +- .../netscript/tixapi/getStockAskPrice.rst | 3 +- .../netscript/tixapi/getStockBidPrice.rst | 3 +- .../netscript/tixapi/getStockForecast.rst | 3 +- .../netscript/tixapi/getStockMaxShares.rst | 3 +- .../netscript/tixapi/getStockPosition.rst | 3 +- doc/source/netscript/tixapi/getStockPrice.rst | 3 +- .../netscript/tixapi/getStockPurchaseCost.rst | 5 +- .../netscript/tixapi/getStockSaleGain.rst | 5 +- .../netscript/tixapi/getStockVolatility.rst | 3 +- doc/source/netscript/tixapi/placeOrder.rst | 2 +- doc/source/netscript/tixapi/sellShort.rst | 3 +- doc/source/netscript/tixapi/sellStock.rst | 3 +- doc/source/netscript/tixapi/shortStock.rst | 3 +- src/Bladeburner.js | 159 ++++++------------ src/Netscript/WorkerScript.ts | 6 +- 176 files changed, 1325 insertions(+), 916 deletions(-) diff --git a/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst b/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst index 4ed8b1e9b..ab8deac84 100644 --- a/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst +++ b/doc/source/netscript/advancedfunctions/getBitNodeMultipliers.rst @@ -3,14 +3,19 @@ getBitNodeMultipliers() Netscript Function .. js:function:: getBitNodeMultipliers() - Returns an object containing the current BitNode multipliers. This function requires Source-File 5 in order - to run. The multipliers are returned in decimal forms (e.g. 1.5 instead of 150%). The multipliers represent - the difference between the current BitNode and the original BitNode (BitNode-1). For example, if the - *CrimeMoney* multiplier has a value of 0.1, then that means that committing crimes in the current BitNode - will only give 10% of the money you would have received in BitNode-1. + :RAM cost: 4 GB - The structure of the returned object is subject to change as BitNode multipliers get added to the game. - Refer to the `source code here `_ + Returns an object containing the current BitNode multipliers. This function + requires Source-File 5 in order to run. The multipliers are returned in + decimal forms (e.g. 1.5 instead of 150%). The multipliers represent the + difference between the current BitNode and the original BitNode (BitNode-1). + For example, if the *CrimeMoney* multiplier has a value of 0.1, then that + means that committing crimes in the current BitNode will only give 10% of + the money you would have received in BitNode-1. + + The structure of the returned object is subject to change as BitNode + multipliers get added to the game. Refer to the `source code here + `_ to see the name of the BitNode multipliers. Example:: @@ -18,5 +23,3 @@ getBitNodeMultipliers() Netscript Function mults = getBitNodeMultipliers(); print(mults.ServerMaxMoney); print(mults.HackExpGain); - - :RAM cost: 4 GB diff --git a/doc/source/netscript/basicfunctions/brutessh.rst b/doc/source/netscript/basicfunctions/brutessh.rst index b1803b3f1..4bd535fe4 100644 --- a/doc/source/netscript/basicfunctions/brutessh.rst +++ b/doc/source/netscript/basicfunctions/brutessh.rst @@ -1,13 +1,17 @@ brutessh() Netscript Function ============================= -.. js:function:: brutessh(hostname/ip) +.. js:function:: brutessh(hostname) - :param string hostname/ip: IP or hostname of the target server :RAM cost: 0.05 GB - Runs the BruteSSH.exe program on the target server. BruteSSH.exe must exist on your home computer. + :param string hostname: Hostname of the target server. - Example:: + Runs the BruteSSH.exe program on the target server. BruteSSH.exe must exist + on your home computer. + + Examples: + + .. code-block:: javascript brutessh("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/clear.rst b/doc/source/netscript/basicfunctions/clear.rst index 90cfee85c..3f4f7fd09 100644 --- a/doc/source/netscript/basicfunctions/clear.rst +++ b/doc/source/netscript/basicfunctions/clear.rst @@ -1,13 +1,16 @@ clear() Netscript Function ========================== -.. js:function:: clear(port/fn) +.. js:function:: clear(portOrFilename) - :param string/number port/fn: Port or text file to clear :RAM cost: 1 GB + :param string/number portOrFilename: Port or text file to clear. + This function is used to clear data in a :ref:`Netscript Port ` or a text file. - If the *port/fn* argument is a number between 1 and 20, then it specifies a port and will clear it (deleting all data from the underlying queue). + If the ``portOrFilename`` argument is a number between 1 and 20, then it + specifies a port and will clear it (deleting all data from the underlying queue). - If the *port/fn* argument is a string, then it specifies the name of a text file (.txt) and will delete all data from that text file. + If the ``portOrFilename`` argument is a string, then it specifies the name + of a text file (.txt) and will delete all data from that text file. diff --git a/doc/source/netscript/basicfunctions/clearLog.rst b/doc/source/netscript/basicfunctions/clearLog.rst index 96bcc694f..1c892b669 100644 --- a/doc/source/netscript/basicfunctions/clearLog.rst +++ b/doc/source/netscript/basicfunctions/clearLog.rst @@ -5,4 +5,13 @@ clearLog() Netscript Function :RAM cost: 0 GB - Clears the script's logs + Clears the script's logs. Useful when making monitoring scripts. + + Examples: + + .. code-block:: javascript + + while(true) { + clearLog(); + print(getServerMoneyAvailable('foodnstuff')); + } diff --git a/doc/source/netscript/basicfunctions/deleteServer.rst b/doc/source/netscript/basicfunctions/deleteServer.rst index e1c400f62..bb073904e 100644 --- a/doc/source/netscript/basicfunctions/deleteServer.rst +++ b/doc/source/netscript/basicfunctions/deleteServer.rst @@ -3,12 +3,12 @@ deleteServer() Netscript Function .. js:function:: deleteServer(hostname) - :param string hostname: Hostname of the server to delete :RAM cost: 2.25 GB + :param string hostname: Hostname of the server to delete. + :returns: ``true`` if successful, ``false`` otherwise. - Deletes one of your purchased servers, which is specified by its hostname. + Deletes the specified purchased server. - The *hostname* argument can be any data type, but it will be converted to a string. Whitespace is automatically removed from - the string. This function will not delete a server that still has scripts running on it. - - Returns true if successful, and false otherwise. + The ``hostname`` argument can be any data type, but it will be converted to + a string. Whitespace is automatically removed from the string. This function + will not delete a server that still has scripts running on it. diff --git a/doc/source/netscript/basicfunctions/disableLog.rst b/doc/source/netscript/basicfunctions/disableLog.rst index dba73c24d..e3b0a393a 100644 --- a/doc/source/netscript/basicfunctions/disableLog.rst +++ b/doc/source/netscript/basicfunctions/disableLog.rst @@ -1,16 +1,17 @@ disableLog() Netscript Function =============================== -.. js:function:: disableLog(fn) +.. js:function:: disableLog(functionName) - :param string fn: Name of function for which to disable logging :RAM cost: 0 GB + :param string functionName: Name of function for which to disable logging. + Disables logging for the given function. Logging can be disabled for all functions by passing 'ALL' as the argument. Note that this does not completely remove all logging functionality. - This only stops a function from logging - when the function is successful. If the function fails, it will still log the reason for failure. + This only stops a function from logging when the function is successful. If + the function fails, it will still log the reason for failure. Notable functions that cannot have their logs disabled: run, exec, exit diff --git a/doc/source/netscript/basicfunctions/enableLog.rst b/doc/source/netscript/basicfunctions/enableLog.rst index 691b9f133..60b3f5606 100644 --- a/doc/source/netscript/basicfunctions/enableLog.rst +++ b/doc/source/netscript/basicfunctions/enableLog.rst @@ -1,10 +1,12 @@ enableLog() Netscript Function ============================== -.. js:function:: enableLog(fn) +.. js:function:: enableLog(functionName) - :param string fn: Name of function for which to enable logging :RAM cost: 0 GB - Re-enables logging for the given function. If 'ALL' is passed into this function - as an argument, then it will revert the effects of disableLog('ALL') + :param string functionName: Name of function for which to enable logging. + + Re-enables logging for the given function. If 'ALL' is passed into this + function as an argument, then it will revert the effects of + ``disableLog('ALL')`` diff --git a/doc/source/netscript/basicfunctions/exec.rst b/doc/source/netscript/basicfunctions/exec.rst index 9ded031b2..d3ee7f011 100644 --- a/doc/source/netscript/basicfunctions/exec.rst +++ b/doc/source/netscript/basicfunctions/exec.rst @@ -1,39 +1,41 @@ exec() Netscript Function ========================= -.. js:function:: exec(script, hostname/ip, [numThreads=1], [args...]) +.. js:function:: exec(script, hostname[, numThreads=1[, args...]]) - :param string script: Filename of script to execute - :param string hostname/ip: IP or hostname of the 'target server' on which to execute the script - :param number numThreads: Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer - :param args...: - Additional arguments to pass into the new script that is being run. Note that if any arguments are being - passed into the new script, then the third argument *numThreads* must be filled in with a value. :RAM cost: 1.3 GB - Run a script as a separate process on a specified server. This is similar to the *run* function except - that it can be used to run a script on any server, instead of just the current server. + :param string script: Filename of script to execute. + :param string hostname: Hostname of the target server on which to execute the script. + :param number numThreads: Optional thread count for new script. Set to 1 by + default. Will be rounded to nearest integer + :param args...: Additional arguments to pass into the new script that is + being run. Note that if any arguments are being + passed into the new script, then the third argument ``numThreads`` must + be filled in with a value. + :returns: Newly created process id on success, 0 on failure. - If the script was successfully started, then this functions returns the PID - of that script. Otherwise, it returns 0. + Run a script as a separate process on a specified server. This is similar to + the :doc:`run` function except that it can be used to run a script on any + server, instead of just the current server. - .. note:: PID stands for Process ID. The PID is a unique identifier for each script. - The PID will always be a positive integer. - - .. warning:: Running this function with a *numThreads* argument of 0 will return 0 without + .. warning:: Running this function with a ``numThreads`` argument of 0 will return 0 without running the script. However, running this function with a negative *numThreads* argument will cause a runtime error. - The simplest way to use the *exec* command is to call it with just the script name and the target server. - The following example will try to run *generic-hack.script* on the *foodnstuff* server:: + The simplest way to use the :doc:`exec` command is to call it with + just the script name and the target server. The following example will try + to run ``generic-hack.script`` on the ``foodnstuff`` server:: exec("generic-hack.script", "foodnstuff"); - The following example will try to run the script *generic-hack.script* on the *joesguns* server with 10 threads:: + The following example will try to run the script ``generic-hack.script`` on + the ``joesguns`` server with 10 threads:: exec("generic-hack.script", "joesguns", 10); - This last example will try to run the script *foo.script* on the *foodnstuff* server with 5 threads. It will also pass - the number 1 and the string "test" in as arguments to the script:: + This last example will try to run the script ``foo.script`` on the + ``foodnstuff`` server with 5 threads. It will also pass the number 1 and the + string "test" in as arguments to the script:: exec("foo.script", "foodnstuff", 5, 1, "test"); diff --git a/doc/source/netscript/basicfunctions/exit.rst b/doc/source/netscript/basicfunctions/exit.rst index 64b8f4c44..d0b6094a4 100644 --- a/doc/source/netscript/basicfunctions/exit.rst +++ b/doc/source/netscript/basicfunctions/exit.rst @@ -5,4 +5,4 @@ exit() Netscript Function :RAM cost: 0 GB - Terminates the current script immediately + Terminates the current script immediately. diff --git a/doc/source/netscript/basicfunctions/fileExists.rst b/doc/source/netscript/basicfunctions/fileExists.rst index a14478a94..eda1c686c 100644 --- a/doc/source/netscript/basicfunctions/fileExists.rst +++ b/doc/source/netscript/basicfunctions/fileExists.rst @@ -1,25 +1,29 @@ fileExists() Netscript Function =============================== -.. js:function:: fileExists(filename, [hostname/ip]) +.. js:function:: fileExists(filename[, hostname]) - :param string filename: Filename of file to check - :param string hostname/ip: - Hostname or IP of target server. This is optional. If it is not specified then the - function will use the current server as the target server :RAM cost: 0.1 GB - Returns a boolean indicating whether the specified file exists on the target server. The filename - for scripts is case-sensitive, but for other types of files it is not. For example, *fileExists("brutessh.exe")* - will work fine, even though the actual program is named "BruteSSH.exe". + :param string filename: Filename of file to check. + :param string hostname: + Hostname of target server. This is optional. If it is not specified then + the function will use the current server as the target server. + :returns: ``true`` if the file exists, ``false`` if it doesn't. - If the *hostname/ip* argument is omitted, then the function will search through the current server (the server - running the script that calls this function) for the file. + The filename for scripts is case-sensitive, but for other types of files it + is not. For example, ``fileExists("brutessh.exe")`` will work fine, even + though the actual program is named ``BruteSSH.exe``. - Examples:: + If the ``hostname`` argument is omitted, then the function will search + through the server running the script that calls this function for the file. - fileExists("foo.script", "foodnstuff"); - fileExists("ftpcrack.exe"); + Examples: - The first example above will return true if the script named *foo.script* exists on the *foodnstuff* server, and false otherwise. - The second example above will return true if the current server contains the *FTPCrack.exe* program, and false otherwise. + .. code-block:: javascript + + fileExists("foo.script", "foodnstuff"); // returns: false + fileExists("ftpcrack.exe"); // returns: true + + The first example above will return true if the script named ``foo.script`` exists on the ``foodnstuff`` server, and false otherwise. + The second example above will return true if the current server contains the ``FTPCrack.exe`` program, and false otherwise. diff --git a/doc/source/netscript/basicfunctions/ftpcrack.rst b/doc/source/netscript/basicfunctions/ftpcrack.rst index 099a6c54e..1391934e9 100644 --- a/doc/source/netscript/basicfunctions/ftpcrack.rst +++ b/doc/source/netscript/basicfunctions/ftpcrack.rst @@ -1,13 +1,18 @@ ftpcrack() Netscript Function ============================= -.. js:function:: ftpcrack(hostname/ip) +.. js:function:: ftpcrack(hostname) - :param string hostname/ip: IP or hostname of the target server :RAM cost: 0.05 GB - Runs the FTPCrack.exe program on the target server. FTPCrack.exe must exist on your home computer. + :param string hostname: Hostname of the target server. - Example:: + Runs the ``FTPCrack.exe`` program on the target server. ``FTPCrack.exe`` + must exist on your home computer. + + + Examples: + + .. code-block:: javascript ftpcrack("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/getFavorToDonate.rst b/doc/source/netscript/basicfunctions/getFavorToDonate.rst index 8c9feb203..133788fbd 100644 --- a/doc/source/netscript/basicfunctions/getFavorToDonate.rst +++ b/doc/source/netscript/basicfunctions/getFavorToDonate.rst @@ -4,5 +4,10 @@ getFavorToDonate() Netscript Function .. js:function:: getFavorToDonate() :RAM cost: 0.1 GB + :returns: Amount of faction favor required to unlock donation. - Returns the amount of Faction favor required to be able to donate to a faction. + Example: + + .. code-block:: javascript + + getFavorToDonate() // returns: 150 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getGrowTime.rst b/doc/source/netscript/basicfunctions/getGrowTime.rst index 0c105c61b..443f76b01 100644 --- a/doc/source/netscript/basicfunctions/getGrowTime.rst +++ b/doc/source/netscript/basicfunctions/getGrowTime.rst @@ -1,16 +1,24 @@ getGrowTime() Netscript Function ================================ -.. js:function:: getGrowTime(hostname/ip[, hackLvl=current level]) +.. js:function:: getGrowTime(hostname[, hackLvl=current level]) - :param string hostname/ip: Hostname or IP of target server - :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level :RAM cost: 0.05 GB - Returns the amount of time in seconds it takes to execute the *grow()* Netscript function on the target server. + :param string hostname: Hostname of target server. + :param number hackLvl: Optional hacking level for the calculation. Defaults + to player's current hacking level. + :returns: seconds it takes to execute :doc:`grow` on that server. - The function takes in an optional *hackLvl* parameter that can be specified - to see what the grow time would be at different hacking levels. + The function takes in an optional ``hackLvl`` parameter that can be + specified to see what the grow time would be at different hacking levels. - .. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will - return :code:`Infinity`. + + Example: + + .. code-block:: javascript + + getGrowTime("foodnstuff"); // returns: 53.4 + +.. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will + return ``Infinity``. diff --git a/doc/source/netscript/basicfunctions/getHackTime.rst b/doc/source/netscript/basicfunctions/getHackTime.rst index 768c26373..6c45c4e03 100644 --- a/doc/source/netscript/basicfunctions/getHackTime.rst +++ b/doc/source/netscript/basicfunctions/getHackTime.rst @@ -1,16 +1,22 @@ getHackTime() Netscript Function ================================ -.. js:function:: getHackTime(hostname/ip[, hackLvl=current level]) +.. js:function:: getHackTime(hostname[, hackLvl=current level]) - :param string hostname/ip: Hostname or IP of target server - :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level :RAM cost: 0.05 GB + :param string hostname: Hostname of target server. + :param number hackLvl: Optional hacking level for the calculation. Defaults + to player's current hacking level. + :returns: seconds it takes to execute :doc:`hack` on that server. - Returns the amount of time in seconds it takes to execute the *hack()* Netscript function on the target server. + The function takes in an optional ``hackLvl`` parameter that can be + specified to see what the hack time would be at different hacking levels. - The function takes in an optional *hackLvl* parameter that can be specified - to see what the hack time would be at different hacking levels. + Example: + + .. code-block:: javascript + + getHackTime("foodnstuff"); // returns: 53.4 .. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will return :code:`Infinity`. diff --git a/doc/source/netscript/basicfunctions/getHackingLevel.rst b/doc/source/netscript/basicfunctions/getHackingLevel.rst index f87e324b6..ed085220e 100644 --- a/doc/source/netscript/basicfunctions/getHackingLevel.rst +++ b/doc/source/netscript/basicfunctions/getHackingLevel.rst @@ -4,5 +4,10 @@ getHackingLevel() Netscript Function .. js:function:: getHackingLevel() :RAM cost: 0.05 GB + :returns: The player's current hacking level. - Returns the player's current hacking level + Example: + + .. code-block:: javascript + + getHackingLevel(); // returns: 124 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getHackingMultipliers.rst b/doc/source/netscript/basicfunctions/getHackingMultipliers.rst index 37032122e..3c08c0cfc 100644 --- a/doc/source/netscript/basicfunctions/getHackingMultipliers.rst +++ b/doc/source/netscript/basicfunctions/getHackingMultipliers.rst @@ -4,9 +4,11 @@ getHackingMultipliers() Netscript Function .. js:function:: getHackingMultipliers() :RAM cost: 4 GB + :returns: object containing the player's hacking multipliers. These + multipliers are returned in decimal forms, not percentages (e.g. 1.5 + instead of 150%). - Returns an object containing the Player's hacking related multipliers. These multipliers are - returned in decimal forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: + Structure:: { chance: Player's hacking chance multiplier, @@ -15,7 +17,9 @@ getHackingMultipliers() Netscript Function growth: Player's hacking growth multiplier } - Example of how this can be used:: + Example: + + .. code-block:: javascript mults = getHackingMultipliers(); print(mults.chance); diff --git a/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst b/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst index d37eda610..b6a372075 100644 --- a/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst +++ b/doc/source/netscript/basicfunctions/getHacknetMultipliers.rst @@ -4,9 +4,11 @@ getHacknetMultipliers() Netscript Function .. js:function:: getHacknetMultipliers() :RAM cost: 4 GB + :returns: object containing the player's hacknet multipliers. These + multipliers are returned in decimal forms, not percentages (e.g. 1.5 + instead of 150%). - Returns an object containing the Player's hacknet related multipliers. These multipliers are - returned in decimal forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: + Structure:: { production: Player's hacknet production multiplier, @@ -16,7 +18,9 @@ getHacknetMultipliers() Netscript Function levelCost: Player's hacknet level cost multiplier } - Example of how this can be used:: + Example: + + .. code-block:: javascript mults = getHacknetMultipliers(); print(mults.production); diff --git a/doc/source/netscript/basicfunctions/getHostname.rst b/doc/source/netscript/basicfunctions/getHostname.rst index 6e14224cd..76b78ac7c 100644 --- a/doc/source/netscript/basicfunctions/getHostname.rst +++ b/doc/source/netscript/basicfunctions/getHostname.rst @@ -4,5 +4,11 @@ getHostname() Netscript Function .. js:function:: getHostname() :RAM cost: 0.05 GB + :returns: Hostname of the server this script is running on. - Returns a string with the hostname of the server that the script is running on + Example: + + .. code-block:: javascript + + getHostname(); // returns: "foodnstuff" + diff --git a/doc/source/netscript/basicfunctions/getPortHandle.rst b/doc/source/netscript/basicfunctions/getPortHandle.rst index a0a6ed05c..e0f800efd 100644 --- a/doc/source/netscript/basicfunctions/getPortHandle.rst +++ b/doc/source/netscript/basicfunctions/getPortHandle.rst @@ -3,9 +3,9 @@ getPortHandle() Netscript Function .. js:function:: getPortHandle(port) - :param number port: Port number :RAM cost: 10 GB - Get a handle to a Netscript Port. See more details here: :ref:`netscript_ports` + :param number port: Port number + :returns: portHandle object. See :ref:`netscript_ports` **WARNING:** Port Handles only work in :ref:`netscriptjs`. They will not work in :ref:`netscript1`. diff --git a/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst b/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst index 764baa309..faf02ba06 100644 --- a/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst +++ b/doc/source/netscript/basicfunctions/getPurchasedServerCost.rst @@ -6,11 +6,10 @@ getPurchasedServerCost() Netscript Function :RAM cost: 0.25 GB :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: Cost to purchase a server with the specified amount of ``ram``. - Returns the cost to purchase a server with the specified amount of *ram*. + Example: - Examples:: + .. code-block:: javascript - for (i = 1; i <= 20; i++) { - tprint(i + " -- " + getPurchasedServerCost(Math.pow(2, i))); - } + getPurchasedServerCost(8192); // returns: 450560000 diff --git a/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst b/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst index 7784203dc..293187b18 100644 --- a/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst +++ b/doc/source/netscript/basicfunctions/getPurchasedServerLimit.rst @@ -4,5 +4,10 @@ getPurchasedServerLimit() Netscript Function .. js:function:: getPurchasedServerLimit() :RAM cost: 0.05 GB + :returns: The maximum number of servers you can purchase. - Returns the maximum number of servers you can purchase + Example: + + .. code-block:: javascript + + getPurchasedServerLimit() // returns: 25 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst b/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst index 844e7ba18..1692f37a4 100644 --- a/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst +++ b/doc/source/netscript/basicfunctions/getPurchasedServerMaxRam.rst @@ -4,5 +4,10 @@ getPurchasedServerMaxRam() Netscript Function .. js:function:: getPurchasedServerMaxRam() :RAM cost: 0.05 GB + :returns: The maximum RAM that a purchased server can have. - Returns the maximum RAM that a purchased server can have + Example: + + .. code-block:: javascript + + getPurchasedServerMaxRam(); // returns: 1048576 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getPurchasedServers.rst b/doc/source/netscript/basicfunctions/getPurchasedServers.rst index 89b3cfedc..c7f360008 100644 --- a/doc/source/netscript/basicfunctions/getPurchasedServers.rst +++ b/doc/source/netscript/basicfunctions/getPurchasedServers.rst @@ -1,11 +1,13 @@ getPurchasedServers() Netscript Function ======================================== -.. js:function:: getPurchasedServers([hostname=true]) +.. js:function:: getPurchasedServers() - :param boolean hostname: - Specifies whether hostnames or IP addresses should be returned. If it's true then hostnames will be returned, and if false - then IPs will be returned. If this argument is omitted then it is true by default :RAM cost: 2.25 GB + :returns: String array of hostnames of all of the servers you have purchased. - Returns an array with either the hostnames or IPs of all of the servers you have purchased. + Example: + + .. code-block:: javascript + + getPurchasedServers(); // returns: ['grow-server-0', 'grow-server-1', 'weaken-server-0'] diff --git a/doc/source/netscript/basicfunctions/getScriptExpGain.rst b/doc/source/netscript/basicfunctions/getScriptExpGain.rst index 65f6f9c86..2bdc50a38 100644 --- a/doc/source/netscript/basicfunctions/getScriptExpGain.rst +++ b/doc/source/netscript/basicfunctions/getScriptExpGain.rst @@ -1,14 +1,18 @@ getScriptExpGain() Netscript Function ===================================== -.. js:function:: getScriptExpGain([scriptname], [hostname/ip], [args...]) +.. js:function:: getScriptExpGain([scriptname[, hostname[, args...]]]) - :param string scriptname: Filename of script - :param string hostname/ip: Server on which script is running - :param args...: Arguments that the script is running with :RAM cost: 0.1 GB + :param string scriptname: Filename of script. + :param string hostname: Server on which script is running. + :param args...: Arguments that the script is running with. + :returns: The amount of hacking experience the specified script generates + while online. - Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for offline experience gains). - Remember that a script is uniquely identified by both its name and its arguments. + This function can also return the total experience gain rate of all of your + active scripts by running the function with no arguments. + + .. note:: A script is uniquely identified by both its name and its + arguments. - This function can also return the total experience gain rate of all of your active scripts by running the function with no arguments. diff --git a/doc/source/netscript/basicfunctions/getScriptIncome.rst b/doc/source/netscript/basicfunctions/getScriptIncome.rst index e3496c015..8dd1a4f3f 100644 --- a/doc/source/netscript/basicfunctions/getScriptIncome.rst +++ b/doc/source/netscript/basicfunctions/getScriptIncome.rst @@ -1,18 +1,19 @@ getScriptIncome() Netscript Function ==================================== -.. js:function:: getScriptIncome([scriptname], [hostname/ip], [args...]) +.. js:function:: getScriptIncome([scriptname[, hostname/ip[, [args...]]]) + :RAM cost: 0.1 GB :param string scriptname: Filename of script :param string hostname/ip: Server on which script is running :param args...: Arguments that the script is running with - :RAM cost: 0.1 GB + :returns: Amount of income the specified script generates while online. - Returns the amount of income the specified script generates while online (when the game is open, does not apply for offline income). - Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script with the arguments - "foodnstuff" and "5" then in order to use this function to get that script's income you must specify those same arguments in the same order - in this function call. + If called with no arguments this function will return an array of two + values. The first value is the total income ($ / second) of all of your + active scripts (scripts that are currently running on any server). The + second value is the total income ($ / second) that you've earned from + scripts since you last installed Augmentations. - This function can also be called with no arguments. If called with no arguments, then this function will return an array of two values. The - first value is the total income ($ / second) of all of your active scripts (scripts that are currently running on any server). The second value - is the total income ($ / second) that you've earned from scripts since you last installed Augmentations. + .. note:: A script is uniquely identified by both its name and its + arguments. \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getScriptLogs.rst b/doc/source/netscript/basicfunctions/getScriptLogs.rst index ac721c4d3..c4b15800a 100644 --- a/doc/source/netscript/basicfunctions/getScriptLogs.rst +++ b/doc/source/netscript/basicfunctions/getScriptLogs.rst @@ -1,27 +1,27 @@ getScriptLogs() Netscript Function ================================== -.. js:function:: getScriptLogs([fn], [hostname/ip=current ip], [args...]) +.. js:function:: getScriptLogs([filename[, hostname=current hostname[, args...]]]) - :param string fn: Optional. Filename of script to get logs from. - :param string ip: Optional. IP or hostname of the server that the script is on - :param args...: Arguments to identify which scripts to get logs for :RAM cost: 0 GB + :param string filename: Optional. Filename of script to get logs from. + :param string hostname: Optional. Hostname of the server running the script. + :param args...: Arguments to identify which scripts to get logs for + :returns: Array of string, each line being a logged line. Chronological. - Returns a script's logs. The logs are returned as an array, where each - line is an element in the array. The most recently logged line is at the - end of the array. - - Note that there is a maximum number of lines that a script stores in its logs. +.. note:: There is a maximum number of lines that a script stores in its logs. This is configurable in the game's options. - If the function is called with no arguments, it will return the current script's logs. + If the function is called with no arguments, it will return the current + script's logs. - Otherwise, the `fn`, `hostname/ip,` and `args...` arguments can be used to get the logs - from another script. Remember that scripts are uniquely identified by both - their names and arguments. + Otherwise, the ``filename``, ``hostname``, and ``args...`` arguments can be + used to get the logs from another script. Remember that scripts are uniquely + identified by both their names and arguments. - Examples:: + Example: + + .. code-block:: javascript // Get logs from foo.script on the current server that was run with no args getScriptLogs("foo.script"); diff --git a/doc/source/netscript/basicfunctions/getScriptName.rst b/doc/source/netscript/basicfunctions/getScriptName.rst index cc7de660b..436041846 100644 --- a/doc/source/netscript/basicfunctions/getScriptName.rst +++ b/doc/source/netscript/basicfunctions/getScriptName.rst @@ -4,5 +4,10 @@ getScriptName() Netscript Function .. js:function:: getScriptName() :RAM cost: 0 GB + :returns: Current script name. - Returns the current script name + Example: + + .. code-block:: javascript + + getScriptName(); // returns: "example.script" diff --git a/doc/source/netscript/basicfunctions/getScriptRam.rst b/doc/source/netscript/basicfunctions/getScriptRam.rst index 2123d8ed0..9010baa25 100644 --- a/doc/source/netscript/basicfunctions/getScriptRam.rst +++ b/doc/source/netscript/basicfunctions/getScriptRam.rst @@ -1,11 +1,16 @@ getScriptRam() Netscript Function ================================= -.. js:function:: getScriptRam(scriptname[, hostname/ip]) +.. js:function:: getScriptRam(filename[, hostname]) - :param string scriptname: Filename of script. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server the script is located on. This is optional, If it is not specified then the function will set the current server as the target server. :RAM cost: 0.1 GB + :param string filename: Filename of script. + :param string hostname: Hostname of target server the script is located on. + Default to the server this script is running on. + :returns: Amount of RAM required to run the script, 0 if it does not exist. - Returns the amount of RAM required to run the specified script on the target server. Returns - 0 if the script does not exist. + Example: + + .. code-block:: javascript + + getScriptRam("grow.script"); // returns: 1.75 diff --git a/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst b/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst index 162ee4c38..59ac978a5 100644 --- a/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst +++ b/doc/source/netscript/basicfunctions/getServerBaseSecurityLevel.rst @@ -1,12 +1,28 @@ getServerBaseSecurityLevel() Netscript Function =============================================== -.. js:function:: getServerBaseSecurityLevel(hostname/ip) +.. js:function:: getServerBaseSecurityLevel(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: Base security level of target server. - Returns the base security level of the target server. This is the security level that the server starts out with. - This is different than *getServerSecurityLevel()* because *getServerSecurityLevel()* returns the current - security level of a server, which can constantly change due to *hack()*, *grow()*, and *weaken()*, calls on that - server. The base security level will stay the same until you reset by installing an Augmentation(s). + The base security level is the security level that the server starts out with. + + This function isn't particularly useful. + :doc:`getServerSecurityLevel` and + :doc:`getServerMinSecurityLevel` are more often + used. + + Example: + + .. code-block:: javascript + + getServerBaseSecurityLevel('foodnstuff'); // returns: 9 + +.. note:: This is different than :doc:`getServerSecurityLevel` + because :doc:`getServerSecurityLevel` returns the current + security level of a server, which can constantly change due to + :doc:`hack`, :doc:`grow`, and :doc:`weaken` calls on + that server. The base security level will stay the same until you reset + by installing augmentation(s). diff --git a/doc/source/netscript/basicfunctions/getServerGrowth.rst b/doc/source/netscript/basicfunctions/getServerGrowth.rst index 8fbdd3d45..e7a721fd4 100644 --- a/doc/source/netscript/basicfunctions/getServerGrowth.rst +++ b/doc/source/netscript/basicfunctions/getServerGrowth.rst @@ -1,12 +1,19 @@ getServerGrowth() Netscript Function ==================================== -.. js:function:: getServerGrowth(hostname/ip) +.. js:function:: getServerGrowth(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: Server growth parameter. - Returns the server's instrinsic "growth parameter". This growth parameter is a number - between 1 and 100 that represents how quickly the server's money grows. This parameter affects the - percentage by which the server's money is increased when using the *grow()* function. A higher - growth parameter will result in a higher percentage increase from *grow()*. + The growth parameter is a number between 1 and 100 affects the percentage by + which the server's money is increased when using the :doc:`grow` + function. A higher growth parameter will result in a higher percentage + increase. + + Example: + + .. code-block:: javascript + + getServerGrowth('foodnstuff'); // returns: 5 diff --git a/doc/source/netscript/basicfunctions/getServerMaxMoney.rst b/doc/source/netscript/basicfunctions/getServerMaxMoney.rst index c9feeb8be..d9cc9017b 100644 --- a/doc/source/netscript/basicfunctions/getServerMaxMoney.rst +++ b/doc/source/netscript/basicfunctions/getServerMaxMoney.rst @@ -1,9 +1,14 @@ getServerMaxMoney() Netscript Function ====================================== -.. js:function:: getServerMaxMoney(hostname/ip) +.. js:function:: getServerMaxMoney(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: Maximum amount of money that can be available on a server. - Returns the maximum amount of money that can be available on a server + Example: + + .. code-block:: javascript + + getServerMaxMoney('foodnstuff'); // returns: 4000000 diff --git a/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst b/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst index 7036c0f7e..4f34fdad5 100644 --- a/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst +++ b/doc/source/netscript/basicfunctions/getServerMinSecurityLevel.rst @@ -1,9 +1,14 @@ getServerMinSecurityLevel() Netscript Function ============================================== -.. js:function:: getServerMinSecurityLevel(hostname/ip) +.. js:function:: getServerMinSecurityLevel(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: The minimum security level of the target server. - Returns the minimum security level of the target server + Example: + + .. code-block:: javascript + + getServerMinSecurityLevel('foodnstuff'); // returns: 3 diff --git a/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst b/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst index 55b909396..cdb30b98e 100644 --- a/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst +++ b/doc/source/netscript/basicfunctions/getServerMoneyAvailable.rst @@ -1,15 +1,19 @@ getServerMoneyAvailable() Netscript Function ============================================ -.. js:function:: getServerMoneyAvailable(hostname/ip) +.. js:function:: getServerMoneyAvailable(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: Money available on that server. - Returns the amount of money available on a server. **Running this function on the home computer will return - the player's money.** + .. note:: - Example:: + Running this function on the home computer will return the player's money. - getServerMoneyAvailable("foodnstuff"); - getServerMoneyAvailable("home"); //Returns player's money + Example: + + .. code-block:: javascript + + getServerMoneyAvailable("foodnstuff"); // returns: 120000 + getServerMoneyAvailable("home"); // returns: 1000 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst b/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst index 1f05a6141..2693695cc 100644 --- a/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst +++ b/doc/source/netscript/basicfunctions/getServerNumPortsRequired.rst @@ -1,9 +1,15 @@ getServerNumPortsRequired() Netscript Function ============================================== -.. js:function:: getServerNumPortsRequired(hostname/ip) +.. js:function:: getServerNumPortsRequired(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: The number of open ports required to successfully run NUKE.exe on + the specified server. - Returns the number of open ports required to successfully run NUKE.exe on the specified server. + Example: + + .. code-block:: javascript + + getServerNumPortsRequired("unitalife"); // returns: 4 diff --git a/doc/source/netscript/basicfunctions/getServerRam.rst b/doc/source/netscript/basicfunctions/getServerRam.rst index a8a8cb200..40e46df42 100644 --- a/doc/source/netscript/basicfunctions/getServerRam.rst +++ b/doc/source/netscript/basicfunctions/getServerRam.rst @@ -1,17 +1,21 @@ getServerRam() Netscript Function ================================= -.. js:function:: getServerRam(hostname/ip) +.. js:function:: getServerRam(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: An array of 2 number, first number is the total RAM, second the + used RAM. Returns an array with two elements that gives information about a server's memory (RAM). The first element in the array is the amount of RAM that the server has total (in GB). The second element in the array is the amount of RAM that is currently being used on the server (in GB). - Example:: + Example: - res = getServerRam("helios"); + .. code-block:: javascript + + res = getServerRam("helios"); // returns: [5, 10] totalRam = res[0]; ramUsed = res[1]; diff --git a/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst b/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst index 122c5b41e..f006a1205 100644 --- a/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst +++ b/doc/source/netscript/basicfunctions/getServerRequiredHackingLevel.rst @@ -1,9 +1,14 @@ getServerRequiredHackingLevel() Netscript Function ================================================== -.. js:function:: getServerRequiredHackingLevel(hostname/ip) +.. js:function:: getServerRequiredHackingLevel(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: The required hacking level of target server. - Returns the required hacking level of the target server + Example: + + .. code-block:: javascript + + getServerRequiredHackingLevel("foodnstuff"); // returns: 5 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst b/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst index a2c612170..b6dd116a4 100644 --- a/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst +++ b/doc/source/netscript/basicfunctions/getServerSecurityLevel.rst @@ -1,10 +1,14 @@ getServerSecurityLevel() Netscript Function =========================================== -.. js:function:: getServerSecurityLevel(hostname/ip) +.. js:function:: getServerSecurityLevel(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: The security level of the target server. - Returns the security level of the target server. A server's security level is denoted by a number, typically - between 1 and 100 (but it can go above 100). + Example: + + .. code-block:: javascript + + getServerSecurityLevel("foodnstuff"); // returns: 3.45 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst b/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst index b81d48482..877eeb7b8 100644 --- a/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst +++ b/doc/source/netscript/basicfunctions/getTimeSinceLastAug.rst @@ -4,5 +4,10 @@ getTimeSinceLastAug() Netscript Function .. js:function:: getTimeSinceLastAug() :RAM cost: 0.05 GB + :returns: Milliseconds since you last installed augmentations. - Returns the amount of time in milliseconds that have passed since you last installed Augmentations + Example: + + .. code-block:: javascript + + getTimeSinceLastAug(); // returns: 13912400 \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/getWeakenTime.rst b/doc/source/netscript/basicfunctions/getWeakenTime.rst index 056aaea27..103895cbb 100644 --- a/doc/source/netscript/basicfunctions/getWeakenTime.rst +++ b/doc/source/netscript/basicfunctions/getWeakenTime.rst @@ -1,16 +1,23 @@ getWeakenTime() Netscript Function ================================== -.. js:function:: getWeakenTime(hostname/ip[, hackLvl=current level]) +.. js:function:: getWeakenTime(hostname[, hackLvl=current level]) - :param string hostname/ip: Hostname or IP of target server - :param number hackLvl: Optional hacking level for the calculation. Defaults to player's current hacking level :RAM cost: 0.05 GB - - Returns the amount of time in seconds it takes to execute the *weaken()* Netscript function on the target server. + :param string hostname: Hostname of target server. + :param number hackLvl: Optional hacking level for the calculation. Defaults + to player's current hacking level. + :returns: seconds it takes to execute the :doc:`weaken` Netscript + function on the target server. The function takes in an optional *hackLvl* parameter that can be specified to see what the weaken time would be at different hacking levels. + Example: + + .. code-block:: javascript + + getWeakenTime("foodnstuff"); // returns: 34.5 + .. note:: For Hacknet Servers (the upgraded version of a Hacknet Node), this function will return :code:`Infinity`. diff --git a/doc/source/netscript/basicfunctions/grow.rst b/doc/source/netscript/basicfunctions/grow.rst index fc5257f11..ae9e43ad2 100644 --- a/doc/source/netscript/basicfunctions/grow.rst +++ b/doc/source/netscript/basicfunctions/grow.rst @@ -1,9 +1,10 @@ grow() Netscript Function ========================= -.. js:function:: grow(hostname/ip[, opts={}]) +.. js:function:: grow(hostname[, opts={}]) - :param string hostname/ip: IP or hostname of the target server to grow + :RAM cost: 0.15 GB + :param string hostname: Hostname of the target server. :param object opts: Optional parameters for configuring function behavior. Properties: * threads (*number*) - Number of threads to use for this function. @@ -12,18 +13,25 @@ grow() Netscript Function :ref:`gameplay_stock_market_player_actions_influencing_stock` :returns: The number by which the money on the server was multiplied for the growth - :RAM cost: 0.15 GB - Use your hacking skills to increase the amount of money available on a server. The runtime for this command depends on your hacking - level and the target server's security level. When grow() completes, the money available on a target server will be increased by a - certain, fixed percentage. This percentage is determined by the target server's growth rate (which varies between servers) and security level. - Generally, higher-level servers have higher growth rates. The getServerGrowth() function can be used to obtain a server's growth rate. + Increase the amount of money available on a server. The time it takes to + execute depends on your hacking level and the target server's security + level. When :doc:`grow` completes, the money available on a target + server will be increased by a certain, fixed percentage. This percentage is + determined by the target server's growth rate (which varies between servers) + and security level. Generally, higher-level servers have higher growth + rates. The :doc:`getServerGrowth` function can be used to + obtain a server's growth rate. - Like hack(), grow() can be called on any server, regardless of where the script is running. The grow() command requires - root access to the target server, but there is no required hacking level to run the command. It also raises the security level - of the target server by 0.004. + Like :doc:`hack`, :doc:`grow` can be called on any server, from + any server. The :doc:`grow` command requires root access to the target + server, but there is no required hacking level to run the command. It also + raises the security level of the target server by 0.004 per thread. - Example:: + Example: - grow("foodnstuff"); - grow("foodnstuff", { threads: 5 }); // Only use 5 threads to grow + .. code-block:: javascript + + while(true) { + grow("foodnstuff"); + } diff --git a/doc/source/netscript/basicfunctions/growthAnalyze.rst b/doc/source/netscript/basicfunctions/growthAnalyze.rst index 76120ae15..2d60915d2 100644 --- a/doc/source/netscript/basicfunctions/growthAnalyze.rst +++ b/doc/source/netscript/basicfunctions/growthAnalyze.rst @@ -1,24 +1,23 @@ growthAnalyze() Netscript Function ================================== -.. js:function:: growthAnalyze(hostname/ip, growthAmount) +.. js:function:: growthAnalyze(hostname, growthAmount) - :param string hostname/ip: IP or hostname of server to analyze - :param number growthAmount: Multiplicative factor by which the server is grown. Decimal form. Must be >= 1. - :returns: The amount of grow() calls needed to grow the specified server by the specified amount :RAM cost: 1 GB + :param string hostname: Hostname of server to analyze. + :param number growthAmount: Multiplicative factor by which the server is + grown. Decimal form. Must be >= 1. + :returns: The amount of :doc:`grow` threads needed to grow the specified + server by the specified amount. - This function returns the number of "growths" needed in order to increase the amount - of money available on the specified server by the specified amount. + Example: - The specified amount is multiplicative and is in decimal form, not percentage. + .. code-block:: javascript - For example, if you want to determine how many `grow()` calls you need - to double the amount of money on `foodnstuff`, you would use:: + // How many grow threads are needed to double the current money on 'foodnstuff' + growthAnalyze("foodnstuff", 2); // returns: 5124 - growthAnalyze("foodnstuff", 2); - - If this returns 100, then this means you need to call `grow()` 100 times - in order to double the money (or once with 100 threads). + If this returns 5124, then this means you need to call :doc:`grow` + 5124 times in order to double the money (or once with 5124 threads). **Warning**: The value returned by this function isn't necessarily a whole number. diff --git a/doc/source/netscript/basicfunctions/hack.rst b/doc/source/netscript/basicfunctions/hack.rst index e7f7718ea..abac13856 100644 --- a/doc/source/netscript/basicfunctions/hack.rst +++ b/doc/source/netscript/basicfunctions/hack.rst @@ -1,29 +1,35 @@ hack() Netscript Function ========================= -.. js:function:: hack(hostname/ip[, opts={}]) +.. js:function:: hack(hostname[, opts={}]) - :param string hostname/ip: IP or hostname of the target server to hack + :RAM cost: 0.1 GB + :param string hostname: Hostname of the target server. :param object opts: Optional parameters for configuring function behavior. Properties: * threads (*number*) - Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. * stock (*boolean*) - If true, the function can affect the stock market. See :ref:`gameplay_stock_market_player_actions_influencing_stock` - :returns: The amount of money stolen if the hack is successful, and zero otherwise - :RAM cost: 0.1 GB - Function that is used to try and hack servers to steal money and gain hacking experience. The runtime for this command depends - on your hacking level and the target server's security level. In order to hack a server you must first gain root access - to that server and also have the required hacking level. + Function that is used to try and hack servers to steal money and gain + hacking experience. The runtime for this command depends on your hacking + level and the target server's security level. In order to hack a server you + must first gain root access to that server and also have the required + hacking level. - A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. For example, - you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. + A script can hack a server from anywhere. It does not need to be running on + the same server to hack that server. For example, you can create a script + that hacks the 'foodnstuff' server and run that script on any server in the + game. - A successful hack() on a server will raise that server's security level by 0.002. + A successful :doc:`hack` on a server will raise that server's security + level by 0.002. - Example:: + Example: + + .. code-block:: javascript hack("foodnstuff"); hack("10.1.2.3"); diff --git a/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst b/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst index b0a64236c..c83e0c07b 100644 --- a/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst +++ b/doc/source/netscript/basicfunctions/hackAnalyzePercent.rst @@ -1,20 +1,22 @@ hackAnalyzePercent() Netscript Function ======================================= -.. js:function:: hackAnalyzePercent(hostname/ip) +.. js:function:: hackAnalyzePercent(hostname) - :param string hostname/ip: IP or hostname of target server - :returns: The percentage of money you will steal from the target server with a single hack :RAM cost: 1 GB + :param string hostname: Hostname of target server. + :returns: The percentage of money you will steal from the target server with + a single hack. Returns the percentage of the specified server's money you will steal with a - single hack. This value is returned in **percentage form, not decimal (Netscript - functions typically return in decimal form, but not this one).** + single hack. This value is returned in percentage form, not decimal. - For example, assume the following returns 1:: + For example, assume the following returns 1: - hackAnalyzePercent("foodnstuff"); + .. code-block:: javascript - This means that if hack the `foodnstuff` server, then you will steal 1% of its - total money. If you `hack()` using N threads, then you will steal N% of its total + hackAnalyzePercent("foodnstuff"); // returns: 1 + + This means that if hack the 'foodnstuff' server, then you will steal 1% of its + total money. If you :doc:`hack` using N threads, then you will steal N% of its total money. diff --git a/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst b/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst index 445b70c4c..05df6387e 100644 --- a/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst +++ b/doc/source/netscript/basicfunctions/hackAnalyzeThreads.rst @@ -1,24 +1,28 @@ hackAnalyzeThreads() Netscript Function ======================================= -.. js:function:: hackAnalyzeThreads(hostname/ip, hackAmount) +.. js:function:: hackAnalyzeThreads(hostname, hackAmount) - :param string hostname/ip: IP or hostname of server to analyze - :param number hackAmount: Amount of money you want to hack from the server - :returns: The number of threads needed to hack() the server for *hackAmount* money :RAM cost: 1 GB + :param string hostname: Hostname of server to analyze. + :param number hackAmount: Amount of money you want to hack from the server. + :returns: The number of threads needed to :doc:`hack` the server for + ``hackAmount`` money. This function returns the number of script threads you need when running - the `hack()` command to steal the specified amount of money from the target server. + the :doc:`hack` command to steal the specified amount of money from + the target server. - If `hackAmount` is less than zero or greater than the amount of money available - on the server, then this function returns -1. + If ``hackAmount`` is less than zero or greater than the amount of money + available on the server, then this function returns -1. - For example, let's say the `foodnstuff` server has $10m and you run:: + For example, let's say the 'foodnstuff' server has $10m and you run: + + .. code-block:: javascript hackAnalyzeThreads("foodnstuff", 1e6); - If this function returns 50, this means that if your next `hack()` call + If this function returns 50, this means that if your next :doc:`hack` call is run on a script with 50 threads, it will steal $1m from the `foodnstuff` server. .. warning:: The value returned by this function isn't necessarily a whole number. diff --git a/doc/source/netscript/basicfunctions/hackChance.rst b/doc/source/netscript/basicfunctions/hackChance.rst index 714b8ef44..a5792da97 100644 --- a/doc/source/netscript/basicfunctions/hackChance.rst +++ b/doc/source/netscript/basicfunctions/hackChance.rst @@ -1,11 +1,16 @@ hackChance() Netscript Function =============================== -.. js:function:: hackChance(hostname/ip) +.. js:function:: hackChance(hostname) - :param string hostname/ip: IP or hostname of target server - :returns: The chance you have of successfully hacking the target server :RAM cost: 1 GB + :param string hostname: Hostname of target server. + :returns: The chance you have of successfully hacking the target server. + in decimal form. - Returns the chance you have of successfully hacking the specified server. This - returned value is in decimal form, not percentage. + Example: + + .. code-block:: javascript + + hackChance("foodnstuff"); // returns: .5 + // So 50% chance to hack "foodnstuff" \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/hasRootAccess.rst b/doc/source/netscript/basicfunctions/hasRootAccess.rst index ee561eb7b..da35cef8a 100644 --- a/doc/source/netscript/basicfunctions/hasRootAccess.rst +++ b/doc/source/netscript/basicfunctions/hasRootAccess.rst @@ -1,14 +1,15 @@ hasRootAccess() Netscript Function ================================== -.. js:function:: hasRootAccess(hostname/ip) +.. js:function:: hasRootAccess(hostname) - :param string hostname/ip: Hostname or IP of the target server :RAM cost: 0.05 GB + :param string hostname: Hostname of the target server. + :returns: ``true`` if you have root access on the target server. - Returns a boolean indicating whether or not the player has root access to the specified target server. + Example: - Example:: + .. code-block:: javascript if (hasRootAccess("foodnstuff") == false) { nuke("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/httpworm.rst b/doc/source/netscript/basicfunctions/httpworm.rst index 56a90ebe6..41a3c9348 100644 --- a/doc/source/netscript/basicfunctions/httpworm.rst +++ b/doc/source/netscript/basicfunctions/httpworm.rst @@ -1,13 +1,16 @@ httpworm() Netscript Function ============================= -.. js:function:: httpworm(hostname/ip) +.. js:function:: httpworm(hostname) - :param string hostname/ip: IP or hostname of the target server :RAM cost: 0.05 GB + :param string hostname: Hostname of the target server. - Runs the HTTPWorm.exe program on the target server. HTTPWorm.exe must exist on your home computer. + Runs the HTTPWorm.exe program on the target server. HTTPWorm.exe must exist + on your home computer. - Example:: + Example: + + .. code-block:: javascript httpworm("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/isLogEnabled.rst b/doc/source/netscript/basicfunctions/isLogEnabled.rst index 8967b4cf7..bcef52e91 100644 --- a/doc/source/netscript/basicfunctions/isLogEnabled.rst +++ b/doc/source/netscript/basicfunctions/isLogEnabled.rst @@ -1,10 +1,14 @@ isLogEnabled() Netscript Function ================================= -.. js:function:: isLogEnabled(fn) +.. js:function:: isLogEnabled(functionName) - :param string fn: Name of function to check :RAM cost: 0 GB + :param string functionName: Name of function to check. + :returns: ``true`` is logs are enabled for this function or for 'ALL' - Returns a boolean indicating whether or not logging is enabled for that - function (or 'ALL') + Example: + + .. code-block:: javascript + + isLogEnabled('hack'); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/isRunning.rst b/doc/source/netscript/basicfunctions/isRunning.rst index 41afdd46a..3b74286df 100644 --- a/doc/source/netscript/basicfunctions/isRunning.rst +++ b/doc/source/netscript/basicfunctions/isRunning.rst @@ -1,29 +1,40 @@ isRunning() Netscript Function ============================== -.. js:function:: isRunning(filename, hostname/ip, [args...]) +.. js:function:: isRunning(filename, hostname, [args...]) - :param string filename: Filename of script to check. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server - :param args...: Arguments to specify/identify which scripts to search for :RAM cost: 0.1 GB + :param string filename: Filename of script to check. case-sensitive. + :param string hostname: Hostname of target server. + :param args...: Arguments to specify/identify which scripts to search for + :returns: ``true`` if that script with those args is running on that server. - Returns a boolean indicating whether the specified script is running on the target server. Remember that a script is - uniquely identified by both its name and its arguments. + .. note:: + + Remember that a script is uniquely identified by both its name and its arguments. **Examples:** - In this first example below, the function call will return true if there is a script named *foo.script* with no arguments - running on the *foodnstuff* server, and false otherwise:: + In this first example below, the function call will return true if there is + a script named ``foo.script`` with no arguments running on the + ``foodnstuff`` server, and false otherwise: - isRunning("foo.script", "foodnstuff"); + .. code-block:: javascript - In this second example below, the function call will return true if there is a script named *foo.script* with no arguments - running on the current server, and false otherwise:: + isRunning("foo.script", "foodnstuff"); - isRunning("foo.script", getHostname()); + In this second example below, the function call will return true if there is + a script named ``foo.script`` with no arguments running on the current + server, and false otherwise: - In this next example below, the function call will return true if there is a script named *foo.script* running with the arguments - 1, 5, and "test" (in that order) on the *joesguns* server, and false otherwise:: + .. code-block:: javascript - isRunning("foo.script", "joesguns", 1, 5, "test"); + isRunning("foo.script", getHostname()); + + In this next example below, the function call will return true if there is a + script named ``foo.script`` running with the arguments 1, 5, and "test" (in + that order) on the ``joesguns`` server, and false otherwise: + + .. code-block:: javascript + + isRunning("foo.script", "joesguns", 1, 5, "test"); diff --git a/doc/source/netscript/basicfunctions/kill.rst b/doc/source/netscript/basicfunctions/kill.rst index 7d695628a..b7de6411c 100644 --- a/doc/source/netscript/basicfunctions/kill.rst +++ b/doc/source/netscript/basicfunctions/kill.rst @@ -1,47 +1,57 @@ kill() Netscript Function ========================= -.. js:function:: kill(script, hostname/ip, [args...]) +.. js:function:: kill(script, hostname, [args...]) - :param string script: Filename of the script to kill - :param string hostname/ip: IP or hostname of the server on which to kill the script - :param args...: Arguments to identify which script to kill :RAM cost: 0.5 GB + :param string script: Filename of the script to kill. + :param string hostname: Hostname of the server on which to kill the script. + :param args...: Arguments to identify which script to kill. + :returns: ``true`` is that script was killed. - Kills the script on the target server specified by the script's name and arguments. Remember that scripts - are uniquely identified by both their name and arguments. For example, if *foo.script* is run with the argument 1, then this - is not the same as *foo.script* run with the argument 2, even though they have the same code. - - If this function successfully kills the specified script, then it will return true. Otherwise, it will return false. + Kills the script on the target server specified by the script's name and + arguments. Remember that scripts are uniquely identified by both their name + and arguments. For example, if ``foo.script`` is run with the argument 1, + then this is not the same as ``foo.script`` run with the argument 2, even + though they have the same code. Examples: - The following example will try to kill a script named *foo.script* on the *foodnstuff* server that was ran with no arguments:: + The following example will try to kill a script named ``foo.script`` on the + ``foodnstuff`` server that was ran with no arguments: + + .. code-block:: javascript kill("foo.script", "foodnstuff"); - The following will try to kill a script named *foo.script* on the current server that was ran with no arguments:: + The following will try to kill a script named ``foo.script`` on the current + server that was ran with no arguments: + + .. code-block:: javascript kill("foo.script", getHostname()); - The following will try to kill a script named *foo.script* on the current server that was ran with the arguments 1 and "foodnstuff":: + The following will try to kill a script named ``foo.script`` on the current + server that was ran with the arguments 1 and "foodnstuff": + + .. code-block:: javascript kill("foo.script", getHostname(), 1, "foodnstuff"); .. js:function:: kill(scriptPid) - :param number scriptPid: PID of the script to kill :RAM cost: 0.5 GB + :param number scriptPid: PID of the script to kill + :returns: ``true`` that script was killed. - Kills the script with the specified PID. Killing a script by its PID will typically - have better performance, especially if you have many scripts running. + Kills the script with the specified PID. Killing a script by its PID will + typically have better performance, especially if you have many scripts + running. - If this function successfully kills the specified script, then it will return true. - Otherwise, it will return false. - *Examples:* + Example: - The following example will try to kill the script with the PID 10:: + .. code-block:: javascript if (kill(10)) { print("Killed script with PID 10!"); diff --git a/doc/source/netscript/basicfunctions/killall.rst b/doc/source/netscript/basicfunctions/killall.rst index 5e1cd87a0..305921fa9 100644 --- a/doc/source/netscript/basicfunctions/killall.rst +++ b/doc/source/netscript/basicfunctions/killall.rst @@ -1,10 +1,17 @@ killall() Netscript Function ============================ -.. js:function:: killall(hostname/ip) +.. js:function:: killall(hostname) - :param string hostname/ip: IP or hostname of the server on which to kill all scripts :RAM cost: 0.5 GB + :param string hostname: Hostname of the server on which to kill all scripts. + :returns: ``true`` if scripts were killed on target server. - Kills all running scripts on the specified server. This function returns true if any scripts were killed, and - false otherwise. In other words, it will return true if there are any scripts running on the target server. + Kills all running scripts on the specified server. + + + Example: + + .. code-block:: javascript + + killall('foodnstuff'); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/ls.rst b/doc/source/netscript/basicfunctions/ls.rst index 7ffdc1fd9..27fda79b6 100644 --- a/doc/source/netscript/basicfunctions/ls.rst +++ b/doc/source/netscript/basicfunctions/ls.rst @@ -1,11 +1,15 @@ ls() Netscript Function ======================= -.. js:function:: ls(hostname/ip, [grep]) +.. js:function:: ls(hostname[, grep]) - :param string hostname/ip: Hostname or IP of the target server - :param string grep: a substring to search for in the filename :RAM cost: 0.2 GB + :param string hostname: Hostname of the target server. + :param string grep: a substring to search for in the filename. + :returns: String array of all files in alphabetical order. - Returns an array with the filenames of all files on the specified server (as strings). The returned array - is sorted in alphabetic order + Example: + + .. code-block:: javascript + + ls("home"); // returns: ["demo.script", "msg1.txt"] \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/nFormat.rst b/doc/source/netscript/basicfunctions/nFormat.rst index 9f634e1d5..2f1f86281 100644 --- a/doc/source/netscript/basicfunctions/nFormat.rst +++ b/doc/source/netscript/basicfunctions/nFormat.rst @@ -3,18 +3,20 @@ nFormat() Netscript Function .. js:function:: nFormat(n, format) - :param number n: Number to format - :param string format: Formatter :RAM cost: 0 GB + :param number n: number to format + :param string format: The format to use. - Converts a number into a string with the specified formatter. This uses the - `numeraljs `_ library, so the formatters must be compatible - with that. + Converts a number into a string with the specified format. This uses the + `numeraljs `_ library, so the formatters must be + compatible with that. - This is the same function that the game itself uses to display numbers. + The game uses the ``$0.000a`` format to display money. - Examples:: + Example: - nFormat(1.23e9, "$0.000a"); // Returns "$1.230b" - nFormat(12345.678, "0,0"); // Returns "12,346" - nFormat(0.84, "0.0%"); // Returns "84.0% + .. code-block:: javascript + + nFormat(1.23e9, "$0.000a"); // returns: "$1.230b" + nFormat(12345.678, "0,0"); // returns: "12,346" + nFormat(0.84, "0.0%"); // returns: "84.0%" diff --git a/doc/source/netscript/basicfunctions/nuke.rst b/doc/source/netscript/basicfunctions/nuke.rst index e42807d40..4e53e3161 100644 --- a/doc/source/netscript/basicfunctions/nuke.rst +++ b/doc/source/netscript/basicfunctions/nuke.rst @@ -1,13 +1,16 @@ nuke() Netscript Function ========================= -.. js:function:: nuke(hostname/ip) +.. js:function:: nuke(hostname) - :param string hostname/ip: IP or hostname of the target server :RAM cost: 0.05 GB + :param string hostname: Hostname of the target server. Runs the NUKE.exe program on the target server. NUKE.exe must exist on your home computer. - Example:: + + Example: + + .. code-block:: javascript nuke("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/peek.rst b/doc/source/netscript/basicfunctions/peek.rst index c118f4307..9a44bfa0d 100644 --- a/doc/source/netscript/basicfunctions/peek.rst +++ b/doc/source/netscript/basicfunctions/peek.rst @@ -3,10 +3,12 @@ peek() Netscript Function .. js:function:: peek(port) - :param number port: Port to peek. Must be an integer between 1 and 20 :RAM cost: 1 GB + :param number port: Port to peek. Must be an integer between 1 and 20. + :returns: First element on that port. - This function is used to peek at the data from a port. It returns the first element in the specified port - without removing that element. If the port is empty, the string "NULL PORT DATA" will be returned. + This function is used to peek at the data from a port. It returns the first + element in the specified port without removing that element. If the port is + empty, the string "NULL PORT DATA" will be returned. Read about how :ref:`netscript_ports` work here diff --git a/doc/source/netscript/basicfunctions/print.rst b/doc/source/netscript/basicfunctions/print.rst index b50ec4666..761efd598 100644 --- a/doc/source/netscript/basicfunctions/print.rst +++ b/doc/source/netscript/basicfunctions/print.rst @@ -3,7 +3,13 @@ print() Netscript Function .. js:function:: print(x) - :param x: Value to be printed :RAM cost: 0 GB + :param x: Value to be printed. Prints a value or a variable to the script's logs. + + Example: + + .. code-block:: javascript + + print("Hello world!"); // Prints "Hello world!" in the logs. \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/prompt.rst b/doc/source/netscript/basicfunctions/prompt.rst index 24c2cc7cf..da651ac90 100644 --- a/doc/source/netscript/basicfunctions/prompt.rst +++ b/doc/source/netscript/basicfunctions/prompt.rst @@ -3,8 +3,21 @@ prompt() Netscript Function .. js:function:: prompt(txt) - :param string txt: Text to appear in the prompt dialog box :RAM cost: 0 GB + :param string txt: Text to appear in the prompt dialog box. + :returns: ``true`` if the player clicks "Yes". - Prompts the player with a dialog box with two options: "Yes" and "No". This function will return true if the player click "Yes" and - false if the player clicks "No". The script's execution is halted until the player selects one of the options. + Prompts the player with a dialog box with two options: "Yes" and "No". This + function will return true if the player click "Yes" and false if the player + clicks "No". The script's execution is halted until the player selects one + of the options. + + Example: + + .. code-block:: javascript + + cost = getPurchasedServerCost(8192); + answer = prompt("Buy a server for $"+cost); + if(answer) { + purchaseServer("my server", 8192); + } \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/ps.rst b/doc/source/netscript/basicfunctions/ps.rst index fcdf2583a..a5cdbaf81 100644 --- a/doc/source/netscript/basicfunctions/ps.rst +++ b/doc/source/netscript/basicfunctions/ps.rst @@ -1,28 +1,29 @@ ps() Netscript Function ======================= -.. js:function:: ps(hostname/ip=current ip) +.. js:function:: ps([hostname=current hostname]) - :param string ip: Hostname or IP address of the target server. - If not specified, it will be the current server's IP by default :RAM cost: 0.2 GB + :param string hostname: Hostname address of the target server. + If not specified, it will be the current server's IP by default. + :returns: array of object - Returns an array with general information about all scripts running on the specified - target server. The information for each server is given in an object with - the following structure:: + Returns an array with general information about all scripts running on the + specified target server. The information for each server is given in an + object with the following structure:: { - filename: Script name, - threads: Number of threads script is running with, - args: Script's arguments + filename: Script name, + threads: Number of threads script is running with, + args: Script's arguments } - Example usage (using :ref:`netscriptjs`):: + Example: - export async function main(ns) { - const ps = ns.ps("home"); - for (let i = 0; i < ps.length; ++i) { - ns.tprint(ps[i].filename + ' ' + ps[i].threads); - ns.tprint(ps[i].args); - } + .. code-block:: javascript + + processes = ps("home"); + for (let i = 0; i < ps.length; ++i) { + tprint(ps[i].filename + ' ' + ps[i].threads); + tprint(ps[i].args); } diff --git a/doc/source/netscript/basicfunctions/purchaseServer.rst b/doc/source/netscript/basicfunctions/purchaseServer.rst index 91052c33b..c2ac2d44f 100644 --- a/doc/source/netscript/basicfunctions/purchaseServer.rst +++ b/doc/source/netscript/basicfunctions/purchaseServer.rst @@ -3,25 +3,29 @@ purchaseServer() Netscript Function .. js:function:: purchaseServer(hostname, ram) - :param string hostname: Hostname of the purchased server - :param number ram: Amount of RAM of the purchased server. Must be a power of 2. Maximum value of :js:func:`getPurchasedServerMaxRam` :RAM cost: 2.25 GB + :param string hostname: Hostname of the purchased server. + :param number ram: Amount of RAM of the purchased server. Must be a power of + 2. Maximum value of :doc:`getPurchasedServerMaxRam` + :returns: The hostname of the newly purchased server. Purchased a server with the specified hostname and amount of RAM. - The *hostname* argument can be any data type, but it will be converted to a string and have whitespace removed. Anything that resolves to an empty string will - cause the function to fail. If there is already a server with the specified hostname, then the function will automatically append - a number at the end of the *hostname* argument value until it finds a unique hostname. For example, if the script calls - *purchaseServer("foo", 4)* but a server named "foo" already exists, the it will automatically change the hostname to "foo-0". If there is already - a server with the hostname "foo-0", then it will change the hostname to "foo-1", and so on. + The ``hostname`` argument can be any data type, but it will be converted to + a string and have whitespace removed. Anything that resolves to an empty + string will cause the function to fail. If there is already a server with + the specified hostname, then the function will automatically append a number + at the end of the ``hostname`` argument value until it finds a unique + hostname. For example, if the script calls ``purchaseServer("foo", 4)`` but + a server named "foo" already exists, the it will automatically change the + hostname to "foo-0". If there is already a server with the hostname "foo-0", + then it will change the hostname to "foo-1", and so on. Note that there is a maximum limit to the amount of servers you can purchase. - Returns the hostname of the newly purchased server as a string. If the function fails to purchase a server, then it will return an - empty string. The function will fail if the arguments passed in are invalid, if the player does not have enough money to purchase - the specified server, or if the player has exceeded the maximum amount of servers. + Example: - Example:: + .. code-block:: javascript ram = 64; hn = "pserv-"; diff --git a/doc/source/netscript/basicfunctions/read.rst b/doc/source/netscript/basicfunctions/read.rst index 21f1cd693..b1cf5ca77 100644 --- a/doc/source/netscript/basicfunctions/read.rst +++ b/doc/source/netscript/basicfunctions/read.rst @@ -1,16 +1,21 @@ read() Netscript Function ========================= -.. js:function:: read(port/fn) +.. js:function:: read(portOrFilename) - :param string/number port/fn: Port or text file to read from :RAM cost: 1 GB + :param string/number portOrFilename: Port or text file to read from. - This function is used to read data from a port, a text file (.txt), or a script (.script, .js, .ns) + This function is used to read data from a port, a text file (.txt), or a + script (.script, .js, .ns). - If the argument *port/fn* is a number between 1 and 20, then it specifies a port and it will read data from that port. Read - about how :ref:`netscript_ports` work here. A port is a serialized queue. This function - will remove the first element from that queue and return it. If the queue is empty, then the string "NULL PORT DATA" will be returned. + If the argument ``portOrFilename`` is a number between 1 and 20, then it + specifies a port and it will read data from that port. Read about how + :ref:`netscript_ports` work here. A port is a serialized queue. This + function will remove the first element from that queue and return it. If the + queue is empty, then the string "NULL PORT DATA" will be returned. - If the argument *port/fn* is a string, then it specifies the name of a text file or script and this function will return the data in the specified text file/script. If - the text file does not exist, an empty string will be returned. + If the argument ``portOrFilename`` is a string, then it specifies the name + of a text file or script and this function will return the data in the + specified text file/script. If the text file does not exist, an empty string + will be returned. diff --git a/doc/source/netscript/basicfunctions/relaysmtp.rst b/doc/source/netscript/basicfunctions/relaysmtp.rst index 457bbafa1..5081e54d8 100644 --- a/doc/source/netscript/basicfunctions/relaysmtp.rst +++ b/doc/source/netscript/basicfunctions/relaysmtp.rst @@ -1,13 +1,17 @@ relaysmtp() Netscript Function ============================== -.. js:function:: relaysmtp(hostname/ip) +.. js:function:: relaysmtp(hostname) - :param string hostname/ip: IP or hostname of the target server :RAM cost: 0.05 GB + :param string hostname: Hostname of the target server. - Runs the relaySMTP.exe program on the target server. relaySMTP.exe must exist on your home computer. - Example:: + Runs the relaySMTP.exe program on the target server. relaySMTP.exe must + exist on your home computer. + + Example: + + .. code-block:: javascript relaysmtp("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/rm.rst b/doc/source/netscript/basicfunctions/rm.rst index e5c64bdfc..a1159cff8 100644 --- a/doc/source/netscript/basicfunctions/rm.rst +++ b/doc/source/netscript/basicfunctions/rm.rst @@ -1,11 +1,13 @@ rm() Netscript Function ======================= -.. js:function:: rm(fn[, hostname/ip=current server]) +.. js:function:: rm(filename[, hostname=current server]) - :param string fn: Filename of file to remove. Must include the extension - :param string hostname/ip: Hostname or IP Address of the server on which to delete the file. Optional. Defaults to current server - :returns: True if it successfully deletes the file, and false otherwise :RAM cost: 1 GB + :param string filename: Filename of file to remove. Must include the extension. + :param string hostname: Hostname address of the server on which to delete + the file. Optional. Defaults to current server + :returns: ``true`` if it successfully deletes the file. - Removes the specified file from the current server. This function works for every file type except message (.msg) files. + Removes the specified file from the current server. This function works for + every file type except ``.msg`` files. diff --git a/doc/source/netscript/basicfunctions/run.rst b/doc/source/netscript/basicfunctions/run.rst index 21f7fbe91..b7ef167e6 100644 --- a/doc/source/netscript/basicfunctions/run.rst +++ b/doc/source/netscript/basicfunctions/run.rst @@ -1,38 +1,44 @@ run() Netscript Function ======================== -.. js:function:: run(script, [numThreads=1], [args...]) +.. js:function:: run(script[, numThreads=1[, args...]]) - :param string script: Filename of script to run - :param number numThreads: Optional thread count for new script. Set to 1 by default. Will be rounded to nearest integer - :param args...: - Additional arguments to pass into the new script that is being run. Note that if any arguments are being - passed into the new script, then the second argument *numThreads* must be filled in with a value. :RAM cost: 1 GB + :param string script: Filename of script to run + :param number numThreads: Optional thread count for new script. Set to 1 by + default. Will be rounded to nearest integer. + :param args...: + Additional arguments to pass into the new script that is being run. Note + that if any arguments are being passed into the new script, then the + second argument ``numThreads`` must be filled in with a value. + :returns: The process id of the new process or 0 on failure. - Run a script as a separate process. This function can only be used to run scripts located on the current server (the server - running the script that calls this function). + Run a script as a separate process. This function can only be used to run + scripts located on the current server (the server running the script that + calls this function). - If the script was successfully started, then this functions returns the PID - of that script. Otherwise, it returns 0. + .. warning:: Running this function with a ``numThreads`` argument of 0 will + return 0 without running the script. However, running this function with + a negative ``numThreads`` argument will cause a runtime error. - .. note:: PID stands for Process ID. The PID is a unique identifier for each script. - The PID will always be a positive integer. + The simplest way to use the :doc:`run` command is to call it with just + the script name. The following example will run ``foo.script`` + single-threaded with no arguments: - .. warning:: Running this function with a *numThreads* argument of 0 will return 0 without - running the script. However, running this function with a negative *numThreads* - argument will cause a runtime error. - - The simplest way to use the *run* command is to call it with just the script name. The following example will run - 'foo.script' single-threaded with no arguments:: + .. code-block:: javascript run("foo.script"); - The following example will run 'foo.script' but with 5 threads instead of single-threaded:: + The following example will run 'foo.script' but with 5 threads instead of + single-threaded: + + .. code-block:: javascript run("foo.script", 5); - This next example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script - as an argument:: + This next example will run ``foo.script`` single-threaded, and will pass the + string ``foodnstuff`` into the script as an argument: + + .. code-block:: javascript run("foo.script", 1, 'foodnstuff'); diff --git a/doc/source/netscript/basicfunctions/scan.rst b/doc/source/netscript/basicfunctions/scan.rst index a3412d260..1db16bc3f 100644 --- a/doc/source/netscript/basicfunctions/scan.rst +++ b/doc/source/netscript/basicfunctions/scan.rst @@ -1,11 +1,15 @@ scan() Netscript Function ========================= -.. js:function:: scan(hostname/ip=current ip[, hostnames=true]) +.. js:function:: scan(hostname=current hostname) - :param string hostname/ip: IP or hostname of the server to scan - :param boolean: Optional boolean specifying whether the function should output hostnames (if true) or IP addresses (if false) :RAM cost: 0.2 GB + :param string hostname: Hostname of the server to scan. + :returns: array of strings of all the host directly connected to the target + server. - Returns an array containing the hostnames or IPs of all servers that are one node way from the specified target server. The - hostnames/IPs in the returned array are strings. + Example: + + .. code-block:: javascript + + scan("home"); // returns: ["foodnstuff", "sigma-cosmetics", "joesguns", "hong-fang-tea", "harakiri-sushi", "iron-gym"] \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/scp.rst b/doc/source/netscript/basicfunctions/scp.rst index a290083fa..93a8436a3 100644 --- a/doc/source/netscript/basicfunctions/scp.rst +++ b/doc/source/netscript/basicfunctions/scp.rst @@ -1,29 +1,33 @@ scp() Netscript Function ======================== -.. js:function:: scp(files, [source], destination) +.. js:function:: scp(files[, source], destination) + :RAM cost: 0.6 GB :param string/array files: Filename or an array of filenames of script/literature files to copy :param string source: - Hostname or IP of the source server, which is the server from which the file will be copied. + Hostname of the source server, which is the server from which the file will be copied. This argument is optional and if it's omitted the source will be the current server. - :param string destination: Hostname or IP of the destination server, which is the server to which the file will be copied. - :RAM cost: 0.6 GB + :param string destination: Hostname of the destination server, which is the server to which the file will be copied. + :returns: ``true`` is the copy was a success. - Copies a script or literature (.lit) file(s) to another server. The *files* argument can be either a string specifying a - single file to copy, or an array of strings specifying multiple files to copy. + Copies a script or literature (.lit) file(s) to another server. The + ``files`` argument can be either a string specifying a single file to copy, + or an array of strings specifying multiple files to copy. - Returns true if the script/literature file is successfully copied over and false otherwise. If the *files* argument is an array - then this function will return true if at least one of the files in the array is successfully copied. + If the ``files`` argument is an array then this function will return true if + at least one of the files in the array is successfully copied. - Examples:: + Example: - //Copies hack-template.script from the current server to foodnstuff - scp("hack-template.script", "foodnstuff"); + .. code-block:: javascript - //Copies foo.lit from the helios server to the home computer - scp("foo.lit", "helios", "home"); + //Copies "hack-template.script" from the current server to "foodnstuff" + scp("hack-template.script", "foodnstuff"); // returns: true - //Tries to copy three files from rothman-uni to home computer + //Copies "foo.lit" from the helios server to the "home" computer + scp("foo.lit", "helios", "home"); // returns: true + + //Tries to copy three files from "rothman-uni" to "home" computer files = ["foo1.lit", "foo2.script", "foo3.script"]; - scp(files, "rothman-uni", "home"); + scp(files, "rothman-uni", "home"); // returns: true diff --git a/doc/source/netscript/basicfunctions/scriptKill.rst b/doc/source/netscript/basicfunctions/scriptKill.rst index 767e48322..a3fd5729d 100644 --- a/doc/source/netscript/basicfunctions/scriptKill.rst +++ b/doc/source/netscript/basicfunctions/scriptKill.rst @@ -1,11 +1,18 @@ scriptKill() Netscript Function =============================== -.. js:function:: scriptKill(scriptname, hostname/ip) +.. js:function:: scriptKill(scriptname, hostname) - :param string scriptname: Filename of script to kill. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server :RAM cost: 1 GB + :param string scriptname: Filename of script to kill. case-sensitive. + :param string hostname: Hostname of target server. + :returns: ``true`` if any scripts were killed. - Kills all scripts with the specified filename on the target server specified by *hostname/ip*, regardless of arguments. Returns - true if one or more scripts were successfully killed, and false if none were. + Kills all scripts with the specified filename on the target server specified + by ``hostname``, regardless of arguments. + + Example: + + .. code-block:: javascript + + scriptKill("demo.script"); // returns: true diff --git a/doc/source/netscript/basicfunctions/scriptRunning.rst b/doc/source/netscript/basicfunctions/scriptRunning.rst index a384ea35e..9d4ff91c5 100644 --- a/doc/source/netscript/basicfunctions/scriptRunning.rst +++ b/doc/source/netscript/basicfunctions/scriptRunning.rst @@ -1,24 +1,30 @@ scriptRunning() Netscript Function ================================== -.. js:function:: scriptRunning(scriptname, hostname/ip) +.. js:function:: scriptRunning(scriptname, hostname) - :param string scriptname: Filename of script to check. This is case-sensitive. - :param string hostname/ip: Hostname or IP of target server :RAM cost: 1 GB + :param string scriptname: Filename of script to check. case-sensitive. + :param string hostname: Hostname of target server. + :returns: ``true`` if any script with that file name is running on that + server. - Returns a boolean indicating whether any instance of the specified script is running on the target server, regardless of - its arguments. + This is different than the :doc:`isRunning` function because it + does not try to identify a specific instance of a running script by its + arguments. - This is different than the *isRunning()* function because it does not try to identify a specific instance of a running script - by its arguments. + Examples: - **Examples:** + The example below will return true if there is any script named + ``foo.script`` running on the ``foodnstuff`` server, and false otherwise: - The example below will return true if there is any script named *foo.script* running on the *foodnstuff* server, and false otherwise:: + .. code-block:: javascript scriptRunning("foo.script", "foodnstuff"); - The example below will return true if there is any script named "foo.script" running on the current server, and false otherwise:: + The example below will return true if there is any script named + ``foo.script`` running on the current server, and false otherwise: + + .. code-block:: javascript scriptRunning("foo.script", getHostname()); diff --git a/doc/source/netscript/basicfunctions/serverExists.rst b/doc/source/netscript/basicfunctions/serverExists.rst index c32dab411..76a8f6228 100644 --- a/doc/source/netscript/basicfunctions/serverExists.rst +++ b/doc/source/netscript/basicfunctions/serverExists.rst @@ -1,9 +1,14 @@ serverExists() Netscript Function ================================= -.. js:function:: serverExists(hostname/ip) +.. js:function:: serverExists(hostname) - :param string hostname/ip: Hostname or IP of target server :RAM cost: 0.1 GB + :param string hostname: Hostname of target server. + :returns: ``true`` if the target server exists. - Returns a boolean denoting whether or not the specified server exists + Example: + + .. code-block:: javascript + + serverExists("foodnstuff"); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/sleep.rst b/doc/source/netscript/basicfunctions/sleep.rst index b9109a9cb..d46c176dd 100644 --- a/doc/source/netscript/basicfunctions/sleep.rst +++ b/doc/source/netscript/basicfunctions/sleep.rst @@ -3,7 +3,14 @@ sleep() Netscript Function .. js:function:: sleep(n) - :param number n: Number of milliseconds to sleep :RAM cost: 0 GB + :param number n: Number of milliseconds to sleep Suspends the script for n milliseconds. + + + Example: + + .. code-block:: javascript + + sleep(3000); // Will wait 3 seconds. \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/spawn.rst b/doc/source/netscript/basicfunctions/spawn.rst index d16fe2f60..538bf39e2 100644 --- a/doc/source/netscript/basicfunctions/spawn.rst +++ b/doc/source/netscript/basicfunctions/spawn.rst @@ -1,20 +1,24 @@ spawn() Netscript Function ========================== -.. js:function:: spawn(script, numThreads, [args...]) +.. js:function:: spawn(script, numThreads[, args...]) + :RAM cost: 2 GB :param string script: Filename of script to execute - :param number numThreads: Number of threads to spawn new script with. Will be rounded to nearest integer + :param number numThreads: Number of threads to spawn new script with. Will + be rounded to nearest integer. :param args...: Additional arguments to pass into the new script that is being run. - :RAM cost: 2 GB - Terminates the current script, and then after a delay of about 10 seconds it will execute the newly-specified script. - The purpose of this function is to execute a new script without being constrained by the RAM usage of the current one. - This function can only be used to run scripts on the local server. + Terminates the current script, and then after a delay of about 10 seconds it + will execute the newly-specified script. The purpose of this function is to + execute a new script without being constrained by the RAM usage of the + current one. This function can only be used to run scripts on the local + server. - Because this function immediately terminates the script, it does not have a return value. - The following example will execute the script 'foo.script' with 10 threads and the arguments 'foodnstuff' and 90:: + Example: - spawn('foo.script', 10, 'foodnstuff', 90); + .. code-block:: javascript + + spawn('foo.script', 10, 'foodnstuff', 90); // "run foo.script 10 foodnstuff 90" in 10 seconds. diff --git a/doc/source/netscript/basicfunctions/sqlinject.rst b/doc/source/netscript/basicfunctions/sqlinject.rst index 678371cb1..24ee86142 100644 --- a/doc/source/netscript/basicfunctions/sqlinject.rst +++ b/doc/source/netscript/basicfunctions/sqlinject.rst @@ -1,13 +1,16 @@ sqlinject() Netscript Function ============================== -.. js:function:: sqlinject(hostname/ip) +.. js:function:: sqlinject(hostname) - :param string hostname/ip: IP or hostname of the target server :RAM cost: 0.05 GB + :param string hostname: Hostname of the target server. - Runs the SQLInject.exe program on the target server. SQLInject.exe must exist on your home computer. + Runs the SQLInject.exe program on the target server. SQLInject.exe must + exist on your home computer. - Example:: + Example: + + .. code-block:: javascript sqlinject("foodnstuff"); diff --git a/doc/source/netscript/basicfunctions/tail.rst b/doc/source/netscript/basicfunctions/tail.rst index 18e32a9c1..75cb8df9e 100644 --- a/doc/source/netscript/basicfunctions/tail.rst +++ b/doc/source/netscript/basicfunctions/tail.rst @@ -1,23 +1,25 @@ tail() Netscript Function ================================== -.. js:function:: tail([fn], [hostname/ip=current ip], [...args]) +.. js:function:: tail([fn[, hostname=current hostname[, [...args]]]) - :param string fn: Optional. Filename of script to get logs from. - :param string ip: Optional. IP or hostname of the server that the script is on - :param args...: Arguments to identify which scripts to get logs for :RAM cost: 0 GB + :param string fn: Optional. Filename of script to get logs from. + :param string hostname: Optional. Hostname of the server that the script is on. + :param args...: Arguments to identify which scripts to get logs for. Opens a script's logs. This is functionally the same as the :ref:`tail_terminal_command` Terminal command. If the function is called with no arguments, it will open the current script's logs. - Otherwise, the `fn`, `hostname/ip,` and `args...` arguments can be used to get the logs - from another script. Remember that scripts are uniquely identified by both - their names and arguments. + Otherwise, the ``fn``, ``hostname``, and ``args...`` arguments can be + used to get the logs from another script. Remember that scripts are uniquely + identified by both their names and arguments. - Examples:: + Example: + + .. code-block:: javascript // Open logs from foo.script on the current server that was run with no args tail("foo.script"); diff --git a/doc/source/netscript/basicfunctions/tprint.rst b/doc/source/netscript/basicfunctions/tprint.rst index 271879c30..a502bf3e2 100644 --- a/doc/source/netscript/basicfunctions/tprint.rst +++ b/doc/source/netscript/basicfunctions/tprint.rst @@ -3,7 +3,13 @@ tprint() Netscript Function .. js:function:: tprint(x) - :param x: Value to be printed :RAM cost: 0 GB + :param x: Value to be printed - Prints a value or a variable to the Terminal + Prints a value or a variable to the Terminal. + + Example: + + .. code-block:: javascript + + tprint("Hello world!"); // Prints "Hello world!" to the terminal. \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/tryWrite.rst b/doc/source/netscript/basicfunctions/tryWrite.rst index 3c9a54e84..2264c466c 100644 --- a/doc/source/netscript/basicfunctions/tryWrite.rst +++ b/doc/source/netscript/basicfunctions/tryWrite.rst @@ -3,10 +3,12 @@ tryWrite() Netscript Function .. js:function:: tryWrite(port, data="") + :RAM cost: 1 GB :param number port: Port to be written to :param string data: Data to try to write - :returns: True if the data is successfully written to the port, and false otherwise - :RAM cost: 1 GB + :returns: ``true`` if the data is successfully written to the port. - Attempts to write data to the specified Netscript Port. If the port is full, the data will - not be written. Otherwise, the data will be written normally + Attempts to write data to the specified Netscript Port. If the port is full, + the data will not be written. Otherwise, the data will be written normally. + + See :ref:`netscript_ports` for more details. \ No newline at end of file diff --git a/doc/source/netscript/basicfunctions/weaken.rst b/doc/source/netscript/basicfunctions/weaken.rst index 2d67ddccc..db87afb79 100644 --- a/doc/source/netscript/basicfunctions/weaken.rst +++ b/doc/source/netscript/basicfunctions/weaken.rst @@ -1,26 +1,31 @@ weaken() Netscript Function =========================== -.. js:function:: weaken(hostname/ip[, opts={}]) +.. js:function:: weaken(hostname[, opts={}]) - :param string hostname/ip: IP or hostname of the target server to weaken + :RAM cost: 0.15 GB + :param string hostname: Hostname of the target server to weaken. :param object opts: Optional parameters for configuring function behavior. Properties: * threads (*number*) - Number of threads to use for this function. Must be less than or equal to the number of threads the script is running with. + :returns: The amount by which the target server's security level was + decreased. This is equivalent to 0.05 multiplied by the number of script + threads. - :returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied - by the number of script threads - :RAM cost: 0.15 GB + Use your hacking skills to attack a server's security, lowering the server's + security level. The runtime for this command depends on your hacking level + and the target server's security level. This function lowers the security + level of the target server by 0.05. - Use your hacking skills to attack a server's security, lowering the server's security level. The runtime for this command - depends on your hacking level and the target server's security level. This function lowers the security level of the target - server by 0.05. + Like :doc:`hack` and :doc:`grow`, :doc:`weaken` can be + called on any server, regardless of where the script is running. This + command requires root access to the target server, but there is no required + hacking level to run the command. - Like hack() and grow(), weaken() can be called on any server, regardless of where the script is running. This command requires - root access to the target server, but there is no required hacking level to run the command. + Example: - Example:: + .. code-block:: javascript weaken("foodnstuff"); weaken("foodnstuff", { threads: 5 }); // Only use 5 threads to weaken diff --git a/doc/source/netscript/basicfunctions/wget.rst b/doc/source/netscript/basicfunctions/wget.rst index 78db9950e..423387a78 100644 --- a/doc/source/netscript/basicfunctions/wget.rst +++ b/doc/source/netscript/basicfunctions/wget.rst @@ -1,12 +1,12 @@ wget() Netscript Function ========================= -.. js:function:: wget(url, target[, hostname/ip=current ip]) +.. js:function:: wget(url, target[, hostname=current hostname]) + :RAM cost: 0 GB :param string url: URL to pull data from :param string target: Filename to write data to. Must be script or text file - :param string ip: Optional hostname/ip of server for target file. - :RAM cost: 0 GB + :param string ip: Optional hostname of server for target file. Retrieves data from a URL and downloads it to a file on the specified server. The data can only be downloaded to a script (.script, .ns, .js) or a text file (.txt). If the file already exists, @@ -20,12 +20,12 @@ wget() Netscript Function **IMPORTANT:** This is an asynchronous function that returns a Promise. The Promise's resolved value will be a boolean indicating whether or not the data was successfully retrieved from the URL. Because the function is async and returns a Promise, - it is recommended you use :code:`wget` in :ref:`netscriptjs`. + it is recommended you use ``wget`` in :ref:`netscriptjs`. In NetscriptJS, you must preface any call to - :code:`wget` with the :code:`await` keyword (like you would :code:`hack` or :code:`sleep`). + ``wget`` with the ``await`` keyword (like you would ``hack`` or ``sleep``). - :code:`wget` will still work in :ref:`netscript1`, but the functions execution will not + ``wget`` will still work in :ref:`netscript1`, but the functions execution will not be synchronous (i.e. it may not execute when you expect/want it to). Furthermore, since Promises are not - supported in ES5, you will not be able to process the returned value of :code:`wget` in + supported in ES5, you will not be able to process the returned value of ``wget`` in Netscript 1.0. diff --git a/doc/source/netscript/basicfunctions/write.rst b/doc/source/netscript/basicfunctions/write.rst index c492ea51d..497e8b54c 100644 --- a/doc/source/netscript/basicfunctions/write.rst +++ b/doc/source/netscript/basicfunctions/write.rst @@ -1,20 +1,27 @@ write() Netscript Function =========================== -.. js:function:: write(port/fn, data="", mode="a") +.. js:function:: write(portOrFilename, data="", mode="a") - :param string/number port/fn: Port or text file/script that will be written to + :RAM cost: 1 GB + :param string/number portOrFilename: Port or text file/script that will be written to :param string data: Data to write :param string mode: Defines the write mode. Only valid when writing to text files or scripts. - :RAM cost: 1 GB - This function can be used to either write data to a port, a text file (.txt), or a script (.script, .js, .ns) - If the first argument is a number between 1 and 20, then it specifies a port and this function will write *data* to that port. Read - about how :ref:`netscript_ports` work here. The third argument, *mode*, is not used + This function can be used to either write data to a port, a text file + (.txt), or a script (.script, .js, .ns) + + If the first argument is a number between 1 and 20, then it specifies a port + and this function will write ``data`` to that port. Read about how + :ref:`netscript_ports` work here. The third argument, ``mode``, is not used when writing to a port. - If the first argument is a string, then it specifies the name of a text file or script and this function will write *data* to that text file/script. If the - specified text file/script does not exist, then it will be created. The third argument *mode*, defines how the data will be written. If *mode* - is set to "w", then the data is written in "write" mode which means that it will overwrite all existing data on the text file/script. If *mode* is set to - any other value then the data will be written in "append" mode which means that the data will be added at the end of the file. + If the first argument is a string, then it specifies the name of a text file + or script and this function will write ``data`` to that text file/script. If + the specified text file/script does not exist, then it will be created. The + third argument ``mode``, defines how the data will be written. If ``mode`` + is set to "w", then the data is written in "write" mode which means that it + will overwrite all existing data on the text file/script. If ``mode`` is set + to any other value then the data will be written in "append" mode which + means that the data will be added at the end of the file. diff --git a/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst b/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst index 7e49939f6..b2dc609ec 100644 --- a/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst +++ b/doc/source/netscript/bladeburnerapi/getActionAutolevel.rst @@ -4,10 +4,12 @@ getActionAutolevel() Netscript Function .. js:function:: getActionAutolevel(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match + :returns: ``true`` if this action is set to auto level. - Return a boolean indicating whether or not this action is currently set to autolevel. + Examples: - Returns false if an invalid action is specified. + .. code-block:: javascript + + bladeburner.getActionAutolevel("Contracts", "Tracking"); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst b/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst index a1938bb9e..2e658118c 100644 --- a/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst +++ b/doc/source/netscript/bladeburnerapi/getActionCountRemaining.rst @@ -4,12 +4,18 @@ getActionCountRemaining() Netscript Function .. js:function:: getActionCountRemaining(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match + :returns: Remaining action count. -1 for invalid actions. - Returns the remaining count of the specified action. + Note that this is meant to be used for 'Contracts' and 'Operations'. + This function will return 'Infinity' for actions such as 'Training' and + 'Field Analysis'. + This function will return 1 for BlackOps not yet completed regardless of + wether the player has the required rank to attempt the mission or not. - Note that this is meant to be used for Contracts and Operations. - This function will return 'Infinity' for actions such as Training and Field Analysis. - This function will return 1 for BlackOps not yet completed regardless of wether the player has the required rank to attempt the mission or not. + Example: + + .. code-block:: javascript + + bladeburner.getActionCountRemaining("Contracts", "Tracking"); // returns: 124 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst b/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst index efb234e8a..c55faedb4 100644 --- a/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst +++ b/doc/source/netscript/bladeburnerapi/getActionCurrentLevel.rst @@ -4,10 +4,12 @@ getActionCurrentLevel() Netscript Function .. js:function:: getActionCurrentLevel(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` - :param string name: Name of action. Must be an exact match + :param string name: Name of action. Must be an exact match. + :returns: Action current level, -1 for invalid actions. - Returns the current level of this action. + Example: - Returns -1 if an invalid action is specified. + .. code-block:: javascript + + bladeburner.getActionCountRemaining("Contracts", "Tracking"); // returns: 7 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst b/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst index 5ca773c2e..0677c180f 100644 --- a/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst +++ b/doc/source/netscript/bladeburnerapi/getActionEstimatedSuccessChance.rst @@ -4,10 +4,12 @@ getActionEstimatedSuccessChance() Netscript Function .. js:function:: getActionEstimatedSuccessChance(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match + :returns: Estimated success chance in decimal - Returns the estimated success chance for the specified action. This chance - is returned as a decimal value, NOT a percentage (e.g. if you have an estimated - success chance of 80%, then this function will return 0.80, NOT 80). + Example: + + .. code-block:: javascript + + bladeburner.getActionEstimatedSuccessChance("Contracts", "Tracking"); // returns: .3 diff --git a/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst b/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst index a42bf7517..92b48f875 100644 --- a/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst +++ b/doc/source/netscript/bladeburnerapi/getActionMaxLevel.rst @@ -4,10 +4,12 @@ getActionMaxLevel() Netscript Function .. js:function:: getActionMaxLevel(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match + :returns: Action max level, -1 for invalid actions. - Returns the maximum level for this action. + Example: - Returns -1 if an invalid action is specified. + .. code-block:: javascript + + bladeburner.getActionMaxLevel("Contracts", "Tracking"); // returns: 15 diff --git a/doc/source/netscript/bladeburnerapi/getActionRepGain.rst b/doc/source/netscript/bladeburnerapi/getActionRepGain.rst index 2d9948a97..5bfeda64d 100644 --- a/doc/source/netscript/bladeburnerapi/getActionRepGain.rst +++ b/doc/source/netscript/bladeburnerapi/getActionRepGain.rst @@ -4,11 +4,15 @@ getActionRepGain() Netscript Function .. js:function:: getActionRepGain(type, name[, level=current level]) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match - :param number level: Optional action level at which to calculate the gain + :param number level: Optional action level at which to calculate the gain. + :returns: Average Bladeburner reputation gain for successfully completing + the specified action. Note that this value is an 'average' and the real + reputation gain may vary slightly from this value. - Returns the average Bladeburner reputation gain for successfully completing - the specified action. Note that this value is an 'average' and the real - reputation gain may vary slightly from this value. + Example: + + .. code-block:: javascript + + bladeburner.getActionRepGain("Contracts", "Tracking"); // returns: 341 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getActionTime.rst b/doc/source/netscript/bladeburnerapi/getActionTime.rst index 42df756fc..e89f39c4f 100644 --- a/doc/source/netscript/bladeburnerapi/getActionTime.rst +++ b/doc/source/netscript/bladeburnerapi/getActionTime.rst @@ -4,8 +4,13 @@ getActionTime() Netscript Function .. js:function:: getActionTime(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match + :returns: Number of seconds it takes to complete the specified action. - Returns the number of seconds it takes to complete the specified action + + Example: + + .. code-block:: javascript + + bladeburner.getActionTime("Contracts", "Tracking"); // returns: 4 diff --git a/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst b/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst index b95edd9bf..310cdf681 100644 --- a/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst +++ b/doc/source/netscript/bladeburnerapi/getBlackOpNames.rst @@ -4,5 +4,10 @@ getBlackOpNames() Netscript Function .. js:function:: getBlackOpNames() :RAM cost: 0.4 GB + :returns: Array of strings containing the names of all Bladeburner Black Ops. - Returns an array of strings containing the names of all Bladeburner Black Ops + Example: + + .. code-block:: javascript + + bladeburner.getBlackOpNames(); // returns: ["Operation Typhoon"] \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getBlackOpRank.rst b/doc/source/netscript/bladeburnerapi/getBlackOpRank.rst index 0aba8a3ad..850cef76c 100644 --- a/doc/source/netscript/bladeburnerapi/getBlackOpRank.rst +++ b/doc/source/netscript/bladeburnerapi/getBlackOpRank.rst @@ -4,9 +4,11 @@ getBlackOpRank() Netscript Function .. js:function:: getBlackOpRank(name) :RAM cost: 2 GB - :param string name: name of the BlackOp. Must be an exact match. + :returns: Rank required to complete this BlackOp. -1 for invalid BlackOp. - Returns the rank required to complete this BlackOp. + Example: - Returns -1 if an invalid action is specified. + .. code-block:: javascript + + bladeburner.getBlackOpRank("Operation Typhoon"); // returns: 2500 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getBonusTime.rst b/doc/source/netscript/bladeburnerapi/getBonusTime.rst index 9fdf7d3cc..fc693a68f 100644 --- a/doc/source/netscript/bladeburnerapi/getBonusTime.rst +++ b/doc/source/netscript/bladeburnerapi/getBonusTime.rst @@ -4,8 +4,7 @@ getBonusTime() Netscript Function .. js:function:: getBonusTime() :RAM cost: 0 GB - - Returns the amount of accumulated "bonus time" (seconds) for the Bladeburner mechanic. + :returns: Amount of accumulated "bonus time" (seconds) for the Bladeburner mechanic. "Bonus time" is accumulated when the game is offline or if the game is inactive in the browser. @@ -14,3 +13,9 @@ getBonusTime() Netscript Function For example, if an action takes 30 seconds to complete but you've accumulated over 30 seconds in bonus time, then the action will only take 6 seconds in real life to complete. + + Example: + + .. code-block:: javascript + + bladeburner.getBonusTime(); // returns: 130 diff --git a/doc/source/netscript/bladeburnerapi/getCity.rst b/doc/source/netscript/bladeburnerapi/getCity.rst index cdc2d775e..49a6bd1b9 100644 --- a/doc/source/netscript/bladeburnerapi/getCity.rst +++ b/doc/source/netscript/bladeburnerapi/getCity.rst @@ -4,5 +4,10 @@ getCity() Netscript Function .. js:function:: getCity() :RAM cost: 4 GB + :returns: City that the player is currently in (for Bladeburner). - Returns the city that the player is currently in (for Bladeburner). + Example: + + .. code-block:: javascript + + bladeburner.getCity(); // returns: "Sector-12" diff --git a/doc/source/netscript/bladeburnerapi/getCityChaos.rst b/doc/source/netscript/bladeburnerapi/getCityChaos.rst index 77fb0b073..e17fa7d8b 100644 --- a/doc/source/netscript/bladeburnerapi/getCityChaos.rst +++ b/doc/source/netscript/bladeburnerapi/getCityChaos.rst @@ -4,7 +4,11 @@ getCityChaos() Netscript Function .. js:function:: getCityChaos(cityName) :RAM cost: 4 GB - :param string cityName: Name of city. Case-sensitive + :returns: Chaos in the specified city, or -1 if an invalid city was specified. - Returns the chaos in the specified city, or -1 if an invalid city was specified + Example: + + .. code-block:: javascript + + bladeburner.getCityChaos("Sector-12"); // returns: 3800.1 diff --git a/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst b/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst index 2dd20c9f2..34cace15f 100644 --- a/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst +++ b/doc/source/netscript/bladeburnerapi/getCityEstimatedCommunities.rst @@ -4,8 +4,12 @@ getCityEstimatedCommunities() Netscript Function .. js:function:: getCityEstimatedCommunities(cityName) :RAM cost: 4 GB - :param string cityName: Name of city. Case-sensitive + :returns: Estimated number of Synthoid communities in the specified city, + or -1 if an invalid city was specified. - Returns the estimated number of Synthoid communities in the specified city, - or -1 if an invalid city was specified. + Example: + + .. code-block:: javascript + + bladeburner.getCityEstimatedCommunities("Sector-12"); // returns: 76 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst b/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst index 328f2aa19..bca2c69ed 100644 --- a/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst +++ b/doc/source/netscript/bladeburnerapi/getCityEstimatedPopulation.rst @@ -4,8 +4,12 @@ getCityEstimatedPopulation() Netscript Function .. js:function:: getCityEstimatedPopulation(cityName) :RAM cost: 4 GB - :param string cityName: Name of city. Case-sensitive + :returns: Estimated number of Synthoids in the specified city, or -1 if an + invalid city was specified. - Returns the estimated number of Synthoids in the specified city, or -1 - if an invalid city was specified. + Example: + + .. code-block:: javascript + + bladeburner.getCityEstimatedPopulation("Sector-12"); // returns: 1240000 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getContractNames.rst b/doc/source/netscript/bladeburnerapi/getContractNames.rst index f5aa79808..612d8e6a4 100644 --- a/doc/source/netscript/bladeburnerapi/getContractNames.rst +++ b/doc/source/netscript/bladeburnerapi/getContractNames.rst @@ -4,5 +4,10 @@ getContractNames() Netscript Function .. js:function:: getContractNames() :RAM cost: 0.4 GB + :returns: Array of strings containing the names of all Bladeburner contracts. - Returns an array of strings containing the names of all Bladeburner contracts + Example: + + .. code-block:: javascript + + bladeburner.getContractNames(); // returns: ["Tracking"] \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getCurrentAction.rst b/doc/source/netscript/bladeburnerapi/getCurrentAction.rst index d15e7fed2..ef4821bbf 100644 --- a/doc/source/netscript/bladeburnerapi/getCurrentAction.rst +++ b/doc/source/netscript/bladeburnerapi/getCurrentAction.rst @@ -4,8 +4,9 @@ getCurrentAction() Netscript Function .. js:function:: getCurrentAction() :RAM cost: 1 GB + :returns: An object that represents the player's current Bladeburner action. - Returns an object that represents the player's current Bladeburner action:: + Result:: { type: Type of Action @@ -14,3 +15,11 @@ getCurrentAction() Netscript Function If the player is not performing an action, the function will return an object with the 'type' property set to "Idle". + + Example: + + .. code-block:: javascript + + action = bladeburner.getCurrentAction(); + print(action.type); // "Contracts" + print(action.name); // "Tracking" diff --git a/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst b/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst index efa335998..a853fbd38 100644 --- a/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst +++ b/doc/source/netscript/bladeburnerapi/getGeneralActionNames.rst @@ -4,5 +4,10 @@ getGeneralActionNames() Netscript Function .. js:function:: getGeneralActionNames() :RAM cost: 0.4 GB + :returns: Array of strings containing the names of all general Bladeburner actions. - Returns an array of strings containing the names of all general Bladeburner actions + Example: + + .. code-block:: javascript + + bladeburner.getGeneralActionNames(); // returns: ["Training"] diff --git a/doc/source/netscript/bladeburnerapi/getOperationNames.rst b/doc/source/netscript/bladeburnerapi/getOperationNames.rst index 0bce307a9..dbb4497be 100644 --- a/doc/source/netscript/bladeburnerapi/getOperationNames.rst +++ b/doc/source/netscript/bladeburnerapi/getOperationNames.rst @@ -4,5 +4,10 @@ getOperationNames() Netscript Function .. js:function:: getOperationNames() :RAM cost: 0.4 GB + :returns: Array of strings containing the names of all Bladeburner operations. - Returns an array of strings containing the names of all Bladeburner operations + Example: + + .. code-block:: javascript + + bladeburner.getOperationNames(); // returns: ["Investigation"] diff --git a/doc/source/netscript/bladeburnerapi/getRank.rst b/doc/source/netscript/bladeburnerapi/getRank.rst index dca51ff25..fec20883c 100644 --- a/doc/source/netscript/bladeburnerapi/getRank.rst +++ b/doc/source/netscript/bladeburnerapi/getRank.rst @@ -4,5 +4,10 @@ getRank() Netscript Function .. js:function:: getRank() :RAM cost: 4 GB + :returns: Player's Bladeburner Rank. - Returns the player's Bladeburner Rank + Example: + + .. code-block:: javascript + + bladeburner.getRank(); // returns: 87135 diff --git a/doc/source/netscript/bladeburnerapi/getSkillLevel.rst b/doc/source/netscript/bladeburnerapi/getSkillLevel.rst index 832e16fa0..0f116dae1 100644 --- a/doc/source/netscript/bladeburnerapi/getSkillLevel.rst +++ b/doc/source/netscript/bladeburnerapi/getSkillLevel.rst @@ -1,12 +1,14 @@ getSkillLevel() Netscript Function ================================== -.. js:function:: getSkillLevel(skillName="") +.. js:function:: getSkillLevel(skillName) :RAM cost: 4 GB + :param string skillName: Name of skill. Case-sensitive. + :returns: Level of specified skill, -1 for invalid skills. - :param string skillName: Name of skill. Case-sensitive and must be an exact match + Example: - This function returns your level in the specified skill. + .. code-block:: javascript - The function returns -1 if an invalid skill name is passed in + bladeburner.getSkillLevel("Overclock"); // returns: 90 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getSkillNames.rst b/doc/source/netscript/bladeburnerapi/getSkillNames.rst index fd5a8ded5..70a811fb6 100644 --- a/doc/source/netscript/bladeburnerapi/getSkillNames.rst +++ b/doc/source/netscript/bladeburnerapi/getSkillNames.rst @@ -4,5 +4,10 @@ getSkillNames() Netscript Function .. js:function:: getSkillNames() :RAM cost: 0.4 GB + :returns: Array of strings containing the names of all Bladeburner skills. - Returns an array of strings containing the names of all Bladeburner skills + Example: + + .. code-block:: javascript + + bladeburner.getSkillNames(); // returns: ["Overclock"] diff --git a/doc/source/netscript/bladeburnerapi/getSkillPoints.rst b/doc/source/netscript/bladeburnerapi/getSkillPoints.rst index a6aabbc02..7323cfb07 100644 --- a/doc/source/netscript/bladeburnerapi/getSkillPoints.rst +++ b/doc/source/netscript/bladeburnerapi/getSkillPoints.rst @@ -4,5 +4,10 @@ getSkillPoints() Netscript Function .. js:function:: getSkillPoints() :RAM cost: 4 GB + :returns: Amount of Bladeburner skill points you have. - Returns the number of Bladeburner skill points you have + Example: + + .. code-block:: javascript + + bladeburner.getSkillPoints(); // returns: 1630 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst b/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst index 6f88df730..27c509615 100644 --- a/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst +++ b/doc/source/netscript/bladeburnerapi/getSkillUpgradeCost.rst @@ -1,13 +1,14 @@ getSkillUpgradeCost() Netscript Function ======================================== -.. js:function:: getSkillUpgradeCost(skillName="") +.. js:function:: getSkillUpgradeCost(skillName) :RAM cost: 4 GB - :param string skillName: Name of skill. Case-sensitive and must be an exact match + :returns: Amount of skill points needed to upgrade the specified skill. -1 for invalid skills. - This function returns the number of skill points needed to upgrade the - specified skill. + Example: - The function returns -1 if an invalid skill name is passed in. + .. code-block:: javascript + + bladeburner.getSkillUpgradeCost("Overclock"); // returns: 120 diff --git a/doc/source/netscript/bladeburnerapi/getStamina.rst b/doc/source/netscript/bladeburnerapi/getStamina.rst index 13b0ebfac..9fbc50ab1 100644 --- a/doc/source/netscript/bladeburnerapi/getStamina.rst +++ b/doc/source/netscript/bladeburnerapi/getStamina.rst @@ -4,14 +4,11 @@ getStamina() Netscript Function .. js:function:: getStamina() :RAM cost: 4 GB + :returns: Array with two elements [Current stamina, Max stamina] - Returns an array with two elements: + Example: - [Current stamina, Max stamina] + .. code-block:: javascript - Example usage:: - - function getStaminaPercentage() { - let res = bladeburner.getStamina(); - return res[0] / res[1]; - } + res = bladeburner.getStamina(); + percentage = res[0] / res[1]; diff --git a/doc/source/netscript/bladeburnerapi/getTeamSize.rst b/doc/source/netscript/bladeburnerapi/getTeamSize.rst index bdfaf9be7..f0052768d 100644 --- a/doc/source/netscript/bladeburnerapi/getTeamSize.rst +++ b/doc/source/netscript/bladeburnerapi/getTeamSize.rst @@ -4,12 +4,16 @@ getTeamSize() Netscript Function .. js:function:: getTeamSize(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match - - Returns the number of Bladeburner team members you have assigned to the - specified action. + :returns: Number of Bladeburner team members you have assigned to the + specified action. Setting a team is only applicable for Operations and BlackOps. This function will return 0 for other action types. + + Example: + + .. code-block:: javascript + + bladeburner.getTeamSize("Operations", "Investigation"); // returns: 7 \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst b/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst index 58f9cbe2e..5274c4e1f 100644 --- a/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst +++ b/doc/source/netscript/bladeburnerapi/joinBladeburnerDivision.rst @@ -4,10 +4,13 @@ joinBladeburnerDivision() Netscript Function .. js:function:: joinBladeburnerDivision() :RAM cost: 4 GB + :returns: ``true`` if you successfully join the Bladeburner division, or if you + are already a member. Attempts to join the Bladeburner division. - Returns true if you successfully join the Bladeburner division, or if you - are already a member. + Example: - Returns false otherwise + .. code-block:: javascript + + bladeburner.joinBladeburnerDivision(); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst b/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst index 8cb103c88..26c4f40cc 100644 --- a/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst +++ b/doc/source/netscript/bladeburnerapi/joinBladeburnerFaction.rst @@ -4,10 +4,13 @@ joinBladeburnerFaction() Netscript Function .. js:function:: joinBladeburnerFaction() :RAM cost: 4 GB + :returns: ``true`` if you successfully join the Bladeburner faction, or if + you are already a member. Attempts to join the Bladeburner faction. - Returns true if you successfully join the Bladeburner faction, or if - you are already a member. + Example: - Returns false otherwise. + .. code-block:: javascript + + bladeburner.joinBladeburnerFaction(); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst b/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst index ede833539..aa42d7af5 100644 --- a/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst +++ b/doc/source/netscript/bladeburnerapi/setActionAutolevel.rst @@ -4,9 +4,14 @@ setActionAutolevel() Netscript Function .. js:function:: setActionAutolevel(type, name, autoLevel) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match :param boolean autoLevel: Whether or not to autolevel this action Enable/disable autoleveling for the specified action. + + Example: + + .. code-block:: javascript + + bladeburner.setActionAutolevel("Contracts", "Tracking", true); diff --git a/doc/source/netscript/bladeburnerapi/setActionLevel.rst b/doc/source/netscript/bladeburnerapi/setActionLevel.rst index 3b4b09366..23a274940 100644 --- a/doc/source/netscript/bladeburnerapi/setActionLevel.rst +++ b/doc/source/netscript/bladeburnerapi/setActionLevel.rst @@ -4,9 +4,14 @@ setActionLevel() Netscript Function .. js:function:: setActionLevel(type, name, level) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match :param level int: Level to set this action to Set the level for the specified action. + + Example: + + .. code-block:: javascript + + bladeburner.setActionLevel("Contracts", "Tracking", 10); diff --git a/doc/source/netscript/bladeburnerapi/setTeamSize.rst b/doc/source/netscript/bladeburnerapi/setTeamSize.rst index c13886473..630d71af0 100644 --- a/doc/source/netscript/bladeburnerapi/setTeamSize.rst +++ b/doc/source/netscript/bladeburnerapi/setTeamSize.rst @@ -4,11 +4,15 @@ setTeamSize() Netscript Function .. js:function:: setTeamSize(type, name, size) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match :param int size: Number of team members to set. Will be converted using Math.round() + :returns: Team size or -1 for invalid actions. Set the team size for the specified Bladeburner action. - Returns the team size that was set, or -1 if the function failed. + Example: + + .. code-block:: javascript + + bladeburner.setTeamSize("Operations", "Investigation", 7); \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/startAction.rst b/doc/source/netscript/bladeburnerapi/startAction.rst index 1c6040135..c2e7cfc7a 100644 --- a/doc/source/netscript/bladeburnerapi/startAction.rst +++ b/doc/source/netscript/bladeburnerapi/startAction.rst @@ -4,9 +4,14 @@ startAction() Netscript Function .. js:function:: startAction(type, name) :RAM cost: 4 GB - :param string type: Type of action. See :ref:`bladeburner_action_types` :param string name: Name of action. Must be an exact match + :returns: ``true`` if the action was started successfully. - Attempts to start the specified Bladeburner action. Returns true if the action - was started successfully, and false otherwise. + Attempts to start the specified Bladeburner action. + + Example: + + .. code-block:: javascript + + bladeburner.startAction("Contracts", "Tracking"); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst b/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst index db59dea95..abb86f97e 100644 --- a/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst +++ b/doc/source/netscript/bladeburnerapi/stopBladeburnerAction.rst @@ -6,3 +6,9 @@ stopBladeburnerAction() Netscript Function :RAM cost: 2 GB Stops the current Bladeburner action + + Example: + + .. code-block:: javascript + + bladeburner.stopBladeburnerAction(); \ No newline at end of file diff --git a/doc/source/netscript/bladeburnerapi/switchCity.rst b/doc/source/netscript/bladeburnerapi/switchCity.rst index a696b5057..ead7399dc 100644 --- a/doc/source/netscript/bladeburnerapi/switchCity.rst +++ b/doc/source/netscript/bladeburnerapi/switchCity.rst @@ -4,9 +4,13 @@ switchCity() Netscript Function .. js:function:: switchCity(cityName) :RAM cost: 4 GB - :param string cityName: Name of city + :returns: ``true`` if successful. Attempts to switch to the specified city (for Bladeburner only). - Returns true if successful, and false otherwise + Example: + + .. code-block:: javascript + + bladeburner.switchCity("Sector-12"); // returns: true diff --git a/doc/source/netscript/bladeburnerapi/upgradeSkill.rst b/doc/source/netscript/bladeburnerapi/upgradeSkill.rst index 191e38429..b5ceb43eb 100644 --- a/doc/source/netscript/bladeburnerapi/upgradeSkill.rst +++ b/doc/source/netscript/bladeburnerapi/upgradeSkill.rst @@ -4,8 +4,13 @@ upgradeSkill() Netscript Function .. js:function:: upgradeSkill(skillName) :RAM cost: 4 GB - :param string skillName: Name of Skill to be upgraded. Case-sensitive and must be an exact match + :returns: ``true`` if the skill is successfully upgraded. - Attempts to upgrade the specified Bladeburner skill. Returns true if the - skill is successfully upgraded, and false otherwise + Attempts to upgrade the specified Bladeburner skill. + + Example: + + .. code-block:: javascript + + bladeburner.upgradeSkill("Overclock"); // returns: true \ No newline at end of file diff --git a/doc/source/netscript/codingcontractapi/attempt.rst b/doc/source/netscript/codingcontractapi/attempt.rst index cbfca63aa..a0d569aec 100644 --- a/doc/source/netscript/codingcontractapi/attempt.rst +++ b/doc/source/netscript/codingcontractapi/attempt.rst @@ -1,22 +1,27 @@ attempt() Netscript Function ============================ -.. js:function:: attempt(answer, fn[, hostname/ip=current ip, opts={}]) +.. js:function:: attempt(answer, filename[, hostname=current hostname[, opts={}]]) + :RAM cost: 10 GB :param answer: Solution for the contract - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. + :param string filename: Filename of the contract + :param string hostname: Hostname of the server containing the contract. Optional. Defaults to current server if not provided :param object opts: Optional parameters for configuring function behavior. Properties: * returnReward (*boolean*) If truthy, then the function will return a string that states the contract's reward when it is successfully solved. + :returns: ``true`` if the solution was correct. If the :code:`returnReward` + option is configured, then the function will instead return a + string. If the contract is successfully solved, the string will + contain a description of the contract's reward. Otherwise, it will + be an empty string. Attempts to solve the Coding Contract with the provided solution. - :returns: Boolean indicating whether the solution was correct. If the :code:`returnReward` - option is configured, then the function will instead return a string. If the - contract is successfully solved, the string will contain a description of the - contract's reward. Otherwise, it will be an empty string. + Example: - :RAM cost: 10 GB + .. code-block:: javascript + + codingcontract.attempt("myanswer!", "contract-123.cct", "home"); diff --git a/doc/source/netscript/codingcontractapi/getContractType.rst b/doc/source/netscript/codingcontractapi/getContractType.rst index a4e4bec64..401a981e6 100644 --- a/doc/source/netscript/codingcontractapi/getContractType.rst +++ b/doc/source/netscript/codingcontractapi/getContractType.rst @@ -1,15 +1,19 @@ getContractType() Netscript Function ==================================== -.. js:function:: getContractType(fn[, hostname/ip=current ip]) - - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Returns a name describing the type of problem posed by the Coding Contract. - (e.g. Find Largest Prime Factor, Total Ways to Sum, etc.) - - :returns: A string with the contract's problem type +.. js:function:: getContractType(filename[, hostname=current hostname]) :RAM cost: 5 GB + :param string filename: Filename of the contract + :param string hostname: Hostname of the server containing the contract. + Optional. Defaults to current server if not provided + :returns: A string with the contract's problem type + + Describes the type of problem posed by the Coding Contract. + (e.g. Find Largest Prime Factor, Total Ways to Sum, etc.) + + Example: + + .. code-block:: javascript + + codingcontract.getContractType("contract-123.cct", "home"); diff --git a/doc/source/netscript/codingcontractapi/getData.rst b/doc/source/netscript/codingcontractapi/getData.rst index 0efe2d224..b330f56cd 100644 --- a/doc/source/netscript/codingcontractapi/getData.rst +++ b/doc/source/netscript/codingcontractapi/getData.rst @@ -1,14 +1,22 @@ getData() Netscript Function ============================ -.. js:function:: getData(fn[, hostname/ip=current ip]) +.. js:function:: getData(filename[, hostname=current hostname]) - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided + :param string filename: Filename of the contract + :param string hostname: Hostname of the server containing the contract. + Optional. Defaults to current server if not provided + :returns: The specified contract's data. Different data type depending on + contract type. Get the data associated with the specific Coding Contract. Note that this is not the same as the contract's description. This is just the data that the contract wants you to act on in order to solve - :returns: The specified contract's data + Example: + + .. code-block:: javascript + + data = codingcontract.getData("contract-123.cct", "home"); + answer = solve(data); + codingcontract.attempt(answer, "contract-123.cct", "home"); \ No newline at end of file diff --git a/doc/source/netscript/codingcontractapi/getDescription.rst b/doc/source/netscript/codingcontractapi/getDescription.rst index b5852eb7b..62fa67d88 100644 --- a/doc/source/netscript/codingcontractapi/getDescription.rst +++ b/doc/source/netscript/codingcontractapi/getDescription.rst @@ -1,14 +1,18 @@ getDescription() Netscript Function =================================== -.. js:function:: getDescription(fn[, hostname/ip=current ip]) - - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided - - Get the full text description for the problem posed by the Coding Contract - - :returns: A string with the contract's text description +.. js:function:: getDescription(filename[, hostname=current hostname]) :RAM cost: 5 GB + :param string filename: Filename of the contract + :param string hostname: Hostname of the server containing the contract. + Optional. Defaults to current server if not provided + :returns: A string with the contract's text description + + Get the full text description for the problem posed by the Coding Contract. + + Example: + + .. code-block:: javascript + + codingcontract.getDescription("contract-123.cct", "home"); \ No newline at end of file diff --git a/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst b/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst index 7451aa6ab..7e8f90207 100644 --- a/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst +++ b/doc/source/netscript/codingcontractapi/getNumTriesRemaining.rst @@ -1,15 +1,19 @@ getNumTriesRemaining() Netscript Function ========================================= -.. js:function:: getNumTriesRemaining(fn[, hostname/ip=current ip]) +.. js:function:: getNumTriesRemaining(filename[, hostname=current hostname]) - :param string fn: Filename of the contract - :param string hostname/ip: Hostname or IP of the server containing the contract. - Optional. Defaults to current server if not provided + :RAM cost: 2 GB + :param string filename: Filename of the contract + :param string hostname: Hostname of the server containing the contract. + Optional. Defaults to current server if not provided + :returns: Number indicating how many attempts are remaining Get the number of tries remaining on the contract before it self-destructs. - :returns: Number indicating how many attempts are remaining + Example: - :RAM cost: 2 GB + .. code-block:: javascript + + codingcontract.getNumTriesRemaining("contract-123.cct", "home"); // returns: 5 \ No newline at end of file diff --git a/doc/source/netscript/gangapi/ascendMember.rst b/doc/source/netscript/gangapi/ascendMember.rst index 268b7691e..d925c373c 100644 --- a/doc/source/netscript/gangapi/ascendMember.rst +++ b/doc/source/netscript/gangapi/ascendMember.rst @@ -4,11 +4,7 @@ ascendMember() Netscript Function .. js:function:: ascendMember(name) :RAM cost: 4 GB - :param string name: Name of member to ascend - - Ascend the specified Gang Member. - :returns: An object with info about the ascension results. The object has the following structure:: @@ -22,3 +18,5 @@ ascendMember() Netscript Function agi: Agility multiplier gained from ascending. Decimal form cha: Charisma multiplier gained from ascending. Decimal form } + + Ascend the specified Gang Member. \ No newline at end of file diff --git a/doc/source/netscript/gangapi/canRecruitMember.rst b/doc/source/netscript/gangapi/canRecruitMember.rst index 967b63808..a4026ef3f 100644 --- a/doc/source/netscript/gangapi/canRecruitMember.rst +++ b/doc/source/netscript/gangapi/canRecruitMember.rst @@ -4,5 +4,4 @@ canRecruitMember() Netscript Function .. js:function:: canRecruitMember() :RAM cost: 1 GB - - :returns: Boolean indicating whether a member can currently be recruited + :returns: ``true`` if a member can be recruited. \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getBonusTime.rst b/doc/source/netscript/gangapi/getBonusTime.rst index dfaff16cc..772b19845 100644 --- a/doc/source/netscript/gangapi/getBonusTime.rst +++ b/doc/source/netscript/gangapi/getBonusTime.rst @@ -4,12 +4,10 @@ getBonusTime() Netscript Function .. js:function:: getBonusTime() :RAM cost: 0 GB - - Returns the amount of accumulated "bonus time" (seconds) for the Gang mechanic. + :returns: Bonus time for the Gang mechanic in seconds "Bonus time" is accumulated when the game is offline or if the game is inactive in the browser. "Bonus time" makes the game progress faster, up to 10x the normal speed. - :returns: Bonus time for the Gang mechanic in seconds diff --git a/doc/source/netscript/gangapi/getChanceToWinClash.rst b/doc/source/netscript/gangapi/getChanceToWinClash.rst index bf48b0aee..db3cae7b7 100644 --- a/doc/source/netscript/gangapi/getChanceToWinClash.rst +++ b/doc/source/netscript/gangapi/getChanceToWinClash.rst @@ -4,8 +4,6 @@ getChanceToWinClash() Netscript Function .. js:function:: getChanceToWinClash(gangName) :RAM cost: 4 GB - :param string gangName: Target gang - - Returns the chance you have to win a clash with the specified gang. The chance - is returned in decimal form, not percentage + :returns: Chance you have to win a clash with the specified gang. The chance + is returned in decimal form. diff --git a/doc/source/netscript/gangapi/getEquipmentCost.rst b/doc/source/netscript/gangapi/getEquipmentCost.rst index c061f51e8..24f0aa237 100644 --- a/doc/source/netscript/gangapi/getEquipmentCost.rst +++ b/doc/source/netscript/gangapi/getEquipmentCost.rst @@ -4,11 +4,9 @@ getEquipmentCost() Netscript Function .. js:function:: getEquipmentCost(equipName) :RAM cost: 2 GB - :param string equipName: Name of equipment + :returns: Cost to purchase the specified Equipment/Augmentation (number). + Infinity for invalid arguments. Get the amount of money it takes to purchase a piece of Equipment or an Augmentation. - If an invalid Equipment/Augmentation is specified, this function will return Infinity. - - :returns: Cost to purchase the specified Equipment/Augmentation (number). Infinity - for invalid arguments + If an invalid Equipment/Augmentation is specified, this function will return Infinity. \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getEquipmentNames.rst b/doc/source/netscript/gangapi/getEquipmentNames.rst index 30568b9d6..9a1ff8e2b 100644 --- a/doc/source/netscript/gangapi/getEquipmentNames.rst +++ b/doc/source/netscript/gangapi/getEquipmentNames.rst @@ -4,8 +4,8 @@ getEquipmentNames() Netscript Function .. js:function:: getEquipmentNames() :RAM cost: 1 GB + :returns: Array of strings of the names of all Equpiment/Augmentations Get the name of all possible equipment/upgrades you can purchase for your Gang Members. This includes Augmentations. - :returns: Array of strings of the names of all Equpiment/Augmentations diff --git a/doc/source/netscript/gangapi/getEquipmentStats.rst b/doc/source/netscript/gangapi/getEquipmentStats.rst index c9f7d2a8e..1b2c55339 100644 --- a/doc/source/netscript/gangapi/getEquipmentStats.rst +++ b/doc/source/netscript/gangapi/getEquipmentStats.rst @@ -1,17 +1,15 @@ getEquipmentStats() Netscript Function -===================================== +====================================== .. js:function:: getEquipmentStats(equipName) :RAM cost: 2 GB - :param string equipName: Name of equipment - :returns: A dictionary containing the stats of the equipment. - Get the specified equipment stats. + Get the specified equipment stats.:: - { - "str":1.04, - "def":1.04 - } + { + "str":1.04, + "def":1.04 + } diff --git a/doc/source/netscript/gangapi/getEquipmentType.rst b/doc/source/netscript/gangapi/getEquipmentType.rst index 05d31b0df..bebd6bdb0 100644 --- a/doc/source/netscript/gangapi/getEquipmentType.rst +++ b/doc/source/netscript/gangapi/getEquipmentType.rst @@ -4,8 +4,8 @@ getEquipmentType() Netscript Function .. js:function:: getEquipmentType(equipName) :RAM cost: 2 GB - :param string equipName: Name of equipment + :returns: A string stating the type of the equipment Get the specified equipment type, which can be one of the following: @@ -14,5 +14,3 @@ getEquipmentType() Netscript Function * Vehicle * Rootkit * Augmentation - - :returns: A string stating the type of the equipment diff --git a/doc/source/netscript/gangapi/getGangInformation.rst b/doc/source/netscript/gangapi/getGangInformation.rst index 1b1135dd5..7cad54aad 100644 --- a/doc/source/netscript/gangapi/getGangInformation.rst +++ b/doc/source/netscript/gangapi/getGangInformation.rst @@ -4,9 +4,6 @@ getGangInformation() Netscript Function .. js:function:: getGangInformation() :RAM cost: 2 GB - - Get general information about the gang - :returns: An object with the gang information. The object has the following structure:: @@ -23,3 +20,5 @@ getGangInformation() Netscript Function wantedLevel: Gang's wanted level wantedLevelGainRate: Wanted level gained/lost per second (negative for losses) } + + Get general information about the gang \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getMemberInformation.rst b/doc/source/netscript/gangapi/getMemberInformation.rst index 3a4d0eb57..4888a2bec 100644 --- a/doc/source/netscript/gangapi/getMemberInformation.rst +++ b/doc/source/netscript/gangapi/getMemberInformation.rst @@ -4,11 +4,7 @@ getMemberInformation() Netscript Function .. js:function:: getMemberInformation(name) :RAM cost: 2 GB - :param string name: Name of member - - Get stat and equipment-related information about a Gang Member - :returns: An object with the gang member information. The object has the following structure:: @@ -36,3 +32,5 @@ getMemberInformation() Netscript Function strengthAscensionMult: Strength multiplier from ascension. Decimal form task: Name of currently assigned task } + + Get stat and equipment-related information about a Gang Member \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getMemberNames.rst b/doc/source/netscript/gangapi/getMemberNames.rst index cd762fc96..ff7ac8d6d 100644 --- a/doc/source/netscript/gangapi/getMemberNames.rst +++ b/doc/source/netscript/gangapi/getMemberNames.rst @@ -4,7 +4,6 @@ getMemberNames() Netscript Function .. js:function:: getMemberNames() :RAM cost: 1 GB - - Get the names of all Gang members - :returns: An array of the names of all Gang members as strings + + Get the names of all Gang members \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getOtherGangInformation.rst b/doc/source/netscript/gangapi/getOtherGangInformation.rst index 653aaac50..55fb99605 100644 --- a/doc/source/netscript/gangapi/getOtherGangInformation.rst +++ b/doc/source/netscript/gangapi/getOtherGangInformation.rst @@ -4,9 +4,6 @@ getOtherGangInformation() Netscript Function .. js:function:: getOtherGangInformation() :RAM cost: 2 GB - - Get territory and power information about all gangs - :returns: An object with information about all gangs The object has the following structure:: @@ -26,3 +23,5 @@ getOtherGangInformation() Netscript Function }, ... (for all six gangs) } + + Get territory and power information about all gangs \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getTaskNames.rst b/doc/source/netscript/gangapi/getTaskNames.rst index eaf0d4757..8749ea3e1 100644 --- a/doc/source/netscript/gangapi/getTaskNames.rst +++ b/doc/source/netscript/gangapi/getTaskNames.rst @@ -4,7 +4,6 @@ getTaskNames() Netscript Function .. js:function:: getTaskNames() :RAM cost: 1 GB - - Get the name of all valid tasks that Gang members can be assigned to - :returns: Array of strings of all task names + + Get the name of all valid tasks that Gang members can be assigned to \ No newline at end of file diff --git a/doc/source/netscript/gangapi/getTaskStats.rst b/doc/source/netscript/gangapi/getTaskStats.rst index 6b0b15d2f..14eb71704 100644 --- a/doc/source/netscript/gangapi/getTaskStats.rst +++ b/doc/source/netscript/gangapi/getTaskStats.rst @@ -4,32 +4,36 @@ getTaskStats() Netscript Function .. js:function:: getTaskStats(taskName) :RAM cost: 1 GB - :param string name: Name of the task. + :returns: Detailed stats of a task. - Get the stats of a gang member stats. This is typically used to evaluate - which action should be executed next. + Examples: - { - name: Terrorism, - desc: "Assign this gang member to commit acts of terrorism + .. code-block:: javascript - Greatly increases respect - Greatly increases wanted level - Scales heavily with territory", - isHacking: false, - isCombat: true, - baseRespect: 0.01, - baseWanted: 6, - baseMoney: 0, - hackWeight: 20, - strWeight: 20, - defWeight: 20, - dexWeight: 20, - agiWeight: 0, - chaWeight: 20, - difficulty: 36, - territory: { - money: 1, - respect: 2, - wanted: 2 + { + name: Terrorism, + desc: "Assign this gang member to commit acts of terrorism + + Greatly increases respect - Greatly increases wanted level - Scales heavily with territory", + isHacking: false, + isCombat: true, + baseRespect: 0.01, + baseWanted: 6, + baseMoney: 0, + hackWeight: 20, + strWeight: 20, + defWeight: 20, + dexWeight: 20, + agiWeight: 0, + chaWeight: 20, + difficulty: 36, + territory: { + money: 1, + respect: 2, + wanted: 2 + } } - } + + Get the stats of a gang task stats. This is typically used to evaluate + which action should be executed next. \ No newline at end of file diff --git a/doc/source/netscript/gangapi/purchaseEquipment.rst b/doc/source/netscript/gangapi/purchaseEquipment.rst index 53b2bbf64..cffec4fc6 100644 --- a/doc/source/netscript/gangapi/purchaseEquipment.rst +++ b/doc/source/netscript/gangapi/purchaseEquipment.rst @@ -4,11 +4,9 @@ purchaseEquipment() Netscript Function .. js:function:: purchaseEquipment(memberName, equipName) :RAM cost: 4 GB - :param string memberName: Name of Gang member to purchase the equipment for :param string equipName: Name of Equipment/Augmentation to purchase + :returns: ``true`` if the equipment was purchased. Attempt to purchase the specified Equipment/Augmentation for the specified Gang member. - - :returns: True if the equipment was successfully purchased. False otherwise diff --git a/doc/source/netscript/gangapi/recruitMember.rst b/doc/source/netscript/gangapi/recruitMember.rst index d757aa77e..eb144364d 100644 --- a/doc/source/netscript/gangapi/recruitMember.rst +++ b/doc/source/netscript/gangapi/recruitMember.rst @@ -4,8 +4,8 @@ recruitMember() Netscript Function .. js:function:: recruitMember(name) :RAM cost: 2 GB - :param string name: Name of member to recruit + :returns: True if the member was successfully recruited. False otherwise Attempt to recruit a new gang member. @@ -13,5 +13,3 @@ recruitMember() Netscript Function * Cannot currently recruit a new member * There already exists a member with the specified name - - :returns: True if the member was successfully recruited. False otherwise diff --git a/doc/source/netscript/gangapi/setMemberTask.rst b/doc/source/netscript/gangapi/setMemberTask.rst index 78d700650..541431640 100644 --- a/doc/source/netscript/gangapi/setMemberTask.rst +++ b/doc/source/netscript/gangapi/setMemberTask.rst @@ -4,11 +4,10 @@ setMemberTask() Netscript Function .. js:function:: setMemberTask(memberName, taskName) :RAM cost: 2 GB - :param string memberName: Name of Gang member to assign :param string taskName: Task to assign + :returns: True if the Gang Member was successfully assigned to the task. False otherwise Attempts to assign the specified Gang Member to the specified task. If an invalid task is specified, the Gang member will be set to idle ("Unassigned") - :returns: True if the Gang Member was successfully assigned to the task. False otherwise diff --git a/doc/source/netscript/gangapi/setTerritoryWarfare.rst b/doc/source/netscript/gangapi/setTerritoryWarfare.rst index e09e36b6a..573b06b85 100644 --- a/doc/source/netscript/gangapi/setTerritoryWarfare.rst +++ b/doc/source/netscript/gangapi/setTerritoryWarfare.rst @@ -4,7 +4,6 @@ setTerritoryWarfare() Netscript Function .. js:function:: setTerritoryWarfare(engage) :RAM cost: 2 GB - :param bool engage: Whether or not to engage in territory warfare Set whether or not the gang should engage in territory warfare diff --git a/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst index 05d4af3bb..aa6c3f6d8 100644 --- a/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst +++ b/doc/source/netscript/hacknetnodeapi/getCacheUpgradeCost.rst @@ -6,14 +6,12 @@ getCacheUpgradeCost() Netscript Function .. js:function:: getCacheUpgradeCost(i, n) :RAM cost: 0 GB - - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number i: Index of Hacknet Node. :ref:`See here for details ` :param number n: Number of times to upgrade cache. Must be positive. Rounded to nearest integer - + :return: Cost of upgrading the cache level of the specified Hacknet Server by ``n``. + .. note:: This function is only applicable for Hacknet Servers (the upgraded version of a Hacknet Node). - Returns the cost of upgrading the cache level of the specified Hacknet Server by *n*. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Server is already at the max cache level, then Infinity is returned. + If an invalid value for ``n`` is provided, then this function returns ``0``. If the + specified Hacknet Server is already at the max cache level, then ``Infinity`` is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst index 2fd84df14..09f0a5a82 100644 --- a/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst +++ b/doc/source/netscript/hacknetnodeapi/getCoreUpgradeCost.rst @@ -4,11 +4,9 @@ getCoreUpgradeCost() Netscript Function .. js:function:: getCoreUpgradeCost(i, n) :RAM cost: 0 GB - - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number i: Index of Hacknet Node. :ref:`See here for details ` :param number n: Number of times to upgrade cores. Must be positive. Rounded to nearest integer + :returns: Cost of upgrading the number of cores of the specified Hacknet Node by ``n``. - Returns the cost of upgrading the number of cores of the specified Hacknet Node by *n*. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Node is already at the max number of cores, then Infinity is returned. + If an invalid value for ``n`` is provided, then this function returns ``0``. If the + specified Hacknet Node is already at the max number of cores, then ``Infinity`` is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst index 64d55d7d0..683be393a 100644 --- a/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst +++ b/doc/source/netscript/hacknetnodeapi/getLevelUpgradeCost.rst @@ -4,11 +4,9 @@ getLevelUpgradeCost() Netscript Function .. js:function:: getLevelUpgradeCost(i, n) :RAM cost: 0 GB - - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number i: Index of Hacknet Node. :ref:`See here for details ` :param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer + :returns: Cost of upgrading the specified Hacknet Node by ``n`` levels. - Returns the cost of upgrading the specified Hacknet Node by *n* levels. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Node is already at max level, then Infinity is returned. + If an invalid value for ``n`` is provided, then this function returns ``0``. If the + specified Hacknet Node is already at max level, then ``Infinity`` is returned. diff --git a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst index c19a67a98..73da1ed06 100644 --- a/doc/source/netscript/hacknetnodeapi/getNodeStats.rst +++ b/doc/source/netscript/hacknetnodeapi/getNodeStats.rst @@ -6,10 +6,10 @@ getNodeStats() Netscript Function .. js:function:: getNodeStats(i) :RAM cost: 0 GB + :param number i: Index of Hacknet Node. :ref:`See here for details ` + :returns: Object containing a variety of stats about the specified Hacknet Node - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` - - Returns an object containing a variety of stats about the specified Hacknet Node:: + :: { name: Node's name ("hacknet-node-5"), @@ -24,5 +24,5 @@ getNodeStats() Netscript Function } .. note:: Note that for Hacknet Nodes, production refers to the amount of money the node generates. - For Hacknet Servers (the upgraded version of Hacknet Nodes), production refers to the amount - of hashes the node generates. + For Hacknet Servers (the upgraded version of Hacknet Nodes), production refers to the amount + of hashes the node generates. diff --git a/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst b/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst index 9990a3a07..0dd53c7a7 100644 --- a/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst +++ b/doc/source/netscript/hacknetnodeapi/getPurchaseNodeCost.rst @@ -4,5 +4,4 @@ getPurchaseNodeCost() Netscript Function .. js:function:: getPurchaseNodeCost() :RAM cost: 0 GB - - Returns the cost of purchasing a new Hacknet Node + :returns: Cost of purchasing a new Hacknet Node. diff --git a/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst b/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst index 9aedf44a3..1db422fb6 100644 --- a/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst +++ b/doc/source/netscript/hacknetnodeapi/getRamUpgradeCost.rst @@ -4,11 +4,9 @@ getRamUpgradeCost() Netscript Function .. js:function:: getRamUpgradeCost(i, n) :RAM cost: 0 GB + :param number i: Index of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer. + :returns: Cost of upgrading the RAM of the specified Hacknet Node ``n`` times. - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` - :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer - - Returns the cost of upgrading the RAM of the specified Hacknet Node *n* times. - - If an invalid value for *n* is provided, then this function returns 0. If the - specified Hacknet Node is already at max RAM, then Infinity is returned. + If an invalid value for ``n`` is provided, then this function returns ``0``. If the + specified Hacknet Node is already at max RAM, then ``Infinity`` is returned. diff --git a/doc/source/netscript/hacknetnodeapi/hashCost.rst b/doc/source/netscript/hacknetnodeapi/hashCost.rst index 2a57cc377..fc5f7b5d4 100644 --- a/doc/source/netscript/hacknetnodeapi/hashCost.rst +++ b/doc/source/netscript/hacknetnodeapi/hashCost.rst @@ -6,20 +6,18 @@ hashCost() Netscript Function .. js:function:: hashCost(upgName) :RAM cost: 0 GB - :param string upgName: Name of upgrade to get the cost of. Must be an exact match + :returns: Number of hashes required for the specified upgrade. The name of + the upgrade must be an exact match. .. note:: This function is only applicable for Hacknet Servers (the upgraded version of a Hacknet Node). - Returns the number of hashes required for the specified upgrade. The name of the - upgrade must be an exact match. - Example: .. code:: javascript - var upgradeName = "Sell for Corporation Funds"; + upgradeName = "Sell for Corporation Funds"; if (hacknet.numHashes() > hacknet.hashCost(upgradeName)) { hacknet.spendHashes(upgName); } diff --git a/doc/source/netscript/hacknetnodeapi/maxNumNodes.rst b/doc/source/netscript/hacknetnodeapi/maxNumNodes.rst index 0007a5036..c39d43110 100644 --- a/doc/source/netscript/hacknetnodeapi/maxNumNodes.rst +++ b/doc/source/netscript/hacknetnodeapi/maxNumNodes.rst @@ -1,8 +1,7 @@ maxNumNodes() Netscript Function -============================= +================================ .. js:function:: maxNumNodes() :RAM cost: 0 GB - - Returns the maximum number of Hacknet Nodes you can own. + :returns: Maximum number of Hacknet Nodes you can own. diff --git a/doc/source/netscript/hacknetnodeapi/numHashes.rst b/doc/source/netscript/hacknetnodeapi/numHashes.rst index 825e554b5..62d54289a 100644 --- a/doc/source/netscript/hacknetnodeapi/numHashes.rst +++ b/doc/source/netscript/hacknetnodeapi/numHashes.rst @@ -6,8 +6,8 @@ numHashes() Netscript Function .. js:function:: numHashes() :RAM cost: 0 GB + :returns: Number of hashes you have. .. note:: This function is only applicable for Hacknet Servers (the upgraded version of a Hacknet Node). - Returns the number of hashes you have diff --git a/doc/source/netscript/hacknetnodeapi/numNodes.rst b/doc/source/netscript/hacknetnodeapi/numNodes.rst index b50977ded..ef53758d1 100644 --- a/doc/source/netscript/hacknetnodeapi/numNodes.rst +++ b/doc/source/netscript/hacknetnodeapi/numNodes.rst @@ -4,5 +4,4 @@ numNodes() Netscript Function .. js:function:: numNodes() :RAM cost: 0 GB - - Returns the number of Hacknet Nodes you own. + :returns: Number of Hacknet Nodes you own. diff --git a/doc/source/netscript/hacknetnodeapi/purchaseNode.rst b/doc/source/netscript/hacknetnodeapi/purchaseNode.rst index 4310aac70..2d198d940 100644 --- a/doc/source/netscript/hacknetnodeapi/purchaseNode.rst +++ b/doc/source/netscript/hacknetnodeapi/purchaseNode.rst @@ -4,10 +4,8 @@ purchaseNode() Netscript Function .. js:function:: purchaseNode() :RAM cost: 0 GB + :returns: Index of the newly purchased node. -1 on failure. - Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. + Purchases a new Hacknet Node. This index is equivalent to the number at the 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 -1. diff --git a/doc/source/netscript/hacknetnodeapi/spendHashes.rst b/doc/source/netscript/hacknetnodeapi/spendHashes.rst index 3eadfddfe..b622b5044 100644 --- a/doc/source/netscript/hacknetnodeapi/spendHashes.rst +++ b/doc/source/netscript/hacknetnodeapi/spendHashes.rst @@ -6,19 +6,19 @@ spendHashes() Netscript Function .. js:function:: spendHashes(upgName, upgTarget) :RAM cost: 0 GB - :param string upgName: Name of upgrade to spend hashes on. Must be an exact match :param string upgTarget: Object to which upgrade applies. Required for certain upgrades + :returns: ``true`` if the purchase was successful. .. note:: This function is only applicable for Hacknet Servers (the upgraded version of a Hacknet Node). - Spend the hashes generated by your Hacknet Servers on an upgrade. Returns a boolean value - - true if the upgrade is successfully purchased, and false otherwise. + Spend the hashes generated by your Hacknet Servers on an upgrade. - The name of the upgrade must be an exact match. The :code:`upgTarget` argument is used - for upgrades such as :code:`Reduce Minimum Security`, which applies to a specific server. - In this case, the :code:`upgTarget` argument must be the hostname of the server. + The name of the upgrade must be an exact match. The ``upgTarget`` argument + is used for upgrades such as ``Reduce Minimum Security``, which applies to a + specific server. In this case, the ``upgTarget`` argument must be the + hostname of the server. Example: diff --git a/doc/source/netscript/hacknetnodeapi/upgradeCache.rst b/doc/source/netscript/hacknetnodeapi/upgradeCache.rst index bee20f638..f670975ea 100644 --- a/doc/source/netscript/hacknetnodeapi/upgradeCache.rst +++ b/doc/source/netscript/hacknetnodeapi/upgradeCache.rst @@ -6,16 +6,11 @@ upgradeCache() Netscript Function .. js:function:: upgradeCache(i, n) :RAM cost: 0 GB - - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number i: Index of Hacknet Node. :ref:`See here for details ` :param number n: Number of cache levels to purchase. Must be positive. Rounded to nearest integer + :returns: ``true`` if the upgrade was successful. .. note:: This function is only applicable for Hacknet Servers (the upgraded version of a Hacknet Node). - Tries to upgrade the specified Hacknet Server's cache *n* times. - - Returns true if it successfully upgrades the Server's cache *n* times, or if - it purchases some positive amount and the Server reaches its max cache level. - - Returns false otherwise. + Tries to upgrade the specified Hacknet Server's cache ``n`` times. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeCore.rst b/doc/source/netscript/hacknetnodeapi/upgradeCore.rst index 19d51b6d2..797fca393 100644 --- a/doc/source/netscript/hacknetnodeapi/upgradeCore.rst +++ b/doc/source/netscript/hacknetnodeapi/upgradeCore.rst @@ -4,13 +4,8 @@ upgradeCore() Netscript Function .. js:function:: upgradeCore(i, n) :RAM cost: 0 GB - - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number i: Index of Hacknet Node. :ref:`See here for details ` :param number n: Number of cores to purchase. Must be positive. Rounded to nearest integer + :returns: ``true`` if the upgrade was successful. - Tries to purchase *n* cores for the specified Hacknet Node. - - Returns true if it successfully purchases *n* cores for the Hacknet Node or if - it purchases some positive amount and the Node reaches its max number of cores. - - Returns false otherwise. + Tries to purchase ``n`` cores for the specified Hacknet Node. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst b/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst index be1bff81b..498834c32 100644 --- a/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst +++ b/doc/source/netscript/hacknetnodeapi/upgradeLevel.rst @@ -4,13 +4,8 @@ upgradeLevel() Netscript Function .. js:function:: upgradeLevel(i, n) :RAM cost: 0 GB - - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` + :param number i: Index of Hacknet Node. :ref:`See here for details ` :param number n: Number of levels to purchase. Must be positive. Rounded to nearest integer + :returns: ``true`` if the upgrade was successful. Tries to upgrade the level of the specified Hacknet Node by *n*. - - Returns true if the Hacknet Node's level is successfully upgraded by *n* or - if it is upgraded by some positive amount and the Node reaches its max level. - - Returns false otherwise. diff --git a/doc/source/netscript/hacknetnodeapi/upgradeRam.rst b/doc/source/netscript/hacknetnodeapi/upgradeRam.rst index 21d5d748d..9d2c7b569 100644 --- a/doc/source/netscript/hacknetnodeapi/upgradeRam.rst +++ b/doc/source/netscript/hacknetnodeapi/upgradeRam.rst @@ -4,15 +4,10 @@ upgradeRam() Netscript Function .. js:function:: upgradeRam(i, n) :RAM cost: 0 GB + :param number i: Index of Hacknet Node. :ref:`See here for details ` + :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer. + :returns: ``true`` if the upgrade was successful. - :param number i: Index/Identifier of Hacknet Node. :ref:`See here for details ` - :param number n: Number of times to upgrade RAM. Must be positive. Rounded to nearest integer - - Tries to upgrade the specified Hacknet Node's RAM *n* times. Note that each upgrade - doubles the Node's RAM. So this is equivalent to multiplying the Node's RAM by - 2 :sup:`n`. - - Returns true if the Hacknet Node's RAM is successfully upgraded *n* times or if - it is upgraded some positive number of times and the Node reaches it max RAM. - - Returns false otherwise. + Tries to upgrade the specified Hacknet Node's RAM ``n`` times. Note that + each upgrade doubles the Node's RAM. So this is equivalent to multiplying + the Node's RAM by 2 :sup:`n`. diff --git a/doc/source/netscript/netscriptgangapi.rst b/doc/source/netscript/netscriptgangapi.rst index d75715e72..24cedd801 100644 --- a/doc/source/netscript/netscriptgangapi.rst +++ b/doc/source/netscript/netscriptgangapi.rst @@ -33,9 +33,11 @@ In :ref:`netscriptjs`:: recruitMember() getTaskNames() setMemberTask() + getTaskStats() getEquipmentNames() getEquipmentCost() getEquipmentType() + getEquipmentStats() purchaseEquipment() ascendMember() setTerritoryWarfare() diff --git a/doc/source/netscript/netscripthacknetnodeapi.rst b/doc/source/netscript/netscripthacknetnodeapi.rst index 0cd7dd897..706cf6495 100644 --- a/doc/source/netscript/netscripthacknetnodeapi.rst +++ b/doc/source/netscript/netscripthacknetnodeapi.rst @@ -29,6 +29,7 @@ In :ref:`netscriptjs`:: :caption: API Functions: numNodes() + maxNumNodes() purchaseNode() getPurchaseNodeCost() getNodeStats() diff --git a/doc/source/netscript/netscriptsingularityfunctions.rst b/doc/source/netscript/netscriptsingularityfunctions.rst index b9ed4ea56..44b311269 100644 --- a/doc/source/netscript/netscriptsingularityfunctions.rst +++ b/doc/source/netscript/netscriptsingularityfunctions.rst @@ -45,10 +45,13 @@ level 3, then you will be able to access all of the Singularity Functions. createProgram() commitCrime() getCrimeChance() + getCrimeStats() getOwnedAugmentations() getOwnedSourceFiles() getAugmentationsFromFaction() getAugmentationPrereq() getAugmentationCost() + getAugmentationStats() purchaseAugmentation() installAugmentations() + softReset() diff --git a/doc/source/netscript/singularityfunctions/applyToCompany.rst b/doc/source/netscript/singularityfunctions/applyToCompany.rst index 7f16e2b0e..c8aee245e 100644 --- a/doc/source/netscript/singularityfunctions/applyToCompany.rst +++ b/doc/source/netscript/singularityfunctions/applyToCompany.rst @@ -4,7 +4,6 @@ applyToCompany() Netscript Function .. js:function:: applyToCompany(companyName, field) :RAM cost: 3 GB - :param string companyName: Name of company to apply to. CASE-SENSITIVE. :param string field: Field to which you want to apply. Not case-sensitive @@ -22,12 +21,10 @@ applyToCompany() Netscript Function * part-time employee * waiter * part-time waiter + :returns: ``true`` if you got the job. If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. This function will automatically try to apply to the specified company for a position in the specified field. This function can also be used to apply for promotions by specifying the company and field you - are already employed at. - - This function will return true if you successfully get a job/promotion, and false otherwise. Note that - if you are trying to use this function to apply for a promotion and you don't get one, it will return false. + are already employed at. \ No newline at end of file diff --git a/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst b/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst index 472e35f0e..4edd9c53a 100644 --- a/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst +++ b/doc/source/netscript/singularityfunctions/checkFactionInvitations.rst @@ -4,7 +4,7 @@ checkFactionInvitations() Netscript Function .. js:function:: checkFactionInvitations() :RAM cost: 3 GB + :returns: Array with the name of all Factions with whom you have oustanding invitations. If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function. - Returns an array with the name of all Factions you currently have oustanding invitations from. diff --git a/doc/source/netscript/singularityfunctions/commitCrime.rst b/doc/source/netscript/singularityfunctions/commitCrime.rst index 4c09f0391..0f8aab6ad 100644 --- a/doc/source/netscript/singularityfunctions/commitCrime.rst +++ b/doc/source/netscript/singularityfunctions/commitCrime.rst @@ -4,7 +4,6 @@ commitCrime() Netscript Function .. js:function:: commitCrime(crime) :RAM cost: 5 GB - :param string crime: Name of crime to attempt. Not case-sensitive. This argument is fairly lenient in terms of what inputs it accepts. Here is a list of valid inputs for all of the crimes: @@ -28,9 +27,9 @@ commitCrime() Netscript Function (such as working for a company or training at a gym), then running this function will automatically cancel that action and give you your earnings. This function returns the number of seconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt the 'Rob Store' crime, - so running *commitCrime('rob store')* will return 60). + so running ``commitCrime('rob store')`` will return 60). Warning: I do not recommend using the time returned from this function to try and schedule your crime attempts. - Instead, I would use the isBusy() Singularity function to check whether you have finished attempting a crime. + Instead, I would use the :doc:`isBusy` Singularity function to check whether you have finished attempting a crime. This is because although the game sets a certain crime to be X amount of seconds, there is no guarantee that your browser will follow that time limit. diff --git a/doc/source/netscript/singularityfunctions/createProgram.rst b/doc/source/netscript/singularityfunctions/createProgram.rst index 2165e75c9..7bfa657f7 100644 --- a/doc/source/netscript/singularityfunctions/createProgram.rst +++ b/doc/source/netscript/singularityfunctions/createProgram.rst @@ -4,8 +4,8 @@ createProgram() Netscript Function .. js:function:: createProgram(programName) :RAM cost: 5 GB - :param string programName: Name of program to create. Not case-sensitive + :returns: ``true`` if you successfully start working on the specified program. If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. @@ -28,5 +28,3 @@ createProgram() Netscript Function * DeepscanV2.exe: 400 * ServerProfiler.exe: 75 * AutoLink.exe: 25 - - This function returns true if you successfully start working on the specified program, and false otherwise. diff --git a/doc/source/netscript/singularityfunctions/donateToFaction.rst b/doc/source/netscript/singularityfunctions/donateToFaction.rst index f614d1536..ef0da9ce1 100644 --- a/doc/source/netscript/singularityfunctions/donateToFaction.rst +++ b/doc/source/netscript/singularityfunctions/donateToFaction.rst @@ -4,11 +4,10 @@ donateToFaction() Netscript Function .. js:function:: donateToFaction(factionName, donateAmt) :RAM cost: 5 GB - :param string factionName: Name of faction to donate to. CASE-SENSITIVE :param number donateAmt: Amount of money to donate + :returns: ``true`` if you successfully donate the money. If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. - Attempts to donate money to the specified faction in exchange for reputation. - Returns true if you successfully donate the money, and false otherwise. + Attempts to donate money to the specified faction in exchange for reputation. \ No newline at end of file diff --git a/doc/source/netscript/singularityfunctions/getAugmentationCost.rst b/doc/source/netscript/singularityfunctions/getAugmentationCost.rst index f09618ed8..01a5735a2 100644 --- a/doc/source/netscript/singularityfunctions/getAugmentationCost.rst +++ b/doc/source/netscript/singularityfunctions/getAugmentationCost.rst @@ -4,12 +4,11 @@ getAugmentationCost() Netscript Function .. js:function:: getAugmentationCost(augName) :RAM cost: 5 GB - - :param string augName: Name of Augmentation. CASE-SENSITIVE + :param string augName: Name of Augmentation. case-sensitive. If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. This function returns an array with two elements that gives the cost for the specified Augmentation. The first element in the returned array is the reputation requirement of the Augmentation, and the second element is the money cost. - If an invalid Augmentation name is passed in for the *augName* argument, this function will return the array [-1, -1]. + If an invalid Augmentation name is passed in for the ``augName`` argument, this function will return the array [-1, -1]. diff --git a/doc/source/netscript/tixapi/buyStock.rst b/doc/source/netscript/tixapi/buyStock.rst index 06e70c891..576b096c2 100644 --- a/doc/source/netscript/tixapi/buyStock.rst +++ b/doc/source/netscript/tixapi/buyStock.rst @@ -3,9 +3,10 @@ buyStock() Netscript Function .. js:function:: buyStock(sym, shares) + :RAM cost: 2.5 GB :param string sym: Symbol of stock to purchase :param number shares: Number of shares to purchased. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB + Attempts to purchase shares of a stock using a `Market Order `_. diff --git a/doc/source/netscript/tixapi/cancelOrder.rst b/doc/source/netscript/tixapi/cancelOrder.rst index da9cb18c0..2271fb7c7 100644 --- a/doc/source/netscript/tixapi/cancelOrder.rst +++ b/doc/source/netscript/tixapi/cancelOrder.rst @@ -3,6 +3,7 @@ cancelOrder() Netscript Function .. js:function:: cancelOrder(sym, shares, price, type, pos) + :RAM cost: 2.5 GB :param string sym: Symbol of stock to player order for :param number shares: Number of shares for order. Must be positive. Will be rounded to nearest integer :param number price: Execution price for the order @@ -17,7 +18,6 @@ cancelOrder() Netscript Function :param string pos: Specifies whether the order is a "Long" or "Short" position. The Values "L" or "S" can also be used. This is NOT case-sensitive. - :RAM cost: 2.5 GB Cancels an oustanding Limit or Stop order on the stock market. diff --git a/doc/source/netscript/tixapi/getStockAskPrice.rst b/doc/source/netscript/tixapi/getStockAskPrice.rst index 8365df502..0d1add629 100644 --- a/doc/source/netscript/tixapi/getStockAskPrice.rst +++ b/doc/source/netscript/tixapi/getStockAskPrice.rst @@ -3,8 +3,9 @@ getStockAskPrice() Netscript Function .. js:function:: getStockAskPrice(sym) - :param string sym: Stock symbol :RAM cost: 2 GB + :param string sym: Stock symbol + Given a stock's symbol, returns the ask price of that stock (the symbol is a sequence of two to four capital letters, **not** the name of the company to which that stock belongs). diff --git a/doc/source/netscript/tixapi/getStockBidPrice.rst b/doc/source/netscript/tixapi/getStockBidPrice.rst index e9e03e950..07e633c45 100644 --- a/doc/source/netscript/tixapi/getStockBidPrice.rst +++ b/doc/source/netscript/tixapi/getStockBidPrice.rst @@ -3,8 +3,9 @@ getStockBidPrice() Netscript Function .. js:function:: getStockBidPrice(sym) - :param string sym: Stock symbol :RAM cost: 2 GB + :param string sym: Stock symbol + Given a stock's symbol, returns the bid price of that stock (the symbol is a sequence of two to four capital letters, **not** the name of the company to which that stock belongs). diff --git a/doc/source/netscript/tixapi/getStockForecast.rst b/doc/source/netscript/tixapi/getStockForecast.rst index 7ce63f319..34886bc47 100644 --- a/doc/source/netscript/tixapi/getStockForecast.rst +++ b/doc/source/netscript/tixapi/getStockForecast.rst @@ -3,8 +3,9 @@ getStockForecast() Netscript Function .. js:function:: getStockForecast(sym) - :param string sym: Symbol of stock :RAM cost: 2.5 GB + :param string sym: Symbol of stock + Returns the probability that the specified stock's price will increase (as opposed to decrease) during the next tick. diff --git a/doc/source/netscript/tixapi/getStockMaxShares.rst b/doc/source/netscript/tixapi/getStockMaxShares.rst index 4c1838183..b654618b0 100644 --- a/doc/source/netscript/tixapi/getStockMaxShares.rst +++ b/doc/source/netscript/tixapi/getStockMaxShares.rst @@ -3,8 +3,9 @@ getStockMaxShares() Netscript Function .. js:function:: getStockMaxShares(sym) - :param string sym: Stock symbol :RAM cost: 2 GB + :param string sym: Stock symbol + Returns the maximum number of shares that the stock has. This is the maximum amount of the stock that can be purchased in both the Long and Short diff --git a/doc/source/netscript/tixapi/getStockPosition.rst b/doc/source/netscript/tixapi/getStockPosition.rst index 048a3bfb3..16a30a1bb 100644 --- a/doc/source/netscript/tixapi/getStockPosition.rst +++ b/doc/source/netscript/tixapi/getStockPosition.rst @@ -3,8 +3,9 @@ getStockPosition() Netscript Function .. js:function:: getStockPosition(sym) - :param string sym: Stock symbol :RAM cost: 2 GB + :param string sym: Stock symbol + Returns an array of four elements that represents the player's position in a stock. diff --git a/doc/source/netscript/tixapi/getStockPrice.rst b/doc/source/netscript/tixapi/getStockPrice.rst index 623e0ce5e..413444aac 100644 --- a/doc/source/netscript/tixapi/getStockPrice.rst +++ b/doc/source/netscript/tixapi/getStockPrice.rst @@ -3,8 +3,9 @@ getStockPrice() Netscript Function .. js:function:: getStockPrice(sym) - :param string sym: Stock symbol :RAM cost: 2 GB + :param string sym: Stock symbol + Given a stock's symbol, returns the price of that stock (the symbol is a sequence of two to four capital letters, **not** the name of the company to which that stock belongs). diff --git a/doc/source/netscript/tixapi/getStockPurchaseCost.rst b/doc/source/netscript/tixapi/getStockPurchaseCost.rst index a686d1bca..9a0acc09e 100644 --- a/doc/source/netscript/tixapi/getStockPurchaseCost.rst +++ b/doc/source/netscript/tixapi/getStockPurchaseCost.rst @@ -1,13 +1,14 @@ getStockPurchaseCost() Netscript Function ========================================= - .. js:function:: getStockPurchaseCost(sym, shares, posType) +.. js:function:: getStockPurchaseCost(sym, shares, posType) + :RAM cost: 2 GB :param string sym: Stock symbol :param number shares: Number of shares to purchase :param string posType: Specifies whether the order is a "Long" or "Short" position. The values "L" or "S" can also be used. - :RAM cost: 2 GB + Calculates and returns how much it would cost to buy a given number of shares of a stock. This takes into account :ref:`spread ` diff --git a/doc/source/netscript/tixapi/getStockSaleGain.rst b/doc/source/netscript/tixapi/getStockSaleGain.rst index 2dcbf8b78..9bcf0f2ae 100644 --- a/doc/source/netscript/tixapi/getStockSaleGain.rst +++ b/doc/source/netscript/tixapi/getStockSaleGain.rst @@ -1,13 +1,14 @@ getStockSaleGain() Netscript Function ===================================== - .. js:function:: getStockSaleGain(sym, shares, posType) +.. js:function:: getStockSaleGain(sym, shares, posType) + :RAM cost: 2 GB :param string sym: Stock symbol :param number shares: Number of shares to sell :param string posType: Specifies whether the order is a "Long" or "Short" position. The values "L" or "S" can also be used. - :RAM cost: 2 GB + Calculates and returns how much you would gain from selling a given number of shares of a stock. This takes into account :ref:`spread ` diff --git a/doc/source/netscript/tixapi/getStockVolatility.rst b/doc/source/netscript/tixapi/getStockVolatility.rst index 0cc5fccb6..b15602126 100644 --- a/doc/source/netscript/tixapi/getStockVolatility.rst +++ b/doc/source/netscript/tixapi/getStockVolatility.rst @@ -3,8 +3,9 @@ getStockVolatility() Netscript Function .. js:function:: getStockVolatility(sym) - :param string sym: Symbol of stock :RAM cost: 2.5 GB + :param string sym: Symbol of stock + Returns the volatility of the specified stock. diff --git a/doc/source/netscript/tixapi/placeOrder.rst b/doc/source/netscript/tixapi/placeOrder.rst index 7edaab223..7bcda6cfe 100644 --- a/doc/source/netscript/tixapi/placeOrder.rst +++ b/doc/source/netscript/tixapi/placeOrder.rst @@ -3,6 +3,7 @@ placeOrder() Netscript Function .. js:function:: placeOrder(sym, shares, price, type, pos) + :RAM cost: 2.5 GB :param string sym: Symbol of stock to player order for :param number shares: Number of shares for order. Must be positive. Will be rounded to nearest integer :param number price: Execution price for the order @@ -17,7 +18,6 @@ placeOrder() Netscript Function :param string pos: Specifies whether the order is a "Long" or "Short" position. The Values "L" or "S" can also be used. This is NOT case-sensitive. - :RAM cost: 2.5 GB Places an order on the stock market. This function only works for :ref:`Limit and Stop Orders `. diff --git a/doc/source/netscript/tixapi/sellShort.rst b/doc/source/netscript/tixapi/sellShort.rst index 2d8291fa5..ca339f235 100644 --- a/doc/source/netscript/tixapi/sellShort.rst +++ b/doc/source/netscript/tixapi/sellShort.rst @@ -3,9 +3,10 @@ sellShort() Netscript Function .. js:function:: sellShort(sym, shares) + :RAM cost: 2.5 GB :param string sym: Symbol of stock to sell :param number shares: Number of shares to sell. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB + Attempts to sell a `short `_ position of a stock using a `Market Order `_. diff --git a/doc/source/netscript/tixapi/sellStock.rst b/doc/source/netscript/tixapi/sellStock.rst index 7c5e66723..b7b76c5ab 100644 --- a/doc/source/netscript/tixapi/sellStock.rst +++ b/doc/source/netscript/tixapi/sellStock.rst @@ -3,9 +3,10 @@ sellStock() Netscript Function .. js:function:: sellStock(sym, shares) + :RAM cost: 2.5 GB :param string sym: Symbol of stock to sell :param number shares: Number of shares to sell. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB + Attempts to sell shares of a stock using a `Market Order `_. diff --git a/doc/source/netscript/tixapi/shortStock.rst b/doc/source/netscript/tixapi/shortStock.rst index cd319cf88..4d623bcc8 100644 --- a/doc/source/netscript/tixapi/shortStock.rst +++ b/doc/source/netscript/tixapi/shortStock.rst @@ -3,9 +3,10 @@ shortStock() Netscript Function .. js:function:: shortStock(sym, shares) + :RAM cost: 2.5 GB :param string sym: Symbol of stock to short :param number shares: Number of shares to short. Must be positive. Will be rounded to nearest integer - :RAM cost: 2.5 GB + Attempts to purchase a `short `_ position of a stock using a `Market Order `_. diff --git a/src/Bladeburner.js b/src/Bladeburner.js index 75b5b1688..5730e8044 100644 --- a/src/Bladeburner.js +++ b/src/Bladeburner.js @@ -3511,12 +3511,10 @@ Bladeburner.prototype.getSkillNamesNetscriptFn = function() { } Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript) { - var errorLogText = "ERROR: bladeburner.startAction() failed due to an invalid action specified. " + - "Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " + - "name of the operation is case-sensitive."; - var actionId = this.getActionIdFromTypeAndName(type, name); + const errorLogText = `Invalid action: type='${type}' name='${name}'`; + const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.startAction", errorLogText); return false; } @@ -3525,13 +3523,13 @@ Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript // Can't start a BlackOp if you don't have the required rank let action = this.getActionObject(actionId); if (action.reqdRank > this.rank) { - workerScript.log(`Failed to start Black Op ${actionId.name} due to insufficient rank`); + workerScript.log("bladeburner.startAction", `Insufficient rank to start Black Op '${actionId.name}'.`); return false; } // Can't start a BlackOp if its already been done if (this.blackops[actionId.name] != null) { - workerScript.log(`Failed to start Black Op ${actionId.name} because its already been completed`); + workerScript.log("bladeburner.startAction", `Black Op ${actionId.name} has already been completed.`); return false; } @@ -3548,43 +3546,38 @@ Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript let i = blackops.indexOf(actionId.name); if (i === -1) { - workerScript.log("ERROR: Invalid Black Operation name passed into bladeburner.startAction(). Note that this name is case-sensitive & whitespace-sensitive"); + workerScript.log("bladeburner.startAction", `Invalid Black Op: '${name}'`); return false; } if (i > 0 && this.blackops[blackops[i-1]] == null) { - workerScript.log(`ERROR: Cannot attempt Black Operation ${actionId.name} because you have not done the preceding one`); + workerScript.log("bladeburner.startAction", `Preceding Black Op must be completed before starting '${actionId.name}'.`); return false; } } try { this.startAction(actionId); - if (workerScript.shouldLog("startAction")) { - workerScript.log("Starting bladeburner action with type " + type + " and name " + name); - } + workerScript.log("bladeburner.startAction", `Starting bladeburner action with type '${type}' and name ${name}"`); return true; } catch(e) { this.resetAction(); - workerScript.log("ERROR: bladeburner.startAction() failed to start action of type " + type + " due to invalid name: " + name + - "Note that this name is case-sensitive and whitespace-sensitive"); + workerScript.log("bladeburner.startAction", errorLogText); return false; } } Bladeburner.prototype.getActionTimeNetscriptFn = function(type, name, workerScript) { - var errorLogText = "ERROR: bladeburner.getActionTime() failed due to an invalid action specified. " + - "Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " + - "name of the operation is case-sensitive."; - var actionId = this.getActionIdFromTypeAndName(type, name); + const errorLogText = `Invalid action: type='${type}' name='${name}'` + const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionTime", errorLogText); return -1; } - var actionObj = this.getActionObject(actionId); + const actionObj = this.getActionObject(actionId); if (actionObj == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionTime", errorLogText); return -1; } @@ -3601,24 +3594,22 @@ Bladeburner.prototype.getActionTimeNetscriptFn = function(type, name, workerScri case ActionTypes["Recruitment"]: return this.getRecruitmentTime(); default: - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionTime", errorLogText); return -1; } } Bladeburner.prototype.getActionEstimatedSuccessChanceNetscriptFn = function(type, name, workerScript) { - var errorLogText = "ERROR: bladeburner.getActionEstimatedSuccessChance() failed due to an invalid action specified. " + - "Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " + - "name of the operation is case-sensitive."; - var actionId = this.getActionIdFromTypeAndName(type, name); + const errorLogText = `Invalid action: type='${type}' name='${name}'` + const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText); return -1; } - var actionObj = this.getActionObject(actionId); + const actionObj = this.getActionObject(actionId); if (actionObj == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText); return -1; } @@ -3635,24 +3626,22 @@ Bladeburner.prototype.getActionEstimatedSuccessChanceNetscriptFn = function(type case ActionTypes["Recruitment"]: return this.getRecruitmentSuccessChance(); default: - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionEstimatedSuccessChance", errorLogText); return -1; } } Bladeburner.prototype.getActionCountRemainingNetscriptFn = function(type, name, workerScript) { - var errorLogText = "ERROR: bladeburner.getActionCountRemaining() failed due to an invalid action specified. " + - "Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " + - "name of the operation is case-sensitive."; - var actionId = this.getActionIdFromTypeAndName(type, name); + const errorLogText = `Invalid action: type='${type}' name='${name}'`; + const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionCountRemaining", errorLogText); return -1; } - var actionObj = this.getActionObject(actionId); + const actionObj = this.getActionObject(actionId); if (actionObj == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionCountRemaining", errorLogText); return -1; } @@ -3672,21 +3661,14 @@ Bladeburner.prototype.getActionCountRemainingNetscriptFn = function(type, name, case ActionTypes["FieldAnalysis"]: return Infinity; default: - workerScript.log(errorLogText); + workerScript.log("bladeburner.getActionCountRemaining", errorLogText); return -1; } } Bladeburner.prototype.getSkillLevelNetscriptFn = function(skillName, workerScript) { - var errorLogText = "ERROR: bladeburner.getSkillLevel() failed due to an invalid skill specified: " + - skillName + ". Note that the name of the skill is case-sensitive"; - - if (skillName === "") { - return -1; - } - - if (!Skills.hasOwnProperty(skillName)) { - workerScript.log(errorLogText); + if (skillName === "" || !Skills.hasOwnProperty(skillName)) { + workerScript.log("bladeburner.getSkillLevel", `Invalid skill: '${skillName}'`); return -1; } @@ -3698,19 +3680,12 @@ Bladeburner.prototype.getSkillLevelNetscriptFn = function(skillName, workerScrip } Bladeburner.prototype.getSkillUpgradeCostNetscriptFn = function(skillName, workerScript) { - var errorLogText = "ERROR: bladeburner.getSkillUpgradeCostNetscriptFn() failed due to an invalid skill specified: " + - skillName + ". Note that the name of the skill is case-sensitive"; - - if (skillName === "") { + if (skillName === "" || !Skills.hasOwnProperty(skillName)) { + workerScript.log("bladeburner.getSkillUpgradeCost", `Invalid skill: '${skillName}'`); return -1; } - if (!Skills.hasOwnProperty(skillName)) { - workerScript.log(errorLogText); - return -1; - } - - var skill = Skills[skillName]; + const skill = Skills[skillName]; if (this.skills[skillName] == null) { return skill.calculateCost(0); } else { @@ -3719,33 +3694,26 @@ Bladeburner.prototype.getSkillUpgradeCostNetscriptFn = function(skillName, worke } Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript) { - var errorLogText = "ERROR: bladeburner.upgradeSkill() failed due to an invalid skill specified: " + - skillName + ". Note that the name of the skill is case-sensitive"; + const errorLogText = `Invalid skill: '${skillName}'`; if (!Skills.hasOwnProperty(skillName)) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.upgradeSkill", errorLogText); return false; } - var skill = Skills[skillName]; - var currentLevel = 0; + const skill = Skills[skillName]; + let currentLevel = 0; if (this.skills[skillName] && !isNaN(this.skills[skillName])) { currentLevel = this.skills[skillName]; } - var cost = skill.calculateCost(currentLevel); + const cost = skill.calculateCost(currentLevel); if(skill.maxLvl && currentLevel >= skill.maxLvl) { - if (workerScript.shouldLog("upgradeSkill")) { - workerScript.log(`bladeburner.upgradeSkill() failed because ${skillName} is already maxed`); - } + workerScript.log("bladeburner.upgradeSkill", `Skill '${skillName}' is already maxed.`); return false; } if (this.skillPoints < cost) { - if (workerScript.shouldLog("upgradeSkill")) { - workerScript.log("bladeburner.upgradeSkill() failed because you do not have enough " + - "skill points to upgrade " + skillName + " (You have " + - this.skillPoints + ", you need " + cost + ")"); - } + workerScript.log("bladeburner.upgradeSkill", `You do not have enough skill points to upgrade ${skillName} (You have ${this.skillPoints}, you need ${cost})`); return false; } @@ -3754,9 +3722,7 @@ Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript if (routing.isOn(Page.Bladeburner) && DomElems.currentTab.toLowerCase() === "skills") { this.createActionAndSkillsContent(); } - if (workerScript.shouldLog("upgradeSkill")) { - workerScript.log(skillName + " successfully upgraded to level " + this.skills[skillName]); - } + workerScript.log("bladeburner.upgradeSkill", `'${skillName}' upgraded to level ${this.skills[skillName]}`); return true; } @@ -3765,19 +3731,16 @@ Bladeburner.prototype.getTeamSizeNetscriptFn = function(type, name, workerScript return this.teamSize; } - var errorLogText = "ERROR: bladeburner.getTeamSize() failed due to an invalid action specified. " + - "Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " + - "name of the operation is case-sensitive."; - - var actionId = this.getActionIdFromTypeAndName(type, name); + const errorLogText = `Invalid action: type='${type}' name='${name}'`; + const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getTeamSize", errorLogText); return -1; } - var actionObj = this.getActionObject(actionId); + const actionObj = this.getActionObject(actionId); if (actionObj == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.getTeamSize", errorLogText); return -1; } @@ -3791,39 +3754,34 @@ Bladeburner.prototype.getTeamSizeNetscriptFn = function(type, name, workerScript } Bladeburner.prototype.setTeamSizeNetscriptFn = function(type, name, size, workerScript) { - var errorLogText = "ERROR: bladeburner.setTeamSize() failed due to an invalid action specified. " + - "Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " + - "name of the operation is case-sensitive."; - var actionId = this.getActionIdFromTypeAndName(type, name); + const errorLogText = `Invalid action: type='${type}' name='${name}'`; + const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.setTeamSize", errorLogText); return -1; } if (actionId.type !== ActionTypes["Operation"] && actionId.type !== ActionTypes["BlackOp"] && actionId.type !== ActionTypes["BlackOperation"]) { - workerScript.log("ERROR: bladeburner.setTeamSize() failed. This function " + - "only works for Operations and BlackOps"); + workerScript.log("bladeburner.setTeamSize", "Only valid for 'Operations' and 'BlackOps'"); return -1; } - var actionObj = this.getActionObject(actionId); + const actionObj = this.getActionObject(actionId); if (actionObj == null) { - workerScript.log(errorLogText); + workerScript.log("bladeburner.setTeamSize", errorLogText); return -1; } - var sanitizedSize = Math.round(size); + const sanitizedSize = Math.round(size); if (isNaN(sanitizedSize)) { - workerScript.log("ERROR: bladeburner.setTeamSize() failed due to an invalid 'size' argument: " + size); + workerScript.log("bladeburner.setTeamSize", `Invalid size: ${size}`); return -1; } if (this.teamSize < sanitizedSize) {sanitizedSize = this.teamSize;} actionObj.teamCount = sanitizedSize; - if (workerScript.shouldLog("setTeamSize")) { - workerScript.log("Team size for " + name + " set to " + sanitizedSize); - } + workerScript.log("bladeburner.setTeamSize", `Team size for '${name}' set to ${sanitizedSize}.`); return sanitizedSize; } @@ -3833,19 +3791,14 @@ Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript) return true; } else if (this.rank >= RankNeededForFaction) { joinFaction(bladeburnerFac); - if (workerScript.shouldLog("joinBladeburnerFaction")) { - workerScript.log("Joined Bladeburners Faction"); - } + workerScript.log("bladeburner.joinBladeburnerFaction", "Joined Bladeburners faction."); if (routing.isOn(Page.Bladeburner)) { removeChildrenFromElement(DomElems.overviewDiv); this.createOverviewContent(); } return true; } else { - if (workerScript.shouldLog("joinBladeburnerFaction")) { - workerScript.log("Failed to join Bladeburners Faction because " + - "you do not have the required " + RankNeededForFaction + " rank"); - } + workerScript.log("bladeburner.joinBladeburnerFaction", `You do not have the required rank (${this.rank}/${RankNeededForFaction}).`); return false; } } diff --git a/src/Netscript/WorkerScript.ts b/src/Netscript/WorkerScript.ts index 13ba99d57..23c5d48e6 100644 --- a/src/Netscript/WorkerScript.ts +++ b/src/Netscript/WorkerScript.ts @@ -190,10 +190,12 @@ export class WorkerScript { log(func: string, txt: string): void { if(this.shouldLog(func)) { - if(func !== "" && txt !== ""){ + if(func && txt){ this.scriptRef.log(`${func}: ${txt}`); + } else if(func) { + this.scriptRef.log(func); } else { - this.scriptRef.log(func+txt); + this.scriptRef.log(txt); } } } From 8b812b92cc50ef12574c51c4f7aa77d1d77d3ee7 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 13:31:27 -0500 Subject: [PATCH 02/13] Ace now creates the list of keywords from the actual ns object, meaning we cant forget to add functions to that list anymore. Also fixes the bug where clearLog would not get highlighted because clear took precedence. --- src/ScriptEditor/AceNetscriptMode.js | 95 ++++++---------------------- 1 file changed, 18 insertions(+), 77 deletions(-) diff --git a/src/ScriptEditor/AceNetscriptMode.js b/src/ScriptEditor/AceNetscriptMode.js index 054d30314..88c21ccd2 100644 --- a/src/ScriptEditor/AceNetscriptMode.js +++ b/src/ScriptEditor/AceNetscriptMode.js @@ -1,4 +1,5 @@ //This file should be copied into brace/mode/netscript.js +import { NetscriptFunctions } from '../NetscriptFunctions'; ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(acequire, exports, module) { "use strict"; @@ -45,7 +46,6 @@ DocCommentHighlightRules.getEndRule = function (start) { }; }; - exports.DocCommentHighlightRules = DocCommentHighlightRules; }); @@ -58,81 +58,22 @@ var DocCommentHighlightRules = acequire("./doc_comment_highlight_rules").DocComm var TextHighlightRules = acequire("./text_highlight_rules").TextHighlightRules; var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"; -let NetscriptFunctions = - "hack|hackAnalyzeThreads|hackAnalyzePercent|hackChance|" + - "sleep|grow|weaken|growthAnalyze|print|tprint|scan|nuke|brutessh|" + - "ftpcrack|" + - "clearLog|disableLog|enableLog|isLogEnabled|getScriptLogs|tail|" + - "relaysmtp|httpworm|sqlinject|run|exec|spawn|kill|killall|exit|" + - "scp|ls|ps|hasRootAccess|" + - "getIp|getHackingMultipliers|getBitNodeMultipliers|getStats|isBusy|" + - "getHacknetMultipliers|" + - "getHostname|getHackingLevel|getServerMoneyAvailable|getServerMaxMoney|" + - "getServerGrowth|getServerSecurityLevel|getServerBaseSecurityLevel|" + - "getServerMinSecurityLevel|" + - "getServerRequiredHackingLevel|getServerNumPortsRequired|getServerRam|" + - "serverExists|fileExists|isRunning|" + - "deleteServer|getPurchasedServers|" + - "getPurchasedServerLimit|getPurchasedServerMaxRam|" + - "getPurchasedServerCost|" + - "purchaseServer|round|write|tryWrite|read|peek|clear|rm|getPortHandle|" + - "scriptRunning|scriptKill|getScriptName|getScriptRam|" + - "getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" + - "getTimeSinceLastAug|prompt|" + +let functions = (function(){ + function recursiveKeywords(namespace) { + const keywords = []; + for(const elem of Object.keys(namespace)) { + keywords.push(elem); + if(typeof namespace[elem] === Object) { + keywords.concat(namespace[elem]); + } + } + return keywords; + } - // Singularity Functions - "universityCourse|getCharacterInformation|" + - "gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" + - "getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" + - "getCompanyFavor|stopAction|getFactionFavor|" + - "getFavorToDonate|getFactionFavorGain|getCompanyFavorGain|" + - "checkFactionInvitations|joinFaction|workForFaction|getFactionRep|" + - "donateToFaction|getCrimeStats|" + - "createProgram|commitCrime|getCrimeChance|getOwnedAugmentations|" + - "getOwnedSourceFiles|getAugmentationsFromFaction|" + - "getAugmentationPrereq|getAugmentationCost|purchaseAugmentation|" + - "softReset|installAugmentations|getAugmentationStats|" + - - // TIX API - "getStockPrice|getStockPosition|getStockSymbols|getStockMaxShares|" + - "getStockAskPrice|getStockBidPrice|getStockPurchaseCost|getStockSaleGain|" + - "buyStock|sellStock|shortStock|sellShort|" + - "placeOrder|cancelOrder|getOrders|getStockVolatility|getStockForecast|" + - "purchase4SMarketData|purchase4SMarketDataTixApi|" + - - // Hacknet Node API - "hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" + - "upgradeLevel|upgradeRam|upgradeCore|upgradeCache|getLevelUpgradeCost|" + - "getRamUpgradeCost|getCoreUpgradeCost|getCacheUpgradeCost|maxNumNodes|" + - - // Gang API - "gang|" + - "getMemberNames|getGangInformation|getMemberInformation|canRecruitMember|" + - "recruitMember|getTaskNames|setMemberTask|getEquipmentNames|" + - "getEquipmentCost|getEquipmentType|purchaseEquipment|ascendMember|" + - "setTerritoryWarfare|getEquipmentStats|getTaskStats|" + - "getChanceToWinClash|getBonusTime|" + - - // Bladeburner API - "bladeburner|getContractNames|getOperationNames|getBlackOpNames|" + - "getGeneralActionNames|getSkillNames|startAction|stopBladeburnerAction|" + - "getActionTime|getActionEstimatedSuccessChance|getActionCountRemaining|" + - "getActionMaxLevel|getActionCurrentLevel|getActionAutolevel|" + - "getActionRepGain|setActionAutolevel|setActionLevel|getBlackOpRank|" + - "getRank|getSkillPoints|getSkillLevel|getSkillUpgradeCost|" + - "upgradeSkill|getTeamSize|getCity|getCurrentAction|" + - "setTeamSize|getCityEstimatedPopulation|getCityEstimatedCommunities|" + - "getCityChaos|switchCity|getStamina|joinBladeburnerFaction|getBonusTime|" + - - // Coding Contract API - "codingcontract|attempt|getContractType|getData|getDescription|" + - "getNumTriesRemaining|" + - - // Sleeve API - "sleeve|getNumSleeves|setToShockRecovery|setToSynchronize|" + - "setToCommitCrime|setToUniversityCourse|travel|setToCompanyWork|" + - "setToFactionWork|setToGymWorkout|getSleeveStats|getTask|getInformation|" + - "getSleeveAugmentations|getSleevePurchasableAugs|purchaseSleeveAug"; + const ns = NetscriptFunctions(null); + // reverse is important so that both clearLog and clear are highlighted. + return recursiveKeywords(ns).sort().reverse().join("|"); +})(); var NetscriptHighlightRules = function(options) { var keywordMapper = this.createKeywordMapper({ @@ -145,7 +86,7 @@ var NetscriptHighlightRules = function(options) { "SyntaxError|TypeError|URIError|" + "decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|eval|isFinite|" + // Non-constructor functions "isNaN|parseFloat|parseInt|" + - "ns|" + NetscriptFunctions +"|" + + "ns|" + functions +"|" + "JSON|Math|" + // Other "this|arguments|prototype|window|document" , // Pseudo "keyword": @@ -291,7 +232,7 @@ var NetscriptHighlightRules = function(options) { regex : /[.](?![.])/ }, { token : "support.function", - regex : "/|" + NetscriptFunctions + "|/" + regex : "/|" + functions + "|/" }, { token : "support.function", regex : /(s(?:h(?:ift|ow(?:Mod(?:elessDialog|alDialog)|Help))|croll(?:X|By(?:Pages|Lines)?|Y|To)?|t(?:op|rike)|i(?:n|zeToContent|debar|gnText)|ort|u(?:p|b(?:str(?:ing)?)?)|pli(?:ce|t)|e(?:nd|t(?:Re(?:sizable|questHeader)|M(?:i(?:nutes|lliseconds)|onth)|Seconds|Ho(?:tKeys|urs)|Year|Cursor|Time(?:out)?|Interval|ZOptions|Date|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Date|FullYear)|FullYear|Active)|arch)|qrt|lice|avePreferences|mall)|h(?:ome|andleEvent)|navigate|c(?:har(?:CodeAt|At)|o(?:s|n(?:cat|textual|firm)|mpile)|eil|lear(?:Timeout|Interval)?|a(?:ptureEvents|ll)|reate(?:StyleSheet|Popup|EventObject))|t(?:o(?:GMTString|S(?:tring|ource)|U(?:TCString|pperCase)|Lo(?:caleString|werCase))|est|a(?:n|int(?:Enabled)?))|i(?:s(?:NaN|Finite)|ndexOf|talics)|d(?:isableExternalCapture|ump|etachEvent)|u(?:n(?:shift|taint|escape|watch)|pdateCommands)|j(?:oin|avaEnabled)|p(?:o(?:p|w)|ush|lugins.refresh|a(?:ddings|rse(?:Int|Float)?)|r(?:int|ompt|eference))|e(?:scape|nableExternalCapture|val|lementFromPoint|x(?:p|ec(?:Script|Command)?))|valueOf|UTC|queryCommand(?:State|Indeterm|Enabled|Value)|f(?:i(?:nd|le(?:ModifiedDate|Size|CreatedDate|UpdatedDate)|xed)|o(?:nt(?:size|color)|rward)|loor|romCharCode)|watch|l(?:ink|o(?:ad|g)|astIndexOf)|a(?:sin|nchor|cos|t(?:tachEvent|ob|an(?:2)?)|pply|lert|b(?:s|ort))|r(?:ou(?:nd|teEvents)|e(?:size(?:By|To)|calc|turnValue|place|verse|l(?:oad|ease(?:Capture|Events)))|andom)|g(?:o|et(?:ResponseHeader|M(?:i(?:nutes|lliseconds)|onth)|Se(?:conds|lection)|Hours|Year|Time(?:zoneOffset)?|Da(?:y|te)|UTC(?:M(?:i(?:nutes|lliseconds)|onth)|Seconds|Hours|Da(?:y|te)|FullYear)|FullYear|A(?:ttention|llResponseHeaders)))|m(?:in|ove(?:B(?:y|elow)|To(?:Absolute)?|Above)|ergeAttributes|a(?:tch|rgins|x))|b(?:toa|ig|o(?:ld|rderWidths)|link|ack))\b(?=\()/ From 3a31ebdce31f47c97c23e49e99f691a56af101e7 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 13:44:06 -0500 Subject: [PATCH 03/13] Sleeves karma gain scales with sync. --- src/PersonObjects/Sleeve/Sleeve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 1d1274401..53c7f9ff9 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -206,7 +206,7 @@ export class Sleeve extends Person { retValue = this.gainExperience(p, successGainRates); this.gainMoney(p, this.gainRatesForTask); - p.karma -= crime.karma; + p.karma -= crime.karma*(this.sync / 100); } else { retValue = this.gainExperience(p, this.gainRatesForTask); } From a4fe6d80d67f488b2630c88941257b4b22e85d33 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 13:47:23 -0500 Subject: [PATCH 04/13] update changelog, just to keep track --- src/Constants.ts | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/src/Constants.ts b/src/Constants.ts index 099b4f038..fddfc3a55 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -228,27 +228,16 @@ export let CONSTANTS: IMap = { LatestUpdate: ` - v0.49.0 - 2021-03-11 Source-File -1 + v0.50.0 - 2021-XX-XX ------- - Source-File -1 - * For advanced players: The game now embraces exploits and will reward - players for doing so. - - Gang - * ascension is less effective as the ascension multiplier goes up. - * territory gain scales with power difference. + Documentation + * readthedocs should now be more consistent and many examples were added. Netscript - * 'gang.getEquipmentStats' returns the stats of the equipment. - * 'gang.getTaskStats' returns the stats of a task. - * 'getCrimeStats' returns the stats of a crime. - * Crashes should now print the ns stack trace. - * Log messages are now more consistent. - * 'softReset' now accepts a callback script like 'installAugmentations' + * Ace editor will now correctly highlight all functions. - Misc. - * Minor formatting under Hacking>Active Scripts - * option menu colors now match the rest of the game, kinda. + Sleeve + * karma gain now scales with sync. ` } From f8d65b924000d4483247c6cfe9c9618c68742570 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 14:09:35 -0500 Subject: [PATCH 05/13] General style improvement in gang --- css/styles.scss | 4 +++- src/Gang.js | 37 +++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/css/styles.scss b/css/styles.scss index 44fb8fe6b..97e818a2c 100644 --- a/css/styles.scss +++ b/css/styles.scss @@ -360,9 +360,11 @@ a:visited { font-size: $defaultFontSize * 0.8125; } +input[type=checkbox] { + filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10); +} .optionCheckbox { - filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10); margin: 5px; float: right; } diff --git a/src/Gang.js b/src/Gang.js index 0aa0c03a4..e2018a8ee 100644 --- a/src/Gang.js +++ b/src/Gang.js @@ -1042,6 +1042,7 @@ Gang.prototype.createGangMemberUpgradeBox = function(player, initialFilter="") { // New popup UIElems.gangMemberUpgradeBoxFilter = createElement("input", { type:"text", placeholder:"Filter gang members", + class: "text-input", value:initialFilter, onkeyup:()=>{ var filterValue = UIElems.gangMemberUpgradeBoxFilter.value.toString(); @@ -1353,6 +1354,7 @@ Gang.prototype.displayGangContent = function(player) { }, placeholder: "Name must be unique", type: "text", + class:"text-input", }); yesBtn = createElement("a", { class: "std-button", @@ -1433,6 +1435,7 @@ Gang.prototype.displayGangContent = function(player) { }); UIElems.gangMemberFilter = createElement("input", { type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px", + class:"text-input", onkeyup:()=>{ this.displayGangMemberList(); } @@ -1638,8 +1641,8 @@ Gang.prototype.updateGangContent = function() { removeChildrenFromElement(UIElems.gangInfo); UIElems.gangInfo.appendChild(createElement("p", { // Respect display: "inline-block", - innerText: "Respect: " + formatNumber(this.respect, 6) + - " (" + formatNumber(5*this.respectGainRate, 6) + " / sec)", + innerText: "Respect: " + numeralWrapper.format(this.respect, '0.00000a') + + " (" + numeralWrapper.format(5*this.respectGainRate, '0.00000a') + " / sec)", tooltip: "Represents the amount of respect your gang has from other gangs and criminal " + "organizations. Your respect affects the amount of money " + "your gang members will earn, and also determines how much " + @@ -1649,8 +1652,8 @@ Gang.prototype.updateGangContent = function() { UIElems.gangInfo.appendChild(createElement("p", { // Wanted level display: "inline-block", - innerText: "Wanted Level: " + formatNumber(this.wanted, 6) + - " (" + formatNumber(5*this.wantedGainRate, 6) + " / sec)", + innerText: "Wanted Level: " + numeralWrapper.format(this.wanted, '0.00000a') + + " (" + numeralWrapper.format(5*this.wantedGainRate, '0.00000a') + " / sec)", tooltip: "Represents how much the gang is wanted by law enforcement. The higher " + "your gang's wanted level, the harder it will be for your gang members " + "to make money and earn respect. Note that the minimum wanted level is 1." @@ -1691,18 +1694,20 @@ Gang.prototype.updateGangContent = function() { UIElems.gangInfo.appendChild(createElement("p", { // Faction reputation display:"inline-block", - innerText:"Faction reputation: " + formatNumber(rep, 3) + innerText:"Faction reputation: " + numeralWrapper.format(rep, '0.000a') })); UIElems.gangInfo.appendChild(createElement("br")); const CyclesPerSecond = 1000 / Engine._idleSpeed; - UIElems.gangInfo.appendChild(createElement("p", { // Stored Cycles - innerText: `Bonus time: ${convertTimeMsToTimeElapsedString(this.storedCycles / CyclesPerSecond*1000)}`, - display: "inline-block", - tooltip: "You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by the browser). " + - "Bonus time makes the Gang mechanic progress faster, up to 5x the normal speed", - })); - UIElems.gangInfo.appendChild(createElement("br")); + if (this.storedCycles / CyclesPerSecond*1000 > 5000) { + UIElems.gangInfo.appendChild(createElement("p", { // Stored Cycles + innerText: `Bonus time: ${convertTimeMsToTimeElapsedString(this.storedCycles / CyclesPerSecond*1000)}`, + display: "inline-block", + tooltip: "You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by the browser). " + + "Bonus time makes the Gang mechanic progress faster, up to 5x the normal speed", + })); + UIElems.gangInfo.appendChild(createElement("br")); + } } else { console.error("gang-info DOM element DNE"); } @@ -1776,12 +1781,12 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) { const popupId = `gang-management-ascend-member ${memberObj.name}`; const ascendBenefits = memberObj.getAscensionResults(); const txt = createElement("pre", { - innerText: ["Are you sure you want to ascend this member? (S)he will lose all of", - "his non-Augmentation upgrades and his/her stats will reset back to 1.", + innerText: ["Are you sure you want to ascend this member? They will lose all of", + "their non-Augmentation upgrades and their stats will reset back to 1.", "", - `Furthermore, your gang will lose ${numeralWrapper.format(memberObj.earnedRespect, "0.000000")} respect`, + `Furthermore, your gang will lose ${numeralWrapper.format(memberObj.earnedRespect, "0.000a")} respect`, "", - "In return, (s)he will gain the following permanent boost to stat multipliers:\n", + "In return, they will gain the following permanent boost to stat multipliers:\n", `Hacking: +${numeralWrapper.format(ascendBenefits.hack, "0.00%")}`, `Strength: +${numeralWrapper.format(ascendBenefits.str, "0.00%")}`, `Defense: +${numeralWrapper.format(ascendBenefits.def, "0.00%")}`, From 1df0af0fa43873dc0e92d568203dc4221f06acda Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 14:20:39 -0500 Subject: [PATCH 06/13] fix bug in ace keywords highlight, more formatting in gang, update changelog --- src/Constants.ts | 3 +++ src/Gang.js | 8 ++++---- src/ScriptEditor/AceNetscriptMode.js | 9 ++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Constants.ts b/src/Constants.ts index fddfc3a55..76751c02e 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -237,6 +237,9 @@ export let CONSTANTS: IMap = { Netscript * Ace editor will now correctly highlight all functions. + Gang + * style improvements + Sleeve * karma gain now scales with sync. ` diff --git a/src/Gang.js b/src/Gang.js index e2018a8ee..3cea9b1e3 100644 --- a/src/Gang.js +++ b/src/Gang.js @@ -1934,10 +1934,10 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) { var gainInfo = document.getElementById(name + "gang-member-gain-info"); if (gainInfo) { gainInfo.innerHTML = - [`Money: $ ${formatNumber(5*memberObj.calculateMoneyGain(this), 2)} / sec`, - `Respect: ${formatNumber(5*memberObj.calculateRespectGain(this), 6)} / sec`, - `Wanted Level: ${formatNumber(5*memberObj.calculateWantedLevelGain(this), 6)} / sec`, - `Total Respect Earned: ${formatNumber(memberObj.earnedRespect, 6)}`].join("
"); + [`Money: ${numeralWrapper.format(5*memberObj.calculateMoneyGain(this), '$0.000a')} / sec`, + `Respect: ${numeralWrapper.format(5*memberObj.calculateRespectGain(this), '0.00000a')} / sec`, + `Wanted Level: ${numeralWrapper.format(5*memberObj.calculateWantedLevelGain(this), '0.00000a')} / sec`, + `Total Respect Earned: ${numeralWrapper.format(memberObj.earnedRespect, '0.00000a')}`].join("
"); } // Update selector to have the correct task diff --git a/src/ScriptEditor/AceNetscriptMode.js b/src/ScriptEditor/AceNetscriptMode.js index 88c21ccd2..1b2cd81c0 100644 --- a/src/ScriptEditor/AceNetscriptMode.js +++ b/src/ScriptEditor/AceNetscriptMode.js @@ -60,11 +60,12 @@ var identifierRe = "[a-zA-Z\\$_\u00a1-\uffff][a-zA-Z\\d\\$_\u00a1-\uffff]*"; let functions = (function(){ function recursiveKeywords(namespace) { - const keywords = []; + let keywords = []; for(const elem of Object.keys(namespace)) { keywords.push(elem); - if(typeof namespace[elem] === Object) { - keywords.concat(namespace[elem]); + if(typeof namespace[elem] == 'object') { + console.log(recursiveKeywords(namespace[elem])); + keywords = keywords.concat(recursiveKeywords(namespace[elem])); } } return keywords; @@ -75,6 +76,8 @@ let functions = (function(){ return recursiveKeywords(ns).sort().reverse().join("|"); })(); +console.log(functions); + var NetscriptHighlightRules = function(options) { var keywordMapper = this.createKeywordMapper({ "variable.language": From 3db440fd95f609066434ed12befb8f3b5653de31 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 14:20:56 -0500 Subject: [PATCH 07/13] remove console.log calls --- src/ScriptEditor/AceNetscriptMode.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ScriptEditor/AceNetscriptMode.js b/src/ScriptEditor/AceNetscriptMode.js index 1b2cd81c0..15e70087a 100644 --- a/src/ScriptEditor/AceNetscriptMode.js +++ b/src/ScriptEditor/AceNetscriptMode.js @@ -64,7 +64,6 @@ let functions = (function(){ for(const elem of Object.keys(namespace)) { keywords.push(elem); if(typeof namespace[elem] == 'object') { - console.log(recursiveKeywords(namespace[elem])); keywords = keywords.concat(recursiveKeywords(namespace[elem])); } } @@ -76,8 +75,6 @@ let functions = (function(){ return recursiveKeywords(ns).sort().reverse().join("|"); })(); -console.log(functions); - var NetscriptHighlightRules = function(options) { var keywordMapper = this.createKeywordMapper({ "variable.language": From c76110b575e3f4070c7b2ef66fb39f7b09b0e244 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 14:32:07 -0500 Subject: [PATCH 08/13] added tFormat to represent times. --- doc/source/netscript/basicfunctions/tFormat.rst | 15 +++++++++++++++ src/Constants.ts | 2 ++ src/NetscriptFunctions.js | 4 ++++ src/index.html | 6 +++--- 4 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 doc/source/netscript/basicfunctions/tFormat.rst diff --git a/doc/source/netscript/basicfunctions/tFormat.rst b/doc/source/netscript/basicfunctions/tFormat.rst new file mode 100644 index 000000000..e2acd5cef --- /dev/null +++ b/doc/source/netscript/basicfunctions/tFormat.rst @@ -0,0 +1,15 @@ +tFormat() Netscript Function +============================ + +.. js:function:: tFormat(milliseconds) + + :RAM cost: 0 GB + :param number milliseconds: Amount of milliseconds to format. + :returns: milliseconds in the "D M H S" format + + Example: + + .. code-block:: javascript + + tFormat(3000); // returns: "3 seconds" + tFormat(10000000); // returns: "2 hours 46 minutes 40 seconds" diff --git a/src/Constants.ts b/src/Constants.ts index 76751c02e..9cddaa04b 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -236,6 +236,8 @@ export let CONSTANTS: IMap = { Netscript * Ace editor will now correctly highlight all functions. + * 'tFormat' is a new netscript function that returns a human readable + representation of milliseconds. eg. "2 hours 15 minute 43 seconds" Gang * style improvements diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index 4ec58a351..c833a6bfa 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -151,6 +151,7 @@ import { numeralWrapper } from "./ui/numeralFormat"; import { post } from "./ui/postToTerminal"; import { setTimeoutRef } from "./utils/SetTimeoutRef"; import { is2DArray } from "./utils/helpers/is2DArray"; +import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions"; import { dialogBoxCreate } from "../utils/DialogBox"; import { formatNumber, isHTML } from "../utils/StringHelperFunctions"; @@ -2349,6 +2350,9 @@ function NetscriptFunctions(workerScript) { return numeralWrapper.format(parseFloat(n), format); }, + tFormat: function(milliseconds) { + return convertTimeMsToTimeElapsedString(milliseconds); + }, getTimeSinceLastAug: function() { updateDynamicRam("getTimeSinceLastAug", getRamCost("getTimeSinceLastAug")); return Player.playtimeSinceLastAug; diff --git a/src/index.html b/src/index.html index fb7af1c5c..d6858f0ad 100644 --- a/src/index.html +++ b/src/index.html @@ -153,17 +153,17 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
- +
- +
- +
From def3846b7238407e720154de6e874da08aad7025 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 14:38:49 -0500 Subject: [PATCH 09/13] bladeburner textbox now match style. --- src/Bladeburner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bladeburner.js b/src/Bladeburner.js index 5730e8044..1bf218f20 100644 --- a/src/Bladeburner.js +++ b/src/Bladeburner.js @@ -2638,7 +2638,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { }); var input = createElement("input", { - type:"number", placeholder: "Team Members" + type:"number", placeholder: "Team size", class: "text-input", }); var setBtn = createElement("a", { innerText:"Confirm", class:"a-link-button", @@ -2794,7 +2794,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { }); var input = createElement("input", { - type:"number", placeholder: "Team Members" + type:"number", placeholder: "Team size", class: "text-input", }); var setBtn = createElement("a", { innerText:"Confirm", class:"a-link-button", From 9ccdd7f4e59cf91d1be1a0a094e12f7c96a47671 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Fri, 12 Mar 2021 15:56:25 -0500 Subject: [PATCH 10/13] unify checkboxes in bladeburner --- src/Bladeburner.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Bladeburner.js b/src/Bladeburner.js index 1bf218f20..10b6dae41 100644 --- a/src/Bladeburner.js +++ b/src/Bladeburner.js @@ -2575,11 +2575,10 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { el.appendChild(createElement("br")); var autolevelCheckboxId = "bladeburner-" + action.name + "-autolevel-checkbox"; el.appendChild(createElement("label", { - for:autolevelCheckboxId, innerText:"Autolevel",color:"white", + for:autolevelCheckboxId, innerText:"Autolevel: ",color:"white", tooltip:"Automatically increase contract level when possible" })); - const checkboxDiv = createElement("div", { class: "bbcheckbox" }); const checkboxInput = createElement("input", { type:"checkbox", id: autolevelCheckboxId, @@ -2588,11 +2587,8 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { action.autoLevel = checkboxInput.checked; }, }); - const checkmarkLabel = createElement("label", { for: autolevelCheckboxId }); - checkboxDiv.appendChild(checkboxInput); - checkboxDiv.appendChild(checkmarkLabel); - el.appendChild(checkboxDiv); + el.appendChild(checkboxInput); } Bladeburner.prototype.updateOperationsUIElement = function(el, action) { @@ -2718,11 +2714,10 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { el.appendChild(createElement("br")); var autolevelCheckboxId = "bladeburner-" + action.name + "-autolevel-checkbox"; el.appendChild(createElement("label", { - for:autolevelCheckboxId, innerText:"Autolevel",color:"white", + for:autolevelCheckboxId, innerText:"Autolevel: ",color:"white", tooltip:"Automatically increase operation level when possible" })); - const checkboxDiv = createElement("div", { class: "bbcheckbox" }); const checkboxInput = createElement("input", { type:"checkbox", id: autolevelCheckboxId, @@ -2731,11 +2726,8 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { action.autoLevel = checkboxInput.checked; }, }); - const checkmarkLabel = createElement("label", { for: autolevelCheckboxId }); - checkboxDiv.appendChild(checkboxInput); - checkboxDiv.appendChild(checkmarkLabel); - el.appendChild(checkboxDiv); + el.appendChild(checkboxInput); } Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) { From d6016f490cbb57c2d167e0198b40997d7afd7069 Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Sat, 13 Mar 2021 15:10:55 -0500 Subject: [PATCH 11/13] bladeburner slowly being converted to typescript, added ScriptHackMoneyGain multiplier which is the money you actually gain from script hacks, not money drained, important for BN8 --- src/BitNode/BitNode.ts | 3 +- src/BitNode/BitNodeMultipliers.ts | 8 + src/Bladeburner.js | 1207 ++------------------ src/Bladeburner/Action.ts | 269 +++++ src/Bladeburner/BlackOperation.ts | 33 + src/Bladeburner/BlackOperations.ts | 345 ++++++ src/Bladeburner/City.ts | 172 +++ src/Bladeburner/Contract.ts | 24 + src/Bladeburner/GeneralActions.ts | 49 + src/Bladeburner/Operation.ts | 55 + src/Bladeburner/Skill.ts | 107 ++ src/Bladeburner/Skills.ts | 90 ++ src/Bladeburner/data/ActionTypes.ts | 14 + src/Bladeburner/data/Constants.ts | 79 ++ src/Bladeburner/data/Help.ts | 116 ++ src/Bladeburner/data/SkillNames.ts | 31 + src/Bladeburner/ui/BlackOperationsPage.tsx | 63 + src/Constants.ts | 6 + src/NetscriptFunctions.js | 39 +- src/PersonObjects/IPlayer.ts | 1 + 20 files changed, 1565 insertions(+), 1146 deletions(-) create mode 100644 src/Bladeburner/Action.ts create mode 100644 src/Bladeburner/BlackOperation.ts create mode 100644 src/Bladeburner/BlackOperations.ts create mode 100644 src/Bladeburner/City.ts create mode 100644 src/Bladeburner/Contract.ts create mode 100644 src/Bladeburner/GeneralActions.ts create mode 100644 src/Bladeburner/Operation.ts create mode 100644 src/Bladeburner/Skill.ts create mode 100644 src/Bladeburner/Skills.ts create mode 100644 src/Bladeburner/data/ActionTypes.ts create mode 100644 src/Bladeburner/data/Constants.ts create mode 100644 src/Bladeburner/data/Help.ts create mode 100644 src/Bladeburner/data/SkillNames.ts create mode 100644 src/Bladeburner/ui/BlackOperationsPage.tsx diff --git a/src/BitNode/BitNode.ts b/src/BitNode/BitNode.ts index b46e5b2fe..28d0e3359 100644 --- a/src/BitNode/BitNode.ts +++ b/src/BitNode/BitNode.ts @@ -353,7 +353,8 @@ export function initBitNodeMultipliers(p: IPlayer) { BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed break; case 8: // Ghost of Wall Street - BitNodeMultipliers.ScriptHackMoney = 0; + BitNodeMultipliers.ScriptHackMoney = 0.3; + BitNodeMultipliers.ScriptHackMoneyGain = 0; BitNodeMultipliers.ManualHackMoney = 0; BitNodeMultipliers.CompanyWorkMoney = 0; BitNodeMultipliers.CrimeMoney = 0; diff --git a/src/BitNode/BitNodeMultipliers.ts b/src/BitNode/BitNodeMultipliers.ts index 0a9334d59..52d7badf1 100644 --- a/src/BitNode/BitNodeMultipliers.ts +++ b/src/BitNode/BitNodeMultipliers.ts @@ -170,6 +170,13 @@ interface IBitNodeMultipliers { */ ScriptHackMoney: number; + /** + * The amount of money actually gained when script hack a server. This is + * different than the above because you can reduce the amount of money but + * not gain that same amount. + */ + ScriptHackMoneyGain: number; + /** * Influences the growth percentage per cycle against a server. */ @@ -233,6 +240,7 @@ export const BitNodeMultipliers: IBitNodeMultipliers = { HacknetNodeMoney: 1, ManualHackMoney: 1, ScriptHackMoney: 1, + ScriptHackMoneyGain: 1, CodingContractMoney: 1, ClassGymExpGain: 1, diff --git a/src/Bladeburner.js b/src/Bladeburner.js index 10b6dae41..2ff0b5850 100644 --- a/src/Bladeburner.js +++ b/src/Bladeburner.js @@ -21,6 +21,19 @@ import { import { setTimeoutRef } from "./utils/SetTimeoutRef"; import { formatNumber } from "../utils/StringHelperFunctions"; +import { ConsoleHelpText } from "./Bladeburner/data/Help"; +import { City } from "./Bladeburner/City"; +import { BladeburnerConstants } from "./Bladeburner/data/Constants"; +import { Skill } from "./Bladeburner/Skill"; +import { Skills } from "./Bladeburner/Skills"; +import { SkillNames } from "./Bladeburner/data/SkillNames"; +import { Operation } from "./Bladeburner/Operation"; +import { BlackOperation } from "./Bladeburner/BlackOperation"; +import { BlackOperations } from "./Bladeburner/BlackOperations"; +import { Contract } from "./Bladeburner/Contract"; +import { GeneralActions } from "./Bladeburner/GeneralActions"; +import { ActionTypes } from "./Bladeburner/data/ActionTypes"; + import { addOffset } from "../utils/helpers/addOffset"; import { clearObject } from "../utils/helpers/clearObject"; import { createProgressBarText } from "../utils/helpers/createProgressBarText"; @@ -40,131 +53,11 @@ import { removeElementById } from "../utils/uiHelpers/removeElementById"; const stealthIcon = ` ` const killIcon = `` -const CityNames = ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"]; - -const CyclesPerSecond = 5; // Game cycle is 200 ms - -const StaminaGainPerSecond = 0.0085; -const BaseStaminaLoss = 0.285; // Base stamina loss per action. Increased based on difficulty -const MaxStaminaToGainFactor = 70000; // Max Stamina is divided by this to get bonus stamina gain - -const DifficultyToTimeFactor = 10; // Action Difficulty divided by this to get base action time - -/** - * The difficulty multiplier affects stamina loss and hp loss of an action. Also affects - * experience gain. Its formula is: - * difficulty ^ exponentialFactor + difficulty / linearFactor - */ -const DiffMultExponentialFactor = 0.28; -const DiffMultLinearFactor = 650; - -/** - * These factors are used to calculate action time. - * They affect how much action time is reduced based on your agility and dexterity - */ -const EffAgiLinearFactor = 10e3; -const EffDexLinearFactor = 10e3; -const EffAgiExponentialFactor = 0.04; -const EffDexExponentialFactor = 0.035; - -const BaseRecruitmentTimeNeeded = 300; // Base time needed (s) to complete a Recruitment action - -const PopulationThreshold = 1e9; // Population which determines baseline success rate -const PopulationExponent = 0.7; // Exponent that influences how different populations affect success rate -const ChaosThreshold = 50; // City chaos level after which it starts making tasks harder - -const BaseStatGain = 1; // Base stat gain per second -const BaseIntGain = 0.001; // Base intelligence stat gain - -const ActionCountGrowthPeriod = 480; // Time (s) it takes for action count to grow by its specified value - -const RankToFactionRepFactor = 2; // Delta Faction Rep = this * Delta Rank -const RankNeededForFaction = 25; - -const ContractSuccessesPerLevel = 3; // How many successes you need to level up a contract -const OperationSuccessesPerLevel = 2.5; // How many successes you need to level up an op - -const RanksPerSkillPoint = 3; // How many ranks needed to get 1 Skill Point - -const ContractBaseMoneyGain = 250e3; // Base Money Gained per contract - -const HrcHpGain = 2; // HP Gained from Hyperbolic Regeneration chamber -const HrcStaminaGain = 1; // Percentage Stamina gained from Hyperbolic Regeneration Chamber - // DOM related variables const ActiveActionCssClass = "bladeburner-active-action"; - // Console related stuff let consoleHistoryIndex = 0; -const consoleHelpText = { - helpList:"Use 'help [command]' to get more information about a particular Bladeburner console command.

" + - "automate [var] [val] [hi/low] Configure simple automation for Bladeburner tasks
" + - "clear/cls Clear the console
" + - "help [cmd] Display this help text, or help text for a specific command
" + - "log [en/dis] [type] Enable or disable logging for events and actions
" + - "skill [action] [name] Level or display info about your Bladeburner skills
" + - "start [type] [name] Start a Bladeburner action/task
" + - "stop Stops your current Bladeburner action/task
", - automate:"automate [var] [val] [hi/low]

" + - "A simple way to automate your Bladeburner actions. This console command can be used " + - "to automatically start an action when your stamina rises above a certain threshold, and " + - "automatically switch to another action when your stamina drops below another threshold.

" + - "automate status - Check the current status of your automation and get a brief description of what it'll do
" + - "automate en - Enable the automation feature
" + - "automate dis - Disable the automation feature

" + - "There are four properties that must be set for this automation to work properly. Here is how to set them:

" + - "automate stamina 100 high
" + - "automate contract Tracking high
" + - "automate stamina 50 low
" + - 'automate general "Field Analysis" low

' + - "Using the four console commands above will set the automation to perform Tracking contracts " + - "if your stamina is 100 or higher, and then switch to Field Analysis if your stamina drops below " + - "50. Note that when setting the action, the name of the action is CASE-SENSITIVE. It must " + - "exactly match whatever the name is in the UI.", - clear:"clear

Clears the console", - cls:"cls

Clears the console", - help:"help [command]

" + - "Running 'help' with no arguments displays the general help text, which lists all console commands " + - "and a brief description of what they do. A command can be specified to get more specific help text " + - "about that particular command. For example:

" + - "help automate

" + - "will display specific information about using the automate console command", - log:"log [en/dis] [type]

" + - "Enable or disable logging. By default, the results of completing actions such as contracts/operations are logged " + - "in the console. There are also random events that are logged in the console as well. The five categories of " + - "things that get logged are:

" + - "[general, contracts, ops, blackops, events]

" + - "The logging for these categories can be enabled or disabled like so:

" + - "log dis contracts - Disables logging that occurs when contracts are completed
" + - "log en contracts - Enables logging that occurs when contracts are completed
" + - "log dis events - Disables logging for Bladeburner random events

" + - "Logging can be universally enabled/disabled using the 'all' keyword:

" + - "log dis all
" + - "log en all", - skill:"skill [action] [name]

" + - "Level or display information about your skills.

" + - "To display information about all of your skills and your multipliers, use:

" + - "skill list

" + - "To display information about a specific skill, specify the name of the skill afterwards. " + - "Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If " + - "the name of the skill has whitespace, enclose the name of the skill in double quotation marks:

" + - "skill list Reaper
" + - 'skill list "Digital Observer"

' + - "This console command can also be used to level up skills:

" + - "skill level [skill name]", - start:"start [type] [name]

" + - "Start an action. An action is specified by its type and its name. The " + - "name is case-sensitive. It must appear exactly as it does in the UI. If " + - "the name of the action has whitespace, enclose it in double quotation marks. " + - "Valid action types include:

" + - "[general, contract, op, blackop]

" + - "Examples:

" + - 'start contract Tracking
' + - 'start op "Undercover Operation"
', - stop:"stop

" + - "Stop your current action and go idle", -} // Keypresses for Console $(document).keydown(function(event) { @@ -224,405 +117,6 @@ $(document).keydown(function(event) { } }); -function City(params={}) { - this.name = params.name ? params.name : CityNames[2]; // Sector-12 - - // Synthoid population and estimate - this.pop = params.pop ? params.pop : getRandomInt(PopulationThreshold, 1.5 * PopulationThreshold); - this.popEst = this.pop * (Math.random() + 0.5); - - // Number of Synthoid communities population and estimate - this.comms = params.comms ? params.comms : getRandomInt(5, 150); - this.commsEst = this.comms + getRandomInt(-5, 5); - if (this.commsEst < 0) {this.commsEst = 0;} - this.chaos = 0; -} - -City.prototype.improvePopulationEstimateByCount = function(n) { - if (isNaN(n)) {throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");} - if (this.popEst < this.pop) { - this.popEst += n; - if (this.popEst > this.pop) {this.popEst = this.pop;} - } else if (this.popEst > this.pop) { - this.popEst -= n; - if (this.popEst < this.pop) {this.popEst = this.pop;} - } -} - -// @p is the percentage, not the multiplier. e.g. pass in p = 5 for 5% -City.prototype.improvePopulationEstimateByPercentage = function(p, skillMult=1) { - p = p*skillMult; - if (isNaN(p)) {throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");} - if (this.popEst < this.pop) { - ++this.popEst; // In case estimate is 0 - this.popEst *= (1 + (p/100)); - if (this.popEst > this.pop) {this.popEst = this.pop;} - } else if (this.popEst > this.pop) { - this.popEst *= (1 - (p/100)); - if (this.popEst < this.pop) {this.popEst = this.pop;} - } -} - -City.prototype.improveCommunityEstimate = function(n=1) { - if (isNaN(n)) {throw new Error("NaN passed into City.improveCommunityEstimate()");} - if (this.commsEst < this.comms) { - this.commsEst += n; - if (this.commsEst > this.comms) {this.commsEst = this.comms;} - } else if (this.commsEst > this.comms) { - this.commsEst -= n; - if (this.commsEst < this.comms) {this.commsEst = this.comms;} - } -} - -/** - * @params options: - * estChange(int): How much the estimate should change by - * estOffset(int): Add offset to estimate (offset by percentage) - */ -City.prototype.changePopulationByCount = function(n, params={}) { - if (isNaN(n)) {throw new Error("NaN passed into City.changePopulationByCount()");} - this.pop += n; - if (params.estChange && !isNaN(params.estChange)) {this.popEst += params.estChange;} - if (params.estOffset) { - this.popEst = addOffset(this.popEst, params.estOffset); - } - this.popEst = Math.max(this.popEst, 0); -} - -/** - * @p is the percentage, not the multiplier. e.g. pass in p = 5 for 5% - * @params options: - * changeEstEqually(bool) - Change the population estimate by an equal amount - * nonZero (bool) - Set to true to ensure that population always changes by at least 1 - */ -City.prototype.changePopulationByPercentage = function(p, params={}) { - if (isNaN(p)) {throw new Error("NaN passed into City.changePopulationByPercentage()");} - if (p === 0) {return;} - var change = Math.round(this.pop * (p/100)); - - // Population always changes by at least 1 - if (params.nonZero && change === 0) { - p > 0 ? change = 1 : change = -1; - } - - this.pop += change; - if (params.changeEstEqually) { - this.popEst += change; - if (this.popEst < 0) {this.popEst = 0;} - } - return change; -} - -City.prototype.changeChaosByCount = function(n) { - if (isNaN(n)) {throw new Error("NaN passed into City.changeChaosByCount()");} - if (n === 0) {return;} - this.chaos += n; - if (this.chaos < 0) {this.chaos = 0;} -} - -// @p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) -City.prototype.changeChaosByPercentage = function(p) { - if (isNaN(p)) {throw new Error("NaN passed into City.chaosChaosByPercentage()");} - if (p === 0) {return;} - var change = this.chaos * (p/100); - this.chaos += change; - if (this.chaos < 0) {this.chaos = 0;} -} - -City.prototype.toJSON = function() { - return Generic_toJSON("City", this); -} -City.fromJSON = function(value) { - return Generic_fromJSON(City, value.data); -} -Reviver.constructors.City = City; - -function Skill(params={name:"foo", desc:"foo"}) { - if (params.name) { - this.name = params.name; - } else { - throw new Error("Failed to initialize Bladeburner Skill. No name was specified in ctor"); - } - if (params.desc) { - this.desc = params.desc; - } else { - throw new Error("Failed to initialize Bladeburner Skills. No desc was specified in ctor"); - } - this.baseCost = params.baseCost ? params.baseCost : 1; // Cost is in Skill Points - this.costInc = params.costInc ? params.costInc : 1; // Additive cost increase per level - - if (params.maxLvl) {this.maxLvl = params.maxLvl;} - - /** - * These benefits are additive. So total multiplier will be level (handled externally) times the - * effects below - */ - if (params.successChanceAll) {this.successChanceAll = params.successChanceAll;} - if (params.successChanceStealth) {this.successChanceStealth = params.successChanceStealth;} - if (params.successChanceKill) {this.successChanceKill = params.successChanceKill;} - if (params.successChanceContract) {this.successChanceContract = params.successChanceContract;} - if (params.successChanceOperation) {this.successChanceOperation = params.successChanceOperation;} - - /** - * This multiplier affects everything that increases synthoid population/community estimate - * e.g. Field analysis, Investigation Op, Undercover Op - */ - if (params.successChanceEstimate) {this.successChanceEstimate = params.successChanceEstimate;} - - if (params.actionTime) {this.actionTime = params.actionTime;} - if (params.effHack) {this.effHack = params.effHack;} - if (params.effStr) {this.effStr = params.effStr;} - if (params.effDef) {this.effDef = params.effDef;} - if (params.effDex) {this.effDex = params.effDex;} - if (params.effAgi) {this.effAgi = params.effAgi;} - if (params.effCha) {this.effCha = params.effCha;} - - if (params.stamina) {this.stamina = params.stamina;} - if (params.money) {this.money = params.money;} - if (params.expGain) {this.expGain = params.expGain;} - - //Equipment - if (params.weaponAbility) {this.weaponAbility = params.weaponAbility;} - if (params.gunAbility) {this.gunAbility = params.gunAbility;} -} - -Skill.prototype.calculateCost = function(currentLevel) { - return Math.floor((this.baseCost + (currentLevel * this.costInc)) * BitNodeMultipliers.BladeburnerSkillCost); -} -const Skills = {}; -const SkillNames = { - BladesIntuition: "Blade's Intuition", - Cloak: "Cloak", - Marksman: "Marksman", - WeaponProficiency: "Weapon Proficiency", - ShortCircuit: "Short-Circuit", - DigitalObserver: "Digital Observer", - Tracer: "Tracer", - Overclock: "Overclock", - Reaper: "Reaper", - EvasiveSystem: "Evasive System", - Datamancer: "Datamancer", - CybersEdge: "Cyber's Edge", - HandsOfMidas: "Hands of Midas", - Hyperdrive: "Hyperdrive", -} - -// Base Class for Contracts, Operations, and BlackOps -function Action(params={}) { - this.name = params.name ? params.name : ""; - this.desc = params.desc ? params.desc : ""; - - // Difficulty scales with level. See getDifficulty() method - this.level = 1; - this.maxLevel = 1; - this.autoLevel = true; - this.baseDifficulty = params.baseDifficulty ? addOffset(params.baseDifficulty, 10) : 100; - this.difficultyFac = params.difficultyFac ? params.difficultyFac : 1.01; - - // Rank increase/decrease is affected by this exponent - this.rewardFac = params.rewardFac ? params.rewardFac : 1.02; - - this.successes = 0; - this.failures = 0; - - // All of these scale with level/difficulty - this.rankGain = params.rankGain ? params.rankGain : 0; - if (params.rankLoss) {this.rankLoss = params.rankLoss;} - if (params.hpLoss) { - this.hpLoss = params.hpLoss; - this.hpLost = 0; - } - - // Action Category. Current categories are stealth and kill - this.isStealth = params.isStealth ? true : false; - this.isKill = params.isKill ? true : false; - - /** - * Number of this contract remaining, and its growth rate - * Growth rate is an integer and the count will increase by that integer every "cycle" - */ - this.count = params.count ? params.count : getRandomInt(1e3, 25e3); - this.countGrowth = params.countGrowth ? params.countGrowth : getRandomInt(1, 5); - - // Weighting of each stat in determining action success rate - var defaultWeights = {hack:1/7,str:1/7,def:1/7,dex:1/7,agi:1/7,cha:1/7,int:1/7}; - this.weights = params.weights ? params.weights : defaultWeights; - - // Check to make sure weights are summed properly - let sum = 0; - for (const weight in this.weights) { - if (this.weights.hasOwnProperty(weight)) { - sum += this.weights[weight]; - } - } - if (sum - 1 >= 10 * Number.EPSILON) { - throw new Error("Invalid weights when constructing Action " + this.name + - ". The weights should sum up to 1. They sum up to :" + 1); - } - - // Diminishing returns of stats (stat ^ decay where 0 <= decay <= 1) - const defaultDecays = { hack: 0.9, str: 0.9, def: 0.9, dex: 0.9, agi: 0.9, cha: 0.9, int: 0.9 }; - this.decays = params.decays ? params.decays : defaultDecays; - for (const decay in this.decays) { - if (this.decays.hasOwnProperty(decay)) { - if (this.decays[decay] > 1) { - throw new Error("Invalid decays when constructing " + - "Action " + this.name + ". " + - "Decay value cannot be greater than 1"); - } - } - } -} - -Action.prototype.getDifficulty = function() { - var difficulty = this.baseDifficulty * Math.pow(this.difficultyFac, this.level-1); - if (isNaN(difficulty)) {throw new Error("Calculated NaN in Action.getDifficulty()");} - return difficulty; -} - -/** - * @inst - Bladeburner Object - * @params - options: - * est (bool): Get success chance estimate instead of real success chance - */ -Action.prototype.getSuccessChance = function(inst, params={}) { - if (inst == null) {throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");} - var difficulty = this.getDifficulty(); - var competence = 0; - for (var stat in this.weights) { - if (this.weights.hasOwnProperty(stat)) { - var playerStatLvl = Player.queryStatFromString(stat); - var key = "eff" + stat.charAt(0).toUpperCase() + stat.slice(1); - var effMultiplier = inst.skillMultipliers[key]; - if (effMultiplier == null) { - console.error(`Failed to find Bladeburner Skill multiplier for: ${stat}`); - effMultiplier = 1; - } - competence += (this.weights[stat] * Math.pow(effMultiplier*playerStatLvl, this.decays[stat])); - } - } - competence *= inst.calculateStaminaPenalty(); - - // For Operations, factor in team members - if (this instanceof Operation || this instanceof BlackOperation) { - if (this.teamCount && this.teamCount > 0) { - this.teamCount = Math.min(this.teamCount, inst.teamSize); - var teamMultiplier = Math.pow(this.teamCount, 0.05); - competence *= teamMultiplier; - } - } - - // Lower city population results in lower chances - if (!(this instanceof BlackOperation)) { - var city = inst.getCurrentCity(); - if (params.est) { - competence *= Math.pow((city.popEst / PopulationThreshold), PopulationExponent); - } else { - competence *= Math.pow((city.pop / PopulationThreshold), PopulationExponent); - } - - // Too high of a chaos results in lower chances - if (city.chaos > ChaosThreshold) { - var diff = 1 + (city.chaos - ChaosThreshold); - var mult = Math.pow(diff, 0.1); - difficulty *= mult; - } - - // For Raid Operations, no communities = fail - if (this instanceof Operation && this.name === "Raid") { - if (city.comms <= 0) {return 0;} - } - } - - // Factor skill multipliers into success chance - competence *= inst.skillMultipliers.successChanceAll; - if (this instanceof Operation || this instanceof BlackOperation) { - competence *= inst.skillMultipliers.successChanceOperation; - } - if (this instanceof Contract) { - competence *= inst.skillMultipliers.successChanceContract; - } - if (this.isStealth) { - competence *= inst.skillMultipliers.successChanceStealth; - } - if (this.isKill) { - competence *= inst.skillMultipliers.successChanceKill; - } - - // Augmentation multiplier - competence *= Player.bladeburner_success_chance_mult; - - if (isNaN(competence)) {throw new Error("Competence calculated as NaN in Action.getSuccessChance()");} - return Math.min(1, competence / difficulty); -} - -/** - * Tests for success. Should be called when an action has completed - * @param inst {Bladeburner} - Bladeburner instance - */ -Action.prototype.attempt = function(inst) { - return (Math.random() < this.getSuccessChance(inst)); -} - -Action.prototype.getActionTime = function(inst) { - var difficulty = this.getDifficulty(); - var baseTime = difficulty / DifficultyToTimeFactor; - var skillFac = inst.skillMultipliers.actionTime; // Always < 1 - - var effAgility = Player.agility * inst.skillMultipliers.effAgi; - var effDexterity = Player.dexterity * inst.skillMultipliers.effDex; - var statFac = 0.5 * (Math.pow(effAgility, EffAgiExponentialFactor) + - Math.pow(effDexterity, EffDexExponentialFactor) + - (effAgility / EffAgiLinearFactor) + - (effDexterity / EffDexLinearFactor)); // Always > 1 - - baseTime = Math.max(1, baseTime * skillFac / statFac); - - if (this instanceof Contract) { - return Math.ceil(baseTime); - } else if (this instanceof Operation) { - return Math.ceil(baseTime); - } else if (this instanceof BlackOperation) { - return Math.ceil(baseTime * 1.5); - } else { - throw new Error("Unrecognized Action Type in Action.getActionTime(this). Must be either Contract, Operation, or BlackOperation"); - } -} - -Action.prototype.getSuccessesNeededForNextLevel = function(baseSuccessesPerLevel) { - return Math.ceil((0.5) * (this.maxLevel) * (2 * baseSuccessesPerLevel + (this.maxLevel-1))); -} - -Action.prototype.setMaxLevel = function(baseSuccessesPerLevel) { - if (this.successes >= this.getSuccessesNeededForNextLevel(baseSuccessesPerLevel)) { - ++this.maxLevel; - } -} - -Action.prototype.toJSON = function() { - return Generic_toJSON("Action", this); -} -Action.fromJSON = function(value) { - return Generic_fromJSON(Action, value.data); -} -Reviver.constructors.Action = Action; -const GeneralActions = {}; // Training, Field Analysis, Recruitment, etc. - -// Action Identifier enum -const ActionTypes = Object.freeze({ - "Idle": 1, - "Contract": 2, - "Operation": 3, - "BlackOp": 4, - "BlackOperation": 4, - "Training": 5, - "Recruitment": 6, - "FieldAnalysis": 7, - "Field Analysis": 7, - "Diplomacy": 8, - "Hyperbolic Regeneration Chamber": 9, -}); - function ActionIdentifier(params={}) { if (params.name) {this.name = params.name;} if (params.type) {this.type = params.type;} @@ -638,65 +132,6 @@ ActionIdentifier.fromJSON = function(value) { Reviver.constructors.ActionIdentifier = ActionIdentifier; -// Contracts -function Contract(params={}) { - Action.call(this, params); -} - -Contract.prototype = Object.create(Action.prototype); - -Contract.prototype.toJSON = function() { - return Generic_toJSON("Contract", this); -} - -Contract.fromJSON = function(value) { - return Generic_fromJSON(Contract, value.data); -} - -Reviver.constructors.Contract = Contract; - -// Operations -function Operation(params={}) { - Action.call(this, params); - this.reqdRank = params.reqdRank ? params.reqdRank : 100; - this.teamCount = params.teamCount ? params.teamCount : 0; //# of team members to use -} - -Operation.prototype = Object.create(Action.prototype); - -Operation.prototype.toJSON = function() { - return Generic_toJSON("Operation", this); -} - -Operation.fromJSON = function(value) { - return Generic_fromJSON(Operation, value.data); -} - -Reviver.constructors.Operation = Operation; - -// Black Operations -function BlackOperation(params={}) { - Operation.call(this, params); - - // Black ops are one time missions - this.count = 1; - this.countGrowth = 0; -} - -BlackOperation.prototype = Object.create(Action.prototype); - -BlackOperation.prototype.toJSON = function() { - return Generic_toJSON("BlackOperation", this); -} - -BlackOperation.fromJSON = function(value) { - return Generic_fromJSON(BlackOperation, value.data); -} - -Reviver.constructors.BlackOperation = BlackOperation; - -const BlackOperations = {}; - function Bladeburner(params={}) { this.numHosp = 0; // Number of hospitalizations this.moneyLost = 0; // Money lost due to hospitalizations @@ -722,10 +157,10 @@ function Bladeburner(params={}) { this.action = new ActionIdentifier({type:idleActionType}); this.cities = {}; - for (var i = 0; i < CityNames.length; ++i) { - this.cities[CityNames[i]] = new City({name:CityNames[i]}); + for (var i = 0; i < BladeburnerConstants.CityNames.length; ++i) { + this.cities[BladeburnerConstants.CityNames[i]] = new City({name: BladeburnerConstants.CityNames[i]}); } - this.city = CityNames[2]; // Sector-12 + this.city = BladeburnerConstants.CityNames[2]; // Sector-12 // Map of SkillNames -> level this.skills = {}; @@ -770,7 +205,6 @@ function Bladeburner(params={}) { this.consoleLogs = []; // Initialization - initBladeburner(); this.initializeDomElementRefs(); if (params.new) {this.create();} } @@ -778,7 +212,7 @@ function Bladeburner(params={}) { Bladeburner.prototype.prestige = function() { this.resetAction(); var bladeburnerFac = Factions["Bladeburners"]; - if (this.rank >= RankNeededForFaction) { + if (this.rank >= BladeburnerConstants.RankNeededForFaction) { joinFaction(bladeburnerFac); } } @@ -902,6 +336,7 @@ Bladeburner.prototype.storeCycles = function(numCycles=1) { this.storedCycles += numCycles; } + Bladeburner.prototype.process = function() { // Edge case condition...if Operation Daedalus is complete trigger the BitNode if (redPillFlag === false && this.blackops.hasOwnProperty("Operation Daedalus")) { @@ -928,10 +363,10 @@ Bladeburner.prototype.process = function() { } // A 'tick' for this mechanic is one second (= 5 game cycles) - if (this.storedCycles >= CyclesPerSecond) { - var seconds = Math.floor(this.storedCycles / CyclesPerSecond); + if (this.storedCycles >= BladeburnerConstants.CyclesPerSecond) { + var seconds = Math.floor(this.storedCycles / BladeburnerConstants.CyclesPerSecond); seconds = Math.min(seconds, 5); // Max of 5 'ticks' - this.storedCycles -= seconds * CyclesPerSecond; + this.storedCycles -= seconds * BladeburnerConstants.CyclesPerSecond; // Stamina this.calculateMaxStamina(); @@ -942,19 +377,19 @@ Bladeburner.prototype.process = function() { for (var contractName in this.contracts) { if (this.contracts.hasOwnProperty(contractName)) { var contract = this.contracts[contractName]; - contract.count += (seconds * contract.countGrowth/ActionCountGrowthPeriod); + contract.count += (seconds * contract.countGrowth/BladeburnerConstants.ActionCountGrowthPeriod); } } for (var operationName in this.operations) { if (this.operations.hasOwnProperty(operationName)) { var op = this.operations[operationName]; - op.count += (seconds * op.countGrowth/ActionCountGrowthPeriod); + op.count += (seconds * op.countGrowth/BladeburnerConstants.ActionCountGrowthPeriod); } } // Chaos goes down very slowly - for (var i = 0; i < CityNames.length; ++i) { - var city = this.cities[CityNames[i]]; + for (var i = 0; i < BladeburnerConstants.CityNames.length; ++i) { + var city = this.cities[BladeburnerConstants.CityNames[i]]; if (!(city instanceof City)) {throw new Error("Invalid City object when processing passive chaos reduction in Bladeburner.process");} city.chaos -= (0.0001 * seconds); city.chaos = Math.max(0, city.chaos); @@ -1006,8 +441,8 @@ Bladeburner.prototype.calculateMaxStamina = function() { Bladeburner.prototype.calculateStaminaGainPerSecond = function() { var effAgility = Player.agility * this.skillMultipliers.effAgi; - var maxStaminaBonus = this.maxStamina / MaxStaminaToGainFactor; - var gain = (StaminaGainPerSecond + maxStaminaBonus) * Math.pow(effAgility, 0.17); + var maxStaminaBonus = this.maxStamina / BladeburnerConstants.MaxStaminaToGainFactor; + var gain = (BladeburnerConstants.StaminaGainPerSecond + maxStaminaBonus) * Math.pow(effAgility, 0.17); return gain * (this.skillMultipliers.stamina * Player.bladeburner_stamina_gain_mult); } @@ -1029,15 +464,15 @@ Bladeburner.prototype.changeRank = function(change) { } if (bladeburnerFac.isMember) { var favorBonus = 1 + (bladeburnerFac.favor / 100); - bladeburnerFac.playerReputation += (RankToFactionRepFactor * change * Player.faction_rep_mult * favorBonus); + bladeburnerFac.playerReputation += (BladeburnerConstants.RankToFactionRepFactor * change * Player.faction_rep_mult * favorBonus); } } // Gain skill points - var rankNeededForSp = (this.totalSkillPoints+1) * RanksPerSkillPoint; + var rankNeededForSp = (this.totalSkillPoints+1) * BladeburnerConstants.RanksPerSkillPoint; if (this.maxRank >= rankNeededForSp) { // Calculate how many skill points to gain - var gainedSkillPoints = Math.floor((this.maxRank - rankNeededForSp) / RanksPerSkillPoint + 1); + var gainedSkillPoints = Math.floor((this.maxRank - rankNeededForSp) / BladeburnerConstants.RanksPerSkillPoint + 1); this.skillPoints += gainedSkillPoints; this.totalSkillPoints += gainedSkillPoints; } @@ -1070,8 +505,6 @@ Bladeburner.prototype.resetSkillMultipliers = function() { stamina: 1, money: 1, expGain: 1, - weaponAbility: 1, - gunAbility: 1, }; } @@ -1241,11 +674,11 @@ Bladeburner.prototype.completeAction = function() { throw new Error("Failed to get Contract/Operation Object for: " + this.action.name); } var difficulty = action.getDifficulty(); - var difficultyMultiplier = Math.pow(difficulty, DiffMultExponentialFactor) + difficulty / DiffMultLinearFactor; + var difficultyMultiplier = Math.pow(difficulty, BladeburnerConstants.DiffMultExponentialFactor) + difficulty / BladeburnerConstants.DiffMultLinearFactor; var rewardMultiplier = Math.pow(action.rewardFac, action.level-1); // Stamina loss is based on difficulty - this.stamina -= (BaseStaminaLoss * difficultyMultiplier); + this.stamina -= (BladeburnerConstants.BaseStaminaLoss * difficultyMultiplier); if (this.stamina < 0) {this.stamina = 0;} // Process Contract/Operation success/failure @@ -1257,15 +690,15 @@ Bladeburner.prototype.completeAction = function() { // Earn money for contracts var moneyGain = 0; if (!isOperation) { - moneyGain = ContractBaseMoneyGain * rewardMultiplier * this.skillMultipliers.money; + moneyGain = BladeburnerConstants.ContractBaseMoneyGain * rewardMultiplier * this.skillMultipliers.money; Player.gainMoney(moneyGain); Player.recordMoneySource(moneyGain, "bladeburner"); } if (isOperation) { - action.setMaxLevel(OperationSuccessesPerLevel); + action.setMaxLevel(BladeburnerConstants.OperationSuccessesPerLevel); } else { - action.setMaxLevel(ContractSuccessesPerLevel); + action.setMaxLevel(BladeburnerConstants.ContractSuccessesPerLevel); } if (action.rankGain) { var gain = addOffset(action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank, 10); @@ -1318,10 +751,10 @@ Bladeburner.prototype.completeAction = function() { throw new Error("Failed to get BlackOperation Object for: " + this.action.name); } var difficulty = action.getDifficulty(); - var difficultyMultiplier = Math.pow(difficulty, DiffMultExponentialFactor) + difficulty / DiffMultLinearFactor; + var difficultyMultiplier = Math.pow(difficulty, BladeburnerConstants.DiffMultExponentialFactor) + difficulty / BladeburnerConstants.DiffMultLinearFactor; // Stamina loss is based on difficulty - this.stamina -= (BaseStaminaLoss * difficultyMultiplier); + this.stamina -= (BladeburnerConstants.BaseStaminaLoss * difficultyMultiplier); if (this.stamina < 0) {this.stamina = 0;} // Team loss variables @@ -1389,7 +822,7 @@ Bladeburner.prototype.completeAction = function() { } break; case ActionTypes["Training"]: - this.stamina -= (0.5 * BaseStaminaLoss); + this.stamina -= (0.5 * BladeburnerConstants.BaseStaminaLoss); var strExpGain = 30 * Player.strength_exp_mult, defExpGain = 30 * Player.defense_exp_mult, dexExpGain = 30 * Player.dexterity_exp_mult, @@ -1423,7 +856,7 @@ Bladeburner.prototype.completeAction = function() { var hackingExpGain = 20 * Player.hacking_exp_mult, charismaExpGain = 20 * Player.charisma_exp_mult; Player.gainHackingExp(hackingExpGain); - Player.gainIntelligenceExp(BaseIntGain); + Player.gainIntelligenceExp(BladeburnerConstants.BaseIntGain); Player.gainCharismaExp(charismaExpGain); this.changeRank(0.1 * BitNodeMultipliers.BladeburnerRank); this.getCurrentCity().improvePopulationEstimateByPercentage(eff * this.skillMultipliers.successChanceEstimate); @@ -1435,14 +868,14 @@ Bladeburner.prototype.completeAction = function() { case ActionTypes["Recruitment"]: var successChance = this.getRecruitmentSuccessChance(); if (Math.random() < successChance) { - var expGain = 2 * BaseStatGain * this.actionTimeToComplete; + var expGain = 2 * BladeburnerConstants.BaseStatGain * this.actionTimeToComplete; Player.gainCharismaExp(expGain); ++this.teamSize; if (this.logging.general) { this.log("Successfully recruited a team member! Gained " + formatNumber(expGain, 1) + " charisma exp"); } } else { - var expGain = BaseStatGain * this.actionTimeToComplete; + var expGain = BladeburnerConstants.BaseStatGain * this.actionTimeToComplete; Player.gainCharismaExp(expGain); if (this.logging.general) { this.log("Failed to recruit a team member. Gained " + formatNumber(expGain, 1) + " charisma exp"); @@ -1460,13 +893,13 @@ Bladeburner.prototype.completeAction = function() { this.startAction(this.action); // Repeat Action break; case ActionTypes["Hyperbolic Regeneration Chamber"]: { - Player.regenerateHp(HrcHpGain); + Player.regenerateHp(BladeburnerConstants.HrcHpGain); - const staminaGain = this.maxStamina * (HrcStaminaGain / 100); + const staminaGain = this.maxStamina * (BladeburnerConstants.HrcStaminaGain / 100); this.stamina = Math.min(this.maxStamina, this.stamina + staminaGain); this.startAction(this.action); if (this.logging.general) { - this.log(`Rested in Hyperbolic Regeneration Chamber. Restored ${HrcHpGain} HP and gained ${numeralWrapper.format(staminaGain, "0.0")} stamina`); + this.log(`Rested in Hyperbolic Regeneration Chamber. Restored ${BladeburnerConstants.HrcHpGain} HP and gained ${numeralWrapper.format(staminaGain, "0.0")} stamina`); } break; } @@ -1585,7 +1018,7 @@ Bladeburner.prototype.completeOperation = function(success) { Bladeburner.prototype.getRecruitmentTime = function() { var effCharisma = Player.charisma * this.skillMultipliers.effCha; var charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90; - return Math.max(10, Math.round(BaseRecruitmentTimeNeeded - charismaFactor)); + return Math.max(10, Math.round(BladeburnerConstants.BaseRecruitmentTimeNeeded - charismaFactor)); } Bladeburner.prototype.getRecruitmentSuccessChance = function() { @@ -1613,13 +1046,13 @@ Bladeburner.prototype.gainActionStats = function(action, success) { * Gain multiplier based on difficulty. If this changes then the * same variable calculated in completeAction() needs to change too */ - var difficultyMult = Math.pow(difficulty, DiffMultExponentialFactor) + difficulty / DiffMultLinearFactor; + var difficultyMult = Math.pow(difficulty, BladeburnerConstants.DiffMultExponentialFactor) + difficulty / BladeburnerConstants.DiffMultLinearFactor; var time = this.actionTimeToComplete; var successMult = success ? 1 : 0.5; - var unweightedGain = time * BaseStatGain * successMult * difficultyMult; - var unweightedIntGain = time * BaseIntGain * successMult * difficultyMult; + var unweightedGain = time * BladeburnerConstants.BaseStatGain * successMult * difficultyMult; + var unweightedIntGain = time * BladeburnerConstants.BaseIntGain * successMult * difficultyMult; const skillMult = this.skillMultipliers.expGain; Player.gainHackingExp(unweightedGain * action.weights.hack * Player.hacking_exp_mult * skillMult); Player.gainStrengthExp(unweightedGain * action.weights.str * Player.strength_exp_mult * skillMult); @@ -1634,15 +1067,15 @@ Bladeburner.prototype.randomEvent = function() { var chance = Math.random(); // Choose random source/destination city for events - var sourceCityName = CityNames[getRandomInt(0, 5)]; + var sourceCityName = BladeburnerConstants.CityNames[getRandomInt(0, 5)]; var sourceCity = this.cities[sourceCityName]; if (!(sourceCity instanceof City)) { throw new Error("sourceCity was not a City object in Bladeburner.randomEvent()"); } - var destCityName = CityNames[getRandomInt(0, 5)]; + var destCityName = BladeburnerConstants.CityNames[getRandomInt(0, 5)]; while (destCityName === sourceCityName) { - destCityName = CityNames[getRandomInt(0, 5)]; + destCityName = BladeburnerConstants.CityNames[getRandomInt(0, 5)]; } var destCity = this.cities[destCityName]; @@ -1726,9 +1159,9 @@ Bladeburner.prototype.triggerPotentialMigration = function(sourceCityName, chanc } Bladeburner.prototype.triggerMigration = function(sourceCityName) { - var destCityName = CityNames[getRandomInt(0, 5)]; + var destCityName = BladeburnerConstants.CityNames[getRandomInt(0, 5)]; while (destCityName === sourceCityName) { - destCityName = CityNames[getRandomInt(0, 5)]; + destCityName = BladeburnerConstants.CityNames[getRandomInt(0, 5)]; } var destCity = this.cities[destCityName]; var sourceCity = this.cities[sourceCityName]; @@ -2009,7 +1442,7 @@ Bladeburner.prototype.createOverviewContent = function() { "in for your Bladeburner duties does not affect " + "your location in the game otherwise", })); - for (var i = 0; i < CityNames.length; ++i) { + for (var i = 0; i < BladeburnerConstants.CityNames.length; ++i) { (function(inst, i) { popupArguments.push(createElement("div", { /** @@ -2017,9 +1450,9 @@ Bladeburner.prototype.createOverviewContent = function() { * so that background color changes when you hover */ class:"cmpy-mgmt-find-employee-option", - innerText:CityNames[i], + innerText:BladeburnerConstants.CityNames[i], clickListener:()=>{ - inst.city = CityNames[i]; + inst.city = BladeburnerConstants.CityNames[i]; removeElementById(popupId); inst.updateOverviewContent(); return false; @@ -2046,7 +1479,7 @@ Bladeburner.prototype.createOverviewContent = function() { Engine.loadFactionContent(); displayFactionContent(bladeburnersFactionName); } else { - if (this.rank >= RankNeededForFaction) { + if (this.rank >= BladeburnerConstants.RankNeededForFaction) { joinFaction(bladeburnerFac); dialogBoxCreate("Congratulations! You were accepted into the Bladeburners faction"); removeChildrenFromElement(DomElems.overviewDiv); @@ -2200,10 +1633,12 @@ Bladeburner.prototype.createOperationsContent = function() { } Bladeburner.prototype.createBlackOpsContent = function() { + if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) { throw new Error("Bladeburner.createBlackOpsContent called with either " + "DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null"); } + DomElems.actionsAndSkillsDesc.innerHTML = "Black Operations (Black Ops) are special, one-time covert operations. " + @@ -2242,7 +1677,7 @@ Bladeburner.prototype.createSkillsContent = function() { // Display Current multipliers DomElems.actionsAndSkillsDesc.innerHTML = - "You will gain one skill point every " + RanksPerSkillPoint + " ranks.

" + + "You will gain one skill point every " + BladeburnerConstants.RanksPerSkillPoint + " ranks.

" + "Note that when upgrading a skill, the benefit for that skill is additive. " + "However, the effects of different skills with each other is multiplicative.

" var multKeys = Object.keys(this.skillMultipliers); @@ -2302,12 +1737,6 @@ Bladeburner.prototype.createSkillsContent = function() { case "expGain": DomElems.actionsAndSkillsDesc.innerHTML += "Exp Gain: x" + mult + "
"; break; - case "weaponAbility": - // TODO in the future if items are ever implemented - break; - case "gunAbility": - // TODO in the future if items are ever implemented - break; default: console.warn(`Unrecognized SkillMult Key: ${multKeys[i]}`); break; @@ -2353,7 +1782,7 @@ Bladeburner.prototype.updateOverviewContent = function() { DomElems.overviewEstComms.childNodes[0].nodeValue = "Est. Synthoid Communities: " + formatNumber(this.getCurrentCity().comms, 0); DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos); DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0); - DomElems.overviewBonusTime.childNodes[0].nodeValue = "Bonus time: " + convertTimeMsToTimeElapsedString(this.storedCycles/CyclesPerSecond*1000); + DomElems.overviewBonusTime.childNodes[0].nodeValue = "Bonus time: " + convertTimeMsToTimeElapsedString(this.storedCycles/BladeburnerConstants.CyclesPerSecond*1000); DomElems.overviewAugSuccessMult.innerText = "Aug. Success Chance Mult: " + formatNumber(Player.bladeburner_success_chance_mult*100, 1) + "%"; DomElems.overviewAugMaxStaminaMult.innerText = "Aug. Max Stamina Mult: " + formatNumber(Player.bladeburner_max_stamina_mult*100, 1) + "%"; DomElems.overviewAugStaminaGainMult.innerText = "Aug. Stamina Gain Mult: " + formatNumber(Player.bladeburner_stamina_gain_mult*100, 1) + "%"; @@ -2530,7 +1959,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) { el.appendChild(createElement("pre", { display:"inline-block", innerText:"Level: " + action.level + " / " + action.maxLevel, - tooltip:action.getSuccessesNeededForNextLevel(ContractSuccessesPerLevel) + " successes " + + tooltip:action.getSuccessesNeededForNextLevel(BladeburnerConstants.ContractSuccessesPerLevel) + " successes " + "needed for next level" })); el.appendChild(createElement("a", { @@ -2668,7 +2097,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) { el.appendChild(createElement("pre", { display:"inline-block", innerText:"Level: " + action.level + " / " + action.maxLevel, - tooltip:action.getSuccessesNeededForNextLevel(OperationSuccessesPerLevel) + " successes " + + tooltip:action.getSuccessesNeededForNextLevel(BladeburnerConstants.OperationSuccessesPerLevel) + " successes " + "needed for next level" })); el.appendChild(createElement("a", { @@ -2928,8 +2357,8 @@ Bladeburner.prototype.executeConsoleCommands = function(commands) { } consoleHistoryIndex = this.consoleHistory.length; - var arrayOfCommands = commands.split(";"); - for (var i = 0; i < arrayOfCommands.length; ++i) { + const arrayOfCommands = commands.split(";"); + for (let i = 0; i < arrayOfCommands.length; ++i) { this.executeConsoleCommand(arrayOfCommands[i]); } } catch(e) { @@ -3131,13 +2560,14 @@ Bladeburner.prototype.executeAutomateConsoleCommand = function(args) { Bladeburner.prototype.executeHelpConsoleCommand = function(args) { if (args.length === 1) { - this.postToConsole(consoleHelpText.helpList); + for(const line of ConsoleHelpText.helpList){ + this.postToConsole(line); + } } else { for (var i = 1; i < args.length; ++i) { - var commandText = consoleHelpText[args[i]]; - if (commandText != null) { - this.postToConsole(commandText); - this.postToConsole("
"); + const helpText = ConsoleHelpText[args[i]]; + for(const line of helpText){ + this.postToConsole(line); } } } @@ -3269,12 +2699,6 @@ Bladeburner.prototype.executeSkillConsoleCommand = function(args) { case "stamina": this.postToConsole("Stamina: x" + mult); break; - case "weaponAbility": - // TODO if items are ever implemented - break; - case "gunAbility": - // TODO if items are ever implemented - break; default: console.warn(`Unrecognized SkillMult Key: ${multKeys[i]}`); break; @@ -3293,7 +2717,11 @@ Bladeburner.prototype.executeSkillConsoleCommand = function(args) { return this.postToConsole("Invalid skill name (Note that this is case-sensitive): " + skillName); } if (args[1].toLowerCase() === "list") { - this.postToConsole(skill.name + ": Level " + formatNumber(this.skills[skill.name]), 0); + let level = 0; + if (this.skills[skill.name] !== undefined) { + level = this.skills[skill.name]; + } + this.postToConsole(skill.name + ": Level " + formatNumber(level), 0); } else if (args[1].toLowerCase() === "level") { var currentLevel = 0; if (this.skills[skillName] && !isNaN(this.skills[skillName])) { @@ -3781,7 +3209,7 @@ Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript) var bladeburnerFac = Factions["Bladeburners"]; if (bladeburnerFac.isMember) { return true; - } else if (this.rank >= RankNeededForFaction) { + } else if (this.rank >= BladeburnerConstants.RankNeededForFaction) { joinFaction(bladeburnerFac); workerScript.log("bladeburner.joinBladeburnerFaction", "Joined Bladeburners faction."); if (routing.isOn(Page.Bladeburner)) { @@ -3790,7 +3218,7 @@ Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript) } return true; } else { - workerScript.log("bladeburner.joinBladeburnerFaction", `You do not have the required rank (${this.rank}/${RankNeededForFaction}).`); + workerScript.log("bladeburner.joinBladeburnerFaction", `You do not have the required rank (${this.rank}/${BladeburnerConstants.RankNeededForFaction}).`); return false; } } @@ -3803,483 +3231,4 @@ Bladeburner.fromJSON = function(value) { } Reviver.constructors.Bladeburner = Bladeburner; -/** - * This initialized Bladeburner-related data that is NOT saved/loaded - * eg: Skill Objects, BLack Operations - * Any data that is saved/loaded should go in Bladeburner object - * eg: contracts, operations - */ -function initBladeburner() { - // Skills - Skills[SkillNames.BladesIntuition] = new Skill({ - name:SkillNames.BladesIntuition, - desc:"Each level of this skill increases your success chance " + - "for all Contracts, Operations, and BlackOps by 3%", - baseCost: 3, costInc: 2.1, - successChanceAll:3 - }); - Skills[SkillNames.Cloak] = new Skill({ - name:SkillNames.Cloak, - desc:"Each level of this skill increases your " + - "success chance in stealth-related Contracts, Operations, and BlackOps by 5.5%", - baseCost: 2, costInc: 1.1, - successChanceStealth:5.5 - }); - - // TODO Marksman - If items are ever implemented - // TODO Weapon Proficiency - If items are ever implemented - - Skills[SkillNames.ShortCircuit] = new Skill({ - name:SkillNames.ShortCircuit, - desc:"Each level of this skill increases your success chance " + - "in Contracts, Operations, and BlackOps that involve retirement by 5.5%", - baseCost: 2, costInc: 2.1, - successChanceKill:5.5 - }); - Skills[SkillNames.DigitalObserver] = new Skill({ - name:SkillNames.DigitalObserver, - desc:"Each level of this skill increases your success chance in " + - "all Operations and BlackOps by 4%", - baseCost: 2, costInc: 2.1, - successChanceOperation:4 - }); - Skills[SkillNames.Tracer] = new Skill({ - name:SkillNames.Tracer, - desc:"Each level of this skill increases your success chance in " + - "all Contracts by 4%", - baseCost: 2, costInc: 2.1, - successChanceContract:4 - }); - Skills[SkillNames.Overclock] = new Skill({ - name:SkillNames.Overclock, - desc:"Each level of this skill decreases the time it takes " + - "to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 90)", - baseCost: 3, costInc: 1.4, maxLvl: 90, - actionTime:1 - }); - Skills[SkillNames.Reaper] = new Skill({ - name: SkillNames.Reaper, - desc: "Each level of this skill increases your effective combat stats for Bladeburner actions by 2%", - baseCost: 2, costInc: 2.1, - effStr: 2, effDef: 2, effDex: 2, effAgi: 2 - }); - Skills[SkillNames.EvasiveSystem] = new Skill({ - name:SkillNames.EvasiveSystem, - desc:"Each level of this skill increases your effective " + - "dexterity and agility for Bladeburner actions by 4%", - baseCost: 2, costInc: 2.1, - effDex: 4, effAgi: 4 - }); - Skills[SkillNames.Datamancer] = new Skill({ - name:SkillNames.Datamancer, - desc:"Each level of this skill increases your effectiveness in " + - "synthoid population analysis and investigation by 5%. " + - "This affects all actions that can potentially increase " + - "the accuracy of your synthoid population/community estimates.", - baseCost:3, costInc:1, - successChanceEstimate:5 - }); - Skills[SkillNames.CybersEdge] = new Skill({ - name:SkillNames.CybersEdge, - desc:"Each level of this skill increases your max stamina by 2%", - baseCost:1, costInc:3, - stamina:2 - }); - Skills[SkillNames.HandsOfMidas] = new Skill({ - name: SkillNames.HandsOfMidas, - desc: "Each level of this skill increases the amount of money you receive from Contracts by 10%", - baseCost: 2, costInc: 2.5, - money: 10, - }); - Skills[SkillNames.Hyperdrive] = new Skill({ - name: SkillNames.Hyperdrive, - desc: "Each level of this skill increases the experience earned from Contracts, Operations, and BlackOps by 10%", - baseCost: 1, costInc: 2.5, - expGain: 10, - }); - - // General Actions - let actionName; - actionName = "Training"; - GeneralActions[actionName] = new Action({ - name:actionName, - desc:"Improve your abilities at the Bladeburner unit's specialized training " + - "center. Doing this gives experience for all combat stats and also " + - "increases your max stamina." - }); - - actionName = "Field Analysis"; - GeneralActions[actionName] = new Action({ - name:actionName, - desc:"Mine and analyze Synthoid-related data. This improve the " + - "Bladeburner's unit intelligence on Synthoid locations and " + - "activities. Completing this action will improve the accuracy " + - "of your Synthoid population estimated in the current city.

" + - "Does NOT require stamina." - }); - - actionName = "Recruitment"; - GeneralActions[actionName] = new Action({ - name:actionName, - desc:"Attempt to recruit members for your Bladeburner team. These members " + - "can help you conduct operations.

" + - "Does NOT require stamina." - }); - - actionName = "Diplomacy"; - GeneralActions[actionName] = new Action({ - name: actionName, - desc: "Improve diplomatic relations with the Synthoid population. " + - "Completing this action will reduce the Chaos level in your current city.

" + - "Does NOT require stamina." - }); - - actionName = "Hyperbolic Regeneration Chamber"; - GeneralActions[actionName] = new Action({ - name: actionName, - desc: "Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. " + - "This will slowly heal your wounds and slightly increase your stamina.

", - }); - - // Black Operations - BlackOperations["Operation Typhoon"] = new BlackOperation({ - name:"Operation Typhoon", - desc:"Obadiah Zenyatta is the leader of a RedWater PMC. It has long " + - "been known among the intelligence community that Zenyatta, along " + - "with the rest of the PMC, is a Synthoid.

" + - "The goal of Operation Typhoon is to find and eliminate " + - "Zenyatta and RedWater by any means necessary. After the task " + - "is completed, the actions must be covered up from the general public.", - baseDifficulty:2000, reqdRank:2.5e3, - rankGain:50, rankLoss:10, hpLoss:100, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Zero"] = new BlackOperation({ - name:"Operation Zero", - desc:"AeroCorp is one of the world's largest defense contractors. " + - "It's leader, Steve Watataki, is thought to be a supporter of " + - "Synthoid rights. He must be removed.

" + - "The goal of Operation Zero is to covertly infiltrate AeroCorp and " + - "uncover any incriminating evidence or " + - "information against Watataki that will cause him to be removed " + - "from his position at AeroCorp. Incriminating evidence can be " + - "fabricated as a last resort. Be warned that AeroCorp has some of " + - "the most advanced security measures in the world.", - baseDifficulty:2500, reqdRank:5e3, - rankGain:60, rankLoss:15, hpLoss:50, - weights:{hack:0.2,str:0.15,def:0.15,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isStealth:true - }); - BlackOperations["Operation X"] = new BlackOperation({ - name:"Operation X", - desc:"We have recently discovered an underground publication " + - "group called Samizdat. Even though most of their publications " + - "are nonsensical conspiracy theories, the average human is " + - "gullible enough to believe them. Many of their works discuss " + - "Synthoids and pose a threat to society. The publications are spreading " + - "rapidly in China and other Eastern countries.

" + - "Samizdat has done a good job of keeping hidden and anonymous. " + - "However, we've just received intelligence that their base of " + - "operations is in Ishima's underground sewer systems. Your task is to " + - "investigate the sewer systems, and eliminate Samizdat. They must " + - "never publish anything again.", - baseDifficulty:3000, reqdRank:7.5e3, - rankGain:75, rankLoss:15, hpLoss:100, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Titan"] = new BlackOperation({ - name:"Operation Titan", - desc:"Several months ago Titan Laboratories' Bioengineering department " + - "was infiltrated by Synthoids. As far as we know, Titan Laboratories' " + - "management has no knowledge about this. We don't know what the " + - "Synthoids are up to, but the research that they could " + - "be conducting using Titan Laboraties' vast resources is potentially " + - "very dangerous.

" + - "Your goal is to enter and destroy the Bioengineering department's " + - "facility in Aevum. The task is not just to retire the Synthoids there, but " + - "also to destroy any information or research at the facility that " + - "is relevant to the Synthoids and their goals.", - baseDifficulty:4000, reqdRank:10e3, - rankGain:100, rankLoss:20, hpLoss:100, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Ares"] = new BlackOperation({ - name:"Operation Ares", - desc:"One of our undercover agents, Agent Carter, has informed us of a " + - "massive weapons deal going down in Dubai between rogue Russian " + - "militants and a radical Synthoid community. These weapons are next-gen " + - "plasma and energy weapons. It is critical for the safety of humanity " + - "that this deal does not happen.

" + - "Your task is to intercept the deal. Leave no survivors.", - baseDifficulty:5000, reqdRank:12.5e3, - rankGain:125, rankLoss:20, hpLoss:200, - weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, - decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Archangel"] = new BlackOperation({ - name:"Operation Archangel", - desc:"Our analysts have discovered that the popular Red Rabbit brothel in " + - "Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence " + - "suggests that the profit from this brothel is used to fund a large " + - "black market arms trafficking operation.

" + - "The goal of this operation is to take out the leaders that are running " + - "the Red Rabbit brothel. Try to limit the number of other casualties, " + - "but do what you must to complete the mission.", - baseDifficulty:7500, reqdRank:15e3, - rankGain:200, rankLoss:20, hpLoss:25, - weights:{hack:0,str:0.2,def:0.2,dex:0.3,agi:0.3,cha:0, int:0}, - decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true, - }); - BlackOperations["Operation Juggernaut"] = new BlackOperation({ - name:"Operation Juggernaut", - desc:"The CIA has just encountered a new security threat. A new " + - "criminal group, lead by a shadowy operative who calls himself " + - "Juggernaut, has been smuggling drugs and weapons (including " + - "suspected bioweapons) into Sector-12. We also have reason " + - "to believe the tried to break into one of Universal Energy's " + - "facilities in order to cause a city-wide blackout. The CIA " + - "suspects that Juggernaut is a heavily-augmented Synthoid, and " + - "have thus enlisted our help.

" + - "Your mission is to eradicate Juggernaut and his followers.", - baseDifficulty:10e3, reqdRank:20e3, - rankGain:300, rankLoss:40, hpLoss:300, - weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, - decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true, - }); - BlackOperations["Operation Red Dragon"] = new BlackOperation({ - name:"Operation Red Dragon", - desc:"The Tetrads criminal organization is suspected of " + - "reverse-engineering the MK-VI Synthoid design. We believe " + - "they altered and possibly improved the design and began " + - "manufacturing their own Synthoid models in order to bolster " + - "their criminal activities.

" + - "Your task is to infiltrate and destroy the Tetrads' base of operations " + - "in Los Angeles. Intelligence tells us that their base houses " + - "one of their Synthoid manufacturing units.", - baseDifficulty:12.5e3, reqdRank:25e3, - rankGain:500, rankLoss:50, hpLoss:500, - weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true, - }); - BlackOperations["Operation K"] = new BlackOperation({ - name:"Operation K", - desc:"CODE RED SITUATION. Our intelligence tells us that VitaLife " + - "has discovered a new android cloning technology. This technology " + - "is supposedly capable of cloning Synthoid, not only physically " + - "but also their advanced AI modules. We do not believe that " + - "VitaLife is trying to use this technology illegally or " + - "maliciously, but if any Synthoids were able to infiltrate the " + - "corporation and take advantage of this technology then the " + - "results would be catastrophic.

" + - "We do not have the power or jurisdiction to shutdown this down " + - "through legal or political means, so we must resort to a covert " + - "operation. Your goal is to destroy this technology and eliminate " + - "anyone who was involved in its creation.", - baseDifficulty:15e3, reqdRank:30e3, - rankGain:750, rankLoss:60, hpLoss:1000, - weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Deckard"] = new BlackOperation({ - name:"Operation Deckard", - desc:"Despite your success in eliminating VitaLife's new android-replicating " + - "technology in Operation K, we've discovered that a small group of " + - "MK-VI Synthoids were able to make off with the schematics and design " + - "of the technology before the Operation. It is almost a certainty that " + - "these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising." + - "The goal of Operation Deckard is to hunt down these Synthoids and retire " + - "them. I don't need to tell you how critical this mission is.", - baseDifficulty:20e3, reqdRank:40e3, - rankGain:1e3, rankLoss:75, hpLoss:200, - weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, - decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true, - }); - BlackOperations["Operation Tyrell"] = new BlackOperation({ - name:"Operation Tyrell", - desc:"A week ago Blade Industries reported a small break-in at one " + - "of their Aevum Augmentation storage facitilities. We figured out " + - "that The Dark Army was behind the heist, and didn't think any more " + - "of it. However, we've just discovered that several known MK-VI Synthoids " + - "were part of that break-in group.

" + - "We cannot have Synthoids upgrading their already-enhanced abilities " + - "with Augmentations. Your task is to hunt down the associated Dark Army " + - "members and eliminate them.", - baseDifficulty:25e3, reqdRank:50e3, - rankGain:1.5e3, rankLoss:100, hpLoss:500, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true, - }); - BlackOperations["Operation Wallace"] = new BlackOperation({ - name:"Operation Wallace", - desc:"Based on information gathered from Operation Tyrell, we've discovered " + - "that The Dark Army was well aware that there were Synthoids amongst " + - "their ranks. Even worse, we believe that The Dark Army is working " + - "together with other criminal organizations such as The Syndicate and " + - "that they are planning some sort of large-scale takeover of multiple major " + - "cities, most notably Aevum. We suspect that Synthoids have infiltrated " + - "the ranks of these criminal factions and are trying to stage another " + - "Synthoid uprising.

" + - "The best way to deal with this is to prevent it before it even happens. " + - "The goal of Operation Wallace is to destroy the Dark Army and " + - "Syndicate factions in Aevum immediately. Leave no survivors.", - baseDifficulty:30e3, reqdRank:75e3, - rankGain:2e3, rankLoss:150, hpLoss:1500, - weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({ - name:"Operation Shoulder of Orion", - desc:"China's Solaris Space Systems is secretly launching the first " + - "manned spacecraft in over a decade using Synthoids. We believe " + - "China is trying to establish the first off-world colonies.

" + - "The mission is to prevent this launch without instigating an " + - "international conflict. When you accept this mission you will be " + - "officially disavowed by the NSA and the national government until after you " + - "successfully return. In the event of failure, all of the operation's " + - "team members must not let themselves be captured alive.", - baseDifficulty:35e3, reqdRank:100e3, - rankGain:2.5e3, rankLoss:500, hpLoss:1500, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isStealth:true - }); - BlackOperations["Operation Hyron"] = new BlackOperation({ - name:"Operation Hyron", - desc:"Our intelligence tells us that Fulcrum Technologies is developing " + - "a quantum supercomputer using human brains as core " + - "processors. This supercomputer " + - "is rumored to be able to store vast amounts of data and " + - "perform computations unmatched by any other supercomputer on the " + - "planet. But more importantly, the use of organic human brains " + - "means that the supercomputer may be able to reason abstractly " + - "and become self-aware.

" + - "I do not need to remind you why sentient-level AIs pose a serious " + - "thread to all of mankind.

" + - "The research for this project is being conducted at one of Fulcrum " + - "Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. " + - "Infiltrate the compound, delete and destroy the work, and then find and kill the " + - "project lead.", - baseDifficulty:40e3, reqdRank:125e3, - rankGain:3e3, rankLoss:1e3, hpLoss:500, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Morpheus"] = new BlackOperation({ - name:"Operation Morpheus", - desc:"DreamSense Technologies is an advertising company that uses " + - "special technology to transmit their ads into the peoples " + - "dreams and subconcious. They do this using broadcast transmitter " + - "towers. Based on information from our agents and informants in " + - "Chonqging, we have reason to believe that one of the broadcast " + - "towers there has been compromised by Synthoids and is being used " + - "to spread pro-Synthoid propaganda.

" + - "The mission is to destroy this broadcast tower. Speed and " + - "stealth are of the upmost important for this.", - baseDifficulty:45e3, reqdRank:150e3, - rankGain:4e3, rankLoss:1e3, hpLoss:100, - weights:{hack:0.05,str:0.15,def:0.15,dex:0.3,agi:0.3,cha:0, int:0.05}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isStealth:true - }); - BlackOperations["Operation Ion Storm"] = new BlackOperation({ - name:"Operation Ion Storm", - desc:"Our analysts have uncovered a gathering of MK-VI Synthoids " + - "that have taken up residence in the Sector-12 Slums. We " + - "don't know if they are rogue Synthoids from the Uprising, " + - "but we do know that they have been stockpiling " + - "weapons, money, and other resources. This makes them dangerous.

" + - "This is a full-scale assault operation to find and retire all of these " + - "Synthoids in the Sector-12 Slums.", - baseDifficulty:50e3, reqdRank:175e3, - rankGain:5e3, rankLoss:1e3, hpLoss:5000, - weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Annihilus"] = new BlackOperation({ - name:"Operation Annihilus", - desc:"Our superiors have ordered us to eradicate everything and everyone " + - "in an underground facility located in Aevum. They tell us " + - "that the facility houses many dangerous Synthoids and " + - "belongs to a terrorist organization called " + - "'The Covenant'. We have no prior intelligence about this " + - "organization, so you are going in blind.", - baseDifficulty:55e3, reqdRank:200e3, - rankGain:7.5e3, rankLoss:1e3, hpLoss:10e3, - weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Ultron"] = new BlackOperation({ - name:"Operation Ultron", - desc:"OmniTek Incorporated, the original designer and manufacturer of Synthoids, " + - "has notified us of a malfunction in their AI design. This malfunction, " + - "when triggered, causes MK-VI Synthoids to become radicalized and seek out " + - "the destruction of humanity. They say that this bug affects all MK-VI Synthoids, " + - "not just the rogue ones from the Uprising.

" + - "OmniTek has also told us they they believe someone has triggered this " + - "malfunction in a large group of MK-VI Synthoids, and that these newly-radicalized Synthoids " + - "are now amassing in Volhaven to form a terrorist group called Ultron.

" + - "Intelligence suggests Ultron is heavily armed and that their members are " + - "augmented. We believe Ultron is making moves to take control of " + - "and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).

" + - "Your task is to find and destroy Ultron.", - baseDifficulty:60e3, reqdRank:250e3, - rankGain:10e3, rankLoss:2e3, hpLoss:10e3, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - isKill:true - }); - BlackOperations["Operation Centurion"] = new BlackOperation({ - name:"Operation Centurion", - desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

" + - "Throughout all of humanity's history, we have relied on " + - "technology to survive, conquer, and progress. Its advancement became our primary goal. " + - "And at the peak of human civilization technology turned into " + - "power. Global, absolute power.

" + - "It seems that the universe is not without a sense of irony.

" + - "D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)", - baseDifficulty:70e3, reqdRank:300e3, - rankGain:15e3, rankLoss:5e3, hpLoss:10e3, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - }); - BlackOperations["Operation Vindictus"] = new BlackOperation({ - name:"Operation Vindictus", - desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

" + - "The bits are all around us. The daemons that hold the Node " + - "together can manifest themselves in many different ways.

" + - "D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)", - baseDifficulty:75e3, reqdRank:350e3, - rankGain:20e3, rankLoss:20e3, hpLoss:20e3, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - }); - BlackOperations["Operation Daedalus"] = new BlackOperation({ - name:"Operation Daedalus", - desc:"Yesterday we obeyed kings and bent our neck to emperors. " + - "Today we kneel only to truth.", - baseDifficulty:80e3, reqdRank:400e3, - rankGain:40e3, rankLoss:10e3, hpLoss:100e3, - weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, - decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, - }); -} - export { Bladeburner }; diff --git a/src/Bladeburner/Action.ts b/src/Bladeburner/Action.ts new file mode 100644 index 000000000..64ea44627 --- /dev/null +++ b/src/Bladeburner/Action.ts @@ -0,0 +1,269 @@ +import { Player } from "../Player"; +import { getRandomInt } from "../../utils/helpers/getRandomInt"; +import { addOffset } from "../../utils/helpers/addOffset"; +import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; +import { BladeburnerConstants } from "./data/Constants"; +// import { Contract } from "./Contract"; +// import { Operation } from "./Operation"; +// import { BlackOperation } from "./BlackOperation"; + +class StatsMultiplier { + hack: number = 0; + str: number = 0; + def: number = 0; + dex: number = 0; + agi: number = 0; + cha: number = 0; + int: number = 0; + + [key: string]: number; +}; + +export interface IActionParams { + name?: string; + desc?: string; + level?: number; + maxLevel?: number; + autoLevel?: boolean; + baseDifficulty?: number; + difficultyFac?: number; + rewardFac?: number; + successes?: number; + failures?: number; + rankGain?: number; + rankLoss?: number; + hpLoss?: number; + hpLost?: number; + isStealth?: boolean; + isKill?: boolean; + count?: number; + countGrowth?: number; + weights?: StatsMultiplier; + decays?: StatsMultiplier; + teamCount?: number; +} + +export class Action { + name: string = ""; + desc: string = ""; + + // Difficulty scales with level. See getDifficulty() method + level: number = 1; + maxLevel: number = 1; + autoLevel: boolean = true; + baseDifficulty: number = 100; + difficultyFac: number = 1.01; + + // Rank increase/decrease is affected by this exponent + rewardFac: number = 1.02; + + successes: number = 0; + failures: number = 0; + + // All of these scale with level/difficulty + rankGain: number = 0; + rankLoss: number = 0; + hpLoss: number = 0; + hpLost: number = 0; + + // Action Category. Current categories are stealth and kill + isStealth: boolean = false; + isKill: boolean = false; + + /** + * Number of this contract remaining, and its growth rate + * Growth rate is an integer and the count will increase by that integer every "cycle" + */ + count: number = getRandomInt(1e3, 25e3); + countGrowth: number = getRandomInt(1, 5); + + // Weighting of each stat in determining action success rate + weights: StatsMultiplier = {hack:1/7,str:1/7,def:1/7,dex:1/7,agi:1/7,cha:1/7,int:1/7}; + // Diminishing returns of stats (stat ^ decay where 0 <= decay <= 1) + decays: StatsMultiplier = { hack: 0.9, str: 0.9, def: 0.9, dex: 0.9, agi: 0.9, cha: 0.9, int: 0.9 }; + teamCount: number = 0; + + // Base Class for Contracts, Operations, and BlackOps + constructor(params: IActionParams| null = null) { // | null = null + if(params && params.name) this.name = params.name; + if(params && params.desc) this.desc = params.desc; + + if(params && params.baseDifficulty) this.baseDifficulty = addOffset(params.baseDifficulty, 10); + if(params && params.difficultyFac) this.difficultyFac = params.difficultyFac; + + if(params && params.rewardFac) this.rewardFac = params.rewardFac; + if(params && params.rankGain) this.rankGain = params.rankGain; + if(params && params.rankLoss) this.rankLoss = params.rankLoss; + if(params && params.hpLoss) this.hpLoss = params.hpLoss; + + if(params && params.isStealth) this.isStealth = params.isStealth; + if(params && params.isKill) this.isKill = params.isKill; + + if(params && params.count) this.count = params.count; + if(params && params.countGrowth) this.countGrowth = params.countGrowth; + + if(params && params.weights) this.weights = params.weights; + if(params && params.decays) this.decays = params.decays; + + // Check to make sure weights are summed properly + let sum = 0; + for (const weight in this.weights) { + if (this.weights.hasOwnProperty(weight)) { + sum += this.weights[weight]; + } + } + if (sum - 1 >= 10 * Number.EPSILON) { + throw new Error("Invalid weights when constructing Action " + this.name + + ". The weights should sum up to 1. They sum up to :" + 1); + } + + for (const decay in this.decays) { + if (this.decays.hasOwnProperty(decay)) { + if (this.decays[decay] > 1) { + throw new Error("Invalid decays when constructing " + + "Action " + this.name + ". " + + "Decay value cannot be greater than 1"); + } + } + } + } + + getDifficulty(): number { + const difficulty = this.baseDifficulty * Math.pow(this.difficultyFac, this.level-1); + if (isNaN(difficulty)) {throw new Error("Calculated NaN in Action.getDifficulty()");} + return difficulty; + } + + /** + * Tests for success. Should be called when an action has completed + * @param inst {Bladeburner} - Bladeburner instance + */ + attempt(inst: any): boolean { + return (Math.random() < this.getSuccessChance(inst)); + } + + // To be implemented by subtypes + getActionTimePenalty(): number { + return 1; + } + + getActionTime(inst: any): number { + const difficulty = this.getDifficulty(); + let baseTime = difficulty / BladeburnerConstants.DifficultyToTimeFactor; + const skillFac = inst.skillMultipliers.actionTime; // Always < 1 + + const effAgility = Player.agility * inst.skillMultipliers.effAgi; + const effDexterity = Player.dexterity * inst.skillMultipliers.effDex; + const statFac = 0.5 * (Math.pow(effAgility, BladeburnerConstants.EffAgiExponentialFactor) + + Math.pow(effDexterity, BladeburnerConstants.EffDexExponentialFactor) + + (effAgility / BladeburnerConstants.EffAgiLinearFactor) + + (effDexterity / BladeburnerConstants.EffDexLinearFactor)); // Always > 1 + + baseTime = Math.max(1, baseTime * skillFac / statFac); + + return Math.ceil(baseTime*this.getActionTimePenalty()); + } + + // For actions that have teams. To be implemented by subtypes. + getTeamSuccessBonus(inst: any): number { + return 1; + } + + getActionTypeSkillSuccessBonus(inst: any): number { + return 1; + } + + getChaosCompetencePenalty(inst: any, params: any): number { + const city = inst.getCurrentCity(); + if (params.est) { + return Math.pow((city.popEst / BladeburnerConstants.PopulationThreshold), BladeburnerConstants.PopulationExponent); + } else { + return Math.pow((city.pop / BladeburnerConstants.PopulationThreshold), BladeburnerConstants.PopulationExponent); + } + } + + getChaosDifficultyBonus(inst: any, params: any): number { + const city = inst.getCurrentCity(); + if (city.chaos > BladeburnerConstants.ChaosThreshold) { + const diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold); + const mult = Math.pow(diff, 0.1); + return mult; + } + + return 1; + } + + /** + * @inst - Bladeburner Object + * @params - options: + * est (bool): Get success chance estimate instead of real success chance + */ + getSuccessChance(inst: any, params: any={}) { + if (inst == null) {throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");} + let difficulty = this.getDifficulty(); + let competence = 0; + for (let stat in this.weights) { + if (this.weights.hasOwnProperty(stat)) { + let playerStatLvl = Player.queryStatFromString(stat); + let key = "eff" + stat.charAt(0).toUpperCase() + stat.slice(1); + let effMultiplier = inst.skillMultipliers[key]; + if (effMultiplier == null) { + console.error(`Failed to find Bladeburner Skill multiplier for: ${stat}`); + effMultiplier = 1; + } + competence += (this.weights[stat] * Math.pow(effMultiplier*playerStatLvl, this.decays[stat])); + } + } + competence *= inst.calculateStaminaPenalty(); + + competence *= this.getTeamSuccessBonus(inst); + + competence *= this.getChaosCompetencePenalty(inst, params); + difficulty *= this.getChaosDifficultyBonus(inst, params); + + if(this.name == "Raid" && inst.getCurrentCity().comms <= 0) { + return 0; + } + + // Factor skill multipliers into success chance + competence *= inst.skillMultipliers.successChanceAll; + competence *= this.getActionTypeSkillSuccessBonus(inst); + if (this.isStealth) { + competence *= inst.skillMultipliers.successChanceStealth; + } + if (this.isKill) { + competence *= inst.skillMultipliers.successChanceKill; + } + + // Augmentation multiplier + competence *= Player.bladeburner_success_chance_mult; + + if (isNaN(competence)) {throw new Error("Competence calculated as NaN in Action.getSuccessChance()");} + return Math.min(1, competence / difficulty); + } + + getSuccessesNeededForNextLevel(baseSuccessesPerLevel: number): number { + return Math.ceil((0.5) * (this.maxLevel) * (2 * baseSuccessesPerLevel + (this.maxLevel-1))); + } + + setMaxLevel(baseSuccessesPerLevel: number): void { + if (this.successes >= this.getSuccessesNeededForNextLevel(baseSuccessesPerLevel)) { + ++this.maxLevel; + } + } + + static fromJSON(value: any): Action { + return Generic_fromJSON(Action, value.data); + } + + toJSON(): any { + return Generic_toJSON("Action", this); + } +} + + + + + + +Reviver.constructors.Action = Action; \ No newline at end of file diff --git a/src/Bladeburner/BlackOperation.ts b/src/Bladeburner/BlackOperation.ts new file mode 100644 index 000000000..11ac83dc4 --- /dev/null +++ b/src/Bladeburner/BlackOperation.ts @@ -0,0 +1,33 @@ +import { Operation, IOperationParams } from "./Operation"; +import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; + +export class BlackOperation extends Operation { + constructor(params: IOperationParams | null = null) { + super(params); + this.count = 1; + this.countGrowth = 0; + } + + // To be implemented by subtypes + getActionTimePenalty(): number { + return 1.5; + } + + getChaosCompetencePenalty(inst: any, params: any): number { + return 1; + } + + getChaosDifficultyBonus(inst: any, params: any): number { + return 1; + } + + static fromJSON(value: any): Operation { + return Generic_fromJSON(BlackOperation, value.data); + } + + toJSON(): any { + return Generic_toJSON("BlackOperation", this); + } +} + +Reviver.constructors.BlackOperation = BlackOperation; \ No newline at end of file diff --git a/src/Bladeburner/BlackOperations.ts b/src/Bladeburner/BlackOperations.ts new file mode 100644 index 000000000..75e6e799e --- /dev/null +++ b/src/Bladeburner/BlackOperations.ts @@ -0,0 +1,345 @@ +import { BlackOperation } from "./BlackOperation"; +import { IMap } from "../types"; + +export const BlackOperations: IMap = {}; + +(function() { + BlackOperations["Operation Typhoon"] = new BlackOperation({ + name:"Operation Typhoon", + desc:"Obadiah Zenyatta is the leader of a RedWater PMC. It has long " + + "been known among the intelligence community that Zenyatta, along " + + "with the rest of the PMC, is a Synthoid.

" + + "The goal of Operation Typhoon is to find and eliminate " + + "Zenyatta and RedWater by any means necessary. After the task " + + "is completed, the actions must be covered up from the general public.", + baseDifficulty:2000, reqdRank:2.5e3, + rankGain:50, rankLoss:10, hpLoss:100, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Zero"] = new BlackOperation({ + name:"Operation Zero", + desc:"AeroCorp is one of the world's largest defense contractors. " + + "It's leader, Steve Watataki, is thought to be a supporter of " + + "Synthoid rights. He must be removed.

" + + "The goal of Operation Zero is to covertly infiltrate AeroCorp and " + + "uncover any incriminating evidence or " + + "information against Watataki that will cause him to be removed " + + "from his position at AeroCorp. Incriminating evidence can be " + + "fabricated as a last resort. Be warned that AeroCorp has some of " + + "the most advanced security measures in the world.", + baseDifficulty:2500, reqdRank:5e3, + rankGain:60, rankLoss:15, hpLoss:50, + weights:{hack:0.2,str:0.15,def:0.15,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isStealth:true + }); + BlackOperations["Operation X"] = new BlackOperation({ + name:"Operation X", + desc:"We have recently discovered an underground publication " + + "group called Samizdat. Even though most of their publications " + + "are nonsensical conspiracy theories, the average human is " + + "gullible enough to believe them. Many of their works discuss " + + "Synthoids and pose a threat to society. The publications are spreading " + + "rapidly in China and other Eastern countries.

" + + "Samizdat has done a good job of keeping hidden and anonymous. " + + "However, we've just received intelligence that their base of " + + "operations is in Ishima's underground sewer systems. Your task is to " + + "investigate the sewer systems, and eliminate Samizdat. They must " + + "never publish anything again.", + baseDifficulty:3000, reqdRank:7.5e3, + rankGain:75, rankLoss:15, hpLoss:100, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Titan"] = new BlackOperation({ + name:"Operation Titan", + desc:"Several months ago Titan Laboratories' Bioengineering department " + + "was infiltrated by Synthoids. As far as we know, Titan Laboratories' " + + "management has no knowledge about this. We don't know what the " + + "Synthoids are up to, but the research that they could " + + "be conducting using Titan Laboraties' vast resources is potentially " + + "very dangerous.

" + + "Your goal is to enter and destroy the Bioengineering department's " + + "facility in Aevum. The task is not just to retire the Synthoids there, but " + + "also to destroy any information or research at the facility that " + + "is relevant to the Synthoids and their goals.", + baseDifficulty:4000, reqdRank:10e3, + rankGain:100, rankLoss:20, hpLoss:100, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Ares"] = new BlackOperation({ + name:"Operation Ares", + desc:"One of our undercover agents, Agent Carter, has informed us of a " + + "massive weapons deal going down in Dubai between rogue Russian " + + "militants and a radical Synthoid community. These weapons are next-gen " + + "plasma and energy weapons. It is critical for the safety of humanity " + + "that this deal does not happen.

" + + "Your task is to intercept the deal. Leave no survivors.", + baseDifficulty:5000, reqdRank:12.5e3, + rankGain:125, rankLoss:20, hpLoss:200, + weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, + decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Archangel"] = new BlackOperation({ + name:"Operation Archangel", + desc:"Our analysts have discovered that the popular Red Rabbit brothel in " + + "Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence " + + "suggests that the profit from this brothel is used to fund a large " + + "black market arms trafficking operation.

" + + "The goal of this operation is to take out the leaders that are running " + + "the Red Rabbit brothel. Try to limit the number of other casualties, " + + "but do what you must to complete the mission.", + baseDifficulty:7500, reqdRank:15e3, + rankGain:200, rankLoss:20, hpLoss:25, + weights:{hack:0,str:0.2,def:0.2,dex:0.3,agi:0.3,cha:0, int:0}, + decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true, + }); + BlackOperations["Operation Juggernaut"] = new BlackOperation({ + name:"Operation Juggernaut", + desc:"The CIA has just encountered a new security threat. A new " + + "criminal group, lead by a shadowy operative who calls himself " + + "Juggernaut, has been smuggling drugs and weapons (including " + + "suspected bioweapons) into Sector-12. We also have reason " + + "to believe the tried to break into one of Universal Energy's " + + "facilities in order to cause a city-wide blackout. The CIA " + + "suspects that Juggernaut is a heavily-augmented Synthoid, and " + + "have thus enlisted our help.

" + + "Your mission is to eradicate Juggernaut and his followers.", + baseDifficulty:10e3, reqdRank:20e3, + rankGain:300, rankLoss:40, hpLoss:300, + weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, + decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true, + }); + BlackOperations["Operation Red Dragon"] = new BlackOperation({ + name:"Operation Red Dragon", + desc:"The Tetrads criminal organization is suspected of " + + "reverse-engineering the MK-VI Synthoid design. We believe " + + "they altered and possibly improved the design and began " + + "manufacturing their own Synthoid models in order to bolster " + + "their criminal activities.

" + + "Your task is to infiltrate and destroy the Tetrads' base of operations " + + "in Los Angeles. Intelligence tells us that their base houses " + + "one of their Synthoid manufacturing units.", + baseDifficulty:12.5e3, reqdRank:25e3, + rankGain:500, rankLoss:50, hpLoss:500, + weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true, + }); + BlackOperations["Operation K"] = new BlackOperation({ + name:"Operation K", + desc:"CODE RED SITUATION. Our intelligence tells us that VitaLife " + + "has discovered a new android cloning technology. This technology " + + "is supposedly capable of cloning Synthoid, not only physically " + + "but also their advanced AI modules. We do not believe that " + + "VitaLife is trying to use this technology illegally or " + + "maliciously, but if any Synthoids were able to infiltrate the " + + "corporation and take advantage of this technology then the " + + "results would be catastrophic.

" + + "We do not have the power or jurisdiction to shutdown this down " + + "through legal or political means, so we must resort to a covert " + + "operation. Your goal is to destroy this technology and eliminate " + + "anyone who was involved in its creation.", + baseDifficulty:15e3, reqdRank:30e3, + rankGain:750, rankLoss:60, hpLoss:1000, + weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Deckard"] = new BlackOperation({ + name:"Operation Deckard", + desc:"Despite your success in eliminating VitaLife's new android-replicating " + + "technology in Operation K, we've discovered that a small group of " + + "MK-VI Synthoids were able to make off with the schematics and design " + + "of the technology before the Operation. It is almost a certainty that " + + "these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising." + + "The goal of Operation Deckard is to hunt down these Synthoids and retire " + + "them. I don't need to tell you how critical this mission is.", + baseDifficulty:20e3, reqdRank:40e3, + rankGain:1e3, rankLoss:75, hpLoss:200, + weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, + decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true, + }); + BlackOperations["Operation Tyrell"] = new BlackOperation({ + name:"Operation Tyrell", + desc:"A week ago Blade Industries reported a small break-in at one " + + "of their Aevum Augmentation storage facitilities. We figured out " + + "that The Dark Army was behind the heist, and didn't think any more " + + "of it. However, we've just discovered that several known MK-VI Synthoids " + + "were part of that break-in group.

" + + "We cannot have Synthoids upgrading their already-enhanced abilities " + + "with Augmentations. Your task is to hunt down the associated Dark Army " + + "members and eliminate them.", + baseDifficulty:25e3, reqdRank:50e3, + rankGain:1.5e3, rankLoss:100, hpLoss:500, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true, + }); + BlackOperations["Operation Wallace"] = new BlackOperation({ + name:"Operation Wallace", + desc:"Based on information gathered from Operation Tyrell, we've discovered " + + "that The Dark Army was well aware that there were Synthoids amongst " + + "their ranks. Even worse, we believe that The Dark Army is working " + + "together with other criminal organizations such as The Syndicate and " + + "that they are planning some sort of large-scale takeover of multiple major " + + "cities, most notably Aevum. We suspect that Synthoids have infiltrated " + + "the ranks of these criminal factions and are trying to stage another " + + "Synthoid uprising.

" + + "The best way to deal with this is to prevent it before it even happens. " + + "The goal of Operation Wallace is to destroy the Dark Army and " + + "Syndicate factions in Aevum immediately. Leave no survivors.", + baseDifficulty:30e3, reqdRank:75e3, + rankGain:2e3, rankLoss:150, hpLoss:1500, + weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({ + name:"Operation Shoulder of Orion", + desc:"China's Solaris Space Systems is secretly launching the first " + + "manned spacecraft in over a decade using Synthoids. We believe " + + "China is trying to establish the first off-world colonies.

" + + "The mission is to prevent this launch without instigating an " + + "international conflict. When you accept this mission you will be " + + "officially disavowed by the NSA and the national government until after you " + + "successfully return. In the event of failure, all of the operation's " + + "team members must not let themselves be captured alive.", + baseDifficulty:35e3, reqdRank:100e3, + rankGain:2.5e3, rankLoss:500, hpLoss:1500, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isStealth:true + }); + BlackOperations["Operation Hyron"] = new BlackOperation({ + name:"Operation Hyron", + desc:"Our intelligence tells us that Fulcrum Technologies is developing " + + "a quantum supercomputer using human brains as core " + + "processors. This supercomputer " + + "is rumored to be able to store vast amounts of data and " + + "perform computations unmatched by any other supercomputer on the " + + "planet. But more importantly, the use of organic human brains " + + "means that the supercomputer may be able to reason abstractly " + + "and become self-aware.

" + + "I do not need to remind you why sentient-level AIs pose a serious " + + "thread to all of mankind.

" + + "The research for this project is being conducted at one of Fulcrum " + + "Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. " + + "Infiltrate the compound, delete and destroy the work, and then find and kill the " + + "project lead.", + baseDifficulty:40e3, reqdRank:125e3, + rankGain:3e3, rankLoss:1e3, hpLoss:500, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Morpheus"] = new BlackOperation({ + name:"Operation Morpheus", + desc:"DreamSense Technologies is an advertising company that uses " + + "special technology to transmit their ads into the peoples " + + "dreams and subconcious. They do this using broadcast transmitter " + + "towers. Based on information from our agents and informants in " + + "Chonqging, we have reason to believe that one of the broadcast " + + "towers there has been compromised by Synthoids and is being used " + + "to spread pro-Synthoid propaganda.

" + + "The mission is to destroy this broadcast tower. Speed and " + + "stealth are of the upmost important for this.", + baseDifficulty:45e3, reqdRank:150e3, + rankGain:4e3, rankLoss:1e3, hpLoss:100, + weights:{hack:0.05,str:0.15,def:0.15,dex:0.3,agi:0.3,cha:0, int:0.05}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isStealth:true + }); + BlackOperations["Operation Ion Storm"] = new BlackOperation({ + name:"Operation Ion Storm", + desc:"Our analysts have uncovered a gathering of MK-VI Synthoids " + + "that have taken up residence in the Sector-12 Slums. We " + + "don't know if they are rogue Synthoids from the Uprising, " + + "but we do know that they have been stockpiling " + + "weapons, money, and other resources. This makes them dangerous.

" + + "This is a full-scale assault operation to find and retire all of these " + + "Synthoids in the Sector-12 Slums.", + baseDifficulty:50e3, reqdRank:175e3, + rankGain:5e3, rankLoss:1e3, hpLoss:5000, + weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Annihilus"] = new BlackOperation({ + name:"Operation Annihilus", + desc:"Our superiors have ordered us to eradicate everything and everyone " + + "in an underground facility located in Aevum. They tell us " + + "that the facility houses many dangerous Synthoids and " + + "belongs to a terrorist organization called " + + "'The Covenant'. We have no prior intelligence about this " + + "organization, so you are going in blind.", + baseDifficulty:55e3, reqdRank:200e3, + rankGain:7.5e3, rankLoss:1e3, hpLoss:10e3, + weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Ultron"] = new BlackOperation({ + name:"Operation Ultron", + desc:"OmniTek Incorporated, the original designer and manufacturer of Synthoids, " + + "has notified us of a malfunction in their AI design. This malfunction, " + + "when triggered, causes MK-VI Synthoids to become radicalized and seek out " + + "the destruction of humanity. They say that this bug affects all MK-VI Synthoids, " + + "not just the rogue ones from the Uprising.

" + + "OmniTek has also told us they they believe someone has triggered this " + + "malfunction in a large group of MK-VI Synthoids, and that these newly-radicalized Synthoids " + + "are now amassing in Volhaven to form a terrorist group called Ultron.

" + + "Intelligence suggests Ultron is heavily armed and that their members are " + + "augmented. We believe Ultron is making moves to take control of " + + "and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).

" + + "Your task is to find and destroy Ultron.", + baseDifficulty:60e3, reqdRank:250e3, + rankGain:10e3, rankLoss:2e3, hpLoss:10e3, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + isKill:true + }); + BlackOperations["Operation Centurion"] = new BlackOperation({ + name:"Operation Centurion", + desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

" + + "Throughout all of humanity's history, we have relied on " + + "technology to survive, conquer, and progress. Its advancement became our primary goal. " + + "And at the peak of human civilization technology turned into " + + "power. Global, absolute power.

" + + "It seems that the universe is not without a sense of irony.

" + + "D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)", + baseDifficulty:70e3, reqdRank:300e3, + rankGain:15e3, rankLoss:5e3, hpLoss:10e3, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + }); + BlackOperations["Operation Vindictus"] = new BlackOperation({ + name:"Operation Vindictus", + desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

" + + "The bits are all around us. The daemons that hold the Node " + + "together can manifest themselves in many different ways.

" + + "D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)", + baseDifficulty:75e3, reqdRank:350e3, + rankGain:20e3, rankLoss:20e3, hpLoss:20e3, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + }); + BlackOperations["Operation Daedalus"] = new BlackOperation({ + name:"Operation Daedalus", + desc:"Yesterday we obeyed kings and bent our neck to emperors. " + + "Today we kneel only to truth.", + baseDifficulty:80e3, reqdRank:400e3, + rankGain:40e3, rankLoss:10e3, hpLoss:100e3, + weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, + decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, + }); +})() \ No newline at end of file diff --git a/src/Bladeburner/City.ts b/src/Bladeburner/City.ts new file mode 100644 index 000000000..d159eab7e --- /dev/null +++ b/src/Bladeburner/City.ts @@ -0,0 +1,172 @@ + +import { BladeburnerConstants } from "./data/Constants"; +import { getRandomInt } from "../../utils/helpers/getRandomInt"; +import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; +import { addOffset } from "../../utils/helpers/addOffset"; + +export class ChangePopulationByCountParams { + estChange: number = 0; + estOffset: number = 0; +} + +export class ChangePopulationByPercentageParams { + nonZero: boolean = false; + changeEstEqually: boolean = false; +} + +export class City { + + /** + * Name of the city. + */ + name: string = ""; + + /** + * Population of the city. + */ + pop: number = 0; + + /** + * Population estimation of the city. + */ + popEst: number = 0; + + /** + * Number of communities in the city. + */ + comms: number = 0; + + /** + * Estimated number of communities in the city. + */ + commsEst: number = 0; + + /** + * Chaos level of the city. + */ + chaos: number = 0; + + constructor(name: string = BladeburnerConstants.CityNames[2]) { + this.name = name; + + // Synthoid population and estimate + this.pop = getRandomInt(BladeburnerConstants.PopulationThreshold, 1.5 * BladeburnerConstants.PopulationThreshold); + this.popEst = this.pop * (Math.random() + 0.5); + + // Number of Synthoid communities population and estimate + this.comms = getRandomInt(5, 150) + this.commsEst = this.comms + getRandomInt(-5, 5); + if (this.commsEst < 0) this.commsEst = 0; + this.chaos = 0; + } + + /** + * p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) + */ + changeChaosByPercentage(p: number): void { + if (isNaN(p)) {throw new Error("NaN passed into City.chaosChaosByPercentage()");} + if (p === 0) {return;} + this.chaos += this.chaos * (p/100); + if (this.chaos < 0) {this.chaos = 0;} + } + + improvePopulationEstimateByCount(n: number): void { + if (isNaN(n)) {throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");} + if (this.popEst < this.pop) { + this.popEst += n; + if (this.popEst > this.pop) {this.popEst = this.pop;} + } else if (this.popEst > this.pop) { + this.popEst -= n; + if (this.popEst < this.pop) {this.popEst = this.pop;} + } + } + + /** + * p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) + */ + improvePopulationEstimateByPercentage(p: number, skillMult: number=1): void { + p = p*skillMult; + if (isNaN(p)) {throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");} + if (this.popEst < this.pop) { + ++this.popEst; // In case estimate is 0 + this.popEst *= (1 + (p/100)); + if (this.popEst > this.pop) {this.popEst = this.pop;} + } else if (this.popEst > this.pop) { + this.popEst *= (1 - (p/100)); + if (this.popEst < this.pop) {this.popEst = this.pop;} + } + } + + improveCommunityEstimate(n: number=1): void { + if (isNaN(n)) {throw new Error("NaN passed into City.improveCommunityEstimate()");} + if (this.commsEst < this.comms) { + this.commsEst += n; + if (this.commsEst > this.comms) {this.commsEst = this.comms;} + } else if (this.commsEst > this.comms) { + this.commsEst -= n; + if (this.commsEst < this.comms) {this.commsEst = this.comms;} + } + } + + /** + * @params options: + * estChange(int): How much the estimate should change by + * estOffset(int): Add offset to estimate (offset by percentage) + */ + changePopulationByCount(n: number, params: ChangePopulationByCountParams=new ChangePopulationByCountParams()): void { + if (isNaN(n)) {throw new Error("NaN passed into City.changePopulationByCount()");} + this.pop += n; + if (params.estChange && !isNaN(params.estChange)) {this.popEst += params.estChange;} + if (params.estOffset) { + this.popEst = addOffset(this.popEst, params.estOffset); + } + this.popEst = Math.max(this.popEst, 0); + } + + /** + * @p is the percentage, not the multiplier. e.g. pass in p = 5 for 5% + * @params options: + * changeEstEqually(bool) - Change the population estimate by an equal amount + * nonZero (bool) - Set to true to ensure that population always changes by at least 1 + */ + changePopulationByPercentage(p: number, params: ChangePopulationByPercentageParams=new ChangePopulationByPercentageParams()): number { + if (isNaN(p)) {throw new Error("NaN passed into City.changePopulationByPercentage()");} + if (p === 0) {return 0;} + let change = Math.round(this.pop * (p/100)); + + // Population always changes by at least 1 + if (params.nonZero && change === 0) { + p > 0 ? change = 1 : change = -1; + } + + this.pop += change; + if (params.changeEstEqually) { + this.popEst += change; + if (this.popEst < 0) {this.popEst = 0;} + } + return change; + } + + changeChaosByCount(n: number): void { + if (isNaN(n)) {throw new Error("NaN passed into City.changeChaosByCount()");} + if (n === 0) {return;} + this.chaos += n; + if (this.chaos < 0) {this.chaos = 0;} + } + + /** + * Initiatizes a City object from a JSON save state. + */ + static fromJSON(value: any): City { + return Generic_fromJSON(City, value.data); + } + + /** + * Serialize the current object to a JSON save state. + */ + toJSON(): any { + return Generic_toJSON("City", this); + } +} + +Reviver.constructors.City = City; diff --git a/src/Bladeburner/Contract.ts b/src/Bladeburner/Contract.ts new file mode 100644 index 000000000..8b9662e66 --- /dev/null +++ b/src/Bladeburner/Contract.ts @@ -0,0 +1,24 @@ +// import { BladeburnerConstants } from "./data/Constants"; +import { Action, IActionParams } from "./Action"; +import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; + +export class Contract extends Action { + + constructor(params: IActionParams | null = null) { + super(params); + } + + getActionTypeSkillSuccessBonus(inst: any): number { + return inst.skillMultipliers.successChanceContract; + } + + static fromJSON(value: any): Contract { + return Generic_fromJSON(Contract, value.data); + } + + toJSON(): any { + return Generic_toJSON("Contract", this); + } +} + +Reviver.constructors.Contract = Contract; \ No newline at end of file diff --git a/src/Bladeburner/GeneralActions.ts b/src/Bladeburner/GeneralActions.ts new file mode 100644 index 000000000..209b60002 --- /dev/null +++ b/src/Bladeburner/GeneralActions.ts @@ -0,0 +1,49 @@ +import { Action } from "./Action"; +import { IMap } from "../types"; + +export const GeneralActions: IMap = {}; + +(function() { + // General Actions + let actionName; + actionName = "Training"; + GeneralActions[actionName] = new Action({ + name:actionName, + desc:"Improve your abilities at the Bladeburner unit's specialized training " + + "center. Doing this gives experience for all combat stats and also " + + "increases your max stamina." + }); + + actionName = "Field Analysis"; + GeneralActions[actionName] = new Action({ + name:actionName, + desc:"Mine and analyze Synthoid-related data. This improve the " + + "Bladeburner's unit intelligence on Synthoid locations and " + + "activities. Completing this action will improve the accuracy " + + "of your Synthoid population estimated in the current city.

" + + "Does NOT require stamina." + }); + + actionName = "Recruitment"; + GeneralActions[actionName] = new Action({ + name:actionName, + desc:"Attempt to recruit members for your Bladeburner team. These members " + + "can help you conduct operations.

" + + "Does NOT require stamina." + }); + + actionName = "Diplomacy"; + GeneralActions[actionName] = new Action({ + name: actionName, + desc: "Improve diplomatic relations with the Synthoid population. " + + "Completing this action will reduce the Chaos level in your current city.

" + + "Does NOT require stamina." + }); + + actionName = "Hyperbolic Regeneration Chamber"; + GeneralActions[actionName] = new Action({ + name: actionName, + desc: "Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. " + + "This will slowly heal your wounds and slightly increase your stamina.

", + }); +})() \ No newline at end of file diff --git a/src/Bladeburner/Operation.ts b/src/Bladeburner/Operation.ts new file mode 100644 index 000000000..12718b493 --- /dev/null +++ b/src/Bladeburner/Operation.ts @@ -0,0 +1,55 @@ +import { BladeburnerConstants } from "./data/Constants"; +import { Action, IActionParams } from "./Action"; +import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; + +export interface IOperationParams extends IActionParams { + reqdRank?: number; + teamCount?: number; +} + +export class Operation extends Action { + reqdRank: number = 100; + teamCount: number = 0; + + constructor(params: IOperationParams | null = null) { + super(params); + if(params && params.reqdRank) this.reqdRank = params.reqdRank; + if(params && params.teamCount) this.teamCount = params.teamCount; + } + + // For actions that have teams. To be implemented by subtypes. + getTeamSuccessBonus(inst: any): number { + if (this.teamCount && this.teamCount > 0) { + this.teamCount = Math.min(this.teamCount, inst.teamSize); + let teamMultiplier = Math.pow(this.teamCount, 0.05); + return teamMultiplier; + } + + return 1; + } + + getActionTypeSkillSuccessBonus(inst: any): number { + return inst.skillMultipliers.successChanceOperation; + } + + getChaosDifficultyBonus(inst: any, params: any): number { + const city = inst.getCurrentCity(); + if (city.chaos > BladeburnerConstants.ChaosThreshold) { + let diff = 1 + (city.chaos - BladeburnerConstants.ChaosThreshold); + let mult = Math.pow(diff, 0.1); + return mult; + } + + return 1; + } + + static fromJSON(value: any): Operation { + return Generic_fromJSON(Operation, value.data); + } + + toJSON(): any { + return Generic_toJSON("Operation", this); + } +} + +Reviver.constructors.Operation = Operation; \ No newline at end of file diff --git a/src/Bladeburner/Skill.ts b/src/Bladeburner/Skill.ts new file mode 100644 index 000000000..d901a25ca --- /dev/null +++ b/src/Bladeburner/Skill.ts @@ -0,0 +1,107 @@ +import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; + +interface ISkillParams { + name: string; + desc: string; + + baseCost?: number; + costInc?: number; + maxLvl?: number; + + successChanceAll?: number; + successChanceStealth?: number; + successChanceKill?: number; + successChanceContract?: number; + successChanceOperation?: number; + successChanceEstimate?: number; + + actionTime?: number; + + effHack?: number; + effStr?: number; + effDef?: number; + effDex?: number; + effAgi?: number; + effCha?: number; + + stamina?: number; + money?: number; + expGain?: number; +} + +export class Skill { + name: string; + desc: string; + // Cost is in Skill Points + baseCost: number = 1; + // Additive cost increase per level + costInc: number = 1; + maxLvl: number = 0; + + /** + * These benefits are additive. So total multiplier will be level (handled externally) times the + * effects below + */ + successChanceAll: number = 0; + successChanceStealth: number = 0; + successChanceKill: number = 0; + successChanceContract: number = 0; + successChanceOperation: number = 0; + + /** + * This multiplier affects everything that increases synthoid population/community estimate + * e.g. Field analysis, Investigation Op, Undercover Op + */ + successChanceEstimate: number = 0; + actionTime: number = 0; + effHack: number = 0; + effStr: number = 0; + effDef: number = 0; + effDex: number = 0; + effAgi: number = 0; + effCha: number = 0; + stamina: number = 0; + money: number = 0; + expGain: number = 0; + + constructor(params: ISkillParams={name:"foo", desc:"foo"}) { + if (!params.name) { + throw new Error("Failed to initialize Bladeburner Skill. No name was specified in ctor"); + } + if (!params.desc) { + throw new Error("Failed to initialize Bladeburner Skills. No desc was specified in ctor"); + } + this.name = params.name; + this.desc = params.desc; + this.baseCost = params.baseCost ? params.baseCost : 1; + this.costInc = params.costInc ? params.costInc : 1; + + if (params.maxLvl) {this.maxLvl = params.maxLvl;} + + if (params.successChanceAll) {this.successChanceAll = params.successChanceAll;} + if (params.successChanceStealth) {this.successChanceStealth = params.successChanceStealth;} + if (params.successChanceKill) {this.successChanceKill = params.successChanceKill;} + if (params.successChanceContract) {this.successChanceContract = params.successChanceContract;} + if (params.successChanceOperation) {this.successChanceOperation = params.successChanceOperation;} + + + if (params.successChanceEstimate) {this.successChanceEstimate = params.successChanceEstimate;} + + if (params.actionTime) {this.actionTime = params.actionTime;} + if (params.effHack) {this.effHack = params.effHack;} + if (params.effStr) {this.effStr = params.effStr;} + if (params.effDef) {this.effDef = params.effDef;} + if (params.effDex) {this.effDex = params.effDex;} + if (params.effAgi) {this.effAgi = params.effAgi;} + if (params.effCha) {this.effCha = params.effCha;} + + if (params.stamina) {this.stamina = params.stamina;} + if (params.money) {this.money = params.money;} + if (params.expGain) {this.expGain = params.expGain;} + } + + calculateCost(currentLevel: number): number { + return Math.floor((this.baseCost + (currentLevel * this.costInc)) * BitNodeMultipliers.BladeburnerSkillCost); + } +} + diff --git a/src/Bladeburner/Skills.ts b/src/Bladeburner/Skills.ts new file mode 100644 index 000000000..f762a296e --- /dev/null +++ b/src/Bladeburner/Skills.ts @@ -0,0 +1,90 @@ +import { Skill } from "./Skill"; +import { SkillNames } from "./data/SkillNames"; +import { IMap } from "../types"; + +export const Skills: IMap = {}; + +(function(){ + Skills[SkillNames.BladesIntuition] = new Skill({ + name:SkillNames.BladesIntuition, + desc:"Each level of this skill increases your success chance " + + "for all Contracts, Operations, and BlackOps by 3%", + baseCost: 3, costInc: 2.1, + successChanceAll:3 + }); + Skills[SkillNames.Cloak] = new Skill({ + name:SkillNames.Cloak, + desc:"Each level of this skill increases your " + + "success chance in stealth-related Contracts, Operations, and BlackOps by 5.5%", + baseCost: 2, costInc: 1.1, + successChanceStealth:5.5 + }); + Skills[SkillNames.ShortCircuit] = new Skill({ + name:SkillNames.ShortCircuit, + desc:"Each level of this skill increases your success chance " + + "in Contracts, Operations, and BlackOps that involve retirement by 5.5%", + baseCost: 2, costInc: 2.1, + successChanceKill:5.5 + }); + Skills[SkillNames.DigitalObserver] = new Skill({ + name:SkillNames.DigitalObserver, + desc:"Each level of this skill increases your success chance in " + + "all Operations and BlackOps by 4%", + baseCost: 2, costInc: 2.1, + successChanceOperation:4 + }); + Skills[SkillNames.Tracer] = new Skill({ + name:SkillNames.Tracer, + desc:"Each level of this skill increases your success chance in " + + "all Contracts by 4%", + baseCost: 2, costInc: 2.1, + successChanceContract:4 + }); + Skills[SkillNames.Overclock] = new Skill({ + name:SkillNames.Overclock, + desc:"Each level of this skill decreases the time it takes " + + "to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 90)", + baseCost: 3, costInc: 1.4, maxLvl: 90, + actionTime:1 + }); + Skills[SkillNames.Reaper] = new Skill({ + name: SkillNames.Reaper, + desc: "Each level of this skill increases your effective combat stats for Bladeburner actions by 2%", + baseCost: 2, costInc: 2.1, + effStr: 2, effDef: 2, effDex: 2, effAgi: 2 + }); + Skills[SkillNames.EvasiveSystem] = new Skill({ + name:SkillNames.EvasiveSystem, + desc:"Each level of this skill increases your effective " + + "dexterity and agility for Bladeburner actions by 4%", + baseCost: 2, costInc: 2.1, + effDex: 4, effAgi: 4 + }); + Skills[SkillNames.Datamancer] = new Skill({ + name:SkillNames.Datamancer, + desc:"Each level of this skill increases your effectiveness in " + + "synthoid population analysis and investigation by 5%. " + + "This affects all actions that can potentially increase " + + "the accuracy of your synthoid population/community estimates.", + baseCost:3, costInc:1, + successChanceEstimate:5 + }); + Skills[SkillNames.CybersEdge] = new Skill({ + name:SkillNames.CybersEdge, + desc:"Each level of this skill increases your max stamina by 2%", + baseCost:1, costInc:3, + stamina:2 + }); + Skills[SkillNames.HandsOfMidas] = new Skill({ + name: SkillNames.HandsOfMidas, + desc: "Each level of this skill increases the amount of money you receive from Contracts by 10%", + baseCost: 2, costInc: 2.5, + money: 10, + }); + Skills[SkillNames.Hyperdrive] = new Skill({ + name: SkillNames.Hyperdrive, + desc: "Each level of this skill increases the experience earned from Contracts, Operations, and BlackOps by 10%", + baseCost: 1, costInc: 2.5, + expGain: 10, + }); +})() \ No newline at end of file diff --git a/src/Bladeburner/data/ActionTypes.ts b/src/Bladeburner/data/ActionTypes.ts new file mode 100644 index 000000000..f4392313c --- /dev/null +++ b/src/Bladeburner/data/ActionTypes.ts @@ -0,0 +1,14 @@ +// Action Identifier enum +export const ActionTypes = Object.freeze({ + "Idle": 1, + "Contract": 2, + "Operation": 3, + "BlackOp": 4, + "BlackOperation": 4, + "Training": 5, + "Recruitment": 6, + "FieldAnalysis": 7, + "Field Analysis": 7, + "Diplomacy": 8, + "Hyperbolic Regeneration Chamber": 9, +}); \ No newline at end of file diff --git a/src/Bladeburner/data/Constants.ts b/src/Bladeburner/data/Constants.ts new file mode 100644 index 000000000..62a0ddb3a --- /dev/null +++ b/src/Bladeburner/data/Constants.ts @@ -0,0 +1,79 @@ +export const BladeburnerConstants: { + CityNames: string[]; + CyclesPerSecond: number; + StaminaGainPerSecond: number; + BaseStaminaLoss: number; + MaxStaminaToGainFactor: number; + DifficultyToTimeFactor: number; + DiffMultExponentialFactor: number; + DiffMultLinearFactor: number; + EffAgiLinearFactor: number; + EffDexLinearFactor: number; + EffAgiExponentialFactor: number; + EffDexExponentialFactor: number; + BaseRecruitmentTimeNeeded: number; + PopulationThreshold: number; + PopulationExponent: number; + ChaosThreshold: number; + BaseStatGain: number; + BaseIntGain: number; + ActionCountGrowthPeriod: number; + RankToFactionRepFactor: number; + RankNeededForFaction: number; + ContractSuccessesPerLevel: number; + OperationSuccessesPerLevel: number; + RanksPerSkillPoint: number; + ContractBaseMoneyGain: number; + HrcHpGain: number; + HrcStaminaGain: number; +} = { + CityNames: ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"], + CyclesPerSecond: 5, // Game cycle is 200 ms + + StaminaGainPerSecond: 0.0085, + BaseStaminaLoss: 0.285, // Base stamina loss per action. Increased based on difficulty + MaxStaminaToGainFactor: 70000, // Max Stamina is divided by this to get bonus stamina gain + + DifficultyToTimeFactor: 10, // Action Difficulty divided by this to get base action time + + /** + * The difficulty multiplier affects stamina loss and hp loss of an action. Also affects + * experience gain. Its formula is: + * difficulty ^ exponentialFactor + difficulty / linearFactor + */ + DiffMultExponentialFactor: 0.28, + DiffMultLinearFactor: 650, + + /** + * These factors are used to calculate action time. + * They affect how much action time is reduced based on your agility and dexterity + */ + EffAgiLinearFactor: 10e3, + EffDexLinearFactor: 10e3, + EffAgiExponentialFactor: 0.04, + EffDexExponentialFactor: 0.035, + + BaseRecruitmentTimeNeeded: 300, // Base time needed (s) to complete a Recruitment action + + PopulationThreshold: 1e9, // Population which determines baseline success rate + PopulationExponent: 0.7, // Exponent that influences how different populations affect success rate + ChaosThreshold: 50, // City chaos level after which it starts making tasks harder + + BaseStatGain: 1, // Base stat gain per second + BaseIntGain: 0.001, // Base intelligence stat gain + + ActionCountGrowthPeriod: 480, // Time (s) it takes for action count to grow by its specified value + + RankToFactionRepFactor: 2, // Delta Faction Rep = this * Delta Rank + RankNeededForFaction: 25, + + ContractSuccessesPerLevel: 3, // How many successes you need to level up a contract + OperationSuccessesPerLevel: 2.5, // How many successes you need to level up an op + + RanksPerSkillPoint: 3, // How many ranks needed to get 1 Skill Point + + ContractBaseMoneyGain: 250e3, // Base Money Gained per contract + + HrcHpGain: 2, // HP Gained from Hyperbolic Regeneration chamber + HrcStaminaGain: 1, // Percentage Stamina gained from Hyperbolic Regeneration Chamber +} \ No newline at end of file diff --git a/src/Bladeburner/data/Help.ts b/src/Bladeburner/data/Help.ts new file mode 100644 index 000000000..ed87118b8 --- /dev/null +++ b/src/Bladeburner/data/Help.ts @@ -0,0 +1,116 @@ +export const ConsoleHelpText: {} = { + helpList: [ + "Use 'help [command]' to get more information about a particular Bladeburner console command.", + "", + " automate [var] [val] [hi/low] Configure simple automation for Bladeburner tasks", + " clear/cls Clear the console", + " help [cmd] Display this help text, or help text for a specific command", + " log [en/dis] [type] Enable or disable logging for events and actions", + " skill [action] [name] Level or display info about your Bladeburner skills", + " start [type] [name] Start a Bladeburner action/task" , + " stop Stops your current Bladeburner action/task" + ], + automate: [ + "automate [var] [val] [hi/low]", + "", + "A simple way to automate your Bladeburner actions. This console command can be used " + + "to automatically start an action when your stamina rises above a certain threshold, and " + + "automatically switch to another action when your stamina drops below another threshold.", + " automate status - Check the current status of your automation and get a brief description of what it'll do", + " automate en - Enable the automation feature", + " automate dis - Disable the automation feature", + "", + "There are four properties that must be set for this automation to work properly. Here is how to set them:", + "", + " automate stamina 100 high", + " automate contract Tracking high", + " automate stamina 50 low", + " automate general 'Field Analysis' low", + "", + "Using the four console commands above will set the automation to perform Tracking contracts " + + "if your stamina is 100 or higher, and then switch to Field Analysis if your stamina drops below " + + "50. Note that when setting the action, the name of the action is CASE-SENSITIVE. It must " + + "exactly match whatever the name is in the UI." + ], + clear: [ + "clear", + "", + "Clears the console" + ], + cls: [ + "cls", + "", + "Clears the console" + ], + help: [ + "help [command]", + "", + "Running 'help' with no arguments displays the general help text, which lists all console commands " + + "and a brief description of what they do. A command can be specified to get more specific help text " + + "about that particular command. For example:", + "", + " help automate", + "", + "will display specific information about using the automate console command" + ], + log: [ + "log [en/dis] [type]", + "", + "Enable or disable logging. By default, the results of completing actions such as contracts/operations are logged " + + "in the console. There are also random events that are logged in the console as well. The five categories of " + + "things that get logged are:", + "", + "[general, contracts, ops, blackops, events]", + "", + "The logging for these categories can be enabled or disabled like so:", + "", + " log dis contracts - Disables logging that occurs when contracts are completed", + " log en contracts - Enables logging that occurs when contracts are completed", + " log dis events - Disables logging for Bladeburner random events", + "", + "Logging can be universally enabled/disabled using the 'all' keyword:", + "", + " log dis all", + " log en all" + ], + skill: [ + "skill [action] [name]", + "", + "Level or display information about your skills.", + "", + "To display information about all of your skills and your multipliers, use:", + "", + " skill list", + "", + "To display information about a specific skill, specify the name of the skill afterwards. " + + "Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If " + + "the name of the skill has whitespace, enclose the name of the skill in double quotation marks:", + "", + " skill list Reaper
" + + " skill list 'Digital Observer'", + "", + "This console command can also be used to level up skills:", + "", + " skill level [skill name]" + ], + start: [ + "start [type] [name]", + "", + "Start an action. An action is specified by its type and its name. The " + + "name is case-sensitive. It must appear exactly as it does in the UI. If " + + "the name of the action has whitespace, enclose it in double quotation marks. " + + "Valid action types include:", + "", + "[general, contract, op, blackop]", + "", + "Examples:", + "", + " start contract Tracking", + " start op 'Undercover Operation'" + ], + stop:[ + "stop", + "", + "Stop your current action and go idle." + ], +} \ No newline at end of file diff --git a/src/Bladeburner/data/SkillNames.ts b/src/Bladeburner/data/SkillNames.ts new file mode 100644 index 000000000..1a71bd63c --- /dev/null +++ b/src/Bladeburner/data/SkillNames.ts @@ -0,0 +1,31 @@ +export const SkillNames: { + BladesIntuition: string; + Cloak: string; + Marksman: string; + WeaponProficiency: string; + ShortCircuit: string; + DigitalObserver: string; + Tracer: string; + Overclock: string; + Reaper: string; + EvasiveSystem: string; + Datamancer: string; + CybersEdge: string; + HandsOfMidas: string; + Hyperdrive: string; +} = { + BladesIntuition: "Blade's Intuition", + Cloak: "Cloak", + Marksman: "Marksman", + WeaponProficiency: "Weapon Proficiency", + ShortCircuit: "Short-Circuit", + DigitalObserver: "Digital Observer", + Tracer: "Tracer", + Overclock: "Overclock", + Reaper: "Reaper", + EvasiveSystem: "Evasive System", + Datamancer: "Datamancer", + CybersEdge: "Cyber's Edge", + HandsOfMidas: "Hands of Midas", + Hyperdrive: "Hyperdrive", +} \ No newline at end of file diff --git a/src/Bladeburner/ui/BlackOperationsPage.tsx b/src/Bladeburner/ui/BlackOperationsPage.tsx new file mode 100644 index 000000000..134147551 --- /dev/null +++ b/src/Bladeburner/ui/BlackOperationsPage.tsx @@ -0,0 +1,63 @@ +import { BlackOperations } from "../BlackOperations"; +/* +if (DomElems.actionsAndSkillsList == null || DomElems.actionsAndSkillsDesc == null) { + throw new Error("Bladeburner.createBlackOpsContent called with either " + + "DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null"); +} + +DomElems.actionsAndSkillsDesc.innerHTML = + "Black Operations (Black Ops) are special, one-time covert operations. " + + "Each Black Op must be unlocked successively by completing " + + "the one before it.

" + + "Your ultimate goal to climb through the ranks of Bladeburners is to complete " + + "all of the Black Ops.

" + + "Like normal operations, you may use a team for Black Ops. Failing " + + "a black op will incur heavy HP and rank losses."; + +// Put Black Operations in sequence of required rank +var blackops = []; +for (var blackopName in BlackOperations) { + if (BlackOperations.hasOwnProperty(blackopName)) { + blackops.push(BlackOperations[blackopName]); + } +} +blackops.sort(function(a, b) { + return (a.reqdRank - b.reqdRank); +}); + +for (var i = blackops.length-1; i >= 0 ; --i) { + if (this.blackops[[blackops[i].name]] == null && i !== 0 && this.blackops[[blackops[i-1].name]] == null) {continue;} // If this one nor the next are completed then this isn't unlocked yet. + DomElems.blackops[blackops[i].name] = createElement("div", { + class:"bladeburner-action", name:blackops[i].name + }); + DomElems.actionsAndSkillsList.appendChild(DomElems.blackops[blackops[i].name]); +} +*/ + + + +import * as React from "react"; + +export function BlackOperationsPage(inst: any): React.ReactElement { + // Put Black Operations in sequence of required rank + const blackops = []; + for (const name in BlackOperations) { + if (BlackOperations.hasOwnProperty(name)) { + blackops.push(BlackOperations[name]); + } + } + blackops.sort(function(a, b) { + return (a.reqdRank - b.reqdRank); + }); + + return (
+

+ Black Operations (Black Ops) are special, one-time covert operations. Each Black Op must be unlocked successively by completing the one before it.

+ Your ultimate goal to climb through the ranks of Bladeburners is to complete all of the Black Ops.

+ Like normal operations, you may use a team for Black Ops. Failing a black op will incur heavy HP and rank losses.

+ {blackops.map( op => +
+
+ )} +
) +} diff --git a/src/Constants.ts b/src/Constants.ts index 9cddaa04b..a5320d689 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -242,6 +242,12 @@ export let CONSTANTS: IMap = { Gang * style improvements + Bladeburner + * style improvements + + Bladeburner + * fix bug where 'skill list SKILL' would crash if skill is level 0. + Sleeve * karma gain now scales with sync. ` diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js index c833a6bfa..eb1633e52 100644 --- a/src/NetscriptFunctions.js +++ b/src/NetscriptFunctions.js @@ -431,14 +431,18 @@ function NetscriptFunctions(workerScript) { } } - const checkBladeburnerAccess = function(func) { - const accessDenied = `You do not ` + - "currently have access to the Bladeburner API. To access the Bladeburner API " + - "you must be employed at the Bladeburner division, AND you must either be in " + - "BitNode-7 or have Source-File 7."; - const hasAccess = Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || Player.sourceFiles.some(a=>{return a.n === 7})); - if(!hasAccess) { - throw makeRuntimeErrorMsg(`bladeburner.${func}`, accessDenied); + const checkBladeburnerAccess = function(func, skipjoined=false) { + const apiAccess = (Player.bitNodeN === 7 || Player.sourceFiles.some(a=>{return a.n === 7})); + if (!apiAccess) { + const apiDenied = `You do not currently have access to the Bladeburner API. You must either be in BitNode-7 or have Source-File 7.`; + throw makeRuntimeErrorMsg(`bladeburner.${func}`, apiDenied); + } + if (!skipjoined) { + const bladeburnerAccess = Player.bladeburner instanceof Bladeburner; + if(!bladeburnerAccess) { + const bladeburnerDenied = `You must be a member of the Bladeburner division to use this API.`; + throw makeRuntimeErrorMsg(`bladeburner.${func}`, bladeburnerDenied); + } } } @@ -707,17 +711,19 @@ function NetscriptFunctions(workerScript) { maxThreadNeeded = 1e6; } - let moneyGained = Math.floor(server.moneyAvailable * percentHacked) * threads; + let moneyDrained = Math.floor(server.moneyAvailable * percentHacked) * threads; // Over-the-top safety checks - if (moneyGained <= 0) { - moneyGained = 0; + if (moneyDrained <= 0) { + moneyDrained = 0; expGainedOnSuccess = expGainedOnFailure; } - if (moneyGained > server.moneyAvailable) {moneyGained = server.moneyAvailable;} - server.moneyAvailable -= moneyGained; + if (moneyDrained > server.moneyAvailable) {moneyDrained = server.moneyAvailable;} + server.moneyAvailable -= moneyDrained; if (server.moneyAvailable < 0) {server.moneyAvailable = 0;} + const moneyGained = moneyDrained * BitNodeMultipliers.ScriptHackMoneyGain; + Player.gainMoney(moneyGained); workerScript.scriptRef.onlineMoneyMade += moneyGained; Player.scriptProdSinceLastAug += moneyGained; @@ -1681,7 +1687,8 @@ function NetscriptFunctions(workerScript) { checkTixApiAccess("buyStock"); const stock = getStockFromSymbol(symbol, "buyStock"); const res = buyStock(stock, shares, workerScript, { rerenderFn: displayStockMarketContent }); - + console.log(stock); + console.log(res); return res ? stock.price : 0; }, sellStock: function(symbol, shares) { @@ -3696,12 +3703,12 @@ function NetscriptFunctions(workerScript) { }, joinBladeburnerFaction: function() { updateDynamicRam("joinBladeburnerFaction", getRamCost("bladeburner", "joinBladeburnerFaction")); - checkBladeburnerAccess("joinBladeburnerFaction"); + checkBladeburnerAccess("joinBladeburnerFaction", true); return Player.bladeburner.joinBladeburnerFactionNetscriptFn(workerScript); }, joinBladeburnerDivision: function() { updateDynamicRam("joinBladeburnerDivision", getRamCost("bladeburner", "joinBladeburnerDivision")); - checkBladeburnerAccess("joinBladeburnerDivision"); + checkBladeburnerAccess("joinBladeburnerDivision", true); if ((Player.bitNodeN === 7 || SourceFileFlags[7] > 0)) { if (Player.bitNodeN === 8) { return false; } if (Player.bladeburner instanceof Bladeburner) { diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index 361ed2212..046b27861 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -176,4 +176,5 @@ export interface IPlayer { startWorkPartTime(companyName: string): void; travel(to: CityName): boolean; giveExploit(exploit: Exploit): void; + queryStatFromString(str: string): number; } From 4ce7981cc00858a84e79db09fcda4cd7d3123d3a Mon Sep 17 00:00:00 2001 From: Olivier Gagnon Date: Sat, 13 Mar 2021 15:15:36 -0500 Subject: [PATCH 12/13] fix issue under Character, Stats where the wrong effective stats was being calculated --- src/ui/CharacterInfo.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/CharacterInfo.tsx b/src/ui/CharacterInfo.tsx index 4383f24ba..35c089683 100644 --- a/src/ui/CharacterInfo.tsx +++ b/src/ui/CharacterInfo.tsx @@ -170,8 +170,8 @@ export function CharacterInfo(p: IPlayer): React.ReactElement {
Date: Sat, 13 Mar 2021 15:19:07 -0500 Subject: [PATCH 13/13] 0.49.3 --- dist/engine.bundle.js | 4 ++-- dist/engineStyle.bundle.js | 2 +- dist/engineStyle.css | 4 +++- dist/vendor.bundle.js | 24 ++++++++++++------------ doc/source/changelog.rst | 31 +++++++++++++++++++++++++++++++ index.html | 6 +++--- package.json | 2 +- src/Constants.ts | 13 ++++++++++--- 8 files changed, 63 insertions(+), 23 deletions(-) diff --git a/dist/engine.bundle.js b/dist/engine.bundle.js index f65ea45c7..6e56af117 100644 --- a/dist/engine.bundle.js +++ b/dist/engine.bundle.js @@ -1,4 +1,4 @@ -!function(e){function t(t){for(var r,o,s=t[0],l=t[1],c=t[2],m=0,p=[];m${e}`;r.getElementById("terminal-input").insertAdjacentHTML("beforebegin",a),function(){const e=r.getElementById("terminal-container");e.scrollTop=e.scrollHeight}()}t.post=function(e){a(e)},t.postError=function(e){a(`ERROR: ${e}`,{color:"#ff2929"})},t.hackProgressBarPost=function(e){a(e,{id:"hack-progress-bar"})},t.hackProgressPost=function(e){a(e,{id:"hack-progress"})},t.postContent=a},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CONSTANTS={Version:"0.49.0",MaxSkillLevel:975,MilliPerCycle:200,CorpFactionRepRequirement:2e5,BaseCostFor1GBOfRamHome:32e3,BaseCostFor1GBOfRamServer:55e3,TravelCost:2e5,BaseFavorToDonate:150,DonateMoneyToRepDivisor:1e6,FactionReputationToFavorBase:500,FactionReputationToFavorMult:1.02,CompanyReputationToFavorBase:500,CompanyReputationToFavorMult:1.02,NeuroFluxGovernorLevelMult:1.14,NumNetscriptPorts:20,HomeComputerMaxRam:1073741824,ServerBaseGrowthRate:1.03,ServerMaxGrowthRate:1.0035,ServerFortifyAmount:.002,ServerWeakenAmount:.05,PurchasedServerLimit:25,PurchasedServerMaxRam:1048576,AugmentationCostMultiplier:5,AugmentationRepMultiplier:2.5,MultipleAugMultiplier:1.9,TorRouterCost:2e5,InfiltrationBribeBaseAmount:1e5,InfiltrationMoneyValue:5e3,InfiltrationRepValue:1.4,InfiltrationExpPow:.8,WSEAccountCost:2e8,TIXAPICost:5e9,MarketData4SCost:1e9,MarketDataTixApi4SCost:25e9,StockMarketCommission:1e5,HospitalCostPerHp:1e5,IntelligenceCrimeWeight:.05,IntelligenceInfiltrationWeight:.1,IntelligenceCrimeBaseExpGain:.001,IntelligenceProgramBaseExpGain:500,IntelligenceTerminalHackBaseExpGain:200,IntelligenceSingFnBaseExpGain:.002,IntelligenceClassBaseExpGain:1e-6,IntelligenceHackingMissionBaseExpGain:.03,HackingMissionRepToDiffConversion:1e4,HackingMissionRepToRewardConversion:7,HackingMissionSpamTimeIncrease:25e3,HackingMissionTransferAttackIncrease:1.05,HackingMissionMiscDefenseIncrease:1.05,HackingMissionDifficultyToHacking:135,HackingMissionHowToPlay:"Hacking missions are a minigame that, if won, will reward you with faction reputation.

In this game you control a set of Nodes and use them to try and defeat an enemy. Your Nodes are colored blue, while the enemy's are red. There are also other nodes on the map colored gray that initially belong to neither you nor the enemy. The goal of the game is to capture all of the enemy's Database nodes within the time limit. If you fail to do this, you will lose.

Each Node has three stats: Attack, Defense, and HP. There are five different actions that a Node can take:

Attack - Targets an enemy Node and lowers its HP. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's defense.

Scan - Targets an enemy Node and lowers its Defense. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's defense.

Weaken - Targets an enemy Node and lowers its Attack. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's defense.

Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level.

Overflow - Raises the Node's Attack but lowers its Defense. The effectiveness is determined by your hacking level.

Note that when determining the effectiveness of the above actions, the TOTAL Attack or Defense of the team is used, not just the Attack/Defense of the individual Node that is performing the action.

To capture a Node, you must lower its HP down to 0.

There are six different types of Nodes:

CPU Core - These are your main Nodes that are used to perform actions. Capable of performing every action

Firewall - Nodes with high defense. These Nodes can 'Fortify'

Database - A special type of Node. The player's objective is to conquer all of the enemy's Database Nodes within the time limit. These Nodes cannot perform any actions

Spam - Conquering one of these Nodes will slow the enemy's trace, giving the player additional time to complete the mission. These Nodes cannot perform any actions

Transfer - Conquering one of these nodes will increase the Attack of all of your CPU Cores by a small fixed percentage. These Nodes are capable of performing every action except the 'Attack' action

Shield - Nodes with high defense. These Nodes can 'Fortify'

To assign an action to a Node, you must first select one of your Nodes. This can be done by simply clicking on it. Double-clicking a node will select all of your Nodes of the same type (e.g. select all CPU Core Nodes or all Transfer Nodes). Note that only Nodes that can perform actions (CPU Core, Transfer, Shield, Firewall) can be selected. Selected Nodes will be denoted with a white highlight. After selecting a Node or multiple Nodes, select its action using the Action Buttons near the top of the screen. Every action also has a corresponding keyboard shortcut.

For certain actions such as attacking, scanning, and weakening, the Node performing the action must have a target. To target another node, simply click-and-drag from the 'source' Node to a target. A Node can only have one target, and you can target any Node that is adjacent to one of your Nodes (immediately above, below, or to the side. NOT diagonal). Furthermore, only CPU Cores and Transfer Nodes can target, since they are the only ones that can perform the related actions. To remove a target, you can simply click on the line that represents the connection between one of your Nodes and its target. Alternatively, you can select the 'source' Node and click the 'Drop Connection' button, or press 'd'.

Other Notes:

-Whenever a miscellenaous Node (not owned by the player or enemy) is conquered, the defense of all remaining miscellaneous Nodes that are not actively being targeted will increase by a fixed percentage.

-Whenever a Node is conquered, its stats are significantly reduced

-Miscellaneous Nodes slowly raise their defense over time

-Nodes slowly regenerate health over time.",MillisecondsPer20Hours:72e6,GameCyclesPer20Hours:36e4,MillisecondsPer10Hours:36e6,GameCyclesPer10Hours:18e4,MillisecondsPer8Hours:288e5,GameCyclesPer8Hours:144e3,MillisecondsPer4Hours:144e5,GameCyclesPer4Hours:72e3,MillisecondsPer2Hours:72e5,GameCyclesPer2Hours:36e3,MillisecondsPerHour:36e5,GameCyclesPerHour:18e3,MillisecondsPerHalfHour:18e5,GameCyclesPerHalfHour:9e3,MillisecondsPerQuarterHour:9e5,GameCyclesPerQuarterHour:4500,MillisecondsPerFiveMinutes:3e5,GameCyclesPerFiveMinutes:1500,FactionWorkHacking:"Faction Hacking Work",FactionWorkField:"Faction Field Work",FactionWorkSecurity:"Faction Security Work",WorkTypeCompany:"Working for Company",WorkTypeCompanyPartTime:"Working for Company part-time",WorkTypeFaction:"Working for Faction",WorkTypeCreateProgram:"Working on Create a Program",WorkTypeStudyClass:"Studying or Taking a class at university",WorkTypeCrime:"Committing a crime",ClassStudyComputerScience:"studying Computer Science",ClassDataStructures:"taking a Data Structures course",ClassNetworks:"taking a Networks course",ClassAlgorithms:"taking an Algorithms course",ClassManagement:"taking a Management course",ClassLeadership:"taking a Leadership course",ClassGymStrength:"training your strength at a gym",ClassGymDefense:"training your defense at a gym",ClassGymDexterity:"training your dexterity at a gym",ClassGymAgility:"training your agility at a gym",ClassDataStructuresBaseCost:40,ClassNetworksBaseCost:80,ClassAlgorithmsBaseCost:320,ClassManagementBaseCost:160,ClassLeadershipBaseCost:320,ClassGymBaseCost:120,ClassStudyComputerScienceBaseExp:.5,ClassDataStructuresBaseExp:1,ClassNetworksBaseExp:2,ClassAlgorithmsBaseExp:4,ClassManagementBaseExp:2,ClassLeadershipBaseExp:4,CrimeShoplift:"shoplift",CrimeRobStore:"rob a store",CrimeMug:"mug someone",CrimeLarceny:"commit larceny",CrimeDrugs:"deal drugs",CrimeBondForgery:"forge corporate bonds",CrimeTraffickArms:"traffick illegal arms",CrimeHomicide:"commit homicide",CrimeGrandTheftAuto:"commit grand theft auto",CrimeKidnap:"kidnap someone for ransom",CrimeAssassination:"assassinate a high-profile target",CrimeHeist:"pull off the ultimate heist",CodingContractBaseFactionRepGain:2500,CodingContractBaseCompanyRepGain:4e3,CodingContractBaseMoneyGain:75e6,TotalNumBitNodes:24,LatestUpdate:"\n v0.49.0 - 2021-03-11 Source-File -1\n -------\n\n Source-File -1\n * For advanced players: The game now embraces exploits and will reward\n players for doing so.\n\n Gang\n * ascension is less effective as the ascension multiplier goes up.\n * territory gain scales with power difference.\n\n Netscript\n * 'gang.getEquipmentStats' returns the stats of the equipment.\n * 'gang.getTaskStats' returns the stats of a task.\n * 'getCrimeStats' returns the stats of a crime.\n * Crashes should now print the ns stack trace.\n * Log messages are now more consistent.\n * 'softReset' now accepts a callback script like 'installAugmentations'\n\n Misc.\n * Minor formatting under Hacking>Active Scripts\n * option menu colors now match the rest of the game, kinda.\n "}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(46);function a(e){return e.every(r.isString)}t.replaceAt=function(e,t,n){return e.substr(0,t)+n+e.substr(t+n.length)},t.convertTimeMsToTimeElapsedString=function(e){const t=Math.floor(e/1e3),n=Math.floor(t/86400),r=t%86400,a=Math.floor(r/3600),i=r%3600,o=Math.floor(i/60);let s="";return n>0&&(s+=`${n} days `),a>0&&(s+=`${a} hours `),o>0&&(s+=`${o} minutes `),s+=`${i%60} seconds`},t.longestCommonStart=function(e){if(!a(e))return"";if(0===e.length)return"";const t=e.concat().sort(),n=t[0],r=t[t.length-1],i=n.length;let o=0;const s=(e,t)=>e.toUpperCase()===t.toUpperCase();for(;o=0;e--)if(1===n[e].nodeType)return!0;return!1},t.generateRandomString=function(e){let t="";const n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let r=0;r=1&&(e(t.target).closest(a[0]).length||i())}),e(document).on("click",".dialog-box-close-button",function(e){i()}),document.addEventListener("keydown",function(e){e.keyCode==r.KEY.ESC&&o&&(i(),e.preventDefault())});let o=!1;function s(e,t=!1){var n=document.createElement("div");n.setAttribute("class","dialog-box-container");var r=document.createElement("div");r.setAttribute("class","dialog-box-content");var i,s=document.createElement("span");s.setAttribute("class","dialog-box-close-button"),s.innerHTML="×",t?(i=document.createElement("pre")).innerHTML=e:(i=document.createElement("p")).innerHTML=e.replace(/(?:\r\n|\r|\n)/g,"
"),r.appendChild(s),r.appendChild(i),n.appendChild(r),document.body.appendChild(n),a.length>=1&&(n.style.visibility="hidden"),a.push(n),setTimeout(function(){o=!0},400)}}.call(this,n(83))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RamCostConstants={ScriptBaseRamCost:1.6,ScriptDomRamCost:25,ScriptHackRamCost:.1,ScriptHackAnalyzeRamCost:1,ScriptGrowRamCost:.15,ScriptGrowthAnalyzeRamCost:1,ScriptWeakenRamCost:.15,ScriptScanRamCost:.2,ScriptPortProgramRamCost:.05,ScriptRunRamCost:1,ScriptExecRamCost:1.3,ScriptSpawnRamCost:2,ScriptScpRamCost:.6,ScriptKillRamCost:.5,ScriptHasRootAccessRamCost:.05,ScriptGetHostnameRamCost:.05,ScriptGetHackingLevelRamCost:.05,ScriptGetMultipliersRamCost:4,ScriptGetServerRamCost:.1,ScriptFileExistsRamCost:.1,ScriptIsRunningRamCost:.1,ScriptHacknetNodesRamCost:4,ScriptHNUpgLevelRamCost:.4,ScriptHNUpgRamRamCost:.6,ScriptHNUpgCoreRamCost:.8,ScriptGetStockRamCost:2,ScriptBuySellStockRamCost:2.5,ScriptGetPurchaseServerRamCost:.25,ScriptPurchaseServerRamCost:2.25,ScriptGetPurchasedServerLimit:.05,ScriptGetPurchasedServerMaxRam:.05,ScriptRoundRamCost:.05,ScriptReadWriteRamCost:1,ScriptArbScriptRamCost:1,ScriptGetScriptRamCost:.1,ScriptGetHackTimeRamCost:.05,ScriptGetFavorToDonate:.1,ScriptCodingContractBaseRamCost:10,ScriptSleeveBaseRamCost:4,ScriptSingularityFn1RamCost:2,ScriptSingularityFn2RamCost:3,ScriptSingularityFn3RamCost:5,ScriptGangApiBaseRamCost:4,ScriptBladeburnerApiBaseRamCost:4},t.RamCosts={hacknet:{numNodes:()=>0,purchaseNode:()=>0,getPurchaseNodeCost:()=>0,getNodeStats:()=>0,upgradeLevel:()=>0,upgradeRam:()=>0,upgradeCore:()=>0,upgradeCache:()=>0,getLevelUpgradeCost:()=>0,getRamUpgradeCost:()=>0,getCoreUpgradeCost:()=>0,getCacheUpgradeCost:()=>0,numHashes:()=>0,hashCost:()=>0,spendHashes:()=>0},sprintf:()=>0,vsprintf:()=>0,scan:()=>t.RamCostConstants.ScriptScanRamCost,hack:()=>t.RamCostConstants.ScriptHackRamCost,hackAnalyzeThreads:()=>t.RamCostConstants.ScriptHackAnalyzeRamCost,hackAnalyzePercent:()=>t.RamCostConstants.ScriptHackAnalyzeRamCost,hackChance:()=>t.RamCostConstants.ScriptHackAnalyzeRamCost,sleep:()=>0,grow:()=>t.RamCostConstants.ScriptGrowRamCost,growthAnalyze:()=>t.RamCostConstants.ScriptGrowthAnalyzeRamCost,weaken:()=>t.RamCostConstants.ScriptWeakenRamCost,print:()=>0,tprint:()=>0,clearLog:()=>0,disableLog:()=>0,enableLog:()=>0,isLogEnabled:()=>0,getScriptLogs:()=>0,nuke:()=>t.RamCostConstants.ScriptPortProgramRamCost,brutessh:()=>t.RamCostConstants.ScriptPortProgramRamCost,ftpcrack:()=>t.RamCostConstants.ScriptPortProgramRamCost,relaysmtp:()=>t.RamCostConstants.ScriptPortProgramRamCost,httpworm:()=>t.RamCostConstants.ScriptPortProgramRamCost,sqlinject:()=>t.RamCostConstants.ScriptPortProgramRamCost,run:()=>t.RamCostConstants.ScriptRunRamCost,exec:()=>t.RamCostConstants.ScriptExecRamCost,spawn:()=>t.RamCostConstants.ScriptSpawnRamCost,kill:()=>t.RamCostConstants.ScriptKillRamCost,killall:()=>t.RamCostConstants.ScriptKillRamCost,exit:()=>0,scp:()=>t.RamCostConstants.ScriptScpRamCost,ls:()=>t.RamCostConstants.ScriptScanRamCost,ps:()=>t.RamCostConstants.ScriptScanRamCost,hasRootAccess:()=>t.RamCostConstants.ScriptHasRootAccessRamCost,getIp:()=>t.RamCostConstants.ScriptGetHostnameRamCost,getHostname:()=>t.RamCostConstants.ScriptGetHostnameRamCost,getHackingLevel:()=>t.RamCostConstants.ScriptGetHackingLevelRamCost,getHackingMultipliers:()=>t.RamCostConstants.ScriptGetMultipliersRamCost,getHacknetMultipliers:()=>t.RamCostConstants.ScriptGetMultipliersRamCost,getBitNodeMultipliers:()=>t.RamCostConstants.ScriptGetMultipliersRamCost,getServerMoneyAvailable:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerSecurityLevel:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerBaseSecurityLevel:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerMinSecurityLevel:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerRequiredHackingLevel:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerMaxMoney:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerGrowth:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerNumPortsRequired:()=>t.RamCostConstants.ScriptGetServerRamCost,getServerRam:()=>t.RamCostConstants.ScriptGetServerRamCost,serverExists:()=>t.RamCostConstants.ScriptGetServerRamCost,fileExists:()=>t.RamCostConstants.ScriptFileExistsRamCost,isRunning:()=>t.RamCostConstants.ScriptIsRunningRamCost,getStockSymbols:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockPrice:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockAskPrice:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockBidPrice:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockPosition:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockMaxShares:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockPurchaseCost:()=>t.RamCostConstants.ScriptGetStockRamCost,getStockSaleGain:()=>t.RamCostConstants.ScriptGetStockRamCost,buyStock:()=>t.RamCostConstants.ScriptBuySellStockRamCost,sellStock:()=>t.RamCostConstants.ScriptBuySellStockRamCost,shortStock:()=>t.RamCostConstants.ScriptBuySellStockRamCost,sellShort:()=>t.RamCostConstants.ScriptBuySellStockRamCost,placeOrder:()=>t.RamCostConstants.ScriptBuySellStockRamCost,cancelOrder:()=>t.RamCostConstants.ScriptBuySellStockRamCost,getOrders:()=>t.RamCostConstants.ScriptBuySellStockRamCost,getStockVolatility:()=>t.RamCostConstants.ScriptBuySellStockRamCost,getStockForecast:()=>t.RamCostConstants.ScriptBuySellStockRamCost,purchase4SMarketData:()=>t.RamCostConstants.ScriptBuySellStockRamCost,purchase4SMarketDataTixApi:()=>t.RamCostConstants.ScriptBuySellStockRamCost,getPurchasedServerLimit:()=>t.RamCostConstants.ScriptGetPurchasedServerLimit,getPurchasedServerMaxRam:()=>t.RamCostConstants.ScriptGetPurchasedServerMaxRam,getPurchasedServerCost:()=>t.RamCostConstants.ScriptGetPurchaseServerRamCost,purchaseServer:()=>t.RamCostConstants.ScriptPurchaseServerRamCost,deleteServer:()=>t.RamCostConstants.ScriptPurchaseServerRamCost,getPurchasedServers:()=>t.RamCostConstants.ScriptPurchaseServerRamCost,write:()=>t.RamCostConstants.ScriptReadWriteRamCost,tryWrite:()=>t.RamCostConstants.ScriptReadWriteRamCost,read:()=>t.RamCostConstants.ScriptReadWriteRamCost,peek:()=>t.RamCostConstants.ScriptReadWriteRamCost,clear:()=>t.RamCostConstants.ScriptReadWriteRamCost,getPortHandle:()=>10*t.RamCostConstants.ScriptReadWriteRamCost,rm:()=>t.RamCostConstants.ScriptReadWriteRamCost,scriptRunning:()=>t.RamCostConstants.ScriptArbScriptRamCost,scriptKill:()=>t.RamCostConstants.ScriptArbScriptRamCost,getScriptName:()=>0,getScriptRam:()=>t.RamCostConstants.ScriptGetScriptRamCost,getHackTime:()=>t.RamCostConstants.ScriptGetHackTimeRamCost,getGrowTime:()=>t.RamCostConstants.ScriptGetHackTimeRamCost,getWeakenTime:()=>t.RamCostConstants.ScriptGetHackTimeRamCost,getScriptIncome:()=>t.RamCostConstants.ScriptGetScriptRamCost,getScriptExpGain:()=>t.RamCostConstants.ScriptGetScriptRamCost,nFormat:()=>0,getTimeSinceLastAug:()=>t.RamCostConstants.ScriptGetHackTimeRamCost,prompt:()=>0,wget:()=>0,getFavorToDonate:()=>t.RamCostConstants.ScriptGetFavorToDonate,universityCourse:()=>t.RamCostConstants.ScriptSingularityFn1RamCost,gymWorkout:()=>t.RamCostConstants.ScriptSingularityFn1RamCost,travelToCity:()=>t.RamCostConstants.ScriptSingularityFn1RamCost,purchaseTor:()=>t.RamCostConstants.ScriptSingularityFn1RamCost,purchaseProgram:()=>t.RamCostConstants.ScriptSingularityFn1RamCost,getStats:()=>t.RamCostConstants.ScriptSingularityFn1RamCost/4,getCharacterInformation:()=>t.RamCostConstants.ScriptSingularityFn1RamCost/4,isBusy:()=>t.RamCostConstants.ScriptSingularityFn1RamCost/4,stopAction:()=>t.RamCostConstants.ScriptSingularityFn1RamCost/2,upgradeHomeRam:()=>t.RamCostConstants.ScriptSingularityFn2RamCost,getUpgradeHomeRamCost:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/2,workForCompany:()=>t.RamCostConstants.ScriptSingularityFn2RamCost,applyToCompany:()=>t.RamCostConstants.ScriptSingularityFn2RamCost,getCompanyRep:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/3,getCompanyFavor:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/3,getCompanyFavorGain:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/4,checkFactionInvitations:()=>t.RamCostConstants.ScriptSingularityFn2RamCost,joinFaction:()=>t.RamCostConstants.ScriptSingularityFn2RamCost,workForFaction:()=>t.RamCostConstants.ScriptSingularityFn2RamCost,getFactionRep:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/3,getFactionFavor:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/3,getFactionFavorGain:()=>t.RamCostConstants.ScriptSingularityFn2RamCost/4,donateToFaction:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,createProgram:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,commitCrime:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getCrimeChance:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getCrimeStats:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getOwnedAugmentations:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getOwnedSourceFiles:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getAugmentationsFromFaction:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getAugmentationPrereq:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getAugmentationCost:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,getAugmentationStats:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,purchaseAugmentation:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,softReset:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,installAugmentations:()=>t.RamCostConstants.ScriptSingularityFn3RamCost,gang:{getMemberNames:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/4,getGangInformation:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getOtherGangInformation:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getMemberInformation:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,canRecruitMember:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/4,recruitMember:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getTaskNames:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/4,getTaskStats:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/4,setMemberTask:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getEquipmentNames:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/4,getEquipmentCost:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getEquipmentType:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getEquipmentStats:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,purchaseEquipment:()=>t.RamCostConstants.ScriptGangApiBaseRamCost,ascendMember:()=>t.RamCostConstants.ScriptGangApiBaseRamCost,setTerritoryWarfare:()=>t.RamCostConstants.ScriptGangApiBaseRamCost/2,getChanceToWinClash:()=>t.RamCostConstants.ScriptGangApiBaseRamCost,getBonusTime:()=>0},bladeburner:{getContractNames:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/10,getOperationNames:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/10,getBlackOpNames:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/10,getBlackOpRank:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/2,getGeneralActionNames:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/10,getSkillNames:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/10,startAction:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,stopBladeburnerAction:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/2,getCurrentAction:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost/4,getActionTime:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getActionEstimatedSuccessChance:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getActionRepGain:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getActionCountRemaining:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getActionMaxLevel:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getActionCurrentLevel:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getActionAutolevel:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,setActionAutolevel:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,setActionLevel:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getRank:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getSkillPoints:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getSkillLevel:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getSkillUpgradeCost:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,upgradeSkill:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getTeamSize:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,setTeamSize:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getCityEstimatedPopulation:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getCityEstimatedCommunities:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getCityChaos:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getCity:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,switchCity:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getStamina:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,joinBladeburnerFaction:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,joinBladeburnerDivision:()=>t.RamCostConstants.ScriptBladeburnerApiBaseRamCost,getBonusTime:()=>0},codingcontract:{attempt:()=>t.RamCostConstants.ScriptCodingContractBaseRamCost,getContractType:()=>t.RamCostConstants.ScriptCodingContractBaseRamCost/2,getData:()=>t.RamCostConstants.ScriptCodingContractBaseRamCost/2,getDescription:()=>t.RamCostConstants.ScriptCodingContractBaseRamCost/2,getNumTriesRemaining:()=>t.RamCostConstants.ScriptCodingContractBaseRamCost/5},sleeve:{getNumSleeves:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToShockRecovery:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToSynchronize:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToCommitCrime:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToUniversityCourse:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,travel:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToCompanyWork:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToFactionWork:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,setToGymWorkout:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,getSleeveStats:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,getTask:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,getInformation:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,getSleeveAugmentations:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,getSleevePurchasableAugs:()=>t.RamCostConstants.ScriptSleeveBaseRamCost,purchaseSleeveAug:()=>t.RamCostConstants.ScriptSleeveBaseRamCost},heart:{break:()=>0}},t.getRamCost=function(...e){if(0===e.length)return console.warn("No arguments passed to getRamCost()"),0;let n=t.RamCosts[e[0]];for(let t=1;t(ce.loadFactionContent(),Object(f.displayFactionContent)(n),!1)})),e.appendChild(Object(te.createElement)("br"))}();ce.Display.factionsContent.appendChild(e),ce.Display.factionsContent.appendChild(Object(te.createElement)("br")),ce.Display.factionsContent.appendChild(Object(te.createElement)("h1",{innerText:"Outstanding Faction Invitations"})),ce.Display.factionsContent.appendChild(Object(te.createElement)("p",{width:"70%",innerText:"Lists factions you have been invited to, as well as factions you have previously rejected. You can accept these faction invitations at any time."}));var n=Object(te.createElement)("ul");for(t=0;t{if(!t.isTrusted)return!1;Object(f.joinFaction)(y.Factions[e]);for(var n=0;n0&&(ce._lastUpdate=e-n,x.Player.lastUpdate=e-n,ce.updateGame(t)),window.requestAnimationFrame(ce.idleTimer)},updateGame:function(e=1){var t=e*ce._idleSpeed;null==x.Player.totalPlaytime&&(x.Player.totalPlaytime=0),null==x.Player.playtimeSinceLastAug&&(x.Player.playtimeSinceLastAug=0),null==x.Player.playtimeSinceLastBitnode&&(x.Player.playtimeSinceLastBitnode=0),x.Player.totalPlaytime+=t,x.Player.playtimeSinceLastAug+=t,x.Player.playtimeSinceLastBitnode+=t,!0===F.a.actionStarted&&(ce._totalActionTime=F.a.actionTime,ce._actionTimeLeft=F.a.actionTime,ce._actionInProgress=!0,ce._actionProgressBarCount=1,ce._actionProgressStr="[ ]",ce._actionTimeStr="Time left: ",F.a.actionStarted=!1),x.Player.isWorking&&(x.Player.workType==_.CONSTANTS.WorkTypeFaction?x.Player.workForFaction(e):x.Player.workType==_.CONSTANTS.WorkTypeCreateProgram?x.Player.createProgramWork(e):x.Player.workType==_.CONSTANTS.WorkTypeStudyClass?x.Player.takeClass(e):x.Player.workType==_.CONSTANTS.WorkTypeCrime?x.Player.commitCrime(e):x.Player.workType==_.CONSTANTS.WorkTypeCompanyPartTime?x.Player.workPartTime(e):x.Player.work(e)),x.Player.hasWseAccount&&Object(j.processStockPrices)(e),x.Player.inGang()&&x.Player.gang.process(e,x.Player),S.c&&S.b&&S.b.process(e),x.Player.corporation instanceof d.c&&x.Player.corporation.storeCycles(e),x.Player.bladeburner instanceof c.a&&x.Player.bladeburner.storeCycles(e);for(let t=0;t0?(t.innerHTML=e,t.setAttribute("class","notification-on")):(t.innerHTML="",t.setAttribute("class","notification-off")),ce.Counters.createProgramNotifications=10}if(ce.Counters.augmentationsNotifications<=0){e=x.Player.queuedAugmentations.length,t=document.getElementById("augmentations-notification");e>0?(t.innerHTML=e,t.setAttribute("class","notification-on")):(t.innerHTML="",t.setAttribute("class","notification-off")),ce.Counters.augmentationsNotifications=10}if(ce.Counters.checkFactionInvitations<=0){var n=x.Player.checkForFactionInvitations();if(n.length>0){!1===x.Player.firstFacInvRecvd&&(x.Player.firstFacInvRecvd=!0,document.getElementById("factions-tab").style.display="list-item",document.getElementById("character-menu-header").click(),document.getElementById("character-menu-header").click());var r=n[Math.floor(Math.random()*n.length)];Object(f.inviteToFaction)(r)}const e=x.Player.factionInvitations.length,t=document.getElementById("factions-notification");e>0?(t.innerHTML=e,t.setAttribute("class","notification-on")):(t.innerHTML="",t.setAttribute("class","notification-off")),ce.Counters.checkFactionInvitations=100}if(ce.Counters.passiveFactionGrowth<=0){var o=Math.floor(600-ce.Counters.passiveFactionGrowth);Object(f.processPassiveFactionRepGain)(o),ce.Counters.passiveFactionGrowth=600}if(ce.Counters.messages<=0&&(Object(T.b)(),i.Augmentations[s.AugmentationNames.TheRedPill].owned?ce.Counters.messages=4500:ce.Counters.messages=150),ce.Counters.mechanicProcess<=0){if(x.Player.corporation instanceof d.c&&x.Player.corporation.process(),x.Player.bladeburner instanceof c.a)try{x.Player.bladeburner.process()}catch(e){Object(ne.exceptionAlert)("Exception caught in Bladeburner.process(): "+e)}ce.Counters.mechanicProcess=5}ce.Counters.contractGeneration<=0&&(Math.random()<=.25&&Object(p.b)(),ce.Counters.contractGeneration=3e3)},_totalActionTime:0,_actionTimeLeft:0,_actionTimeStr:"Time left: ",_actionProgressStr:"[ ]",_actionProgressBarCount:1,_actionInProgress:!1,updateHackProgress:function(e=1){var t=e*ce._idleSpeed;ce._actionTimeLeft-=t/1e3,ce._actionTimeLeft=Math.max(ce._actionTimeLeft,0);for(var n=Math.round(100*(1-ce._actionTimeLeft/ce._totalActionTime));2*ce._actionProgressBarCount<=n;)ce._actionProgressStr=Object(r.replaceAt)(ce._actionProgressStr,ce._actionProgressBarCount,"|"),ce._actionProgressBarCount+=1;ce._actionTimeStr="Time left: "+Math.max(0,Math.round(ce._actionTimeLeft)).toString()+"s",document.getElementById("hack-progress").innerHTML=ce._actionTimeStr,document.getElementById("hack-progress-bar").innerHTML=ce._actionProgressStr.replace(/ /g," "),n>=100&&(ce._actionInProgress=!1,F.a.finishAction())},closeMainMenuHeader:function(e){for(var t=0;t"+Y.numeralWrapper.formatMoney(K)+" and your Hacknet Nodes generated "+e+"");var V=[t,n,a,s,p,g,A,R,B];x.Player.firstFacInvRecvd?V.push(u):u.style.display="none",x.Player.firstAugPurchased?V.push(m):m.style.display="none",""!==x.Player.companyName?V.push(C):C.style.display="none",x.Player.firstTimeTraveled?V.push(b):b.style.display="none",x.Player.firstProgramAvailable?V.push(i):i.style.display="none",x.Player.hasWseAccount?V.push(P):P.style.display="none",x.Player.bladeburner instanceof c.a?V.push(S):S.style.display="none",x.Player.corporation instanceof d.c?V.push(O):O.style.display="none",x.Player.inGang()?V.push(w):w.style.display="none",ce.closeMainMenuHeader(V)}else{Object(l.initBitNodeMultipliers)(x.Player),Object(W.initSpecialServerIps)(),ce.setDisplayElements(),ce.start(),x.Player.init(),Object(I.initForeignServers)(x.Player.getHomeComputer()),Object(h.initCompanies)(),Object(y.initFactions)(),Object(o.d)(),Object(T.c)(),Object(k.a)(),Object(L.updateSourceFileFlags)(x.Player),document.getElementById("hacking-menu-header").classList.toggle("opened"),document.getElementById("character-menu-header").classList.toggle("opened"),document.getElementById("world-menu-header").classList.toggle("opened"),document.getElementById("help-menu-header").classList.toggle("opened"),u.style.display="none",m.style.display="none",C.style.display="none",P.style.display="none",b.style.display="none",i.style.display="none",S.style.display="none",O.style.display="none",w.style.display="none",B.style.display="none",ce.openMainMenuHeader([t,n,a,s,p,g,A,R]),Object(v.c)(),Object(re.removeLoadingScreen)()}Object(z.a)(),Object(D.d)(),F.a.resetTerminalInput()},setDisplayElements:function(){if(ce.Display.terminalContent=document.getElementById("terminal-container"),q.routing.navigateTo(q.Page.Terminal),ce.Display.characterContent=document.getElementById("character-container"),ce.Display.characterContent.style.display="none",ce.Display.scriptEditorContent=document.getElementById("script-editor-container"),ce.Display.scriptEditorContent.style.display="none",ce.Display.activeScriptsContent=document.getElementById("active-scripts-container"),ce.Display.activeScriptsContent.style.display="none",ce.Display.hacknetNodesContent=document.getElementById("hacknet-nodes-container"),ce.Display.hacknetNodesContent.style.display="none",ce.Display.createProgramContent=document.getElementById("create-program-container"),ce.Display.createProgramContent.style.display="none",ce.Display.factionsContent=document.getElementById("factions-container"),ce.Display.factionsContent.style.display="none",ce.Display.factionContent=document.getElementById("faction-container"),ce.Display.factionContent.style.display="none",ce.Display.augmentationsContent=document.getElementById("augmentations-container"),ce.Display.augmentationsContent.style.display="none",ce.Display.tutorialContent=document.getElementById("tutorial-container"),ce.Display.tutorialContent.style.display="none",ce.Display.infiltrationContent=document.getElementById("infiltration-container"),ce.Display.infiltrationContent.style.display="none",ce.Display.stockMarketContent=document.getElementById("stock-market-container"),ce.Display.stockMarketContent.style.display="none",ce.Display.missionContent=document.getElementById("mission-container"),ce.Display.missionContent.style.display="none",ce.Display.characterInfo=document.getElementById("character-content"),ce.Display.locationContent=document.getElementById("location-container"),ce.Display.locationContent.style.display="none",ce.Display.workInProgressContent=document.getElementById("work-in-progress-container"),ce.Display.workInProgressContent.style.display="none",ce.Display.redPillContent=document.getElementById("red-pill-container"),ce.Display.redPillContent.style.display="none",ce.Display.cinematicTextContent=document.getElementById("cinematic-text-container"),ce.Display.cinematicTextContent.style.display="none",!Object(X.initializeMainMenuLinks)()){const e="Failed to initialize Main Menu Links. Please try refreshing the page. If that doesn't work, report the issue to the developer";return Object(ne.exceptionAlert)(new Error(e)),void console.error(e)}},init:function(){if(document.getElementById("import-game-link").onclick=function(){N.b.importGame()},!Object(J.initializeMainMenuHeaders)(x.Player,!1)){const e="Failed to initialize Main Menu Headers. Please try refreshing the page. If that doesn't work, report the issue to the developer";return Object(ne.exceptionAlert)(new Error(e)),void console.error(e)}(X.MainMenuLinks.Terminal.addEventListener("click",function(){return ce.loadTerminalContent(),!1}),X.MainMenuLinks.ScriptEditor.addEventListener("click",function(){return ce.loadScriptEditorContent(),!1}),X.MainMenuLinks.ActiveScripts.addEventListener("click",function(){return ce.loadActiveScriptsContent(),!1}),X.MainMenuLinks.CreateProgram.addEventListener("click",function(){return ce.loadCreateProgramContent(),!1}),X.MainMenuLinks.Stats.addEventListener("click",function(){return ce.loadCharacterContent(),!1}),X.MainMenuLinks.Factions.addEventListener("click",function(){return ce.loadFactionsContent(),!1}),X.MainMenuLinks.Augmentations.addEventListener("click",function(){return ce.loadAugmentationsContent(),!1}),X.MainMenuLinks.HacknetNodes.addEventListener("click",function(){return ce.loadHacknetNodesContent(),!1}),X.MainMenuLinks.Sleeves.addEventListener("click",function(){return ce.loadSleevesContent(),X.MainMenuLinks.Sleeves.classList.add("active"),!1}),X.MainMenuLinks.City.addEventListener("click",function(){return ce.loadLocationContent(),!1}),X.MainMenuLinks.Travel.addEventListener("click",function(){return ce.loadTravelContent(),!1}),X.MainMenuLinks.Job.addEventListener("click",function(){return ce.loadJobContent(),!1}),X.MainMenuLinks.StockMarket.addEventListener("click",function(){return ce.loadStockMarketContent(),X.MainMenuLinks.StockMarket.classList.add("active"),!1}),X.MainMenuLinks.Bladeburner.addEventListener("click",function(){return ce.loadBladeburnerContent(),!1}),X.MainMenuLinks.Corporation.addEventListener("click",function(){return ce.loadCorporationContent(),X.MainMenuLinks.Corporation.classList.add("active"),!1}),X.MainMenuLinks.Gang.addEventListener("click",function(){return ce.loadGangContent(),!1}),X.MainMenuLinks.Tutorial.addEventListener("click",function(){return ce.loadTutorialContent(),!1}),X.MainMenuLinks.DevMenu.addEventListener("click",function(){return!1}),ce.ActiveScriptsList=document.getElementById("active-scripts-list"),ce.Clickables.saveMainMenuButton=document.getElementById("save-game-link"),ce.Clickables.saveMainMenuButton.addEventListener("click",function(){return N.b.saveGame(ue),!1}),ce.Clickables.deleteMainMenuButton=document.getElementById("delete-game-link"),ce.Clickables.deleteMainMenuButton.addEventListener("click",function(){return N.b.deleteGame(ue),!1}),document.getElementById("export-game-link").addEventListener("click",function(){return N.b.exportGame(),!1}),document.getElementById("character-overview-save-button").addEventListener("click",function(){return N.b.saveGame(ue),!1}),document.getElementById("character-overview-options-button").addEventListener("click",function(){return Object(Z.b)(),!1}),Object(A.c)(),Object(F.b)(),x.Player.isWorking)&&(document.getElementById("work-in-progress-cancel-button").addEventListener("click",function(){if(x.Player.workType==_.CONSTANTS.WorkTypeFaction){y.Factions[x.Player.currentWorkFactionName];x.Player.finishFactionWork(!0)}else x.Player.workType==_.CONSTANTS.WorkTypeCreateProgram?x.Player.finishCreateProgramWork(!0):x.Player.workType==_.CONSTANTS.WorkTypeStudyClass?x.Player.finishClass():x.Player.workType==_.CONSTANTS.WorkTypeCrime?x.Player.finishCrime(!0):x.Player.workType==_.CONSTANTS.WorkTypeCompanyPartTime?x.Player.finishWorkPartTime():x.Player.finishWork(!0)}),ce.loadWorkInProgressContent());document.getElementById("character-overview-container").style.display="block",document.getElementById("terminal-menu-link").removeAttribute("class"),document.getElementById("stats-menu-link").removeAttribute("class"),document.getElementById("create-script-menu-link").removeAttribute("class"),document.getElementById("active-scripts-menu-link").removeAttribute("class"),document.getElementById("hacknet-nodes-menu-link").removeAttribute("class"),document.getElementById("city-menu-link").removeAttribute("class"),document.getElementById("tutorial-menu-link").removeAttribute("class"),document.getElementById("copy-save-to-clipboard-link").addEventListener("click",function(){const e=N.b.getSaveString();if(navigator.clipboard)navigator.clipboard.writeText(e).then(function(){Object(K.createStatusText)("Copied save to clipboard")},function(e){console.error("Unable to copy save data to clipboard using Async API"),Object(K.createStatusText)("Failed to copy save")});else{const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="absolute",t.left="-9999px",document.body.appendChild(t),t.focus(),t.select();try{document.execCommand("copy")?Object(K.createStatusText)("Copied save to clipboard"):Object(K.createStatusText)("Failed to copy save")}catch(e){console.error("Unable to copy save data to clipboard using document.execCommand('copy')"),Object(K.createStatusText)("Failed to copy save")}document.body.removeChild(t)}}),document.getElementById("debug-delete-scripts-link").addEventListener("click",function(){return x.Player.getHomeComputer().runningScripts=[],Object(Q.dialogBoxCreate)("Forcefully deleted all running scripts on home computer. Please save and refresh page"),Object(Z.a)(),!1}),document.getElementById("debug-soft-reset").addEventListener("click",function(){return Object(Q.dialogBoxCreate)("Soft Reset!"),Object(w.a)(),Object(Z.a)(),!1})},start:function(){ce.idleTimer()}};var ue,me;window.onload=function(){if(!window.indexedDB)return ce.load(null);(me=window.indexedDB.open("bitburnerSave",1)).onerror=function(e){return console.error("Error opening indexedDB: "),console.error(e),ce.load(null)},me.onsuccess=function(e){var t=(ue=e.target.result).transaction(["savestring"]).objectStore("savestring").get("save");t.onerror=function(e){return console.error("Error in Database request to get savestring: "+e),ce.load(null)},t.onsuccess=function(e){ce.load(t.result)}},me.onupgradeneeded=function(e){e.target.result.createObjectStore("savestring")}}}.call(this,n(83))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(73),a=n(257),i=n(16);function o(e){const n=e.name;t.Factions[n]=e}function s(e){return t.Factions.hasOwnProperty(e)}function l(e){if(!(e instanceof r.Faction))throw new Error("Invalid argument 'newFactionObject' passed into resetFaction()");const n=e.name;s(n)&&(e.favor=t.Factions[n].favor,delete t.Factions[n]),o(e)}t.Factions={},t.loadFactions=function(e){t.Factions=JSON.parse(e,i.Reviver)},t.AddToFactions=o,t.factionExists=s,t.initFactions=function(e=1){for(const e in a.FactionInfos)l(new r.Faction(e))},t.resetFaction=l},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getRandomInt=function(e,t){const n=Math.min(e,t),r=Math.max(e,t);return Math.floor(Math.random()*(r-n+1))+n}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(6),a=n(18),i=n(13),o=n(16);class s{constructor(e={info:"",moneyCost:0,name:"",repCost:0}){this.baseCost=0,this.baseRepRequirement=0,this.info="",this.isSpecial=!1,this.level=0,this.name="",this.owned=!1,this.prereqs=[],this.mults={},this.startingCost=0,this.name=e.name,this.info=e.info,this.prereqs=e.prereqs?e.prereqs:[],this.baseRepRequirement=e.repCost*r.CONSTANTS.AugmentationRepMultiplier*a.BitNodeMultipliers.AugmentationRepCost,this.baseCost=e.moneyCost*r.CONSTANTS.AugmentationCostMultiplier*a.BitNodeMultipliers.AugmentationMoneyCost,this.startingCost=this.baseCost,e.isSpecial&&(this.isSpecial=!0),this.level=0,e.hacking_mult&&(this.mults.hacking_mult=e.hacking_mult),e.strength_mult&&(this.mults.strength_mult=e.strength_mult),e.defense_mult&&(this.mults.defense_mult=e.defense_mult),e.dexterity_mult&&(this.mults.dexterity_mult=e.dexterity_mult),e.agility_mult&&(this.mults.agility_mult=e.agility_mult),e.charisma_mult&&(this.mults.charisma_mult=e.charisma_mult),e.hacking_exp_mult&&(this.mults.hacking_exp_mult=e.hacking_exp_mult),e.strength_exp_mult&&(this.mults.strength_exp_mult=e.strength_exp_mult),e.defense_exp_mult&&(this.mults.defense_exp_mult=e.defense_exp_mult),e.dexterity_exp_mult&&(this.mults.dexterity_exp_mult=e.dexterity_exp_mult),e.agility_exp_mult&&(this.mults.agility_exp_mult=e.agility_exp_mult),e.charisma_exp_mult&&(this.mults.charisma_exp_mult=e.charisma_exp_mult),e.hacking_chance_mult&&(this.mults.hacking_chance_mult=e.hacking_chance_mult),e.hacking_speed_mult&&(this.mults.hacking_speed_mult=e.hacking_speed_mult),e.hacking_money_mult&&(this.mults.hacking_money_mult=e.hacking_money_mult),e.hacking_grow_mult&&(this.mults.hacking_grow_mult=e.hacking_grow_mult),e.company_rep_mult&&(this.mults.company_rep_mult=e.company_rep_mult),e.faction_rep_mult&&(this.mults.faction_rep_mult=e.faction_rep_mult),e.crime_money_mult&&(this.mults.crime_money_mult=e.crime_money_mult),e.crime_success_mult&&(this.mults.crime_success_mult=e.crime_success_mult),e.work_money_mult&&(this.mults.work_money_mult=e.work_money_mult),e.hacknet_node_money_mult&&(this.mults.hacknet_node_money_mult=e.hacknet_node_money_mult),e.hacknet_node_purchase_cost_mult&&(this.mults.hacknet_node_purchase_cost_mult=e.hacknet_node_purchase_cost_mult),e.hacknet_node_ram_cost_mult&&(this.mults.hacknet_node_ram_cost_mult=e.hacknet_node_ram_cost_mult),e.hacknet_node_core_cost_mult&&(this.mults.hacknet_node_core_cost_mult=e.hacknet_node_core_cost_mult),e.hacknet_node_level_cost_mult&&(this.mults.hacknet_node_level_cost_mult=e.hacknet_node_level_cost_mult),e.bladeburner_max_stamina_mult&&(this.mults.bladeburner_max_stamina_mult=e.bladeburner_max_stamina_mult),e.bladeburner_stamina_gain_mult&&(this.mults.bladeburner_stamina_gain_mult=e.bladeburner_stamina_gain_mult),e.bladeburner_analysis_mult&&(this.mults.bladeburner_analysis_mult=e.bladeburner_analysis_mult),e.bladeburner_success_chance_mult&&(this.mults.bladeburner_success_chance_mult=e.bladeburner_success_chance_mult)}static fromJSON(e){return o.Generic_fromJSON(s,e.data)}addToFactions(e){for(let t=0;t{switch(typeof e){case"number":return e;case"object":return s.getRandomInt(e.min,e.max);default:throw Error(`Do not know how to convert the type '${typeof e}' to a number`)}};for(const e of i.serverMetadata){const i={hostname:e.hostname,ip:u(),numOpenPortsRequired:e.numOpenPortsRequired,organizationName:e.organizationName};void 0!==e.maxRamExponent&&(i.maxRam=Math.pow(2,o(e.maxRamExponent)));for(const t of n)void 0!==e[t]&&(i[t]=o(e[t]));const s=new r.Server(i);for(const t of e.literature||[])s.messages.push(t);void 0!==e.specialName&&a.SpecialServerIps.addIp(e.specialName,s.ip),m(s),void 0!==e.networkLayer&&t[o(e.networkLayer)-1].push(s)}const l=(e,t)=>{e.serversOnNetwork.push(t.ip),t.serversOnNetwork.push(e.ip)},c=e=>e[Math.floor(Math.random()*e.length)],p=(e,t)=>{for(const n of e)l(n,t())};p(t[0],()=>e);for(let e=1;ec(t[e-1]))},t.prestigeAllServers=function(){for(var e in t.AllServers)delete t.AllServers[e];t.AllServers={}},t.loadAllServers=function(e){t.AllServers=JSON.parse(e,l.Reviver)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EmployeePositions={Operations:"Operations",Engineer:"Engineer",Business:"Business",Management:"Management",RandD:"Research & Development",Training:"Training",Unassigned:"Unassigned"}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(19),a=n(110),i=n(18),o=n(6),s=n(31),l=n(656),c=n(163);function u(e,t,n){let r=1+(o.CONSTANTS.ServerBaseGrowthRate-1)/e.hackDifficulty;r>o.CONSTANTS.ServerMaxGrowthRate&&(r=o.CONSTANTS.ServerMaxGrowthRate);const a=e.serverGrowth/100;return Math.log(t)/(Math.log(r)*n.hacking_grow_mult*a*i.BitNodeMultipliers.ServerGrowthRate)}function m(e){for(var t in r.AllServers)if(r.AllServers.hasOwnProperty(t)&&r.AllServers[t].hostname==e)return r.AllServers[t];return null}t.safetlyCreateUniqueServer=function(e){if(null!=e.ip&&r.ipExists(e.ip)&&(e.ip=r.createUniqueRandomIp()),null!=m(e.hostname)){let t=e.hostname;for(let n=0;n<200&&null!=m(t=`${e.hostname}-${n}`);++n);e.hostname=t}return new a.Server(e)},t.numCycleForGrowth=u,t.processSingleServerGrowth=function(e,t,n){const r=Math.max(Math.floor(t/450),0);var a=1+(o.CONSTANTS.ServerBaseGrowthRate-1)/e.hackDifficulty;a>o.CONSTANTS.ServerMaxGrowthRate&&(a=o.CONSTANTS.ServerMaxGrowthRate);const s=r*(e.serverGrowth/100)*i.BitNodeMultipliers.ServerGrowthRate;let c=Math.pow(a,s*n.hacking_grow_mult);c<1&&(console.warn("serverGrowth calculated to be less than 1"),c=1);const m=e.moneyAvailable;if(e.moneyAvailable*=c,l.isValidNumber(e.moneyMax)&&isNaN(e.moneyAvailable)&&(e.moneyAvailable=e.moneyMax),l.isValidNumber(e.moneyMax)&&e.moneyAvailable>e.moneyMax&&(e.moneyAvailable=e.moneyMax),m!==e.moneyAvailable){let t=u(e,e.moneyAvailable/m,n);t=Math.max(0,t),e.fortify(2*o.CONSTANTS.ServerFortifyAmount*Math.ceil(t))}return e.moneyAvailable/m},t.prestigeHomeComputer=function(e){const t=e.programs.includes(s.Programs.BitFlume.name);e.programs.length=0,e.runningScripts=[],e.serversOnNetwork=[],e.isConnectedTo=!0,e.ramUsed=0,e.programs.push(s.Programs.NukeProgram.name),t&&e.programs.push(s.Programs.BitFlume.name),e.scripts.forEach(function(t){t.updateRamUsage(e.scripts)}),e.messages.length=0,e.messages.push("hackers-starting-handbook.lit")},t.GetServerByHostname=m,t.getServer=function(e){return c.isValidIPAddress(e)?void 0!==r.AllServers[e]?r.AllServers[e]:null:m(e)},t.getServerOnNetwork=function(e,t){if(!(t>e.serversOnNetwork.length))return r.AllServers[e.serversOnNetwork[t]];console.error("Tried to get server on network that was out of range")}},function(e,t,n){"use strict";n.d(t,"h",function(){return E}),n.d(t,"m",function(){return v}),n.d(t,"i",function(){return k}),n.d(t,"b",function(){return C}),n.d(t,"c",function(){return P}),n.d(t,"f",function(){return T}),n.d(t,"g",function(){return S}),n.d(t,"e",function(){return O}),n.d(t,"d",function(){return M}),n.d(t,"o",function(){return x}),n.d(t,"p",function(){return w}),n.d(t,"l",function(){return A}),n.d(t,"k",function(){return R}),n.d(t,"q",function(){return N}),n.d(t,"a",function(){return D}),n.d(t,"j",function(){return I}),n.d(t,"r",function(){return L}),n.d(t,"n",function(){return W});var r=n(52),a=n(32),i=n(102),o=n(137),s=n(117),l=n(38),c=n(0),u=n(19),m=n(21),p=n(37),h=n(11),d=(n(109),n(1)),_=n.n(d),g=n(50),y=n.n(g),f=n(172);let b;function E(){return 9===c.Player.bitNodeN||p.SourceFileFlags[9]>0}function v(){if(l.a.isRunning){if(l.a.currStep!==l.d.HacknetNodesIntroduction)return;Object(l.b)()}const e=c.Player.hacknetNodes.length;if(E()){const t=P();if(isNaN(t))throw new Error("Calculated cost of purchasing HacknetServer is NaN");if(!c.Player.canAfford(t))return-1;c.Player.loseMoney(t);c.Player.createHacknetServer();return L(),e}{const t=C();if(isNaN(t))throw new Error("Calculated cost of purchasing HacknetNode is NaN");if(!c.Player.canAfford(t))return-1;const n="hacknet-node-"+e,a=new r.HacknetNode(n,c.Player.hacknet_node_money_mult);return c.Player.loseMoney(t),c.Player.hacknetNodes.push(a),e}}function k(){return E()&&c.Player.hacknetNodes.length>=a.MaxNumberHacknetServers}function C(){const e=c.Player.hacknetNodes.length,t=r.HacknetNodePurchaseNextMult;return r.BaseCostForHacknetNode*Math.pow(t,e)*c.Player.hacknet_node_purchase_cost_mult}function P(){const e=c.Player.hacknetNodes.length,t=a.HacknetServerPurchaseMult;return e>=a.MaxNumberHacknetServers?1/0:a.BaseCostForHacknetServer*Math.pow(t,e)*c.Player.hacknet_node_purchase_cost_mult}function T(e,t){if(null==t)throw new Error("getMaxNumberLevelUpgrades() called without maxLevel arg");if(c.Player.money.lt(e.calculateLevelUpgradeCost(1,c.Player.hacknet_node_level_cost_mult)))return 0;let n=1,r=t-1,a=t-e.level;if(c.Player.money.gt(e.calculateLevelUpgradeCost(a,c.Player.hacknet_node_level_cost_mult)))return a;for(;n<=r;){var i=(n+r)/2|0;if(i!==t&&c.Player.money.gt(e.calculateLevelUpgradeCost(i,c.Player.hacknet_node_level_cost_mult))&&c.Player.money.lt(e.calculateLevelUpgradeCost(i+1,c.Player.hacknet_node_level_cost_mult)))return Math.min(a,i);if(c.Player.money.lt(e.calculateLevelUpgradeCost(i,c.Player.hacknet_node_level_cost_mult)))r=i-1;else{if(!c.Player.money.gt(e.calculateLevelUpgradeCost(i,c.Player.hacknet_node_level_cost_mult)))return Math.min(a,i);n=i+1}}return 0}function S(e,t){if(null==t)throw new Error("getMaxNumberRamUpgrades() called without maxLevel arg");if(c.Player.money.lt(e.calculateRamUpgradeCost(1,c.Player.hacknet_node_ram_cost_mult)))return 0;let n;if(n=e instanceof a.HacknetServer?Math.round(Math.log2(t/e.maxRam)):Math.round(Math.log2(t/e.ram)),c.Player.money.gt(e.calculateRamUpgradeCost(n,c.Player.hacknet_node_ram_cost_mult)))return n;for(let t=n-1;t>=0;--t)if(c.Player.money.gt(e.calculateRamUpgradeCost(t,c.Player.hacknet_node_ram_cost_mult)))return t;return 0}function O(e,t){if(null==t)throw new Error("getMaxNumberCoreUpgrades() called without maxLevel arg");if(c.Player.money.lt(e.calculateCoreUpgradeCost(1,c.Player.hacknet_node_core_cost_mult)))return 0;let n=1,r=t-1;const a=t-e.cores;if(c.Player.money.gt(e.calculateCoreUpgradeCost(a,c.Player.hacknet_node_core_cost_mult)))return a;for(;n<=r;){let i=(n+r)/2|0;if(i!=t&&c.Player.money.gt(e.calculateCoreUpgradeCost(i,c.Player.hacknet_node_core_cost_mult))&&c.Player.money.lt(e.calculateCoreUpgradeCost(i+1,c.Player.hacknet_node_core_cost_mult)))return Math.min(a,i);if(c.Player.money.lt(e.calculateCoreUpgradeCost(i,c.Player.hacknet_node_core_cost_mult)))r=i-1;else{if(!c.Player.money.gt(e.calculateCoreUpgradeCost(i,c.Player.hacknet_node_core_cost_mult)))return Math.min(a,i);n=i+1}}return 0}function M(e,t){if(null==t)throw new Error("getMaxNumberCacheUpgrades() called without maxLevel arg");if(!c.Player.canAfford(e.calculateCacheUpgradeCost(1)))return 0;let n=1,r=t-1;const a=t-e.cache;if(c.Player.canAfford(e.calculateCacheUpgradeCost(a)))return a;for(;n<=r;){let i=(n+r)/2|0;if(i!=t&&c.Player.canAfford(e.calculateCacheUpgradeCost(i))&&!c.Player.canAfford(e.calculateCacheUpgradeCost(i+1)))return Math.min(a,i);if(c.Player.canAfford(e.calculateCacheUpgradeCost(i))){if(!c.Player.canAfford(e.calculateCacheUpgradeCost(i)))return Math.min(a,i);n=i+1}else r=i-1}return 0}function x(e,t=1){const n=Math.round(t),i=e.calculateLevelUpgradeCost(n,c.Player.hacknet_node_level_cost_mult);if(isNaN(i)||i<=0||n<0)return!1;const o=e instanceof a.HacknetServer;if(e.level>=(o?a.HacknetServerMaxLevel:r.HacknetNodeMaxLevel))return!1;if(e.level+n>(o?a.HacknetServerMaxLevel:r.HacknetNodeMaxLevel)){return x(e,Math.max(0,(o?a.HacknetServerMaxLevel:r.HacknetNodeMaxLevel)-e.level))}return!!c.Player.canAfford(i)&&(c.Player.loseMoney(i),e.upgradeLevel(n,c.Player.hacknet_node_money_mult),!0)}function w(e,t=1){const n=Math.round(t),i=e.calculateRamUpgradeCost(n,c.Player.hacknet_node_ram_cost_mult);if(isNaN(i)||i<=0||n<0)return!1;const o=e instanceof a.HacknetServer;if(e.ram>=(o?a.HacknetServerMaxRam:r.HacknetNodeMaxRam))return!1;if(o){if(e.maxRam*Math.pow(2,n)>a.HacknetServerMaxRam){return w(e,Math.max(0,Math.log2(Math.round(a.HacknetServerMaxRam/e.maxRam))))}}else if(e.ram*Math.pow(2,n)>r.HacknetNodeMaxRam){return w(e,Math.max(0,Math.log2(Math.round(r.HacknetNodeMaxRam/e.ram))))}return!!c.Player.canAfford(i)&&(c.Player.loseMoney(i),e.upgradeRam(n,c.Player.hacknet_node_money_mult),!0)}function A(e,t=1){const n=Math.round(t),i=e.calculateCoreUpgradeCost(n,c.Player.hacknet_node_core_cost_mult);if(isNaN(i)||i<=0||n<0)return!1;const o=e instanceof a.HacknetServer;if(e.cores>=(o?a.HacknetServerMaxCores:r.HacknetNodeMaxCores))return!1;if(e.cores+n>(o?a.HacknetServerMaxCores:r.HacknetNodeMaxCores)){return A(e,Math.max(0,(o?a.HacknetServerMaxCores:r.HacknetNodeMaxCores)-e.cores))}return!!c.Player.canAfford(i)&&(c.Player.loseMoney(i),e.upgradeCore(n,c.Player.hacknet_node_money_mult),!0)}function R(e,t=1){const n=Math.round(t),r=e.calculateCacheUpgradeCost(n);if(isNaN(r)||r<=0||n<0)return!1;if(!(e instanceof a.HacknetServer))return console.warn("purchaseCacheUpgrade() called for a non-HacknetNode"),!1;if(e.cache+n>a.HacknetServerMaxCache){return R(e,Math.max(0,a.HacknetServerMaxCache-e.cache))}return!!c.Player.canAfford(r)&&(c.Player.loseMoney(r),e.upgradeCache(n),!0)}function N(){h.routing.isOn(h.Page.HacknetNodes)&&y.a.render(_.a.createElement(f.a,null),b)}function D(){b instanceof HTMLElement&&y.a.unmountComponentAtNode(b),b.style.display="none"}function I(e){return 0===c.Player.hacknetNodes.length?0:E()?function(e){if(!(c.Player.hashManager instanceof i.HashManager))throw new Error("Player does not have a HashManager (should be in 'hashManager' prop)");let t=0;for(let n=0;n{!function(e){null!=t.Companies[e.name]&&console.warn(`Duplicate Company Position being defined: ${e.name}`),t.Companies[e.name]=new a.Company(e)}(e)});for(const n in t.Companies){const r=t.Companies[n];e[n]instanceof a.Company?(r.favor=e[n].favor,isNaN(r.favor)&&(r.favor=0)):r.favor=0}},t.loadCompanies=function(e){t.Companies=JSON.parse(e,i.Reviver)},t.companyExists=function(e){return t.Companies.hasOwnProperty(e)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(697),a=n(2);t.Industries={Energy:"Energy",Utilities:"Water Utilities",Agriculture:"Agriculture",Fishing:"Fishing",Mining:"Mining",Food:"Food",Tobacco:"Tobacco",Chemical:"Chemical",Pharmaceutical:"Pharmaceutical",Computer:"Computer Hardware",Robotics:"Robotics",Software:"Software",Healthcare:"Healthcare",RealEstate:"RealEstate"},t.IndustryStartingCosts={Energy:225e9,Utilities:15e10,Agriculture:4e10,Fishing:8e10,Mining:3e11,Food:1e10,Tobacco:2e10,Chemical:7e10,Pharmaceutical:2e11,Computer:5e11,Robotics:1e12,Software:25e9,Healthcare:75e10,RealEstate:6e11},t.IndustryDescriptions={Energy:"Engage in the production and distribution of energy.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Energy,"$0.000a")+"
Recommended starting Industry: NO",Utilities:"Distribute water and provide wastewater services.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Utilities,"$0.000a")+"
Recommended starting Industry: NO",Agriculture:"Cultivate crops and breed livestock to produce food.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Agriculture,"$0.000a")+"
Recommended starting Industry: YES",Fishing:"Produce food through the breeding and processing of fish and fish products.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Fishing,"$0.000a")+"
Recommended starting Industry: NO",Mining:"Extract and process metals from the earth.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Mining,"$0.000a")+"
Recommended starting Industry: NO",Food:"Create your own restaurants all around the world.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Food,"$0.000a")+"
Recommended starting Industry: YES",Tobacco:"Create and distribute tobacco and tobacco-related products.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Tobacco,"$0.000a")+"
Recommended starting Industry: YES",Chemical:"Produce industrial chemicals.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Chemical,"$0.000a")+"
Recommended starting Industry: NO",Pharmaceutical:"Discover, develop, and create new pharmaceutical drugs.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Pharmaceutical,"$0.000a")+"
Recommended starting Industry: NO",Computer:"Develop and manufacture new computer hardware and networking infrastructures.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Computer,"$0.000a")+"
Recommended starting Industry: NO",Robotics:"Develop and create robots.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Robotics,"$0.000a")+"
Recommended starting Industry: NO",Software:"Develop computer software and create AI Cores.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Software,"$0.000a")+"
Recommended starting Industry: YES",Healthcare:"Create and manage hospitals.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.Healthcare,"$0.000a")+"
Recommended starting Industry: NO",RealEstate:"Develop and manage real estate properties.

Starting cost: "+a.numeralWrapper.format(t.IndustryStartingCosts.RealEstate,"$0.000a")+"
Recommended starting Industry: NO"},t.IndustryResearchTrees={Energy:r.getBaseResearchTreeCopy(),Utilities:r.getBaseResearchTreeCopy(),Agriculture:r.getBaseResearchTreeCopy(),Fishing:r.getBaseResearchTreeCopy(),Mining:r.getBaseResearchTreeCopy(),Food:r.getProductIndustryResearchTreeCopy(),Tobacco:r.getProductIndustryResearchTreeCopy(),Chemical:r.getBaseResearchTreeCopy(),Pharmaceutical:r.getProductIndustryResearchTreeCopy(),Computer:r.getProductIndustryResearchTreeCopy(),Robotics:r.getProductIndustryResearchTreeCopy(),Software:r.getProductIndustryResearchTreeCopy(),Healthcare:r.getProductIndustryResearchTreeCopy(),RealEstate:r.getProductIndustryResearchTreeCopy()},t.resetIndustryResearchTrees=function(){t.IndustryResearchTrees.Energy=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Utilities=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Agriculture=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Fishing=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Mining=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Food=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Tobacco=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Chemical=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Pharmaceutical=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Computer=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Robotics=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Software=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.Healthcare=r.getBaseResearchTreeCopy(),t.IndustryResearchTrees.RealEstate=r.getBaseResearchTreeCopy()}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.KEY={A:65,B:66,C:67,CTRL:17,D:68,DOWNARROW:40,E:69,ENTER:13,ESC:27,F:70,H:72,J:74,K:75,L:76,M:77,N:78,O:79,P:80,R:82,S:83,TAB:9,U:85,UPARROW:38,W:87,1:49,2:50}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(109),a=n(80);t.removeElementById=function(e){try{const t=r.getElementById(e);a.removeElement(t)}catch(e){}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){e.Aevum="Aevum",e.Chongqing="Chongqing",e.Ishima="Ishima",e.NewTokyo="New Tokyo",e.Sector12="Sector-12",e.Volhaven="Volhaven"}(t.CityName||(t.CityName={}))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(109);t.clearEventListeners=function(e){try{let t;const n=(t="string"==typeof e?r.getElementById(e):e).cloneNode(!0);return null!==t.parentNode&&t.parentNode.replaceChild(n,t),n}catch(e){return console.error(e),null}}},function(module,__webpack_exports__,__webpack_require__){"use strict";(function($){__webpack_require__.d(__webpack_exports__,"f",function(){return IssueNewSharesCooldown}),__webpack_require__.d(__webpack_exports__,"k",function(){return SellSharesCooldown}),__webpack_require__.d(__webpack_exports__,"m",function(){return WarehouseInitialCost}),__webpack_require__.d(__webpack_exports__,"n",function(){return WarehouseInitialSize}),__webpack_require__.d(__webpack_exports__,"o",function(){return WarehouseUpgradeBaseCost}),__webpack_require__.d(__webpack_exports__,"g",function(){return OfficeInitialCost}),__webpack_require__.d(__webpack_exports__,"h",function(){return OfficeInitialSize}),__webpack_require__.d(__webpack_exports__,"a",function(){return BribeThreshold}),__webpack_require__.d(__webpack_exports__,"b",function(){return BribeToRepRatio}),__webpack_require__.d(__webpack_exports__,"j",function(){return ProductProductionCostRatio}),__webpack_require__.d(__webpack_exports__,"d",function(){return DividendMaxPercentage}),__webpack_require__.d(__webpack_exports__,"c",function(){return Corporation}),__webpack_require__.d(__webpack_exports__,"e",function(){return Industry}),__webpack_require__.d(__webpack_exports__,"i",function(){return OfficeSpace});var _CorporationState__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(210),_CorporationState__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(_CorporationState__WEBPACK_IMPORTED_MODULE_0__),_data_CorporationUnlockUpgrades__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(175),_data_CorporationUnlockUpgrades__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_data_CorporationUnlockUpgrades__WEBPACK_IMPORTED_MODULE_1__),_data_CorporationUpgrades__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(174),_data_CorporationUpgrades__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_data_CorporationUpgrades__WEBPACK_IMPORTED_MODULE_2__),_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(20),_EmployeePositions__WEBPACK_IMPORTED_MODULE_3___default=__webpack_require__.n(_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__),_IndustryData__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(24),_IndustryData__WEBPACK_IMPORTED_MODULE_4___default=__webpack_require__.n(_IndustryData__WEBPACK_IMPORTED_MODULE_4__),_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(154),_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5___default=__webpack_require__.n(_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5__),_Material__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(149),_Material__WEBPACK_IMPORTED_MODULE_6___default=__webpack_require__.n(_Material__WEBPACK_IMPORTED_MODULE_6__),_MaterialSizes__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(93),_MaterialSizes__WEBPACK_IMPORTED_MODULE_7___default=__webpack_require__.n(_MaterialSizes__WEBPACK_IMPORTED_MODULE_7__),_Product__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(128),_Product__WEBPACK_IMPORTED_MODULE_8___default=__webpack_require__.n(_Product__WEBPACK_IMPORTED_MODULE_8__),_ResearchMap__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(167),_ResearchMap__WEBPACK_IMPORTED_MODULE_9___default=__webpack_require__.n(_ResearchMap__WEBPACK_IMPORTED_MODULE_9__),_Warehouse__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(87),_Warehouse__WEBPACK_IMPORTED_MODULE_10___default=__webpack_require__.n(_Warehouse__WEBPACK_IMPORTED_MODULE_10__);__webpack_require__.d(__webpack_exports__,"l",function(){return _Warehouse__WEBPACK_IMPORTED_MODULE_10__.Warehouse});var _BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(18),_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11___default=__webpack_require__.n(_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11__),_Constants__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(6),_Constants__WEBPACK_IMPORTED_MODULE_12___default=__webpack_require__.n(_Constants__WEBPACK_IMPORTED_MODULE_12__),_Faction_Factions__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(13),_Faction_Factions__WEBPACK_IMPORTED_MODULE_13___default=__webpack_require__.n(_Faction_Factions__WEBPACK_IMPORTED_MODULE_13__),_Literature__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(127),_Locations_Cities__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(99),_Locations_Cities__WEBPACK_IMPORTED_MODULE_15___default=__webpack_require__.n(_Locations_Cities__WEBPACK_IMPORTED_MODULE_15__),_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(27),_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16___default=__webpack_require__.n(_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__),_Player__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(0),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(2),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18___default=__webpack_require__.n(_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(11),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19___default=__webpack_require__.n(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__),_utils_calculateEffectWithFactors__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(304),_utils_calculateEffectWithFactors__WEBPACK_IMPORTED_MODULE_20___default=__webpack_require__.n(_utils_calculateEffectWithFactors__WEBPACK_IMPORTED_MODULE_20__),_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(8),_utils_uiHelpers_clearSelector__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(202),_utils_uiHelpers_clearSelector__WEBPACK_IMPORTED_MODULE_22___default=__webpack_require__.n(_utils_uiHelpers_clearSelector__WEBPACK_IMPORTED_MODULE_22__),_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(16),_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(76),_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24___default=__webpack_require__.n(_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24__),_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__=__webpack_require__(3),_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25___default=__webpack_require__.n(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__),_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__=__webpack_require__(35),_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26___default=__webpack_require__.n(_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__),_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27__=__webpack_require__(55),_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27___default=__webpack_require__.n(_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27__),_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__=__webpack_require__(7),_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28___default=__webpack_require__.n(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__),_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__=__webpack_require__(14),_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29___default=__webpack_require__.n(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__),_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__=__webpack_require__(46),_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30___default=__webpack_require__.n(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__),_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__=__webpack_require__(25),_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31___default=__webpack_require__.n(_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__),_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32__=__webpack_require__(80),_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32___default=__webpack_require__.n(_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32__),_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__=__webpack_require__(26),_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33___default=__webpack_require__.n(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__),_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__=__webpack_require__(43),_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34___default=__webpack_require__.n(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__),react__WEBPACK_IMPORTED_MODULE_35__=__webpack_require__(1),react__WEBPACK_IMPORTED_MODULE_35___default=__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_35__),react_dom__WEBPACK_IMPORTED_MODULE_36__=__webpack_require__(50),react_dom__WEBPACK_IMPORTED_MODULE_36___default=__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_36__),_ui_CorporationUIEventHandler__WEBPACK_IMPORTED_MODULE_37__=__webpack_require__(303),_ui_Root__WEBPACK_IMPORTED_MODULE_38__=__webpack_require__(302),_ui_Routing__WEBPACK_IMPORTED_MODULE_39__=__webpack_require__(136),_ui_Routing__WEBPACK_IMPORTED_MODULE_39___default=__webpack_require__.n(_ui_Routing__WEBPACK_IMPORTED_MODULE_39__),decimal_js__WEBPACK_IMPORTED_MODULE_40__=__webpack_require__(41);const INITIALSHARES=1e9,SHARESPERPRICEUPDATE=1e6,IssueNewSharesCooldown=216e3,SellSharesCooldown=18e3,CyclesPerMarketCycle=50,CyclesPerIndustryStateCycle=CyclesPerMarketCycle/_CorporationState__WEBPACK_IMPORTED_MODULE_0__.AllCorporationStates.length,SecsPerMarketCycle=CyclesPerMarketCycle/5,Cities=["Aevum","Chongqing","Sector-12","New Tokyo","Ishima","Volhaven"],WarehouseInitialCost=5e9,WarehouseInitialSize=100,WarehouseUpgradeBaseCost=1e9,OfficeInitialCost=4e9,OfficeInitialSize=3,OfficeUpgradeBaseCost=1e9,BribeThreshold=1e14,BribeToRepRatio=1e9,ProductProductionCostRatio=5,DividendMaxPercentage=50,EmployeeSalaryMultiplier=3,CyclesPerEmployeeRaise=400,EmployeeRaiseAmount=50,BaseMaxProducts=3;let researchTreeBoxOpened=!1,researchTreeBox=null;$(document).mousedown(function(e){researchTreeBoxOpened&&null==$(e.target).closest("#corporation-research-popup-box-content").get(0)&&(Object(_utils_uiHelpers_removeElement__WEBPACK_IMPORTED_MODULE_32__.removeElement)(researchTreeBox),researchTreeBox=null,researchTreeBoxOpened=!1)});var empManualAssignmentModeActive=!1;function Industry(e={}){this.offices={[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Aevum]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Chongqing]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Sector12]:new OfficeSpace({loc:_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Sector12,size:OfficeInitialSize}),[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.NewTokyo]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Ishima]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Volhaven]:0},this.name=e.name?e.name:0,this.type=e.type?e.type:0,this.sciResearch=new _Material__WEBPACK_IMPORTED_MODULE_6__.Material({name:"Scientific Research"}),this.researched={},this.reqMats={},this.prodMats=[],this.products={},this.makesProducts=!1,this.awareness=0,this.popularity=0,this.startingCost=0,this.reFac=0,this.sciFac=0,this.hwFac=0,this.robFac=0,this.aiFac=0,this.advFac=0,this.prodMult=0,this.lastCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.lastCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0);var t=Object.keys(_IndustryUpgrades__WEBPACK_IMPORTED_MODULE_5__.IndustryUpgrades).length;this.upgrades=Array(t).fill(0),this.state="START",this.newInd=!0,this.warehouses={[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Aevum]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Chonqing]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Sector12]:new _Warehouse__WEBPACK_IMPORTED_MODULE_10__.Warehouse({corp:e.corp,industry:this,loc:_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Sector12,size:WarehouseInitialSize}),[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.NewTokyo]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Ishima]:0,[_Locations_data_CityNames__WEBPACK_IMPORTED_MODULE_16__.CityName.Volhaven]:0},this.init()}function Employee(e={}){if(!(this instanceof Employee))return new Employee(e);this.name=e.name?e.name:"Bobby",this.mor=e.morale?e.morale:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),this.hap=e.happiness?e.happiness:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),this.ene=e.energy?e.energy:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),this.int=e.intelligence?e.intelligence:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.cha=e.charisma?e.charisma:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.exp=e.experience?e.experience:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.cre=e.creativity?e.creativity:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.eff=e.efficiency?e.efficiency:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(10,50),this.sal=e.salary?e.salary:Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(.1,5),this.pro=0,this.cyclesUntilRaise=CyclesPerEmployeeRaise,this.loc=e.loc?e.loc:"",this.pos=_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Unassigned}Industry.prototype.init=function(){switch(this.startingCost=_IndustryData__WEBPACK_IMPORTED_MODULE_4__.IndustryStartingCosts[this.type],this.type){case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Energy:this.reFac=.65,this.sciFac=.7,this.robFac=.05,this.aiFac=.3,this.advFac=.08,this.reqMats={Hardware:.1,Metal:.2},this.prodMats=["Energy"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Utilities:case"Utilities":this.reFac=.5,this.sciFac=.6,this.robFac=.4,this.aiFac=.4,this.advFac=.08,this.reqMats={Hardware:.1,Metal:.1},this.prodMats=["Water"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Agriculture:this.reFac=.72,this.sciFac=.5,this.hwFac=.2,this.robFac=.3,this.aiFac=.3,this.advFac=.04,this.reqMats={Water:.5,Energy:.5},this.prodMats=["Plants","Food"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Fishing:this.reFac=.15,this.sciFac=.35,this.hwFac=.35,this.robFac=.5,this.aiFac=.2,this.advFac=.08,this.reqMats={Energy:.5},this.prodMats=["Food"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Mining:this.reFac=.3,this.sciFac=.26,this.hwFac=.4,this.robFac=.45,this.aiFac=.45,this.advFac=.06,this.reqMats={Energy:.8},this.prodMats=["Metal"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Food:this.sciFac=.12,this.hwFac=.15,this.robFac=.3,this.aiFac=.25,this.advFac=.25,this.reFac=.05,this.reqMats={Food:.5,Water:.5,Energy:.2},this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Tobacco:this.reFac=.15,this.sciFac=.75,this.hwFac=.15,this.robFac=.2,this.aiFac=.15,this.advFac=.2,this.reqMats={Plants:1,Water:.2},this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Chemical:this.reFac=.25,this.sciFac=.75,this.hwFac=.2,this.robFac=.25,this.aiFac=.2,this.advFac=.07,this.reqMats={Plants:1,Energy:.5,Water:.5},this.prodMats=["Chemicals"];break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Pharmaceutical:this.reFac=.05,this.sciFac=.8,this.hwFac=.15,this.robFac=.25,this.aiFac=.2,this.advFac=.16,this.reqMats={Chemicals:2,Energy:1,Water:.5},this.prodMats=["Drugs"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Computer:case"Computer":this.reFac=.2,this.sciFac=.62,this.robFac=.36,this.aiFac=.19,this.advFac=.17,this.reqMats={Metal:2,Energy:1},this.prodMats=["Hardware"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Robotics:this.reFac=.32,this.sciFac=.65,this.aiFac=.36,this.advFac=.18,this.hwFac=.19,this.reqMats={Hardware:5,Energy:3},this.prodMats=["Robots"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Software:this.sciFac=.62,this.advFac=.16,this.hwFac=.25,this.reFac=.15,this.aiFac=.18,this.robFac=.05,this.reqMats={Hardware:.5,Energy:.5},this.prodMats=["AICores"],this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Healthcare:this.reFac=.1,this.sciFac=.75,this.advFac=.11,this.hwFac=.1,this.robFac=.1,this.aiFac=.1,this.reqMats={Robots:10,AICores:5,Energy:5,Water:5},this.makesProducts=!0;break;case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.RealEstate:this.robFac=.6,this.aiFac=.6,this.advFac=.25,this.sciFac=.05,this.hwFac=.05,this.reqMats={Metal:5,Energy:5,Water:2,Hardware:4},this.prodMats=["RealEstate"],this.makesProducts=!0;break;default:return void console.error(`Invalid Industry Type passed into Industry.init(): ${this.type}`)}},Industry.prototype.getProductDescriptionText=function(){if(this.makesProducts)switch(this.type){case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Food:return"create and manage restaurants";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Tobacco:return"create tobacco and tobacco-related products";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Pharmaceutical:return"develop new pharmaceutical drugs";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Computer:case"Computer":return"create new computer hardware and networking infrastructures";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Robotics:return"build specialized robots and robot-related products";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Software:return"develop computer software";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.Healthcare:return"build and manage hospitals";case _IndustryData__WEBPACK_IMPORTED_MODULE_4__.Industries.RealEstate:return"develop and manage real estate properties";default:return console.error("Invalid industry type in Industry.getProductDescriptionText"),""}},Industry.prototype.getMaximumNumberProducts=function(){if(!this.makesProducts)return 0;let e=0;return this.hasResearch("uPgrade: Capacity.I")&&++e,this.hasResearch("uPgrade: Capacity.II")&&++e,BaseMaxProducts+e},Industry.prototype.hasMaximumNumberProducts=function(){return Object.keys(this.products).length>=this.getMaximumNumberProducts()},Industry.prototype.calculateProductionFactors=function(){for(var e=0,t=0;t0&&(e.breakdown+=t+": "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(n.data[e.loc][0]*n.siz,0)+"
")}},Industry.prototype.process=function(e=1,t,n){if(this.state=t,"START"===t){(isNaN(this.thisCycleRevenue)||isNaN(this.thisCycleExpenses))&&(console.error("NaN in Corporation's computed revenue/expenses"),Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Something went wrong when compting Corporation's revenue/expenses. This is a bug. Please report to game developer"),this.thisCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0)),this.lastCycleRevenue=this.thisCycleRevenue.dividedBy(e*SecsPerMarketCycle),this.lastCycleExpenses=this.thisCycleExpenses.dividedBy(e*SecsPerMarketCycle),this.thisCycleRevenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.thisCycleExpenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.lastCycleRevenue.gt(0)&&(this.newInd=!1);var r=0;for(var a in this.offices)this.offices[a]instanceof OfficeSpace&&(r+=this.offices[a].process(e,{industry:this,corporation:n}));this.thisCycleExpenses=this.thisCycleExpenses.plus(r),this.processMaterialMarket(e),this.processProductMarket(e),this.popularity-=1e-4*e,this.popularity=Math.max(0,this.popularity);var i=n.getDreamSenseGain(),o=4*i;return void(i>0&&(this.popularity+=i*e,this.awareness+=o*e))}let s=this.processMaterials(e,n);Array.isArray(s)&&(this.thisCycleRevenue=this.thisCycleRevenue.plus(s[0]),this.thisCycleExpenses=this.thisCycleExpenses.plus(s[1])),s=this.processProducts(e,n),Array.isArray(s)&&(this.thisCycleRevenue=this.thisCycleRevenue.plus(s[0]),this.thisCycleExpenses=this.thisCycleExpenses.plus(s[1]))},Industry.prototype.processMaterialMarket=function(e=1){for(var t=this.reqMats,n=this.prodMats,r=0;r0&&(a.qty+=r,expenses+=r*a.bCost)}(matName,industry),this.updateWarehouseSizeUsed(warehouse));break;case"PRODUCTION":if(warehouse.smartSupplyStore=0,this.prodMats.length>0){var mat=warehouse.materials[this.prodMats[0]],maxProd=this.getOfficeProductivity(office)*this.prodMult*company.getProductionMultiplier()*this.getProductionMultiplier();let e;e=mat.prdman[0]?Math.min(maxProd,mat.prdman[1]):maxProd,e*=SecsPerMarketCycle*marketCycles;var totalMatSize=0;for(let e=0;e0){var maxAmt=Math.floor((warehouse.size-warehouse.sizeUsed)/totalMatSize);e=Math.min(maxAmt,e)}e<0&&(e=0),warehouse.smartSupplyStore+=e/(SecsPerMarketCycle*marketCycles);var producableFrac=1;for(var reqMatName in this.reqMats)if(this.reqMats.hasOwnProperty(reqMatName)){var req=this.reqMats[reqMatName]*e;warehouse.materials[reqMatName].qty0&&e>0){for(const t in this.reqMats){var reqMatQtyNeeded=this.reqMats[t]*e*producableFrac;warehouse.materials[t].qty-=reqMatQtyNeeded,warehouse.materials[t].prd=0,warehouse.materials[t].prd-=reqMatQtyNeeded/(SecsPerMarketCycle*marketCycles)}for(let t=0;tmat.bCost?sCost-mat.bCost>markupLimit&&(markup=Math.pow(markupLimit/(sCost-mat.bCost),2)):sCost=0?(mat.qty-=sellAmt,revenue+=sellAmt*sCost,mat.sll=sellAmt/(SecsPerMarketCycle*marketCycles)):mat.sll=0}break;case"EXPORT":for(var matName in warehouse.materials)if(warehouse.materials.hasOwnProperty(matName)){var mat=warehouse.materials[matName];mat.totalExp=0;for(var expI=0;expI=expWarehouse.size)return[0,0];var maxAmt=Math.floor((expWarehouse.size-expWarehouse.sizeUsed)/_MaterialSizes__WEBPACK_IMPORTED_MODULE_7__.MaterialSizes[matName]);amt=Math.min(maxAmt,amt),expWarehouse.materials[matName].imp+=amt/(SecsPerMarketCycle*marketCycles),expWarehouse.materials[matName].qty+=amt,expWarehouse.materials[matName].qlt=mat.qlt,mat.qty-=amt,mat.totalExp+=amt,expIndustry.updateWarehouseSizeUsed(expWarehouse);break}}}mat.totalExp/=SecsPerMarketCycle*marketCycles}break;case"START":break;default:console.error(`Invalid state: ${this.state}`)}this.updateWarehouseSizeUsed(warehouse)}office instanceof OfficeSpace&&(this.sciResearch.qty+=.004*Math.pow(office.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.RandD],.5)*company.getScientificResearchMultiplier()*this.getScientificResearchMultiplier())}return[revenue,expenses]},Industry.prototype.processProducts=function(e=1,t){var n=0;if("PRODUCTION"===this.state)for(const t in this.products){const n=this.products[t];if(!n.fin){const t=n.createCity,r=this.offices[t],a=r.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Engineer],i=r.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Management],o=r.employeeProd[_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Operations],s=a+i+o;if(s<=0)break;const l=1+i/(1.2*s),c=(Math.pow(a,.34)+Math.pow(o,.2))*l;n.createProduct(e,c),n.prog>=100&&n.finishProduct(r.employeeProd,this);break}}for(var r in this.products)if(this.products.hasOwnProperty(r)){var a=this.products[r];a instanceof _Product__WEBPACK_IMPORTED_MODULE_8__.Product&&a.fin&&(n+=this.processProduct(e,a,t))}return[n,0]},Industry.prototype.processProduct=function(marketCycles=1,product,corporation){let totalProfit=0;for(let i=0;i0){var maxAmt=Math.floor((warehouse.size-warehouse.sizeUsed)/netStorageSize);prod=Math.min(maxAmt,prod)}warehouse.smartSupplyStore+=prod/(SecsPerMarketCycle*marketCycles);var producableFrac=1;for(var reqMatName in product.reqMats)if(product.reqMats.hasOwnProperty(reqMatName)){var req=product.reqMats[reqMatName]*prod;warehouse.materials[reqMatName].qty0&&prod>0){for(var reqMatName in product.reqMats)if(product.reqMats.hasOwnProperty(reqMatName)){var reqMatQtyNeeded=product.reqMats[reqMatName]*prod*producableFrac;warehouse.materials[reqMatName].qty-=reqMatQtyNeeded,warehouse.materials[reqMatName].prd-=reqMatQtyNeeded/(SecsPerMarketCycle*marketCycles)}product.data[city][0]+=prod*producableFrac}product.data[city][1]=prod*producableFrac/(SecsPerMarketCycle*marketCycles);break;case"SALE":for(var reqMatName in product.pCost=0,product.reqMats)product.reqMats.hasOwnProperty(reqMatName)&&(product.pCost+=product.reqMats[reqMatName]*warehouse.materials[reqMatName].bCost);product.pCost*=ProductProductionCostRatio;const businessFactor=this.getBusinessFactor(office),advertisingFactor=this.getAdvertisingFactors()[0],marketFactor=this.getMarketFactor(product),markupLimit=product.rat/product.mku;var sCost;if(product.marketTa2){const e=product.data[city][1],t=markupLimit,n=e,r=.5*Math.pow(product.rat,.65)*marketFactor*corporation.getSalesMultiplier()*businessFactor*advertisingFactor*this.getSalesMultiplier(),a=Math.sqrt(n/r);let i;0===r||0===a?0===n?i=0:(i=product.pCost+markupLimit,console.warn("In Corporation, found illegal 0s when trying to calculate MarketTA2 sale cost")):i=t/a+product.pCost,product.marketTa2Price[city]=i,sCost=i}else product.marketTa1?sCost=product.pCost+markupLimit:Object(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__.isString)(product.sCost)?(sCost=product.sCost.replace(/MP/g,product.pCost+product.rat/product.mku),sCost=eval(sCost)):sCost=product.sCost;var markup=1;sCost>product.pCost&&sCost-product.pCost>markupLimit&&(markup=markupLimit/(sCost-product.pCost));var maxSell=.5*Math.pow(product.rat,.65)*marketFactor*corporation.getSalesMultiplier()*Math.pow(markup,2)*businessFactor*advertisingFactor*this.getSalesMultiplier(),sellAmt;if(product.sllman[city][0]&&Object(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_30__.isString)(product.sllman[city][1])){var tmp=product.sllman[city][1].replace(/MAX/g,maxSell);tmp=tmp.replace(/PROD/g,product.data[city][1]);try{tmp=eval(tmp)}catch(e){Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Error evaluating your sell price expression for "+product.name+" in "+this.name+"'s "+city+" office. Sell price is being set to MAX"),tmp=maxSell}sellAmt=Math.min(maxSell,tmp)}else sellAmt=product.sllman[city][0]&&product.sllman[city][1]>0?Math.min(maxSell,product.sllman[city][1]):!1===product.sllman[city][0]?0:maxSell;sellAmt<0&&(sellAmt=0),sellAmt=sellAmt*SecsPerMarketCycle*marketCycles,sellAmt=Math.min(product.data[city][0],sellAmt),sellAmt&&sCost?(product.data[city][0]-=sellAmt,totalProfit+=sellAmt*sCost,product.data[city][2]=sellAmt/(SecsPerMarketCycle*marketCycles)):product.data[city][2]=0;break;case"START":case"PURCHASE":case"EXPORT":break;default:console.error(`Invalid State: ${this.state}`)}}return totalProfit},Industry.prototype.discontinueProduct=function(e){for(var t in this.products)this.products.hasOwnProperty(t)&&e===this.products[t]&&delete this.products[t]},Industry.prototype.upgrade=function(e,t){var n=t.corporation,r=(t.division,t.office),a=e[0];for(e[1],e[2],e[3];this.upgrades.length<=a;)this.upgrades.push(0);switch(++this.upgrades[a],a){case 0:for(let e=0;e{if(this.sciResearch.qty>=n.cost)return this.sciResearch.qty-=n.cost,t.research(r[e]),this.researched[r[e]]=!0,Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)(`Researched ${r[e]}. It may take a market cycle `+`(~${SecsPerMarketCycle} seconds) before the effects of `+"the Research apply."),this.createResearchBox();Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)(`You do not have enough Scientific Research for ${n.name}`)}):console.warn(`Could not find Research Tree div for ${a}`)}const a=document.getElementById(`${e}-content`);null!=a&&(Object(_utils_uiHelpers_appendLineBreaks__WEBPACK_IMPORTED_MODULE_24__.appendLineBreaks)(a,2),a.appendChild(Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("pre",{display:"block",innerText:"Multipliers from research:\n"+` * Advertising Multiplier: x${t.getAdvertisingMultiplier()}\n`+` * Employee Charisma Multiplier: x${t.getEmployeeChaMultiplier()}\n`+` * Employee Creativity Multiplier: x${t.getEmployeeCreMultiplier()}\n`+` * Employee Efficiency Multiplier: x${t.getEmployeeEffMultiplier()}\n`+` * Employee Intelligence Multiplier: x${t.getEmployeeIntMultiplier()}\n`+` * Production Multiplier: x${t.getProductionMultiplier()}\n`+` * Sales Multiplier: x${t.getSalesMultiplier()}\n`+` * Scientific Research Multiplier: x${t.getScientificResearchMultiplier()}\n`+` * Storage Multiplier: x${t.getStorageMultiplier()}`})),a.appendChild(Object(_utils_uiHelpers_createPopupCloseButton__WEBPACK_IMPORTED_MODULE_27__.createPopupCloseButton)(researchTreeBox,{class:"std-button",display:"block",innerText:"Close"}))),researchTreeBoxOpened=!0},Industry.prototype.toJSON=function(){return Object(_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__.Generic_toJSON)("Industry",this)},Industry.fromJSON=function(e){return Object(_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__.Generic_fromJSON)(Industry,e.data)},_utils_JSONReviver__WEBPACK_IMPORTED_MODULE_23__.Reviver.constructors.Industry=Industry,Employee.prototype.process=function(e=1,t){var n=.003*e,r=n*Math.random();this.exp+=n,this.cyclesUntilRaise-=e,this.cyclesUntilRaise<=0&&(this.salary+=EmployeeRaiseAmount,this.cyclesUntilRaise+=CyclesPerEmployeeRaise);var a=n*Math.random();return this.pos===_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Training&&(this.cha+=a,this.exp+=a,this.eff+=a),this.ene-=r,this.hap-=r,this.eneHappiness: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.hap,3)+"
Energy: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.ene,3)+"
Intelligence: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(i,3)+"
Charisma: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(a,3)+"
Experience: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(this.exp,3)+"
Creativity: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(r,3)+"
Efficiency: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(o,3)+"
Salary: "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(this.sal,"$0.000a")+"/ s
"}));var s=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("select",{});for(var l in _EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions)_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.hasOwnProperty(l)&&s.add(Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("option",{text:_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions[l],value:_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions[l]}));s.addEventListener("change",()=>{this.pos=s.options[s.selectedIndex].value});for(var c=0;c=this.size},OfficeSpace.prototype.process=function(e=1,t){t.corporation;var n=t.industry;if(n.hasResearch("HRBuddy-Recruitment")&&!this.atCapacity()){const e=this.hireRandomEmployee();n.hasResearch("HRBuddy-Training")&&(e.pos=_EmployeePositions__WEBPACK_IMPORTED_MODULE_3__.EmployeePositions.Training)}this.maxEne=100,this.maxHap=100,this.maxMor=100,n.hasResearch("Go-Juice")&&(this.maxEne+=10),n.hasResearch("JoyWire")&&(this.maxHap+=10),n.hasResearch("Sti.mu")&&(this.maxMor+=10);var r=1;n.funds<0&&n.lastCycleRevenue<0?r=Math.pow(.99,e):n.funds>0&&n.lastCycleRevenue>0&&(r=Math.pow(1.01,e));const a=n.hasResearch("AutoBrew"),i=n.hasResearch("AutoPartyManager");var o=0;for(let t=0;tCharisma: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.cha,1)+"
Experience: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.exp,1)+"
Creativity: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.cre,1)+"
Efficiency: "+Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.formatNumber)(t.eff,1)+"
Salary: "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(t.sal,"$0.000a")+" s
",clickListener:()=>(n.hireEmployee(t,e),Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-hire-employee-popup"),!1)})},_=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("a",{class:"a-link-button",innerText:"Cancel",float:"right",clickListener:()=>(Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-hire-employee-popup"),!1)}),g=[h,d(u,this),d(m,this),d(p,this),_];Object(_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__.createPopup)("cmpy-mgmt-hire-employee-popup",g)}},OfficeSpace.prototype.hireEmployee=function(e,t){var n=t.corporation,r=(t.industry,Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxGetYesButton)()),a=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxGetNoButton)();r.innerHTML="Hire",a.innerHTML="Cancel",r.addEventListener("click",()=>{for(var t=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxGetInput)(),r=0;rObject(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxClose)()),Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoTxtInpBoxCreate)("Give your employee a nickname!")},OfficeSpace.prototype.hireRandomEmployee=function(){if(!this.atCapacity()&&null==document.getElementById("cmpy-mgmt-hire-employee-popup")){var e=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(76,100)/100,t=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),n=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),r=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),a=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),i=Object(_utils_helpers_getRandomInt__WEBPACK_IMPORTED_MODULE_29__.getRandomInt)(50,100),o=new Employee({intelligence:t*e,charisma:n*e,experience:r*e,creativity:a*e,efficiency:i*e,salary:EmployeeSalaryMultiplier*(t+n+r+a+i)*e}),s=Object(_utils_StringHelperFunctions__WEBPACK_IMPORTED_MODULE_28__.generateRandomString)(7);for(let e=0;e=CyclesPerIndustryStateCycle){const t=this.getState(),n=1,r=n*CyclesPerIndustryStateCycle;if(this.storedCycles-=r,this.divisions.forEach(function(r){r.process(n,t,e)}),this.shareSaleCooldown>0&&(this.shareSaleCooldown-=r),this.issueNewSharesCooldown>0&&(this.issueNewSharesCooldown-=r),"START"===t){this.revenue=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.expenses=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(0),this.divisions.forEach(e=>{e.lastCycleRevenue!==-1/0&&e.lastCycleRevenue!==1/0&&e.lastCycleExpenses!==-1/0&&e.lastCycleExpenses!==1/0&&(this.revenue=this.revenue.plus(e.lastCycleRevenue),this.expenses=this.expenses.plus(e.lastCycleExpenses))});const e=this.revenue.minus(this.expenses).times(n*SecsPerMarketCycle);if(isNaN(this.funds)&&(Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("There was an error calculating your Corporations funds and they got reset to 0. This is a bug. Please report to game developer.

(Your funds have been set to $150b for the inconvenience)"),this.funds=new decimal_js__WEBPACK_IMPORTED_MODULE_40__.a(15e10)),this.dividendPercentage>0&&e>0)if(isNaN(this.dividendPercentage)||this.dividendPercentage<0||this.dividendPercentage>DividendMaxPercentage)console.error(`Invalid Corporation dividend percentage: ${this.dividendPercentage}`);else{const t=this.dividendPercentage/100*e,n=e-t,r=t/this.totalShares,a=this.numShares*r*(1-this.dividendTaxPercentage/100);_Player__WEBPACK_IMPORTED_MODULE_17__.Player.gainMoney(a),_Player__WEBPACK_IMPORTED_MODULE_17__.Player.recordMoneySource(a,"corporation"),this.funds=this.funds.plus(n)}else this.funds=this.funds.plus(e);this.updateSharePrice()}this.state.nextState(),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__.routing.isOn(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_19__.Page.Corporation)&&this.rerender()}},Corporation.prototype.determineValuation=function(){var e,t=this.revenue.minus(this.expenses).toNumber();return this.public?(this.dividendPercentage>0&&(t*=(100-this.dividendPercentage)/100),e=this.funds.toNumber()+85e3*t,e*=Math.pow(1.1,this.divisions.length),e=Math.max(e,0)):(e=1e10+Math.max(this.funds.toNumber(),0)/3,t>0?(e+=315e3*t,e*=Math.pow(1.1,this.divisions.length)):e=1e10*Math.pow(1.1,this.divisions.length),e-=e%1e6),e*_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_11__.BitNodeMultipliers.CorporationValuation},Corporation.prototype.getInvestment=function(){var e,t=this.determineValuation();let n=4;switch(this.fundingRound){case 0:e=.1,n=4;break;case 1:e=.35,n=3;break;case 2:e=.25,n=3;break;case 3:e=.2,n=2.5;break;case 4:return}var r=t*e*n,a=Math.floor(INITIALSHARES*e),i=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxGetYesButton)(),o=Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxGetNoButton)();i.innerHTML="Accept",o.innerHML="Reject",i.addEventListener("click",()=>(++this.fundingRound,this.funds=this.funds.plus(r),this.numShares-=a,this.rerender(),Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxClose)())),o.addEventListener("click",()=>Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxClose)()),Object(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_34__.yesNoBoxCreate)("An investment firm has offered you "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(r,"$0.000a")+" in funding in exchange for a "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(100*e,"0.000a")+"% stake in the company ("+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(a,"0.000a")+" shares).

Do you accept or reject this offer?

Hint: Investment firms will offer more money if your corporation is turning a profit")},Corporation.prototype.goPublic=function(){var e,t=this.determineValuation()/this.totalShares,n=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("p",{innerHTML:"Enter the number of shares you would like to issue for your IPO. These shares will be publicly sold and you will no longer own them. Your Corporation will receive "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(t,"$0.000a")+" per share (the IPO money will be deposited directly into your Corporation's funds).

You have a total of "+_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.format(this.numShares,"0.000a")+" of shares that you can issue."}),r=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("input",{type:"number",placeholder:"Shares to issue",onkeyup:t=>{t.preventDefault(),t.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_31__.KEY.ENTER&&e.click()}}),a=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("br",{});e=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("a",{class:"a-link-button",innerText:"Go Public",clickListener:()=>{var e=Math.round(r.value),t=this.determineValuation()/this.totalShares;return isNaN(e)?(Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Invalid value for number of issued shares"),!1):e>this.numShares?(Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("Error: You don't have that many shares to issue!"),!1):(this.public=!0,this.sharePrice=t,this.issuedShares=e,this.numShares-=e,this.funds=this.funds.plus(e*t),this.rerender(),Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-go-public-popup"),Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)(`You took your ${this.name} public and earned `+`${_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_18__.numeralWrapper.formatMoney(e*t)} in your IPO`),!1)}});var i=Object(_utils_uiHelpers_createElement__WEBPACK_IMPORTED_MODULE_25__.createElement)("a",{class:"a-link-button",innerText:"Cancel",clickListener:()=>(Object(_utils_uiHelpers_removeElementById__WEBPACK_IMPORTED_MODULE_33__.removeElementById)("cmpy-mgmt-go-public-popup"),!1)});Object(_utils_uiHelpers_createPopup__WEBPACK_IMPORTED_MODULE_26__.createPopup)("cmpy-mgmt-go-public-popup",[n,a,r,e,i])},Corporation.prototype.getTargetSharePrice=function(){return this.determineValuation()/(2*(this.totalShares-this.numShares)+1)},Corporation.prototype.updateSharePrice=function(){const e=this.getTargetSharePrice();this.sharePrice<=e?this.sharePrice*=1+.01*Math.random():this.sharePrice*=1-.01*Math.random(),this.sharePrice<=.01&&(this.sharePrice=.01)},Corporation.prototype.immediatelyUpdateSharePrice=function(){this.sharePrice=this.getTargetSharePrice()},Corporation.prototype.calculateShareSale=function(e){let t=e,n=this.shareSalesUntilPriceUpdate,r=this.sharePrice,a=0,i=0;const o=Math.ceil(e/SHARESPERPRICEUPDATE);if(!(isNaN(o)||o>1e7)){for(let e=0;e3600?`${Math.floor(t/3600)} hour(s)`:t>60?`${Math.floor(t/60)} minute(s)`:`${Math.floor(t)} second(s)`},Corporation.prototype.unlock=function(e){const t=e[0],n=e[1];for(;this.unlockUpgrades.length<=t;)this.unlockUpgrades.push(0);this.funds.lt(n)?Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("You don't have enough funds to unlock this!"):(this.unlockUpgrades[t]=1,this.funds=this.funds.minus(n),5===t?this.dividendTaxPercentage-=5:6===t&&(this.dividendTaxPercentage-=10))},Corporation.prototype.upgrade=function(e){for(var t=e[0],n=e[1],r=e[2],a=e[3];this.upgrades.length<=t;)this.upgrades.push(0);for(;this.upgradeMultipliers.length<=t;)this.upgradeMultipliers.push(1);var i=n*Math.pow(r,this.upgrades[t]);if(this.funds.lt(i))Object(_utils_DialogBox__WEBPACK_IMPORTED_MODULE_21__.dialogBoxCreate)("You don't have enough funds to purchase this!");else if(++this.upgrades[t],this.funds=this.funds.minus(i),this.upgradeMultipliers[t]=1+this.upgrades[t]*a,1===t)for(var o=0;o=t.HacknetServerMaxCache)return 1/0;const r=t.HacknetServerUpgradeCacheMult;let a=0,i=this.cache;for(let e=0;e=t.HacknetServerMaxCores)return 1/0;const a=t.HacknetServerUpgradeCoreMult;let i=0,o=this.cores;for(let e=0;e=t.HacknetServerMaxLevel)return 1/0;const a=t.HacknetServerUpgradeLevelMult;let i=0,o=this.level;for(let e=0;e=t.HacknetServerMaxRam)return 1/0;let a=0,i=Math.round(Math.log2(this.maxRam)),o=this.maxRam;for(let e=0;eh.Start&&(d.currStep-=1);g()}(),!1}),Object(l.clearEventListeners)("interactive-tutorial-next").addEventListener("click",function(){return y(),!1}),g()}function g(){if(d.isRunning){var e=Object(l.clearEventListeners)("terminal-menu-link"),t=Object(l.clearEventListeners)("stats-menu-link"),n=Object(l.clearEventListeners)("active-scripts-menu-link"),a=Object(l.clearEventListeners)("hacknet-nodes-menu-link"),i=Object(l.clearEventListeners)("city-menu-link"),o=Object(l.clearEventListeners)("tutorial-menu-link");e.removeAttribute("class"),t.removeAttribute("class"),n.removeAttribute("class"),a.removeAttribute("class"),i.removeAttribute("class"),o.removeAttribute("class");var s=document.getElementById("interactive-tutorial-next");switch(d.currStep){case h.Start:r.Engine.loadTerminalContent(),b("Welcome to Bitburner, a cyberpunk-themed incremental RPG! The game takes place in a dark, dystopian future...The year is 2077...

This tutorial will show you the basics of the game. You may skip the tutorial at any time."),s.style.display="inline-block";break;case h.GoToCharacterPage:r.Engine.loadTerminalContent(),b("Let's start by heading to the Stats page. Click the 'Stats' tab on the main navigation menu (left-hand side of the screen)"),s.style.display="none",t.setAttribute("class","flashing-button"),t.addEventListener("click",function(){return r.Engine.loadCharacterContent(),y(),!1});break;case h.CharacterPage:r.Engine.loadCharacterContent(),b("The Stats page shows a lot of important information about your progress, such as your skills, money, and bonuses/multipliers. "),s.style.display="inline-block";break;case h.CharacterGoToTerminalPage:r.Engine.loadCharacterContent(),b("Let's head to your computer's terminal by clicking the 'Terminal' tab on the main navigation menu."),s.style.display="none",e.setAttribute("class","flashing-button"),e.addEventListener("click",function(){return r.Engine.loadTerminalContent(),y(),!1});break;case h.TerminalIntro:r.Engine.loadTerminalContent(),b("The Terminal is used to interface with your home computer as well as all of the other machines around the world."),s.style.display="inline-block";break;case h.TerminalHelp:r.Engine.loadTerminalContent(),b("Let's try it out. Start by entering the 'help' command into the Terminal (Don't forget to press Enter after typing the command)"),s.style.display="none";break;case h.TerminalLs:r.Engine.loadTerminalContent(),b("The 'help' command displays a list of all available Terminal commands, how to use them, and a description of what they do.

Let's try another command. Enter the 'ls' command"),s.style.display="none";break;case h.TerminalScan:r.Engine.loadTerminalContent(),b("'ls' is a basic command that shows all of the contents (programs/scripts) on the computer. Right now, it shows that you have a program called 'NUKE.exe' on your computer. We'll get to what this does later.

Using your home computer's terminal, you can connect to other machines throughout the world. Let's do that now by first entering the 'scan' command."),s.style.display="none";break;case h.TerminalScanAnalyze1:r.Engine.loadTerminalContent(),b("The 'scan' command shows all available network connections. In other words, it displays a list of all servers that can be connected to from your current machine. A server is identified by either its IP or its hostname.

That's great and all, but there's so many servers. Which one should you go to? The 'scan-analyze' command gives some more detailed information about servers on the network. Try it now"),s.style.display="none";break;case h.TerminalScanAnalyze2:r.Engine.loadTerminalContent(),b("You just ran 'scan-analyze' with a depth of one. This command shows more detailed information about each server that you can connect to (servers that are a distance of one node away).

It is also possible to run 'scan-analyze' with a higher depth. Let's try a depth of two with the following command: 'scan-analyze 2'."),s.style.display="none";break;case h.TerminalConnect:r.Engine.loadTerminalContent(),b("Now you can see information about all servers that are up to two nodes away, as well as figure out how to navigate to those servers through the network. You can only connect to a server that is one node away. To connect to a machine, use the 'connect [ip/hostname]' command. You can type in the ip or the hostname, but dont use both.

From the results of the 'scan-analyze' command, we can see that the 'foodnstuff' server is only one node away. Let's connect so it now using: 'connect foodnstuff'"),s.style.display="none";break;case h.TerminalAnalyze:r.Engine.loadTerminalContent(),b("You are now connected to another machine! What can you do now? You can hack it!

In the year 2077, currency has become digital and decentralized. People and corporations store their money on servers and computers. Using your hacking abilities, you can hack servers to steal money and gain experience.

Before you try to hack a server, you should run diagnostics using the 'analyze' command"),s.style.display="none";break;case h.TerminalNuke:r.Engine.loadTerminalContent(),b("When the 'analyze' command finishes running it will show useful information about hacking the server.

For this server, the required hacking skill is only 1, which means you can hack it right now. However, in order to hack a server you must first gain root access. The 'NUKE.exe' program that we saw earlier on your home computer is a virus that will grant you root access to a machine if there are enough open ports.

The 'analyze' results shows that there do not need to be any open ports on this machine for the NUKE virus to work, so go ahead and run the virus using the 'run NUKE.exe' command."),s.style.display="none";break;case h.TerminalManualHack:r.Engine.loadTerminalContent(),b("You now have root access! You can hack the server using the 'hack' command. Try doing that now."),s.style.display="none";break;case h.TerminalHackingMechanics:r.Engine.loadTerminalContent(),b("You are now attempting to hack the server. Note that performing a hack takes time and only has a certain percentage chance of success. This time and success chance is determined by a variety of factors, including your hacking skill and the server's security level.

If your attempt to hack the server is successful, you will steal a certain percentage of the server's total money. This percentage is affected by your hacking skill and the server's security level.

The amount of money on a server is not limitless. So, if you constantly hack a server and deplete its money, then you will encounter diminishing returns in your hacking."),s.style.display="inline-block";break;case h.TerminalCreateScript:r.Engine.loadTerminalContent(),b("Hacking is the core mechanic of the game and is necessary for progressing. However, you don't want to be hacking manually the entire time. You can automate your hacking by writing scripts!

To create a new script or edit an existing one, you can use the 'nano' command. Scripts must end with the '.script' extension. Let's make a script now by entering 'nano foodnstuff.script' after the hack command finishes running (Sidenote: Pressing ctrl + c will end a command like hack early)"),s.style.display="none";break;case h.TerminalTypeScript:r.Engine.loadScriptEditorContent("foodnstuff.script",""),b("This is the script editor. You can use it to program your scripts. Scripts are written in the Netscript language, a programming language created for this game. There are details about the Netscript language in the documentation, which can be accessed in the 'Tutorial' tab on the main navigation menu. I highly suggest you check it out after this tutorial. For now, just copy and paste the following code into the script editor:

while(true) {
  hack('foodnstuff');
}

For anyone with basic programming experience, this code should be straightforward. This script will continuously hack the 'foodnstuff' server.

To save and close the script editor, press the button in the bottom left, or press ctrl + b."),s.style.display="none";break;case h.TerminalFree:r.Engine.loadTerminalContent(),b("Now we'll run the script. Scripts require a certain amount of RAM to run, and can be run on any machine which you have root access to. Different servers have different amounts of RAM. You can also purchase more RAM for your home server.

To check how much RAM is available on this machine, enter the 'free' command."),s.style.display="none";break;case h.TerminalRunScript:r.Engine.loadTerminalContent(),b("We have 16GB of free RAM on this machine, which is enough to run our script. Let's run our script using 'run foodnstuff.script'."),s.style.display="none";break;case h.TerminalGoToActiveScriptsPage:r.Engine.loadTerminalContent(),b("Your script is now running! The script might take a few seconds to 'fully start up'. Your scripts will continuously run in the background and will automatically stop if the code ever completes (the 'foodnstuff.script' will never complete because it runs an infinite loop).

These scripts can passively earn you income and hacking experience. Your scripts will also earn money and experience while you are offline, although at a much slower rate.

Let's check out some statistics for our running scripts by clicking the 'Active Scripts' link in the main navigation menu."),s.style.display="none",n.setAttribute("class","flashing-button"),n.addEventListener("click",function(){return r.Engine.loadActiveScriptsContent(),y(),!1});break;case h.ActiveScriptsPage:r.Engine.loadActiveScriptsContent(),b("This page displays stats/information about all of your scripts that are running across every existing server. You can use this to gauge how well your scripts are doing. Let's go back to the Terminal now using the 'Terminal' link."),s.style.display="none",e.setAttribute("class","flashing-button"),e.addEventListener("click",function(){return r.Engine.loadTerminalContent(),y(),!1});break;case h.ActiveScriptsToTerminal:r.Engine.loadTerminalContent(),b("One last thing about scripts, each active script contains logs that detail what it's doing. We can check these logs using the 'tail' command. Do that now for the script we just ran by typing 'tail foodnstuff.script'"),s.style.display="none";break;case h.TerminalTailScript:r.Engine.loadTerminalContent(),b("The log for this script won't show much right now (it might show nothing at all) because it just started running...but check back again in a few minutes!

This pretty much covers the basics of hacking. To learn more about writing scripts using the Netscript language, select the 'Tutorial' link in the main navigation menu to look at the documentation. If you are an experienced JavaScript developer, I would highly suggest you check out the section on NetscriptJS/Netscript 2.0.

For now, let's move on to something else!"),s.style.display="inline-block";break;case h.GoToHacknetNodesPage:r.Engine.loadTerminalContent(),b("Hacking is not the only way to earn money. One other way to passively earn money is by purchasing and upgrading Hacknet Nodes. Let's go to the 'Hacknet Nodes' page through the main navigation menu now."),s.style.display="none",a.setAttribute("class","flashing-button"),a.addEventListener("click",function(){return r.Engine.loadHacknetNodesContent(),y(),!1});break;case h.HacknetNodesIntroduction:r.Engine.loadHacknetNodesContent(),b("From this page you can purchase new Hacknet Nodes and upgrade your existing ones. Let's purchase a new one now."),s.style.display="none";break;case h.HacknetNodesGoToWorldPage:r.Engine.loadHacknetNodesContent(),b("You just purchased a Hacknet Node! This Hacknet Node will passively earn you money over time, both online and offline. When you get enough money, you can upgrade your newly-purchased Hacknet Node below.

Let's go to the 'City' page through the main navigation menu."),s.style.display="none",i.setAttribute("class","flashing-button"),i.addEventListener("click",function(){return r.Engine.loadLocationContent(),y(),!1});break;case h.WorldDescription:r.Engine.loadLocationContent(),b("This page lists all of the different locations you can currently travel to. Each location has something that you can do. There's a lot of content out in the world, make sure you explore and discover!

Lastly, click on the 'Tutorial' link in the main navigation menu."),s.style.display="none",o.setAttribute("class","flashing-button"),o.addEventListener("click",function(){return r.Engine.loadTutorialContent(),y(),!1});break;case h.TutorialPageInfo:r.Engine.loadTutorialContent(),b("This page contains a lot of different documentation about the game's content and mechanics. I know it's a lot, but I highly suggest you read (or at least skim) through this before you start playing. That's the end of the tutorial. Hope you enjoy the game!"),s.style.display="inline-block",s.innerHTML="Finish Tutorial";break;case h.End:f();break;default:throw new Error("Invalid tutorial step")}!0===d.stepIsDone[d.currStep]&&(s.style.display="inline-block")}}function y(){d.currStep===h.GoToCharacterPage&&document.getElementById("stats-menu-link").removeAttribute("class"),d.currStep===h.CharacterGoToTerminalPage&&document.getElementById("terminal-menu-link").removeAttribute("class"),d.currStep===h.TerminalGoToActiveScriptsPage&&document.getElementById("active-scripts-menu-link").removeAttribute("class"),d.currStep===h.ActiveScriptsPage&&document.getElementById("terminal-menu-link").removeAttribute("class"),d.currStep===h.GoToHacknetNodesPage&&document.getElementById("hacknet-nodes-menu-link").removeAttribute("class"),d.currStep===h.HacknetNodesGoToWorldPage&&document.getElementById("city-menu-link").removeAttribute("class"),d.currStep===h.WorldDescription&&document.getElementById("tutorial-menu-link").removeAttribute("class"),d.stepIsDone[d.currStep]=!0,d.currStep
Getting Started GuideDocumentation

The Beginner's Guide to Hacking was added to your home computer! It contains some tips/pointers for starting out with the game. To read it, go to Terminal and enter

cat hackers-starting-handbook.lit"}),n=Object(c.createElement)("a",{class:"a-link-button",float:"right",padding:"6px",innerText:"Got it!",clickListener:()=>{Object(m.removeElementById)(e)}});Object(u.createPopup)(e,[t,n]),a.Player.getHomeComputer().messages.push("hackers-starting-handbook.lit")}function b(e){var t=document.getElementById("interactive-tutorial-text");if(null==t)throw new Error("Could not find text box");t.innerHTML=e,t.parentElement.scrollTop=0}},,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(116),a=n(481),i=n(480),o=n(111),s=n(479),l=n(478),c=n(84),u=n(75),m=n(146),p=n(477),h=n(6),d=n(115),_=n(0),g=n(198),y=n(11),f=n(2),b=n(8),E=n(16),v=n(1),k=n(50);function C(e,n,r,s,l,c=null){const u=c instanceof d.WorkerScript;if(!(e instanceof o.Stock))return u?c.log("placeOrder",`Invalid stock: '${e}'`):b.dialogBoxCreate("ERROR: Invalid stock passed to placeOrder() function"),!1;if("number"!=typeof n||"number"!=typeof r)return u?c.log("placeOrder",`Invalid arguments: shares='${n}' price='${r}'`):b.dialogBoxCreate("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument"),!1;const m=new a.Order(e.symbol,n,r,s,l);if(null==t.StockMarket.Orders){const e={};for(const n in t.StockMarket){const r=t.StockMarket[n];r instanceof o.Stock&&(e[r.symbol]=[])}t.StockMarket.Orders=e}t.StockMarket.Orders[e.symbol].push(m);const p={rerenderFn:R,stockMarket:t.StockMarket,symbolToStockMap:t.SymbolToStockMap};return i.processOrders(e,m.type,m.pos,p),R(),!0}function P(e,n=null){var r=n instanceof d.WorkerScript;if(null==t.StockMarket.Orders)return!1;if(e.order&&e.order instanceof a.Order){const n=e.order;for(var i=t.StockMarket.Orders[n.stockSymbol],s=0;s=n.cap&&(s=.1,n.b=!1),isNaN(s)&&(s=.5);const l=Math.random(),m={rerenderFn:R,stockMarket:t.StockMarket,symbolToStockMap:t.SymbolToStockMap};l{!function(e){null!=t.CompanyPositions[e.name]&&console.warn(`Duplicate Company Position being defined: ${e.name}`),t.CompanyPositions[e.name]=new a.CompanyPosition(e)}(e)})},function(e,t,n){"use strict";var r=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(a,i){function o(e){try{l(r.next(e))}catch(e){i(e)}}function s(e){try{l(r.throw(e))}catch(e){i(e)}}function l(e){e.done?a(e.value):new n(function(t){t(e.value)}).then(o,s)}l((r=r.apply(e,t||[])).next())})};Object.defineProperty(t,"__esModule",{value:!0});const a=n(704),i=n(16),o=n(25),s=n(3),l=n(35),c=n(26);class u{constructor(e,t,n,r,a,i){this.name=e,this.desc=t,this.generate=n,this.solver=r,this.difficulty=a,this.numTries=i}}t.CodingContractType=u,t.CodingContractTypes={};for(const e of a.codingContractTypesMetadata)t.CodingContractTypes[e.name]=new u(e.name,e.desc,e.gen,e.solver,e.difficulty,e.numTries);var m;!function(e){e[e.FactionReputation=0]="FactionReputation",e[e.FactionReputationAll=1]="FactionReputationAll",e[e.CompanyReputation=2]="CompanyReputation",e[e.Money=3]="Money"}(t.CodingContractRewardType||(t.CodingContractRewardType={})),function(e){e[e.Success=0]="Success",e[e.Failure=1]="Failure",e[e.Cancelled=2]="Cancelled"}(m=t.CodingContractResult||(t.CodingContractResult={}));class p{constructor(e="",n="Find Largest Prime Factor",r=null){if(this.tries=0,this.fn=e,this.fn.endsWith(".cct")||(this.fn+=".cct"),null==t.CodingContractTypes[n])throw new Error(`Error: invalid contract type: ${n} please contact developer`);this.type=n,this.data=t.CodingContractTypes[n].generate(),this.reward=r}static fromJSON(e){return i.Generic_fromJSON(p,e.data)}getData(){return this.data}getDescription(){return t.CodingContractTypes[this.type].desc(this.data)}getDifficulty(){return t.CodingContractTypes[this.type].difficulty}getMaxNumTries(){return t.CodingContractTypes[this.type].numTries}getType(){return t.CodingContractTypes[this.type].name}isSolution(e){return t.CodingContractTypes[this.type].solver(this.data,e)}prompt(){return r(this,void 0,void 0,function*(){return new Promise((e,n)=>{const r=t.CodingContractTypes[this.type],a=`coding-contract-prompt-popup-${this.fn}`,i=s.createElement("p",{innerHTML:["You are attempting to solve a Coding Contract. You have",`${this.getMaxNumTries()-this.tries} tries remaining,`,"after which the contract will self-destruct.

",`${r.desc(this.data).replace(/\n/g,"
")}`].join(" ")});let u,p,h;u=s.createElement("input",{onkeydown:e=>{e.keyCode===o.KEY.ENTER&&""!==u.value?(e.preventDefault(),p.click()):e.keyCode===o.KEY.ESC&&(e.preventDefault(),h.click())},placeholder:"Enter Solution here",width:"50%"}),p=s.createElement("a",{class:"a-link-button",clickListener:()=>{const t=u.value;this.isSolution(t)?e(m.Success):e(m.Failure),c.removeElementById(a)},innerText:"Solve"}),h=s.createElement("a",{class:"a-link-button",clickListener:()=>{e(m.Cancelled),c.removeElementById(a)},innerText:"Cancel"});const d=s.createElement("br");l.createPopup(a,[i,d,d,u,p,h]),u.focus()})})}toJSON(){return i.Generic_toJSON("CodingContract",this)}}t.CodingContract=p,i.Reviver.constructors.CodingContract=p},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isString=function(e){return"string"==typeof e||e instanceof String}},function(e,t,n){"use strict";n.d(t,"c",function(){return o}),n.d(t,"b",function(){return s}),n.d(t,"d",function(){return l}),n.d(t,"a",function(){return c});var r=n(63),a=(n(163),n(46)),i=n(19);function o(e,t){return new Promise(function(n,a){t.delay=Object(r.setTimeoutRef)(()=>{t.delay=null,n()},e),t.delayResolve=n})}function s(e,t,n=null){var r="";null!=n&&(r=" (Line "+function(e,t){var n=t.scriptRef.codeCode();try{return((n=n.substring(0,e.start)).match(/\n/g)||[]).length+1}catch(e){return-1}}(n,e)+")");const a=i.AllServers[e.serverIp];if(null==a)throw new Error(`WorkerScript constructed with invalid server ip: ${this.serverIp}`);return"|"+a.hostname+"|"+e.name+"|"+t+r}function l(e,t,n){const r=e.scriptRef.threads;if(!n)return isNaN(r)||r<1?1:r;const a=0|n;if(isNaN(n)||a<1)throw s(e,`Invalid thread count passed to ${t}: ${n}. Threads must be a positive number.`);if(n>r)throw s(e,`Too many threads requested by ${t}. Requested: ${n}. Has: ${r}.`);return a}function c(e){if(!Object(a.isString)(e))return!1;let t=e.split("|");if(4!=t.length)return!1;t[1];return!0}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(8);t.exceptionAlert=function(e){console.error(e),r.dialogBoxCreate("Caught an exception: "+e+"

Filename: "+(e.fileName||"UNKNOWN FILE NAME")+"

Line Number: "+(e.lineNumber||"UNKNOWN LINE NUMBER")+"

This is a bug, please report to game developer with this message as well as details about how to reproduce the bug.

If you want to be safe, I suggest refreshing the game WITHOUT saving so that your safe doesn't get corrupted",!1)}},function(e,t,n){"use strict";n.r(t),n.d(t,"inviteToFaction",function(){return T}),n.d(t,"joinFaction",function(){return S}),n.d(t,"startHackingMission",function(){return O}),n.d(t,"displayFactionContent",function(){return M}),n.d(t,"purchaseAugmentationBoxCreate",function(){return x}),n.d(t,"hasAugmentationPrereqs",function(){return w}),n.d(t,"purchaseAugmentation",function(){return A}),n.d(t,"getNextNeurofluxLevel",function(){return R}),n.d(t,"processPassiveFactionRepGain",function(){return N});var r=n(1),a=n.n(r),i=n(50),o=n.n(i),s=n(288),l=n(10),c=n(69),u=n(124),m=n(4),p=n(18),h=n(6),d=n(12),_=n(73),g=n(13),y=n(67),f=n(0),b=n(17),E=n(11),v=n(8),k=n(287),C=(n(16),n(7)),P=n(43);function T(e){b.Settings.SuppressFactionInvites?(e.alreadyInvited=!0,f.Player.factionInvitations.push(e.name),E.routing.isOn(E.Page.Factions)&&d.Engine.loadFactionsContent()):Object(k.a)(e)}function S(e){e.isMember=!0,f.Player.factions.push(e.name);const t=e.getInfo();for(const e in t.enemies){const n=t.enemies[e];g.Factions[n]instanceof _.Faction&&(g.Factions[n].isBanned=!0)}}function O(e){const t=new y.a(e.playerReputation,e);Object(y.d)(!0,t),t.init()}function M(e,t=!1){const n=g.Factions[e];if(null==n)throw new Error(`Invalid factionName passed into displayFactionContent(): ${e}`);if(!n.isMember)throw new Error("Not a member of this faction. Cannot display faction information");o.a.render(a.a.createElement(s.FactionRoot,{engine:d.Engine,initiallyOnAugmentationsPage:t,faction:n,p:f.Player,startHackingMissionFn:O}),d.Engine.Display.factionContent)}function x(e,t){const n=t.getInfo(),r=Object(P.yesNoBoxGetYesButton)();r.innerHTML="Purchase",r.addEventListener("click",function(){!Object(c.f)(e)&&f.Player.hasAugmentation(e)||(A(e,t),Object(P.yesNoBoxClose)())});const a=Object(P.yesNoBoxGetNoButton)();a.innerHTML="Cancel",a.addEventListener("click",function(){Object(P.yesNoBoxClose)()}),Object(P.yesNoBoxCreate)("

"+e.name+"


"+e.info+"


Would you like to purchase the "+e.name+" Augmentation for $"+Object(C.formatNumber)(e.baseCost*n.augmentationPriceMult,2)+"?")}function w(e){let t=!0;if(e.prereqs&&e.prereqs.length>0)for(let n=0;n=t.HacknetNodeMaxCores)return 1/0;const a=t.BaseCostForHacknetNodeCore,i=t.HacknetNodeUpgradeCoreMult;let o=0,s=this.cores;for(let e=0;e=t.HacknetNodeMaxLevel)return 1/0;const a=t.HacknetNodeUpgradeLevelMult;let i=0,o=this.level;for(let e=0;e=t.HacknetNodeMaxRam)return 1/0;let a=0,i=Math.round(Math.log2(this.ram)),o=this.ram;for(let e=0;e1?1:r<0?0:r}function o(e){null==e.baseDifficulty&&(e.baseDifficulty=e.hackDifficulty);var t=3;return(t+=e.baseDifficulty*a.Player.hacking_exp_mult*.3)*r.BitNodeMultipliers.HackExpGain}function s(e){const t=(100-e.hackDifficulty)/100*((a.Player.hacking_skill-(e.requiredHackingSkill-1))/a.Player.hacking_skill)*a.Player.hacking_money_mult/240;return t<0?0:t>1?1:t*r.BitNodeMultipliers.ScriptHackMoney}function l(e,t,n){const r=e.requiredHackingSkill*e.hackDifficulty;null==t&&(t=a.Player.hacking_skill),null==n&&(n=a.Player.intelligence);var i=2.5*r+500;return 5*(i/=t+50+.1*n)/a.Player.hacking_speed_mult}function c(e,t,n){return 3.2*l(e,t,n)}function u(e,t,n){return 4*l(e,t,n)}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const r=n(3),a=n(80);t.createPopupCloseButton=function(e,t){let n;function i(e){27===e.keyCode&&n.click()}return n=r.createElement("button",{class:t.class?t.class:"popup-box-button",display:t.display?t.display:"inline-block",innerText:null==t.innerText?"Cancel":t.innerText,clickListener:()=>{if(e instanceof Element)a.removeElement(e);else try{const t=document.getElementById(e);t instanceof Element&&a.removeElement(t)}catch(e){console.error(`createPopupCloseButton() threw: ${e}`)}return document.removeEventListener("keydown",i),!1}}),document.addEventListener("keydown",i),n}},,function(e,t,n){"use strict";n.d(t,"a",function(){return x}),n.d(t,"c",function(){return A}),n.d(t,"e",function(){return N}),n.d(t,"f",function(){return I}),n.d(t,"b",function(){return B}),n.d(t,"d",function(){return L});var r=n(65),a=n(115),i=n(85),o=n(100),s=n(153),l=n(6),c=n(12),u=n(277),m=n(47),p=n(126),h=n(200),d=n(106),_=n(0),g=n(113),y=n(170),f=n(71),b=n(19),E=n(17),v=n(63),k=n(181),C=n(8),P=(n(147),n(81)),T=n(151),S=n(7),O=n(79);const M=n(176),x=[];for(var w=0;w{i=!0;let t=e.source.value;t.startsWith("./")&&(t=t.slice(2));let n=function(e){for(let t=0;t{n.push(e.id.name),r.push(e)}}),a+="var "+t+";\n(function (namespace) {\n",r.forEach(e=>{a+=Object(k.generate)(e),a+="\n"}),n.forEach(e=>{a+="namespace."+e+" = "+e,a+="\n"}),a+="})("+t+" || ("+t+" = {}));\n"}else{let t=[];e.specifiers.forEach(e=>{t.push(e.local.name)});let n=[];M.simple(o,{FunctionDeclaration:e=>{t.includes(e.id.name)&&n.push(e)}}),n.forEach(e=>{a+=Object(k.generate)(e),a+="\n"})}}}),!i)return{code:e,lineOffset:0};var o=0;if("Program"!==n.type||null==n.body)throw new Error("Code could not be properly parsed");for(let e=n.body.length-1;e>=0;--e)"ImportDeclaration"===n.body[e].type&&(n.body.splice(e,1),++o);var s=(a.match(/\n/g)||[]).length-o;return e=Object(k.generate)(n),{code:e=a+e,lineOffset:s}}(t,e);n=a.code,i=a.lineOffset}catch(t){return Object(C.dialogBoxCreate)("Error processing Imports in "+e.name+":
"+t),e.env.stopFlag=!0,e.running=!1,void Object(r.killWorkerScript)(e)}var o;try{o=new u.a(n,function(t,n){var r=Object(p.a)(e);for(let e in r){let a=r[e];if("function"==typeof a)if("hack"===e||"grow"===e||"weaken"===e||"sleep"===e||"prompt"===e){let r=function(){let e=[];for(let n=0;n"+t),e.env.stopFlag=!0,e.running=!1,void Object(r.killWorkerScript)(e)}return new Promise(function(t,n){try{!function r(){try{if(e.env.stopFlag)return n(e);o.step()?Object(v.setTimeoutRef)(r,E.Settings.CodeInstructionRunTime):t(e)}catch(t){return t=t.toString(),Object(m.a)(t)||(t=Object(m.b)(e,t)),e.errorMessage=t,n(e)}}()}catch(t){return Object(S.isString)(t)?(e.errorMessage=t,n(e)):t instanceof a.WorkerScript?n(t):n(e)}})}function N(e,t){return D(e,t)?(t.runScript(e,_.Player.hacknet_node_money_mult),e.pid):0}function D(e,t){e.filename;let n=1;e.threads&&!isNaN(e.threads)?n=e.threads:e.threads=1;const l=Object(T.roundToTwo)(Object(y.getRamUsageFromRunningScript)(e)*n);if(l>t.maxRam-t.ramUsed)return Object(C.dialogBoxCreate)(`Not enough RAM to run script ${e.filename} with args `+`${Object(P.arrayToString)(e.args)}. This likely occurred because you re-loaded `+"the game and the script's RAM usage increased (either because of an update to the game or your changes to the script.)"),!1;t.ramUsed=Object(T.roundToTwo)(t.ramUsed+l);const c=Object(s.generateNextPid)();if(-1===c)throw new Error("Failed to start script because could not find available PID. This is most because you have too many scripts running.");const u=new a.WorkerScript(e,c,p.a);u.ramUsage=l,i.workerScripts.set(c,u),o.WorkerScriptStartStopEventEmitter.emitEvent();let d=null;if(u.name.endsWith(".js")||u.name.endsWith(".ns"))d=function(e){e.running=!0;let t=null;function n(n,r){return function(...a){if(e.env.stopFlag)throw e;if("sleep"===n)return r(...a);if(t)throw e.errorMessage=Object(m.b)(e,sprintf("Concurrent calls to Netscript functions not allowed! Did you forget to await hack(), grow(), or some other promise-returning function? (Currently running: %s tried to run: %s)",t,n),null),e;let i;t=n;try{i=r(...a)}catch(e){throw t=null,e}return i&&void 0!==i.finally?i.finally(function(){t=null}):(t=null,i)}}for(let t in e.env.vars)"function"==typeof e.env.vars[t]&&(e.env.vars[t]=n(t,e.env.vars[t]));return Object(h.a)(e.getServer().scripts,e).then(function(t){return void 0===t?e:[t,e]}).catch(t=>{if(t instanceof Error)throw e.errorMessage=Object(m.b)(e,t.message+(t.stack&&"\nstack:\n"+t.stack.toString()||"")),e;if(Object(m.a)(t))throw e.errorMessage=t,e;throw t})}(u);else if(!((d=R(u))instanceof Promise))return!1;return d.then(function(e){e.running&&(Object(r.killWorkerScript)(u),e.log("","Script finished running"))}).catch(function(e){if(e instanceof Error)return Object(C.dialogBoxCreate)("Script runtime unknown error. This is a bug please contact game developer"),void console.error("Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: "+e.toString());if(e instanceof a.WorkerScript){if(!Object(m.a)(e.errorMessage))return void e.log("","Script killed");{const t=e.errorMessage.split("|");if(4!=t.length)return console.error("ERROR: Something wrong with Error text in evaluator..."),void console.error("Error text: "+errorText);const n=t[1],r=t[2],a=t[3];let i=`RUNTIME ERROR
${r}@${n}
`;e.args.length>0&&(i+=`Args: ${Object(P.arrayToString)(e.args)}
`),i+="
",i+=a,Object(C.dialogBoxCreate)(i),e.log("","Script crashed with runtime error")}e.running=!1,e.env.stopFlag=!0}else{if(Object(m.a)(e))return Object(C.dialogBoxCreate)("Script runtime unknown error. This is a bug please contact game developer"),void console.error("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: "+e.toString());Object(C.dialogBoxCreate)("An unknown script died for an unknown reason. This is a bug please contact game dev"),console.error(e)}Object(r.killWorkerScript)(u)}),!0}function I(e=1){var t=e*c.Engine._idleSpeed/1e3;for(const e of i.workerScripts.values())e.scriptRef.onlineRunningTime+=t}function B(){var e=0;let t=-1!==window.location.href.toLowerCase().indexOf("?noscripts");t&&console.info("Skipping the load of any scripts during startup");for(const n in b.AllServers)if(b.AllServers.hasOwnProperty(n)){const r=b.AllServers[n];r.ramUsed=0;for(let e=0;ec)return i.log(e,`Cannot run script '${n}' (t=${o}) on '${t.hostname}' because there is not enough available RAM!`),0;{i.log(e,`'${n}' on '${t.hostname}' with ${o} threads and args: ${Object(P.arrayToString)(r)}.`);let a=new g.RunningScript(s,r);return a.threads=o,N(a,t)}}return i.log(e,`Could not find script '${n}' on '${t.hostname}'`),0}},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return P}),n.d(t,"f",function(){return T}),n.d(t,"e",function(){return S}),n.d(t,"b",function(){return O}),n.d(t,"c",function(){return A}),n.d(t,"d",function(){return N});var r=n(286),a=n(285),i=n(12),o=n(73),s=n(13),l=n(49),c=n(11),u=n(2),m=n(8),p=n(16),h=n(7),d=n(48),_=n(14),g=n(25),y=n(201),f=n(3),b=n(35),E=n(42),v=n(80),k=n(26);e(document).keydown(function(e){if(c.routing.isOn(c.Page.Gang)&&e.altKey){if(null!=D.gangMemberFilter&&D.gangMemberFilter===document.activeElement)return;e.keyCode===g.KEY[1]?"block"===D.gangTerritorySubpage.style.display&&D.managementButton.click():e.keyCode===g.KEY[2]&&"block"===D.gangManagementSubpage.style.display&&D.territoryButton.click()}}),e(document).mousedown(function(t){D.gangMemberUpgradeBoxOpened&&null==e(t.target).closest("#gang-member-upgrade-popup-box-content").get(0)&&(Object(v.removeElement)(D.gangMemberUpgradeBox),D.gangMemberUpgradeBox=null,D.gangMemberUpgradeBoxContent=null,D.gangMemberUpgradeBoxOpened=!1,D.gangMemberUpgradeBoxElements=null)});const C=["Slum Snakes","Tetrads","The Syndicate","The Dark Army","Speakers for the Dead","NiteSec","The Black Hand"];let P={"Slum Snakes":{power:1,territory:1/7},Tetrads:{power:1,territory:1/7},"The Syndicate":{power:1,territory:1/7},"The Dark Army":{power:1,territory:1/7},"Speakers for the Dead":{power:1,territory:1/7},NiteSec:{power:1,territory:1/7},"The Black Hand":{power:1,territory:1/7}};function T(){P={"Slum Snakes":{power:1,territory:1/7},Tetrads:{power:1,territory:1/7},"The Syndicate":{power:1,territory:1/7},"The Dark Army":{power:1,territory:1/7},"Speakers for the Dead":{power:1,territory:1/7},NiteSec:{power:1,territory:1/7},"The Black Hand":{power:1,territory:1/7}}}function S(e){P=JSON.parse(e,p.Reviver)}function O(e,t=!1){this.facName=e,this.members=[],this.wanted=1,this.respect=1,this.isHackingGang=t,this.respectGainRate=0,this.wantedGainRate=0,this.moneyGainRate=0,this.storedCycles=0,this.storedTerritoryAndPowerCycles=0,this.territoryClashChance=0,this.territoryWarfareEngaged=!1,this.notifyMemberDeath=!0}function M(e,t){const n=Math.max(1,1+Math.log(P[e].power/P[t].power)/Math.log(50));return Math.min(P[t].territory,1e-4*n*(Math.random()+.5))}function x(e){this.name=e,this.task="Unassigned",this.earnedRespect=0,this.hack=1,this.str=1,this.def=1,this.dex=1,this.agi=1,this.cha=1,this.hack_exp=0,this.str_exp=0,this.def_exp=0,this.dex_exp=0,this.agi_exp=0,this.cha_exp=0,this.hack_mult=1,this.str_mult=1,this.def_mult=1,this.dex_mult=1,this.agi_mult=1,this.cha_mult=1,this.hack_asc_mult=1,this.str_asc_mult=1,this.def_asc_mult=1,this.dex_asc_mult=1,this.agi_asc_mult=1,this.cha_asc_mult=1,this.upgrades=[],this.augmentations=[]}function w(e="",t="",n=!1,r=!1,a={baseRespect:0,baseWanted:0,baseMoney:0,hackWeight:0,strWeight:0,defWeight:0,dexWeight:0,agiWeight:0,chaWeight:0,difficulty:0}){this.name=e,this.desc=t,this.isHacking=n,this.isCombat=r,this.baseRespect=a.baseRespect?a.baseRespect:0,this.baseWanted=a.baseWanted?a.baseWanted:0,this.baseMoney=a.baseMoney?a.baseMoney:0,this.hackWeight=a.hackWeight?a.hackWeight:0,this.strWeight=a.strWeight?a.strWeight:0,this.defWeight=a.defWeight?a.defWeight:0,this.dexWeight=a.dexWeight?a.dexWeight:0,this.agiWeight=a.agiWeight?a.agiWeight:0,this.chaWeight=a.chaWeight?a.chaWeight:0,100!=Math.round(this.hackWeight+this.strWeight+this.defWeight+this.dexWeight+this.agiWeight+this.chaWeight)&&console.error(`GangMemberTask ${this.name} weights do not add up to 100`),this.difficulty=a.difficulty?a.difficulty:1,this.territory=a.territory?a.territory:{money:1,respect:1,wanted:1}}O.prototype.getPower=function(){return P[this.facName].power},O.prototype.getTerritory=function(){return P[this.facName].territory},O.prototype.process=function(e=1,t){const n=1e3/i.Engine._idleSpeed;if(isNaN(e)&&console.error(`NaN passed into Gang.process(): ${e}`),this.storedCycles+=e,this.storedCycles<2*n)return;const r=Math.min(this.storedCycles,5*n);try{this.processGains(r,t),this.processExperienceGains(r),this.processTerritoryAndPowerGains(r),this.storedCycles-=r}catch(e){Object(d.exceptionAlert)(`Exception caught when processing Gang: ${e}`)}},O.prototype.processGains=function(e=1,t){for(var n=0,r=0,a=0,i=0;it&&(n=1),this.wanted=n,this.wanted<1&&(this.wanted=1)}else console.warn("ERROR: wantedLevelGains is NaN");"number"==typeof n?(t.gainMoney(n*e),t.recordMoneySource(n*e,"gang")):console.warn("ERROR: respectGains is NaN")},O.prototype.processTerritoryAndPowerGains=function(e=1){if(this.storedTerritoryAndPowerCycles+=e,this.storedTerritoryAndPowerCycles<100)return;this.storedTerritoryAndPowerCycles-=100;const t=this.facName;for(const e in P)if(P.hasOwnProperty(e))if(e==t)P[e].power+=this.calculatePower();else{const t=Math.random();if(t<.5){const t=.005*P[e].power;P[e].power+=Math.min(.85,t)}else{const n=.75*t*P[e].territory;P[e].power+=n}}this.territoryWarfareEngaged?this.territoryClashChance=1:this.territoryClashChance>0&&(this.territoryClashChance=Math.max(0,this.territoryClashChance-.01));for(let e=0;et!==C[e]),r=Object(_.getRandomInt)(0,n.length-1),a=C[e],i=n[r];if(!(a!==t&&i!==t||Math.random()=30)&&this.respect>=this.getRespectNeededToRecruitMember()},O.prototype.getRespectNeededToRecruitMember=function(){if(this.members.length<3)return 0;const e=this.members.length-2;return Math.round(.9*Math.pow(e,3)+Math.pow(e,2))},O.prototype.recruitMember=function(e){if(""===(e=String(e))||!this.canRecruitMember())return!1;if(this.members.filter(t=>t.name===e).length>=1)return!1;let t=new x(e);return this.members.push(t),c.routing.isOn(c.Page.Gang)&&(this.createGangMemberDisplayElement(t),this.updateGangContent()),!0},O.prototype.getWantedPenalty=function(){return this.respect/(this.respect+this.wanted)},O.prototype.processExperienceGains=function(e=1){for(var t=0;t=0;--e){const n=this.members[e];if("Territory Warfare"!==n.task)continue;const r=t/Math.pow(n.def,.6);Math.random()")):t.log(`Ascended Gang member ${e.name}`),c.routing.isOn(c.Page.Gang)&&this.displayGangMemberList(),n}catch(e){if(null!=t)throw e;Object(d.exceptionAlert)(e)}},O.prototype.getDiscount=function(){const e=this.getPower(),t=this.respect,n=Math.pow(t,.01)+t/5e6+Math.pow(e,.01)+e/1e6-1;return Math.max(1,n)},O.prototype.getAllTaskNames=function(){let e=[];const t=Object.keys(A);return e=this.isHackingGang?t.filter(e=>{let t=A[e];return null!=t&&("Unassigned"!==e&&t.isHacking)}):t.filter(e=>{let t=A[e];return null!=t&&("Unassigned"!==e&&t.isCombat)})},O.prototype.getAllUpgradeNames=function(){return Object.keys(N)},O.prototype.getUpgradeCost=function(e){return null==N[e]?1/0:N[e].getCost(this)},O.prototype.getUpgradeType=function(e){const t=N[e];if(null==t)return"";switch(t.type){case"w":return"Weapon";case"a":return"Armor";case"v":return"Vehicle";case"r":return"Rootkit";case"g":return"Augmentation";default:return""}},O.prototype.toJSON=function(){return Object(p.Generic_toJSON)("Gang",this)},O.fromJSON=function(e){return Object(p.Generic_fromJSON)(O,e.data)},p.Reviver.constructors.Gang=O,x.prototype.calculateSkill=function(e,t=1){return Math.max(Math.floor(t*(32*Math.log(e+534.5)-200)),1)},x.prototype.updateSkillLevels=function(){this.hack=this.calculateSkill(this.hack_exp,this.hack_mult*this.hack_asc_mult),this.str=this.calculateSkill(this.str_exp,this.str_mult*this.str_asc_mult),this.def=this.calculateSkill(this.def_exp,this.def_mult*this.def_asc_mult),this.dex=this.calculateSkill(this.dex_exp,this.dex_mult*this.dex_asc_mult),this.agi=this.calculateSkill(this.agi_exp,this.agi_mult*this.agi_asc_mult),this.cha=this.calculateSkill(this.cha_exp,this.cha_mult*this.cha_asc_mult)},x.prototype.calculatePower=function(){return(this.hack+this.str+this.def+this.dex+this.agi+this.cha)/95},x.prototype.assignToTask=function(e){return A.hasOwnProperty(e)?(this.task=e,!0):(this.task="Unassigned",!1)},x.prototype.unassignFromTask=function(){this.task="Unassigned"},x.prototype.getTask=function(){return this.task instanceof w&&(this.task=this.task.name),A.hasOwnProperty(this.task)?A[this.task]:A.Unassigned},x.prototype.calculateRespectGain=function(e){const t=this.getTask();if(null==t||!(t instanceof w)||0===t.baseRespect)return 0;var n=t.hackWeight/100*this.hack+t.strWeight/100*this.str+t.defWeight/100*this.def+t.dexWeight/100*this.dex+t.agiWeight/100*this.agi+t.chaWeight/100*this.cha;if((n-=4*t.difficulty)<=0)return 0;const r=Math.pow(100*P[e.facName].territory,t.territory.respect)/100;if(isNaN(r)||r<=0)return 0;var a=e.getWantedPenalty();return 11*t.baseRespect*n*r*a},x.prototype.calculateWantedLevelGain=function(e){const t=this.getTask();if(null==t||!(t instanceof w)||0===t.baseWanted)return 0;let n=t.hackWeight/100*this.hack+t.strWeight/100*this.str+t.defWeight/100*this.def+t.dexWeight/100*this.dex+t.agiWeight/100*this.agi+t.chaWeight/100*this.cha;if((n-=3.5*t.difficulty)<=0)return 0;const r=Math.pow(100*P[e.facName].territory,t.territory.wanted)/100;if(isNaN(r)||r<=0)return 0;if(t.baseWanted<0)return.4*t.baseWanted*n*r;{const e=7*t.baseWanted/Math.pow(3*n*r,.8);return Math.min(100,e)}},x.prototype.calculateMoneyGain=function(e){const t=this.getTask();if(null==t||!(t instanceof w)||0===t.baseMoney)return 0;var n=t.hackWeight/100*this.hack+t.strWeight/100*this.str+t.defWeight/100*this.def+t.dexWeight/100*this.dex+t.agiWeight/100*this.agi+t.chaWeight/100*this.cha;if((n-=3.2*t.difficulty)<=0)return 0;const r=Math.pow(100*P[e.facName].territory,t.territory.money)/100;if(isNaN(r)||r<=0)return 0;var a=e.getWantedPenalty();return 5*t.baseMoney*n*r*a},x.prototype.gainExperience=function(e=1){const t=this.getTask();if(null==t||!(t instanceof w)||t===A.Unassigned)return;const n=Math.pow(t.difficulty,.9)*e;this.hack_exp+=t.hackWeight/1500*n,this.str_exp+=t.strWeight/1500*n,this.def_exp+=t.defWeight/1500*n,this.dex_exp+=t.dexWeight/1500*n,this.agi_exp+=t.agiWeight/1500*n,this.cha_exp+=t.chaWeight/1500*n},x.prototype.recordEarnedRespect=function(e=1,t){this.earnedRespect+=this.calculateRespectGain(t)*e},x.prototype.ascend=function(){const e=this.getAscensionResults(),t=e.hack,n=e.str,r=e.def,a=e.dex,i=e.agi,o=e.cha;this.hack_asc_mult+=t,this.str_asc_mult+=n,this.def_asc_mult+=r,this.dex_asc_mult+=a,this.agi_asc_mult+=i,this.cha_asc_mult+=o,this.upgrades.length=0,this.hack_mult=1,this.str_mult=1,this.def_mult=1,this.dex_mult=1,this.agi_mult=1,this.cha_mult=1;for(let e=0;e{!function(e,t,n,r,a){A[e]=new w(e,t,n,r,a)}(e.name,e.desc,e.isHacking,e.isCombat,e.params)}),R.prototype.getCost=function(e){const t=e.getDiscount();return this.cost/t},R.prototype.createDescription=function(){const e=["Increases:"];null!=this.mults.str&&e.push(`* Strength by ${Math.round(100*(this.mults.str-1))}%`),null!=this.mults.def&&e.push(`* Defense by ${Math.round(100*(this.mults.def-1))}%`),null!=this.mults.dex&&e.push(`* Dexterity by ${Math.round(100*(this.mults.dex-1))}%`),null!=this.mults.agi&&e.push(`* Agility by ${Math.round(100*(this.mults.agi-1))}%`),null!=this.mults.cha&&e.push(`* Charisma by ${Math.round(100*(this.mults.cha-1))}%`),null!=this.mults.hack&&e.push(`* Hacking by ${Math.round(100*(this.mults.hack-1))}%`),this.desc=e.join("
")},R.prototype.apply=function(e){null!=this.mults.str&&(e.str_mult*=this.mults.str),null!=this.mults.def&&(e.def_mult*=this.mults.def),null!=this.mults.dex&&(e.dex_mult*=this.mults.dex),null!=this.mults.agi&&(e.agi_mult*=this.mults.agi),null!=this.mults.cha&&(e.cha_mult*=this.mults.cha),null!=this.mults.hack&&(e.hack_mult*=this.mults.hack)},R.prototype.toJSON=function(){return Object(p.Generic_toJSON)("GangMemberUpgrade",this)},R.fromJSON=function(e){return Object(p.Generic_fromJSON)(R,e.data)},p.Reviver.constructors.GangMemberUpgrade=R;const N={};a.gangMemberUpgradesMetadata.forEach(e=>{!function(e,t,n,r){N[e]=new R(e,t,n,r)}(e.name,e.cost,e.upgType,e.mults)}),O.prototype.createGangMemberUpgradeBox=function(e,t=""){const n="gang-member-upgrade-popup-box";if(D.gangMemberUpgradeBoxOpened){if(null==D.gangMemberUpgradeBoxElements||null==D.gangMemberUpgradeBox||null==D.gangMemberUpgradeBoxContent)return void console.error("Refreshing Gang member upgrade box throws error because required elements are null");for(var r=2;r-1||this.members[r].task.indexOf(a)>-1){var i=this.members[r].createGangMemberUpgradePanel(this,e);D.gangMemberUpgradeBoxContent.appendChild(i),D.gangMemberUpgradeBoxElements.push(i)}}else{D.gangMemberUpgradeBoxFilter=Object(f.createElement)("input",{type:"text",placeholder:"Filter gang members",value:t,onkeyup:()=>{var t=D.gangMemberUpgradeBoxFilter.value.toString();this.createGangMemberUpgradeBox(e,t)}}),D.gangMemberUpgradeBoxDiscount=Object(f.createElement)("p",{innerText:"Discount: -"+u.numeralWrapper.format(1-1/this.getDiscount(),"0.00%"),marginLeft:"6px",tooltip:"You get a discount on equipment and upgrades based on your gang's respect and power. More respect and power leads to more discounts."}),D.gangMemberUpgradeBoxElements=[D.gangMemberUpgradeBoxFilter,D.gangMemberUpgradeBoxDiscount];for(a=D.gangMemberUpgradeBoxFilter.value.toString(),r=0;r-1||this.members[r].task.indexOf(a)>-1)&&D.gangMemberUpgradeBoxElements.push(this.members[r].createGangMemberUpgradePanel(this,e));D.gangMemberUpgradeBox=Object(b.createPopup)(n,D.gangMemberUpgradeBoxElements),D.gangMemberUpgradeBoxContent=document.getElementById(n+"-content"),D.gangMemberUpgradeBoxOpened=!0}},x.prototype.createGangMemberUpgradePanel=function(e,t){var n=Object(f.createElement)("div",{border:"1px solid white"}),r=Object(f.createElement)("h1",{innerText:this.name+" ("+this.task+")"});n.appendChild(r);var a=Object(f.createElement)("pre",{fontSize:"14px",display:"inline-block",width:"20%",innerText:"Hack: "+this.hack+" (x"+Object(h.formatNumber)(this.hack_mult*this.hack_asc_mult,2)+")\nStr: "+this.str+" (x"+Object(h.formatNumber)(this.str_mult*this.str_asc_mult,2)+")\nDef: "+this.def+" (x"+Object(h.formatNumber)(this.def_mult*this.def_asc_mult,2)+")\nDex: "+this.dex+" (x"+Object(h.formatNumber)(this.dex_mult*this.dex_asc_mult,2)+")\nAgi: "+this.agi+" (x"+Object(h.formatNumber)(this.agi_mult*this.agi_asc_mult,2)+")\nCha: "+this.cha+" (x"+Object(h.formatNumber)(this.cha_mult*this.cha_asc_mult,2)+")\n"});const i=[];function o(e){const t=N[e];null!=t?i.push(Object(f.createElement)("div",{class:"gang-owned-upgrade",innerText:e,tooltip:t.desc})):console.error(`Could not find GangMemberUpgrade object for name ${e}`)}for(const e of this.upgrades)o(e);for(const e of this.augmentations)o(e);var s=Object(f.createElement)("div",{class:"gang-owned-upgrades-div",innerText:"Purchased Upgrades:"});for(const e of i)s.appendChild(e);n.appendChild(a),n.appendChild(s),n.appendChild(Object(f.createElement)("br",{}));const l=[],c=[],m=[],p=[],d=[];for(let n in N)if(N.hasOwnProperty(n)){let r=N[n];if(t.money.lt(r.getCost(e)))continue;if(this.upgrades.includes(n)||this.augmentations.includes(n))continue;switch(r.type){case"w":l.push(r);break;case"a":c.push(r);break;case"v":m.push(r);break;case"r":p.push(r);break;case"g":d.push(r);break;default:console.error(`ERROR: Invalid Gang Member Upgrade Type: ${r.type}`)}}const _=Object(f.createElement)("div",{width:"20%",display:"inline-block"}),g=Object(f.createElement)("div",{width:"20%",display:"inline-block"}),y=Object(f.createElement)("div",{width:"20%",display:"inline-block"}),b=Object(f.createElement)("div",{width:"20%",display:"inline-block"}),E=Object(f.createElement)("div",{width:"20%",display:"inline-block"});_.appendChild(Object(f.createElement)("h2",{innerText:"Weapons"})),g.appendChild(Object(f.createElement)("h2",{innerText:"Armor"})),y.appendChild(Object(f.createElement)("h2",{innerText:"Vehicles"})),b.appendChild(Object(f.createElement)("h2",{innerText:"Rootkits"})),E.appendChild(Object(f.createElement)("h2",{innerText:"Augmentations"}));const v=[l,c,m,p,d],k=[_,g,y,b,E];for(let n=0;n(a.buyUpgrade(n,t,e),!1)};i>=3?s.tooltipleft=n.desc:s.tooltip=n.desc,r.appendChild(Object(f.createElement)("a",s))}(r[i],a,this,n,e)}}return n.appendChild(_),n.appendChild(g),n.appendChild(y),n.appendChild(b),n.appendChild(E),n};const D={gangContentCreated:!1,gangContainer:null,managementButton:null,territoryButton:null,gangManagementSubpage:null,gangTerritorySubpage:null,gangDesc:null,gangInfo:null,gangRecruitMemberButton:null,gangRecruitRequirementText:null,gangExpandAllButton:null,gangCollapseAllButton:null,gangMemberFilter:null,gangManageEquipmentButton:null,gangMemberList:null,gangMemberPanels:{},gangMemberUpgradeBoxOpened:!1,gangMemberUpgradeBox:null,gangMemberUpgradeBoxContent:null,gangMemberUpgradeBoxFilter:null,gangMemberUpgradeBoxDiscount:null,gangMemberUpgradeBoxElements:null,gangTerritoryDescText:null,gangTerritoryWarfareCheckbox:null,gangTerritoryWarfareCheckboxLabel:null,gangTerritoryWarfareClashChance:null,gangTerritoryDeathNotifyCheckbox:null,gangTerritoryDeathNotifyCheckboxLabel:null,gangTerritoryInfoText:null};O.prototype.displayGangContent=function(e){if(!D.gangContentCreated||null==D.gangContainer){D.gangContentCreated=!0,D.gangContainer=Object(f.createElement)("div",{id:"gang-container",class:"generic-menupage-container"});var t=this.facName;this.members,this.wanted,this.respect;D.gangContainer.appendChild(Object(f.createElement)("a",{class:"a-link-button",display:"inline-block",innerText:"Back",clickListener:()=>(i.Engine.loadFactionContent(),Object(l.displayFactionContent)(t),!1)})),D.managementButton=Object(f.createElement)("a",{id:"gang-management-subpage-button",class:"a-link-button-inactive",display:"inline-block",innerHTML:"Gang Management (Alt+1)",clickListener:()=>(D.gangManagementSubpage.style.display="block",D.gangTerritorySubpage.style.display="none",D.managementButton.classList.toggle("a-link-button-inactive"),D.managementButton.classList.toggle("a-link-button"),D.territoryButton.classList.toggle("a-link-button-inactive"),D.territoryButton.classList.toggle("a-link-button"),this.updateGangContent(),!1)}),D.territoryButton=Object(f.createElement)("a",{id:"gang-territory-subpage-button",class:"a-link-button",display:"inline-block",innerHTML:"Gang Territory (Alt+2)",clickListener:()=>(D.gangManagementSubpage.style.display="none",D.gangTerritorySubpage.style.display="block",D.managementButton.classList.toggle("a-link-button-inactive"),D.managementButton.classList.toggle("a-link-button"),D.territoryButton.classList.toggle("a-link-button-inactive"),D.territoryButton.classList.toggle("a-link-button"),this.updateGangContent(),!1)}),D.gangContainer.appendChild(D.managementButton),D.gangContainer.appendChild(D.territoryButton),D.gangManagementSubpage=Object(f.createElement)("div",{display:"block",id:"gang-management-subpage"});var n="";n=this.isHackingGang?"Ethical Hacking":"Vigilante Justice",D.gangDesc=Object(f.createElement)("p",{width:"70%",innerHTML:"This page is used to manage your gang members and get an overview of your gang's stats.

If a gang member is not earning much money or respect, the task that you have assigned to that member might be too difficult. Consider training that member's stats or choosing an easier task. The tasks closer to the top of the dropdown list are generally easier. Alternatively, the gang member's low production might be due to the fact that your wanted level is too high. Consider assigning a few members to the '"+n+"' task to lower your wanted level.

Installing Augmentations does NOT reset your progress with your Gang. Furthermore, after installing Augmentations, you will automatically be a member of whatever Faction you created your gang with.

You can also manage your gang programmatically through Netscript using the Gang API"}),D.gangManagementSubpage.appendChild(D.gangDesc),D.gangInfo=Object(f.createElement)("p",{id:"gang-info",width:"70%"}),D.gangManagementSubpage.appendChild(D.gangInfo),D.gangRecruitMemberButton=Object(f.createElement)("a",{id:"gang-management-recruit-member-btn",class:"a-link-button-inactive",innerHTML:"Recruit Gang Member",display:"inline-block",margin:"10px",clickListener:()=>{const e="recruit-gang-member-popup";let t;const n=Object(f.createElement)("p",{innerText:"Please enter a name for your new Gang member:"}),r=Object(f.createElement)("br"),a=Object(f.createElement)("input",{onkeyup:e=>{e.keyCode===g.KEY.ENTER&&t.click()},placeholder:"Name must be unique",type:"text"});t=Object(f.createElement)("a",{class:"std-button",clickListener:()=>{let t=a.value;return""===t?(Object(m.dialogBoxCreate)("You must enter a name for your Gang member!"),!1):this.canRecruitMember()?this.recruitMember(t)?(Object(k.removeElementById)(e),!1):(Object(m.dialogBoxCreate)("You already have a gang member with this name!"),!1):(Object(m.dialogBoxCreate)("You cannot recruit another Gang member!"),!1)},innerText:"Recruit Gang Member"});const i=Object(f.createElement)("a",{class:"std-button",clickListener:()=>(Object(k.removeElementById)(e),!1),innerText:"Cancel"});Object(b.createPopup)(e,[n,r,a,t,i]),a.focus()}}),D.gangManagementSubpage.appendChild(D.gangRecruitMemberButton),D.gangRecruitRequirementText=Object(f.createElement)("p",{color:"red",id:"gang-recruit-requirement-text",margin:"10px"}),D.gangManagementSubpage.appendChild(D.gangRecruitRequirementText),D.gangManagementSubpage.appendChild(Object(f.createElement)("br",{})),D.gangExpandAllButton=Object(f.createElement)("a",{class:"a-link-button",display:"inline-block",innerHTML:"Expand All",clickListener:()=>{for(var e=D.gangManagementSubpage.getElementsByClassName("accordion-header"),t=0;t{for(var e=D.gangManagementSubpage.getElementsByClassName("accordion-header"),t=0;t{this.displayGangMemberList()}}),D.gangManageEquipmentButton=Object(f.createElement)("a",{class:"a-link-button",display:"inline-block",innerHTML:"Manage Equipment",clickListener:()=>{this.createGangMemberUpgradeBox(e)}}),D.gangManagementSubpage.appendChild(D.gangExpandAllButton),D.gangManagementSubpage.appendChild(D.gangCollapseAllButton),D.gangManagementSubpage.appendChild(D.gangMemberFilter),D.gangManagementSubpage.appendChild(D.gangManageEquipmentButton),D.gangMemberList=Object(f.createElement)("ul",{id:"gang-member-list"}),this.displayGangMemberList(),D.gangManagementSubpage.appendChild(D.gangMemberList),D.gangTerritorySubpage=Object(f.createElement)("div",{id:"gang-territory-subpage",display:"none"}),D.gangTerritoryDescText=Object(f.createElement)("p",{width:"70%",innerHTML:"This page shows how much territory your Gang controls. This statistic is listed as a percentage, which represents how much of the total territory you control.

Every ~20 seconds, your gang has a chance to 'clash' with other gangs. Your chance to win a clash depends on your gang's power, which is listed in the display below. Your gang's power slowly accumulates over time. The accumulation rate is determined by the stats of all Gang members you have assigned to the 'Territory Warfare' task. Gang members that are not assigned to this task do not contribute to your gang's power. Your gang also loses a small amount of power whenever you lose a clash

NOTE: Gang members assigned to 'Territory Warfare' can be killed during clashes. This can happen regardless of whether you win or lose the clash. A gang member being killed results in both respect and power loss for your gang.

The amount of territory you have affects all aspects of your Gang members' production, including money, respect, and wanted level. It is very beneficial to have high territory control.

"}),D.gangTerritorySubpage.appendChild(D.gangTerritoryDescText),D.gangTerritoryWarfareCheckbox=Object(f.createElement)("input",{display:"inline-block",id:"gang-management-territory-warfare-checkbox",changeListener:()=>{this.territoryWarfareEngaged=D.gangTerritoryWarfareCheckbox.checked},margin:"2px",type:"checkbox"}),D.gangTerritoryWarfareCheckbox.checked=this.territoryWarfareEngaged,D.gangTerritoryWarfareCheckboxLabel=Object(f.createElement)("label",{color:"white",display:"inline-block",for:"gang-management-territory-warfare-checkbox",innerText:"Engage in Territory Warfare",tooltip:"Engaging in Territory Warfare sets your clash chance to 100%. Disengaging will cause your clash chance to gradually decrease until it reaches 0%"}),D.gangTerritorySubpage.appendChild(D.gangTerritoryWarfareCheckbox),D.gangTerritorySubpage.appendChild(D.gangTerritoryWarfareCheckboxLabel),D.gangTerritorySubpage.appendChild(Object(f.createElement)("br")),D.gangTerritoryWarfareClashChance=Object(f.createElement)("p",{display:"inline-block"}),D.gangTerritorySubpage.appendChild(D.gangTerritoryWarfareClashChance),D.gangTerritorySubpage.appendChild(Object(f.createElement)("div",{class:"help-tip",display:"inline-block",innerText:"?",clickListener:()=>{Object(m.dialogBoxCreate)("This percentage represents the chance you have of 'clashing' with with another gang. If you do not wish to gain/lose territory, then keep this percentage at 0% by not engaging in territory warfare.")}})),D.gangTerritoryDeathNotifyCheckbox=Object(f.createElement)("input",{display:"inline-block",id:"gang-management-notify-member-death-checkbox",changeListener:()=>{this.notifyMemberDeath=D.gangTerritoryDeathNotifyCheckbox.checked},margin:"2px",type:"checkbox"}),D.gangTerritoryDeathNotifyCheckbox.checked=this.notifyMemberDeath,D.gangTerritoryDeathNotifyCheckboxLabel=Object(f.createElement)("label",{color:"white",display:"inline-block",for:"gang-management-notify-member-death-checkbox",innerText:"Notify about Gang Member Deaths",tooltip:"If this is enabled, then you will receive a pop-up notifying you whenever one of your Gang Members dies in a territory clash."}),D.gangTerritorySubpage.appendChild(Object(f.createElement)("br")),D.gangTerritorySubpage.appendChild(D.gangTerritoryDeathNotifyCheckbox),D.gangTerritorySubpage.appendChild(D.gangTerritoryDeathNotifyCheckboxLabel),D.gangTerritorySubpage.appendChild(Object(f.createElement)("br"));var r=Object(f.createElement)("fieldset",{display:"block",margin:"6px",width:"50%"});D.gangTerritoryInfoText=Object(f.createElement)("p"),r.appendChild(D.gangTerritoryInfoText),D.gangTerritorySubpage.appendChild(r),D.gangContainer.appendChild(D.gangTerritorySubpage),D.gangContainer.appendChild(D.gangManagementSubpage),document.getElementById("entire-game-container").appendChild(D.gangContainer)}D.gangContainer.style.display="block",this.updateGangContent()},O.prototype.displayGangMemberList=function(){Object(E.removeChildrenFromElement)(D.gangMemberList),D.gangMemberPanels={};const e=this.members,t=D.gangMemberFilter.value.toString();for(var n=0;n-1||e[n].task.indexOf(t)>-1)&&this.createGangMemberDisplayElement(e[n])},O.prototype.updateGangContent=function(){if(D.gangContentCreated)if(D.gangMemberUpgradeBoxOpened&&(D.gangMemberUpgradeBoxDiscount.childNodes[0].nodeValue="Discount: -"+u.numeralWrapper.format(1-1/this.getDiscount(),"0.00%")),"block"===D.gangTerritorySubpage.style.display){D.gangTerritoryWarfareClashChance.innerText=`Territory Clash Chance: ${u.numeralWrapper.format(this.territoryClashChance,"0.000%")}`,D.gangTerritoryWarfareCheckbox.checked=this.territoryWarfareEngaged,D.gangTerritoryInfoText.innerHTML="";const e=P[this.facName].power;let t=Object.keys(P).filter(e=>e!=this.facName);t.unshift(this.facName);for(const n of t)if(P.hasOwnProperty(n)){const t=P[n];let r,a=100*t.territory;if(r=a<=0?Object(h.formatNumber)(0,2):a>=100?Object(h.formatNumber)(100,2):Object(h.formatNumber)(a,2),n===this.facName){let e=`${n}
Power: ${Object(h.formatNumber)(t.power,6)}
`;e+=`Territory: ${r}%

`,D.gangTerritoryInfoText.innerHTML+=e}else{const a=e/(t.power+e);let i=`${n}
Power: ${Object(h.formatNumber)(t.power,6)}
`;i+=`Territory: ${r}%
`,i+=`Chance to win clash with this gang: ${u.numeralWrapper.format(a,"0.000%")}

`,D.gangTerritoryInfoText.innerHTML+=i}}}else{if(D.gangInfo instanceof Element){var e,t=s.Factions[this.facName];e=t instanceof o.Faction?t.playerReputation:"ERROR",Object(E.removeChildrenFromElement)(D.gangInfo),D.gangInfo.appendChild(Object(f.createElement)("p",{display:"inline-block",innerText:"Respect: "+Object(h.formatNumber)(this.respect,6)+" ("+Object(h.formatNumber)(5*this.respectGainRate,6)+" / sec)",tooltip:"Represents the amount of respect your gang has from other gangs and criminal organizations. Your respect affects the amount of money your gang members will earn, and also determines how much reputation you are earning with your gang's corresponding Faction."})),D.gangInfo.appendChild(Object(f.createElement)("br")),D.gangInfo.appendChild(Object(f.createElement)("p",{display:"inline-block",innerText:"Wanted Level: "+Object(h.formatNumber)(this.wanted,6)+" ("+Object(h.formatNumber)(5*this.wantedGainRate,6)+" / sec)",tooltip:"Represents how much the gang is wanted by law enforcement. The higher your gang's wanted level, the harder it will be for your gang members to make money and earn respect. Note that the minimum wanted level is 1."})),D.gangInfo.appendChild(Object(f.createElement)("br"));var n=this.getWantedPenalty();n=100*(1-n),D.gangInfo.appendChild(Object(f.createElement)("p",{display:"inline-block",innerText:`Wanted Level Penalty: -${Object(h.formatNumber)(n,2)}%`,tooltip:"Penalty for respect and money gain rates due to Wanted Level"})),D.gangInfo.appendChild(Object(f.createElement)("br")),D.gangInfo.appendChild(Object(f.createElement)("p",{display:"inline-block",innerText:`Money gain rate: ${u.numeralWrapper.format(5*this.moneyGainRate,"$0.000a")} / sec`})),D.gangInfo.appendChild(Object(f.createElement)("br"));var r=100*P[this.facName].territory;let a;a=r<=0?Object(h.formatNumber)(0,2):r>=100?Object(h.formatNumber)(100,2):Object(h.formatNumber)(r,2),D.gangInfo.appendChild(Object(f.createElement)("p",{display:"inline-block",innerText:`Territory: ${Object(h.formatNumber)(a,3)}%`,tooltip:"The percentage of total territory your Gang controls"})),D.gangInfo.appendChild(Object(f.createElement)("br")),D.gangInfo.appendChild(Object(f.createElement)("p",{display:"inline-block",innerText:"Faction reputation: "+Object(h.formatNumber)(e,3)})),D.gangInfo.appendChild(Object(f.createElement)("br"));const l=1e3/i.Engine._idleSpeed;D.gangInfo.appendChild(Object(f.createElement)("p",{innerText:`Bonus time: ${Object(h.convertTimeMsToTimeElapsedString)(this.storedCycles/l*1e3)}`,display:"inline-block",tooltip:"You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by the browser). Bonus time makes the Gang mechanic progress faster, up to 5x the normal speed"})),D.gangInfo.appendChild(Object(f.createElement)("br"))}else console.error("gang-info DOM element DNE");const a=this.members.length,l=this.getRespectNeededToRecruitMember(),c=D.gangRecruitMemberButton;a>=30?(c.className="a-link-button-inactive",D.gangRecruitRequirementText.style.display="inline-block",D.gangRecruitRequirementText.innerHTML="You have reached the maximum amount of gang members"):this.canRecruitMember()?(c.className="a-link-button",D.gangRecruitRequirementText.style.display="none"):(c.className="a-link-button-inactive",D.gangRecruitRequirementText.style.display="inline-block",D.gangRecruitRequirementText.innerHTML=`${Object(h.formatNumber)(l,2)} respect needed to recruit next member`);for(let e=0;e")});D.gangMemberPanels[t].statsDiv=i;const o=Object(f.createElement)("pre",{display:"inline",id:t+"gang-member-stats-text"}),s=Object(f.createElement)("br"),l=Object(f.createElement)("button",{class:"accordion-button",innerText:"Ascend",clickListener:()=>{const t=`gang-management-ascend-member ${e.name}`,n=e.getAscensionResults(),r=Object(f.createElement)("pre",{innerText:["Are you sure you want to ascend this member? (S)he will lose all of","his non-Augmentation upgrades and his/her stats will reset back to 1.","",`Furthermore, your gang will lose ${u.numeralWrapper.format(e.earnedRespect,"0.000000")} respect`,"","In return, (s)he will gain the following permanent boost to stat multipliers:\n",`Hacking: +${u.numeralWrapper.format(n.hack,"0.00%")}`,`Strength: +${u.numeralWrapper.format(n.str,"0.00%")}`,`Defense: +${u.numeralWrapper.format(n.def,"0.00%")}`,`Dexterity: +${u.numeralWrapper.format(n.dex,"0.00%")}`,`Agility: +${u.numeralWrapper.format(n.agi,"0.00%")}`,`Charisma: +${u.numeralWrapper.format(n.cha,"0.00%")}`].join("\n")}),a=Object(f.createElement)("button",{class:"std-button",clickListener:()=>(this.ascendMember(e),this.updateGangMemberDisplayElement(e),Object(k.removeElementById)(t),!1),innerText:"Ascend"}),i=Object(f.createElement)("button",{class:"std-button",clickListener:()=>(Object(k.removeElementById)(t),!1),innerText:"Cancel"});Object(b.createPopup)(t,[r,a,i])}}),c=Object(f.createElement)("div",{class:"help-tip",clickListener:()=>{Object(m.dialogBoxCreate)(["Ascending a Gang Member resets the member's progress and stats in exchange","for a permanent boost to their stat multipliers.","

The additional stat multiplier that the Gang Member gains upon ascension","is based on the amount of multipliers the member has from non-Augmentation Equipment.","

Upon ascension, the member will lose all of its non-Augmentation Equipment and your","gang will lose respect equal to the total respect earned by the member."].join(" "))},innerText:"?",marginTop:"5px"});i.appendChild(o),i.appendChild(s),i.appendChild(l),i.appendChild(c);const p=Object(f.createElement)("div",{class:"gang-member-info-div",id:t+"gang-member-task"}),h=Object(f.createElement)("select",{class:"dropdown",id:t+"gang-member-task-selector"});let d=this.getAllTaskNames();d.unshift("---");for(var _=0;_{var t=h.options[h.selectedIndex].text;e.assignToTask(t),this.setGangMemberTaskDescription(e,t),this.updateGangContent()}),A.hasOwnProperty(e.task)){var E=e.task,v=0;for(let e=0;e"))}var a=document.getElementById(t+"gang-member-gain-info");a&&(a.innerHTML=[`Money: $ ${Object(h.formatNumber)(5*e.calculateMoneyGain(this),2)} / sec`,`Respect: ${Object(h.formatNumber)(5*e.calculateRespectGain(this),6)} / sec`,`Wanted Level: ${Object(h.formatNumber)(5*e.calculateWantedLevelGain(this),6)} / sec`,`Total Respect Earned: ${Object(h.formatNumber)(e.earnedRespect,6)}`].join("
"));const i=document.getElementById(t+"gang-member-task-selector");if(i){let t=this.getAllTaskNames();if(t.unshift("---"),A.hasOwnProperty(e.task)){const n=e.task;let r=0;for(let e=0;e0){if("unalias"===n[0])return n.join(" ");null!=(i=function(e){return t.Aliases.hasOwnProperty(e)?t.Aliases[e]:null}(n[0]))?n[0]=i:null!=(i=a(n[0]))&&(n[0]=i);for(var r=0;r

This message was saved as "+e.filename+" onto your home computer.";Object(p.dialogBoxCreate)(t)}function g(){var e=f[E.Jumper0],t=f[E.Jumper1],n=f[E.Jumper2],r=f[E.Jumper3],u=f[E.Jumper4],m=f[E.CyberSecTest],h=f[E.NiteSecTest],_=f[E.BitRunnersTest],g=f[E.RedPill],y=!1;if(a.Augmentations[i.AugmentationNames.TheRedPill].owned&&(y=!0),g&&y&&0===l.Player.sourceFiles.length&&!c.b&&!s.c)p.dialogBoxOpened||d(g,!0);else if(g&&y)c.b||s.c||p.dialogBoxOpened||d(g);else if(e&&!e.recvd&&l.Player.hacking_skill>=25){d(e);const t=o.Programs.Flight.name,n=l.Player.getHomeComputer();n.programs.includes(t)||n.programs.push(t)}else t&&!t.recvd&&l.Player.hacking_skill>=40?d(t):m&&!m.recvd&&l.Player.hacking_skill>=50?d(m):n&&!n.recvd&&l.Player.hacking_skill>=175?d(n):h&&!h.recvd&&l.Player.hacking_skill>=200?d(h):r&&!r.recvd&&l.Player.hacking_skill>=350?d(r):u&&!u.recvd&&l.Player.hacking_skill>=490?d(u):_&&!_.recvd&&l.Player.hacking_skill>=500&&d(_)}function y(e){f[e.filename]=e}let f={};function b(e){f=JSON.parse(e,h.Reviver)}let E={Jumper0:"j0.msg",Jumper1:"j1.msg",Jumper2:"j2.msg",Jumper3:"j3.msg",Jumper4:"j4.msg",CyberSecTest:"csec-test.msg",NiteSecTest:"nitesec-test.msg",BitRunnersTest:"19dfj3l1nd.msg",RedPill:"icarus.msg"};function v(){f={},y(new r.Message(E.Jumper0,"I know you can sense it. I know you're searching for it. It's why you spend night after night at your computer.

It's real, I've seen it. And I can help you find it. But not right now. You're not ready yet.

Use this program to track your progress

The fl1ght.exe program was added to your home computer

-jump3R")),y(new r.Message(E.Jumper1,"Soon you will be contacted by a hacking group known as CyberSec. They can help you with your search.

You should join them, garner their favor, and exploit them for their Augmentations. But do not trust them. They are not what they seem. No one is.

-jump3R")),y(new r.Message(E.Jumper2,"Do not try to save the world. There is no world to save. If you want to find the truth, worry only about yourself. Ethics and morals will get you killed.

Watch out for a hacking group known as NiteSec.

-jump3R")),y(new r.Message(E.Jumper3,"You must learn to walk before you can run. And you must run before you can fly. Look for the black hand.

I.I.I.I

-jump3R")),y(new r.Message(E.Jumper4,"To find what you are searching for, you must understand the bits. The bits are all around us. The runners will help you.

-jump3R")),y(new r.Message(E.CyberSecTest,"We've been watching you. Your skills are very impressive. But you're wasting your talents. If you join us, you can put your skills to good use and change the world for the better. If you join us, we can unlock your full potential.

But first, you must pass our test. Find and hack our server using the Terminal.

-CyberSec")),y(new r.Message(E.NiteSecTest,"People say that the corrupted governments and corporations rule the world. Yes, maybe they do. But do you know who everyone really fears? People like us. Because they can't hide from us. Because they can't fight shadows and ideas with bullets.

Join us, and people will fear you, too.

Find and hack our hidden server using the Terminal. Then, we will contact you again.

-NiteSec")),y(new r.Message(E.BitRunnersTest,"We know what you are doing. We know what drives you. We know what you are looking for.

We can help you find the answers.

run4theh111z")),y(new r.Message(E.RedPill,"@)(#V%*N)@(#*)*C)@#%*)*V)@#(*%V@)(#VN%*)@#(*%
)@B(*#%)@)M#B*%V)____FIND___#$@)#%(B*)@#(*%B)
@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB
DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)"))}},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return C}),n.d(t,"c",function(){return h}),n.d(t,"d",function(){return _}),n.d(t,"b",function(){return d});var r=n(6),a=n(12),i=n(49),o=n(0),s=n(8),l=n(7),c=n(86),u=n(14),m=n(46),p=n(28);n(661);let h=!1,d=null;function _(e,t){h=e,d=e?t:null}e(document).keydown(function(e){if(h&&d&&0!=d.selectedNode.length)switch(e.keyCode){case 65:d.actionButtons[0].click();break;case 83:d.actionButtons[1].click();break;case 87:d.actionButtons[2].click();break;case 70:d.actionButtons[3].click();break;case 82:d.actionButtons[4].click();break;case 68:d.actionButtons[5].click()}});let g={Core:"CPU Core Node",Firewall:"Firewall Node",Database:"Database Node",Spam:"Spam Node",Transfer:"Transfer Node",Shield:"Shield Node"},y="Attacking",f="Scanning",b="Weakening",E="Fortifying",v="Overflowing";function k(e,t){this.type=e,this.atk=t.atk?t.atk:0,this.def=t.def?t.def:0,this.hp=t.hp?t.hp:0,this.maxhp=this.hp,this.plyrCtrl=!1,this.enmyCtrl=!1,this.pos=[0,0],this.el=null,this.action=null,this.targetedCount=0,this.conn=null}function C(e,t){this.faction=t,this.started=!1,this.time=18e4,this.playerCores=[],this.playerNodes=[],this.playerAtk=0,this.playerDef=0,this.enemyCores=[],this.enemyDatabases=[],this.enemyNodes=[],this.enemyAtk=0,this.enemyDef=0,this.miscNodes=[],this.selectedNode=[],this.actionButtons=[],this.availablePositions=[];for(var n=0;n<8;++n)for(var a=0;a<8;++a)this.availablePositions.push([n,a]);this.map=[];for(var i=0;i<8;++i)this.map.push([null,null,null,null,null,null,null,null]);this.jsplumbinstance=null,this.difficulty=e/r.CONSTANTS.HackingMissionRepToDiffConversion+1,this.reward=250+e/r.CONSTANTS.HackingMissionRepToRewardConversion}function P(e){e.selectedNode.length>0&&(e.selectedNode.forEach(function(t){t.deselect(e.actionButtons)}),e.selectedNode.length=0)}k.prototype.setPosition=function(e,t){this.pos=[e,t]},k.prototype.setControlledByPlayer=function(){this.plyrCtrl=!0,this.enmyCtrl=!1,this.el&&(this.el.classList.remove("hack-mission-enemy-node"),this.el.classList.add("hack-mission-player-node"))},k.prototype.setControlledByEnemy=function(){this.plyrCtrl=!1,this.enmyCtrl=!0,this.el&&(this.el.classList.remove("hack-mission-player-node"),this.el.classList.add("hack-mission-enemy-node"))},k.prototype.select=function(e){if(!this.enmyCtrl){this.el.classList.add("hack-mission-player-node-active");for(var t=0;t(this.start(),!1));var m=document.createElement("a");m.innerHTML="Forfeit Mission (Exit)",m.classList.add("a-link-button"),m.classList.add("hack-mission-header-element"),m.style.display="inline-block",m.addEventListener("click",()=>(this.finishMission(!1),!1));var p=document.createElement("p");p.setAttribute("id","hacking-mission-timer"),p.style.display="inline-block",p.style.margin="6px";var h=document.createElement("span");h.style.display="block",h.classList.add("hack-mission-action-buttons-container");for(var d=0;d<6;++d)this.actionButtons.push(document.createElement("a")),this.actionButtons[d].style.display="inline-block",this.actionButtons[d].classList.add("a-link-button-inactive"),this.actionButtons[d].classList.add("tooltip"),this.actionButtons[d].classList.add("hack-mission-header-element"),h.appendChild(this.actionButtons[d]);this.actionButtons[0].innerText="Attack(a)";var _=document.createElement("span");_.classList.add("tooltiptexthigh"),_.innerText="Lowers the targeted node's HP. The effectiveness of this depends on this node's Attack level, your hacking level, and the opponent's defense level.",this.actionButtons[0].appendChild(_),this.actionButtons[1].innerText="Scan(s)";var k=document.createElement("span");k.classList.add("tooltiptexthigh"),k.innerText="Lowers the targeted node's defense. The effectiveness of this depends on this node's Attack level, your hacking level, and the opponent's defense level.",this.actionButtons[1].appendChild(k),this.actionButtons[2].innerText="Weaken(w)";var C=document.createElement("span");C.classList.add("tooltiptexthigh"),C.innerText="Lowers the targeted node's attack. The effectiveness of this depends on this node's Attack level, your hacking level, and the opponent's defense level.",this.actionButtons[2].appendChild(C),this.actionButtons[3].innerText="Fortify(f)";var P=document.createElement("span");P.classList.add("tooltiptexthigh"),P.innerText="Raises this node's Defense level. The effectiveness of this depends on your hacking level",this.actionButtons[3].appendChild(P),this.actionButtons[4].innerText="Overflow(r)";var T=document.createElement("span");T.classList.add("tooltiptexthigh"),T.innerText="Raises this node's Attack level but lowers its Defense level. The effectiveness of this depends on your hacking level.",this.actionButtons[4].appendChild(T),this.actionButtons[5].innerText="Drop Connection(d)";var S=document.createElement("span");S.classList.add("tooltiptexthigh"),S.innerText="Removes this Node's current connection to some target Node, if it has one. This can also be done by simply clicking the white connection line.",this.actionButtons[5].appendChild(S);var O=document.createElement("p"),M=document.createElement("p");O.style.display="inline-block",M.style.display="inline-block",O.style.color="#00ccff",M.style.color="red",O.style.margin="4px",M.style.margin="4px",O.setAttribute("id","hacking-mission-player-stats"),M.setAttribute("id","hacking-mission-enemy-stats"),h.appendChild(O),h.appendChild(M),this.actionButtons[0].addEventListener("click",()=>{this.selectedNode.length>0?this.selectedNode[0].type===g.Core&&(this.setActionButtonsActive(this.selectedNode[0].type),this.setActionButton(y,!1),this.selectedNode.forEach(function(e){e.action=y})):console.error("Pressing Action button without selected node")}),this.actionButtons[1].addEventListener("click",()=>{if(this.selectedNode.length>0){var e=this.selectedNode[0].type;e!==g.Core&&e!==g.Transfer||(this.setActionButtonsActive(e),this.setActionButton(f,!1),this.selectedNode.forEach(function(e){e.action=f}))}else console.error("Pressing Action button without selected node")}),this.actionButtons[2].addEventListener("click",()=>{if(this.selectedNode.length>0){var e=this.selectedNode[0].type;e!==g.Core&&e!==g.Transfer||(this.setActionButtonsActive(e),this.setActionButton(b,!1),this.selectedNode.forEach(function(e){e.action=b}))}else console.error("Pressing Action button without selected node")}),this.actionButtons[3].addEventListener("click",()=>{this.selectedNode.length>0?(this.setActionButtonsActive(this.selectedNode[0].type),this.setActionButton(E,!1),this.selectedNode.forEach(function(e){e.action=E})):console.error("Pressing Action button without selected node")}),this.actionButtons[4].addEventListener("click",()=>{if(this.selectedNode.length>0){var e=this.selectedNode[0].type;e!==g.Core&&e!==g.Transfer||(this.setActionButtonsActive(e),this.setActionButton(v,!1),this.selectedNode.forEach(function(e){e.action=v}))}else console.error("Pressing Action button without selected node")}),this.actionButtons[5].addEventListener("click",()=>{this.selectedNode.length>0?this.selectedNode.forEach(function(e){if(e.conn){var t=e.conn.endpoints;t[0].detachFrom(t[1])}e.action=E}):console.error("Pressing Action button without selected node")});var x=document.createElement("p");e.appendChild(a),e.appendChild(i),e.appendChild(c),e.appendChild(u),e.appendChild(m),e.appendChild(p),e.appendChild(h),e.appendChild(x)},C.prototype.setActionButtonsInactive=function(){for(var e=0;ePlayer Defense: "+Object(l.formatNumber)(this.playerDef,1),e=0;for(t=0;tEnemy Defense: "+Object(l.formatNumber)(this.enemyDef,1)},C.prototype.calculateDefenses=function(){for(var e=0,t=0;tPlayer Defense: "+Object(l.formatNumber)(this.playerDef,1),e=0;for(t=0;tEnemy Defense: "+Object(l.formatNumber)(this.enemyDef,1)},C.prototype.removeAvailablePosition=function(e,t){for(var n=0;nDef: "+Object(l.formatNumber)(e.def,1),n.innerHTML=r,t.appendChild(n),document.getElementById("hacking-mission-map").appendChild(t)},C.prototype.updateNodeDomElement=function(e){if(null!=e.el){var t,n="hacking-mission-node-"+e.pos[0]+"-"+e.pos[1],r=(document.getElementById(n),document.getElementById(n+"-txt"));switch(e.type){case g.Core:t="CPU Core
HP: "+Object(l.formatNumber)(e.hp,1);break;case g.Firewall:t="Firewall
HP: "+Object(l.formatNumber)(e.hp,1);break;case g.Database:t="Database
HP: "+Object(l.formatNumber)(e.hp,1);break;case g.Spam:t="Spam
HP: "+Object(l.formatNumber)(e.hp,1);break;case g.Transfer:t="Transfer
HP: "+Object(l.formatNumber)(e.hp,1);break;case g.Shield:default:t="Shield
HP: "+Object(l.formatNumber)(e.hp,1)}t+="
Atk: "+Object(l.formatNumber)(e.atk,1)+"
Def: "+Object(l.formatNumber)(e.def,1),e.action&&(t+="
"+e.action),r.innerHTML=t}else console.error("Calling updateNodeDomElement on a Node without an element")},C.prototype.getNodeFromElement=function(e){var t=(Object(m.isString)(e)?e:e.id).replace("hacking-mission-node-","").split("-");if(2!=t.length)return console.error("Parsing hacking mission node id. could not find coordinates"),null;var n=t[0],r=t[1];return isNaN(n)||isNaN(r)||n>=8||r>=8||n<0||r<0?(console.error(`Unexpected values (${n}, ${r}) for (x, y)`),null):this.map[n][r]},C.prototype.configurePlayerNodeElement=function(e){null==this.getNodeFromElement(e)&&console.error("Failed getting Node object");var t=this;function n(){!function(e,t){var n=e.getNodeFromElement(t);null==n&&console.error("Failed getting Node object"),n.plyrCtrl&&(P(e),n.select(e.actionButtons),e.selectedNode.push(n))}(t,e)}e.addEventListener("click",n),e.addEventListener("dblclick",function(){!function(e,t){var n=e.getNodeFromElement(t);if(null==n&&console.error("Failed getting Node Object in multiselectNode()"),n.plyrCtrl){P(e);var r=n.type;r===g.Core?e.playerCores.forEach(function(t){t.select(e.actionButtons),e.selectedNode.push(t)}):e.playerNodes.forEach(function(t){t.type===r&&(t.select(e.actionButtons),e.selectedNode.push(t))})}}(t,e)}),e.firstChild&&e.firstChild.addEventListener("click",n)},C.prototype.configureEnemyNodeElement=function(e){for(var t=this.getNodeFromElement(e),n=0;n0&&this.map[t-1][n].plyrCtrl)||(!!(t<7&&this.map[t+1][n].plyrCtrl)||(!!(n>0&&this.map[t][n-1].plyrCtrl)||!!(n<7&&this.map[t][n+1].plyrCtrl)))},C.prototype.nodeReachableByEnemy=function(e){if(null==e)return!1;var t=e.pos[0],n=e.pos[1];return!!(t>0&&this.map[t-1][n].enmyCtrl)||(!!(t<7&&this.map[t+1][n].enmyCtrl)||(!!(n>0&&this.map[t][n-1].enmyCtrl)||!!(n<7&&this.map[t][n+1].enmyCtrl)))},C.prototype.start=function(){this.started=!0,this.initJsPlumb();var e=Object(p.clearEventListeners)("hack-mission-start-btn");e.classList.remove("a-link-button"),e.classList.add("a-link-button-inactive")},C.prototype.initJsPlumb=function(){var e=jsPlumb.getInstance({DragOptions:{cursor:"pointer",zIndex:2e3},PaintStyle:{gradient:{stops:[[0,"#FFFFFF"],[1,"#FFFFFF"]]},stroke:"#FFFFFF",strokeWidth:8}});this.jsplumbinstance=e;for(var t=0;t{if(!this.getNodeFromElement(e.source).enmyCtrl){var n=e.endpoints;n[0].detachFrom(n[1])}}),e.bind("connection",e=>{var t=this.getNodeFromElement(e.target);this.getNodeFromElement(e.source).enmyCtrl||(this.nodeReachable(t)?(this.getNodeFromElement(e.source).conn=e.connection,++(t=this.getNodeFromElement(e.target)).targetedCount):e.sourceEndpoint.detachFrom(e.targetEndpoint))}),e.bind("connectionDetached",(e,t)=>{this.getNodeFromElement(e.source).conn=null,this.getNodeFromElement(e.target).untarget()})},C.prototype.dropAllConnectionsFromNode=function(e){for(var t=this.jsplumbinstance.getAllConnections(),n=t.length-1;n>=0;--n)t[n].source==e.el&&t[n].endpoints[0].detachFrom(t[n].endpoints[1])},C.prototype.dropAllConnectionsToNode=function(e){for(var t=this.jsplumbinstance.getAllConnections(),n=t.length-1;n>=0;--n)t[n].target==e.el&&t[n].endpoints[0].detachFrom(t[n].endpoints[1]);e.beingTargeted=!1};var T=0;C.prototype.process=function(e=1){if(this.started&&!((T+=e)<2)){var t=!1;this.playerCores.forEach(e=>{t|=this.processNode(e,T)}),this.playerNodes.forEach(e=>{e.type!==g.Transfer&&e.type!==g.Shield&&e.type!==g.Firewall||(t|=this.processNode(e,T))}),this.enemyCores.forEach(e=>{this.enemyAISelectAction(e),t|=this.processNode(e,T)}),this.enemyNodes.forEach(e=>{e.type!==g.Transfer&&e.type!==g.Shield&&e.type!==g.Firewall||(this.enemyAISelectAction(e),t|=this.processNode(e,T))}),this.enemyDatabases.forEach(e=>{e.maxhp+=.1*T,e.hp+=.1*T}),t&&(this.calculateAttacks(),this.calculateDefenses()),0!==this.enemyDatabases.length?0!==this.playerCores.length?(this.miscNodes.forEach(e=>{e.def+=.1*T,e.maxhp+=.05*T,e.hp+=.1*T,e.hp>e.maxhp&&(e.hp=e.maxhp),this.updateNodeDomElement(e)}),this.time-=T*a.Engine._idleSpeed,this.time<=0?this.finishMission(!1):(this.updateTimer(),T=0)):this.finishMission(!1):this.finishMission(!0)}},C.prototype.processNode=function(e,t=1){if(null!=e.action){var n,a,i=null;e.conn&&(null==(i=null!=e.conn.target?this.getNodeFromElement(e.conn.target):this.getNodeFromElement(e.conn.targetId))||(i.plyrCtrl?(n=this.playerDef,a=this.enemyAtk):i.enmyCtrl?(n=this.enemyDef,a=this.playerAtk):(n=i.def,a=e.plyrCtrl?this.playerAtk:this.enemyAtk)));var s=!1,l=e.plyrCtrl,c=this.difficulty*r.CONSTANTS.HackingMissionDifficultyToHacking;switch(e.action){case y:if(null==i)break;if(null==e.conn)break;var u=this.calculateAttackDamage(a,n,l?o.Player.hacking_skill:c);i.hp-=u/5*t;break;case f:if(null==i)break;if(null==e.conn)break;var m=this.calculateScanEffect(a,n,l?o.Player.hacking_skill:c);i.def-=m/5*t,s=!0;break;case b:if(null==i)break;if(null==e.conn)break;m=this.calculateWeakenEffect(a,n,l?o.Player.hacking_skill:c);i.atk-=m/5*t,s=!0;break;case E:m=this.calculateFortifyEffect(o.Player.hacking_skill);e.def+=m/5*t,s=!0;break;case v:m=this.calculateOverflowEffect(o.Player.hacking_skill);if(e.def{0===e.targetedCount&&(e.def*=r.CONSTANTS.HackingMissionMiscDefenseIncrease)})}return this.updateNodeDomElement(e),i&&this.updateNodeDomElement(i),s}},C.prototype.enemyAISelectAction=function(e){if(null!=e)switch(e.type){case g.Core:if(null==e.conn){if(0===this.miscNodes.length){var t=Object(u.getRandomInt)(0,this.playerNodes.length-1);if(n=0===this.playerNodes.length?null:this.playerNodes[t],this.nodeReachableByEnemy(n))e.conn=this.jsplumbinstance.connect({source:e.el,target:n.el}),++n.targetedCount;else{if(t=Object(u.getRandomInt)(0,this.playerCores.length-1),0===this.playerCores.length)return;n=this.playerCores[t],this.nodeReachableByEnemy(n)&&(e.conn=this.jsplumbinstance.connect({source:e.el,target:n.el}),++n.targetedCount)}}else{t=Object(u.getRandomInt)(0,this.miscNodes.length-1);var n=this.miscNodes[t];this.nodeReachableByEnemy(n)&&(e.conn=this.jsplumbinstance.connect({source:e.el,target:n.el}),++n.targetedCount)}e.action=E}else{var r;null==(r=e.conn.target?this.getNodeFromElement(e.conn.target):this.getNodeFromElement(e.conn.targetId))&&console.error("Error getting Target node Object in enemyAISelectAction()"),r.def>this.enemyAtk+15?e.def<50?e.action=E:e.action=v:Math.abs(r.def-this.enemyAtk)<=15?e.action=f:e.action=y}break;case g.Transfer:e.def<125?e.action=E:e.action=v;break;case g.Firewall:case g.Shield:e.action=E}};C.prototype.calculateAttackDamage=function(e,t,n=0){return Math.max(.55*(e+n/80-t),1)},C.prototype.calculateScanEffect=function(e,t,n=0){return Math.max(.6*(e+n/25-.95*t),2)},C.prototype.calculateWeakenEffect=function(e,t,n=0){return Math.max(e+n/25-.95*t,2)},C.prototype.calculateFortifyEffect=function(e=0){return.9*e/130},C.prototype.calculateOverflowEffect=function(e=0){return.95*e/130},C.prototype.updateTimer=function(){var e=document.getElementById("hacking-mission-timer"),t=Math.round(this.time/1e3),n=Math.trunc(t/60);t%=60;var r=("0"+n).slice(-2)+":"+("0"+t).slice(-2);e.innerText="Time left: "+r},C.prototype.finishMission=function(e){if(h=!1,d=null,e){var t=1+this.faction.favor/100,n=this.reward*o.Player.faction_rep_mult*t;Object(s.dialogBoxCreate)("Mission won! You earned "+Object(l.formatNumber)(n,3)+" reputation with "+this.faction.name),o.Player.gainIntelligenceExp(this.difficulty*r.CONSTANTS.IntelligenceHackingMissionBaseExpGain),this.faction.playerReputation+=n}else Object(s.dialogBoxCreate)("Mission lost/forfeited! You did not gain any faction reputation.");for(var c=document.getElementById("mission-container");c.firstChild;)c.removeChild(c.firstChild);document.getElementById("mainmenu-container").style.visibility="visible",document.getElementById("character-overview-wrapper").style.visibility="visible",a.Engine.loadFactionContent(),Object(i.displayFactionContent)(this.faction.name)}}).call(this,n(83))},function(e,t,n){"use strict";(function(e){n.d(t,"a",function(){return X});var r=n(10),a=n(4),i=n(18),o=n(6),s=n(12),l=n(73),c=n(13),u=n(49),m=n(0),p=n(78),h=n(11),d=n(2),_=n(8),g=n(16),y=n(63),f=n(7),b=n(86),E=n(105),v=n(103),k=n(48),C=n(14),P=n(150),T=n(25),S=n(42),O=n(76),M=n(3),x=n(35),w=n(80),A=n(26);const R=' ',N='',D=["Aevum","Chongqing","Sector-12","New Tokyo","Ishima","Volhaven"],I=1e9,B="bladeburner-active-action";let L=0;const W={helpList:"Use 'help [command]' to get more information about a particular Bladeburner console command.

automate [var] [val] [hi/low] Configure simple automation for Bladeburner tasks
clear/cls Clear the console
help [cmd] Display this help text, or help text for a specific command
log [en/dis] [type] Enable or disable logging for events and actions
skill [action] [name] Level or display info about your Bladeburner skills
start [type] [name] Start a Bladeburner action/task
stop Stops your current Bladeburner action/task
",automate:'automate [var] [val] [hi/low]

A simple way to automate your Bladeburner actions. This console command can be used to automatically start an action when your stamina rises above a certain threshold, and automatically switch to another action when your stamina drops below another threshold.

automate status - Check the current status of your automation and get a brief description of what it\'ll do
automate en - Enable the automation feature
automate dis - Disable the automation feature

There are four properties that must be set for this automation to work properly. Here is how to set them:

automate stamina 100 high
automate contract Tracking high
automate stamina 50 low
automate general "Field Analysis" low

Using the four console commands above will set the automation to perform Tracking contracts if your stamina is 100 or higher, and then switch to Field Analysis if your stamina drops below 50. Note that when setting the action, the name of the action is CASE-SENSITIVE. It must exactly match whatever the name is in the UI.',clear:"clear

Clears the console",cls:"cls

Clears the console",help:"help [command]

Running 'help' with no arguments displays the general help text, which lists all console commands and a brief description of what they do. A command can be specified to get more specific help text about that particular command. For example:

help automate

will display specific information about using the automate console command",log:"log [en/dis] [type]

Enable or disable logging. By default, the results of completing actions such as contracts/operations are logged in the console. There are also random events that are logged in the console as well. The five categories of things that get logged are:

[general, contracts, ops, blackops, events]

The logging for these categories can be enabled or disabled like so:

log dis contracts - Disables logging that occurs when contracts are completed
log en contracts - Enables logging that occurs when contracts are completed
log dis events - Disables logging for Bladeburner random events

Logging can be universally enabled/disabled using the 'all' keyword:

log dis all
log en all",skill:'skill [action] [name]

Level or display information about your skills.

To display information about all of your skills and your multipliers, use:

skill list

To display information about a specific skill, specify the name of the skill afterwards. Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If the name of the skill has whitespace, enclose the name of the skill in double quotation marks:

skill list Reaper
skill list "Digital Observer"

This console command can also be used to level up skills:

skill level [skill name]',start:'start [type] [name]

Start an action. An action is specified by its type and its name. The name is case-sensitive. It must appear exactly as it does in the UI. If the name of the action has whitespace, enclose it in double quotation marks. Valid action types include:

[general, contract, op, blackop]

Examples:

start contract Tracking
start op "Undercover Operation"
',stop:"stop

Stop your current action and go idle"};function j(e={}){this.name=e.name?e.name:D[2],this.pop=e.pop?e.pop:Object(C.getRandomInt)(I,1.5*I),this.popEst=this.pop*(Math.random()+.5),this.comms=e.comms?e.comms:Object(C.getRandomInt)(5,150),this.commsEst=this.comms+Object(C.getRandomInt)(-5,5),this.commsEst<0&&(this.commsEst=0),this.chaos=0}function F(e={name:"foo",desc:"foo"}){if(!e.name)throw new Error("Failed to initialize Bladeburner Skill. No name was specified in ctor");if(this.name=e.name,!e.desc)throw new Error("Failed to initialize Bladeburner Skills. No desc was specified in ctor");this.desc=e.desc,this.baseCost=e.baseCost?e.baseCost:1,this.costInc=e.costInc?e.costInc:1,e.maxLvl&&(this.maxLvl=e.maxLvl),e.successChanceAll&&(this.successChanceAll=e.successChanceAll),e.successChanceStealth&&(this.successChanceStealth=e.successChanceStealth),e.successChanceKill&&(this.successChanceKill=e.successChanceKill),e.successChanceContract&&(this.successChanceContract=e.successChanceContract),e.successChanceOperation&&(this.successChanceOperation=e.successChanceOperation),e.successChanceEstimate&&(this.successChanceEstimate=e.successChanceEstimate),e.actionTime&&(this.actionTime=e.actionTime),e.effHack&&(this.effHack=e.effHack),e.effStr&&(this.effStr=e.effStr),e.effDef&&(this.effDef=e.effDef),e.effDex&&(this.effDex=e.effDex),e.effAgi&&(this.effAgi=e.effAgi),e.effCha&&(this.effCha=e.effCha),e.stamina&&(this.stamina=e.stamina),e.money&&(this.money=e.money),e.expGain&&(this.expGain=e.expGain),e.weaponAbility&&(this.weaponAbility=e.weaponAbility),e.gunAbility&&(this.gunAbility=e.gunAbility)}e(document).keydown(function(e){if(h.routing.isOn(h.Page.Bladeburner)){if(!(m.Player.bladeburner instanceof X))return;let i=m.Player.bladeburner.consoleHistory;if(e.keyCode===T.KEY.ENTER){e.preventDefault();var t=Q.consoleInput.value;t.length>0&&(m.Player.bladeburner.postToConsole("> "+t),m.Player.bladeburner.resetConsoleInput(),m.Player.bladeburner.executeConsoleCommands(t))}if(e.keyCode===T.KEY.UPARROW){if(null==Q.consoleInput)return;var n=L;if(0===(a=i.length))return;(n<0||n>a)&&(L=a),0!==n&&--L;var r=i[L];Q.consoleInput.value=r,Object(y.setTimeoutRef)(function(){Q.consoleInput.selectionStart=Q.consoleInput.selectionEnd=1e4},0)}if(e.keyCode===T.KEY.DOWNARROW){if(null==Q.consoleInput)return;var a;n=L;if(0==(a=i.length))return;if((n<0||n>a)&&(L=a),n==a||n==a-1)L=a,Q.consoleInput.value="";else{r=i[++L];Q.consoleInput.value=r}}}}),j.prototype.improvePopulationEstimateByCount=function(e){if(isNaN(e))throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");this.popEstthis.pop&&(this.popEst=this.pop)):this.popEst>this.pop&&(this.popEst-=e,this.popEstthis.pop&&(this.popEst=this.pop)):this.popEst>this.pop&&(this.popEst*=1-e/100,this.popEstthis.comms&&(this.commsEst=this.comms)):this.commsEst>this.comms&&(this.commsEst-=e,this.commsEst0?1:-1),this.pop+=n,t.changeEstEqually&&(this.popEst+=n,this.popEst<0&&(this.popEst=0)),n}},j.prototype.changeChaosByCount=function(e){if(isNaN(e))throw new Error("NaN passed into City.changeChaosByCount()");0!==e&&(this.chaos+=e,this.chaos<0&&(this.chaos=0))},j.prototype.changeChaosByPercentage=function(e){if(isNaN(e))throw new Error("NaN passed into City.chaosChaosByPercentage()");if(0!==e){var t=this.chaos*(e/100);this.chaos+=t,this.chaos<0&&(this.chaos=0)}},j.prototype.toJSON=function(){return Object(g.Generic_toJSON)("City",this)},j.fromJSON=function(e){return Object(g.Generic_fromJSON)(j,e.data)},g.Reviver.constructors.City=j,F.prototype.calculateCost=function(e){return Math.floor((this.baseCost+e*this.costInc)*i.BitNodeMultipliers.BladeburnerSkillCost)};const U={},H={BladesIntuition:"Blade's Intuition",Cloak:"Cloak",Marksman:"Marksman",WeaponProficiency:"Weapon Proficiency",ShortCircuit:"Short-Circuit",DigitalObserver:"Digital Observer",Tracer:"Tracer",Overclock:"Overclock",Reaper:"Reaper",EvasiveSystem:"Evasive System",Datamancer:"Datamancer",CybersEdge:"Cyber's Edge",HandsOfMidas:"Hands of Midas",Hyperdrive:"Hyperdrive"};function G(e={}){this.name=e.name?e.name:"",this.desc=e.desc?e.desc:"",this.level=1,this.maxLevel=1,this.autoLevel=!0,this.baseDifficulty=e.baseDifficulty?Object(b.addOffset)(e.baseDifficulty,10):100,this.difficultyFac=e.difficultyFac?e.difficultyFac:1.01,this.rewardFac=e.rewardFac?e.rewardFac:1.02,this.successes=0,this.failures=0,this.rankGain=e.rankGain?e.rankGain:0,e.rankLoss&&(this.rankLoss=e.rankLoss),e.hpLoss&&(this.hpLoss=e.hpLoss,this.hpLost=0),this.isStealth=!!e.isStealth,this.isKill=!!e.isKill,this.count=e.count?e.count:Object(C.getRandomInt)(1e3,25e3),this.countGrowth=e.countGrowth?e.countGrowth:Object(C.getRandomInt)(1,5);this.weights=e.weights?e.weights:{hack:1/7,str:1/7,def:1/7,dex:1/7,agi:1/7,cha:1/7,int:1/7};let t=0;for(const e in this.weights)this.weights.hasOwnProperty(e)&&(t+=this.weights[e]);if(t-1>=10*Number.EPSILON)throw new Error("Invalid weights when constructing Action "+this.name+". The weights should sum up to 1. They sum up to :1");this.decays=e.decays?e.decays:{hack:.9,str:.9,def:.9,dex:.9,agi:.9,cha:.9,int:.9};for(const e in this.decays)if(this.decays.hasOwnProperty(e)&&this.decays[e]>1)throw new Error("Invalid decays when constructing Action "+this.name+". Decay value cannot be greater than 1")}G.prototype.getDifficulty=function(){var e=this.baseDifficulty*Math.pow(this.difficultyFac,this.level-1);if(isNaN(e))throw new Error("Calculated NaN in Action.getDifficulty()");return e},G.prototype.getSuccessChance=function(e,t={}){if(null==e)throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");var n=this.getDifficulty(),r=0;for(var a in this.weights)if(this.weights.hasOwnProperty(a)){var i=m.Player.queryStatFromString(a),o="eff"+a.charAt(0).toUpperCase()+a.slice(1),s=e.skillMultipliers[o];null==s&&(console.error(`Failed to find Bladeburner Skill multiplier for: ${a}`),s=1),r+=this.weights[a]*Math.pow(s*i,this.decays[a])}(r*=e.calculateStaminaPenalty(),this instanceof z||this instanceof V)&&(this.teamCount&&this.teamCount>0&&(this.teamCount=Math.min(this.teamCount,e.teamSize),r*=Math.pow(this.teamCount,.05)));if(!(this instanceof V)){var l=e.getCurrentCity();if(t.est?r*=Math.pow(l.popEst/I,.7):r*=Math.pow(l.pop/I,.7),l.chaos>50){var c=l.chaos-50+1;n*=Math.pow(c,.1)}if(this instanceof z&&"Raid"===this.name&&l.comms<=0)return 0}if(r*=e.skillMultipliers.successChanceAll,(this instanceof z||this instanceof V)&&(r*=e.skillMultipliers.successChanceOperation),this instanceof Y&&(r*=e.skillMultipliers.successChanceContract),this.isStealth&&(r*=e.skillMultipliers.successChanceStealth),this.isKill&&(r*=e.skillMultipliers.successChanceKill),r*=m.Player.bladeburner_success_chance_mult,isNaN(r))throw new Error("Competence calculated as NaN in Action.getSuccessChance()");return Math.min(1,r/n)},G.prototype.attempt=function(e){return Math.random()=this.getSuccessesNeededForNextLevel(e)&&++this.maxLevel},G.prototype.toJSON=function(){return Object(g.Generic_toJSON)("Action",this)},G.fromJSON=function(e){return Object(g.Generic_fromJSON)(G,e.data)},g.Reviver.constructors.Action=G;const K={},$=Object.freeze({Idle:1,Contract:2,Operation:3,BlackOp:4,BlackOperation:4,Training:5,Recruitment:6,FieldAnalysis:7,"Field Analysis":7,Diplomacy:8,"Hyperbolic Regeneration Chamber":9});function q(e={}){e.name&&(this.name=e.name),e.type&&(this.type=e.type)}function Y(e={}){G.call(this,e)}function z(e={}){G.call(this,e),this.reqdRank=e.reqdRank?e.reqdRank:100,this.teamCount=e.teamCount?e.teamCount:0}function V(e={}){z.call(this,e),this.count=1,this.countGrowth=0}q.prototype.toJSON=function(){return Object(g.Generic_toJSON)("ActionIdentifier",this)},q.fromJSON=function(e){return Object(g.Generic_fromJSON)(q,e.data)},g.Reviver.constructors.ActionIdentifier=q,Y.prototype=Object.create(G.prototype),Y.prototype.toJSON=function(){return Object(g.Generic_toJSON)("Contract",this)},Y.fromJSON=function(e){return Object(g.Generic_fromJSON)(Y,e.data)},g.Reviver.constructors.Contract=Y,z.prototype=Object.create(G.prototype),z.prototype.toJSON=function(){return Object(g.Generic_toJSON)("Operation",this)},z.fromJSON=function(e){return Object(g.Generic_fromJSON)(z,e.data)},g.Reviver.constructors.Operation=z,V.prototype=Object.create(G.prototype),V.prototype.toJSON=function(){return Object(g.Generic_toJSON)("BlackOperation",this)},V.fromJSON=function(e){return Object(g.Generic_fromJSON)(V,e.data)},g.Reviver.constructors.BlackOperation=V;const J={};function X(e={}){this.numHosp=0,this.moneyLost=0,this.rank=0,this.maxRank=0,this.skillPoints=0,this.totalSkillPoints=0,this.teamSize=0,this.teamLost=0,this.storedCycles=0,this.randomEventCounter=Object(C.getRandomInt)(240,600),this.actionTimeToComplete=0,this.actionTimeCurrent=0;var t=$.Idle;this.action=new q({type:t}),this.cities={};for(var n=0;n
Does NOT require stamina."}),K[e="Recruitment"]=new G({name:e,desc:"Attempt to recruit members for your Bladeburner team. These members can help you conduct operations.

Does NOT require stamina."}),K[e="Diplomacy"]=new G({name:e,desc:"Improve diplomatic relations with the Synthoid population. Completing this action will reduce the Chaos level in your current city.

Does NOT require stamina."}),K[e="Hyperbolic Regeneration Chamber"]=new G({name:e,desc:"Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. This will slowly heal your wounds and slightly increase your stamina.

"}),J["Operation Typhoon"]=new V({name:"Operation Typhoon",desc:"Obadiah Zenyatta is the leader of a RedWater PMC. It has long been known among the intelligence community that Zenyatta, along with the rest of the PMC, is a Synthoid.

The goal of Operation Typhoon is to find and eliminate Zenyatta and RedWater by any means necessary. After the task is completed, the actions must be covered up from the general public.",baseDifficulty:2e3,reqdRank:2500,rankGain:50,rankLoss:10,hpLoss:100,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Zero"]=new V({name:"Operation Zero",desc:"AeroCorp is one of the world's largest defense contractors. It's leader, Steve Watataki, is thought to be a supporter of Synthoid rights. He must be removed.

The goal of Operation Zero is to covertly infiltrate AeroCorp and uncover any incriminating evidence or information against Watataki that will cause him to be removed from his position at AeroCorp. Incriminating evidence can be fabricated as a last resort. Be warned that AeroCorp has some of the most advanced security measures in the world.",baseDifficulty:2500,reqdRank:5e3,rankGain:60,rankLoss:15,hpLoss:50,weights:{hack:.2,str:.15,def:.15,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isStealth:!0}),J["Operation X"]=new V({name:"Operation X",desc:"We have recently discovered an underground publication group called Samizdat. Even though most of their publications are nonsensical conspiracy theories, the average human is gullible enough to believe them. Many of their works discuss Synthoids and pose a threat to society. The publications are spreading rapidly in China and other Eastern countries.

Samizdat has done a good job of keeping hidden and anonymous. However, we've just received intelligence that their base of operations is in Ishima's underground sewer systems. Your task is to investigate the sewer systems, and eliminate Samizdat. They must never publish anything again.",baseDifficulty:3e3,reqdRank:7500,rankGain:75,rankLoss:15,hpLoss:100,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Titan"]=new V({name:"Operation Titan",desc:"Several months ago Titan Laboratories' Bioengineering department was infiltrated by Synthoids. As far as we know, Titan Laboratories' management has no knowledge about this. We don't know what the Synthoids are up to, but the research that they could be conducting using Titan Laboraties' vast resources is potentially very dangerous.

Your goal is to enter and destroy the Bioengineering department's facility in Aevum. The task is not just to retire the Synthoids there, but also to destroy any information or research at the facility that is relevant to the Synthoids and their goals.",baseDifficulty:4e3,reqdRank:1e4,rankGain:100,rankLoss:20,hpLoss:100,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Ares"]=new V({name:"Operation Ares",desc:"One of our undercover agents, Agent Carter, has informed us of a massive weapons deal going down in Dubai between rogue Russian militants and a radical Synthoid community. These weapons are next-gen plasma and energy weapons. It is critical for the safety of humanity that this deal does not happen.

Your task is to intercept the deal. Leave no survivors.",baseDifficulty:5e3,reqdRank:12500,rankGain:125,rankLoss:20,hpLoss:200,weights:{hack:0,str:.25,def:.25,dex:.25,agi:.25,cha:0,int:0},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Archangel"]=new V({name:"Operation Archangel",desc:"Our analysts have discovered that the popular Red Rabbit brothel in Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence suggests that the profit from this brothel is used to fund a large black market arms trafficking operation.

The goal of this operation is to take out the leaders that are running the Red Rabbit brothel. Try to limit the number of other casualties, but do what you must to complete the mission.",baseDifficulty:7500,reqdRank:15e3,rankGain:200,rankLoss:20,hpLoss:25,weights:{hack:0,str:.2,def:.2,dex:.3,agi:.3,cha:0,int:0},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Juggernaut"]=new V({name:"Operation Juggernaut",desc:"The CIA has just encountered a new security threat. A new criminal group, lead by a shadowy operative who calls himself Juggernaut, has been smuggling drugs and weapons (including suspected bioweapons) into Sector-12. We also have reason to believe the tried to break into one of Universal Energy's facilities in order to cause a city-wide blackout. The CIA suspects that Juggernaut is a heavily-augmented Synthoid, and have thus enlisted our help.

Your mission is to eradicate Juggernaut and his followers.",baseDifficulty:1e4,reqdRank:2e4,rankGain:300,rankLoss:40,hpLoss:300,weights:{hack:0,str:.25,def:.25,dex:.25,agi:.25,cha:0,int:0},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Red Dragon"]=new V({name:"Operation Red Dragon",desc:"The Tetrads criminal organization is suspected of reverse-engineering the MK-VI Synthoid design. We believe they altered and possibly improved the design and began manufacturing their own Synthoid models in order to bolster their criminal activities.

Your task is to infiltrate and destroy the Tetrads' base of operations in Los Angeles. Intelligence tells us that their base houses one of their Synthoid manufacturing units.",baseDifficulty:12500,reqdRank:25e3,rankGain:500,rankLoss:50,hpLoss:500,weights:{hack:.05,str:.2,def:.2,dex:.25,agi:.25,cha:0,int:.05},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation K"]=new V({name:"Operation K",desc:"CODE RED SITUATION. Our intelligence tells us that VitaLife has discovered a new android cloning technology. This technology is supposedly capable of cloning Synthoid, not only physically but also their advanced AI modules. We do not believe that VitaLife is trying to use this technology illegally or maliciously, but if any Synthoids were able to infiltrate the corporation and take advantage of this technology then the results would be catastrophic.

We do not have the power or jurisdiction to shutdown this down through legal or political means, so we must resort to a covert operation. Your goal is to destroy this technology and eliminate anyone who was involved in its creation.",baseDifficulty:15e3,reqdRank:3e4,rankGain:750,rankLoss:60,hpLoss:1e3,weights:{hack:.05,str:.2,def:.2,dex:.25,agi:.25,cha:0,int:.05},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Deckard"]=new V({name:"Operation Deckard",desc:"Despite your success in eliminating VitaLife's new android-replicating technology in Operation K, we've discovered that a small group of MK-VI Synthoids were able to make off with the schematics and design of the technology before the Operation. It is almost a certainty that these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising.The goal of Operation Deckard is to hunt down these Synthoids and retire them. I don't need to tell you how critical this mission is.",baseDifficulty:2e4,reqdRank:4e4,rankGain:1e3,rankLoss:75,hpLoss:200,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:0,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Tyrell"]=new V({name:"Operation Tyrell",desc:"A week ago Blade Industries reported a small break-in at one of their Aevum Augmentation storage facitilities. We figured out that The Dark Army was behind the heist, and didn't think any more of it. However, we've just discovered that several known MK-VI Synthoids were part of that break-in group.

We cannot have Synthoids upgrading their already-enhanced abilities with Augmentations. Your task is to hunt down the associated Dark Army members and eliminate them.",baseDifficulty:25e3,reqdRank:5e4,rankGain:1500,rankLoss:100,hpLoss:500,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Wallace"]=new V({name:"Operation Wallace",desc:"Based on information gathered from Operation Tyrell, we've discovered that The Dark Army was well aware that there were Synthoids amongst their ranks. Even worse, we believe that The Dark Army is working together with other criminal organizations such as The Syndicate and that they are planning some sort of large-scale takeover of multiple major cities, most notably Aevum. We suspect that Synthoids have infiltrated the ranks of these criminal factions and are trying to stage another Synthoid uprising.

The best way to deal with this is to prevent it before it even happens. The goal of Operation Wallace is to destroy the Dark Army and Syndicate factions in Aevum immediately. Leave no survivors.",baseDifficulty:3e4,reqdRank:75e3,rankGain:2e3,rankLoss:150,hpLoss:1500,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Shoulder of Orion"]=new V({name:"Operation Shoulder of Orion",desc:"China's Solaris Space Systems is secretly launching the first manned spacecraft in over a decade using Synthoids. We believe China is trying to establish the first off-world colonies.

The mission is to prevent this launch without instigating an international conflict. When you accept this mission you will be officially disavowed by the NSA and the national government until after you successfully return. In the event of failure, all of the operation's team members must not let themselves be captured alive.",baseDifficulty:35e3,reqdRank:1e5,rankGain:2500,rankLoss:500,hpLoss:1500,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isStealth:!0}),J["Operation Hyron"]=new V({name:"Operation Hyron",desc:"Our intelligence tells us that Fulcrum Technologies is developing a quantum supercomputer using human brains as core processors. This supercomputer is rumored to be able to store vast amounts of data and perform computations unmatched by any other supercomputer on the planet. But more importantly, the use of organic human brains means that the supercomputer may be able to reason abstractly and become self-aware.

I do not need to remind you why sentient-level AIs pose a serious thread to all of mankind.

The research for this project is being conducted at one of Fulcrum Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. Infiltrate the compound, delete and destroy the work, and then find and kill the project lead.",baseDifficulty:4e4,reqdRank:125e3,rankGain:3e3,rankLoss:1e3,hpLoss:500,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Morpheus"]=new V({name:"Operation Morpheus",desc:"DreamSense Technologies is an advertising company that uses special technology to transmit their ads into the peoples dreams and subconcious. They do this using broadcast transmitter towers. Based on information from our agents and informants in Chonqging, we have reason to believe that one of the broadcast towers there has been compromised by Synthoids and is being used to spread pro-Synthoid propaganda.

The mission is to destroy this broadcast tower. Speed and stealth are of the upmost important for this.",baseDifficulty:45e3,reqdRank:15e4,rankGain:4e3,rankLoss:1e3,hpLoss:100,weights:{hack:.05,str:.15,def:.15,dex:.3,agi:.3,cha:0,int:.05},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isStealth:!0}),J["Operation Ion Storm"]=new V({name:"Operation Ion Storm",desc:"Our analysts have uncovered a gathering of MK-VI Synthoids that have taken up residence in the Sector-12 Slums. We don't know if they are rogue Synthoids from the Uprising, but we do know that they have been stockpiling weapons, money, and other resources. This makes them dangerous.

This is a full-scale assault operation to find and retire all of these Synthoids in the Sector-12 Slums.",baseDifficulty:5e4,reqdRank:175e3,rankGain:5e3,rankLoss:1e3,hpLoss:5e3,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Annihilus"]=new V({name:"Operation Annihilus",desc:"Our superiors have ordered us to eradicate everything and everyone in an underground facility located in Aevum. They tell us that the facility houses many dangerous Synthoids and belongs to a terrorist organization called 'The Covenant'. We have no prior intelligence about this organization, so you are going in blind.",baseDifficulty:55e3,reqdRank:2e5,rankGain:7500,rankLoss:1e3,hpLoss:1e4,weights:{hack:0,str:.24,def:.24,dex:.24,agi:.24,cha:0,int:.04},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Ultron"]=new V({name:"Operation Ultron",desc:"OmniTek Incorporated, the original designer and manufacturer of Synthoids, has notified us of a malfunction in their AI design. This malfunction, when triggered, causes MK-VI Synthoids to become radicalized and seek out the destruction of humanity. They say that this bug affects all MK-VI Synthoids, not just the rogue ones from the Uprising.

OmniTek has also told us they they believe someone has triggered this malfunction in a large group of MK-VI Synthoids, and that these newly-radicalized Synthoids are now amassing in Volhaven to form a terrorist group called Ultron.

Intelligence suggests Ultron is heavily armed and that their members are augmented. We believe Ultron is making moves to take control of and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).

Your task is to find and destroy Ultron.",baseDifficulty:6e4,reqdRank:25e4,rankGain:1e4,rankLoss:2e3,hpLoss:1e4,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75},isKill:!0}),J["Operation Centurion"]=new V({name:"Operation Centurion",desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

Throughout all of humanity's history, we have relied on technology to survive, conquer, and progress. Its advancement became our primary goal. And at the peak of human civilization technology turned into power. Global, absolute power.

It seems that the universe is not without a sense of irony.

D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",baseDifficulty:7e4,reqdRank:3e5,rankGain:15e3,rankLoss:5e3,hpLoss:1e4,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75}}),J["Operation Vindictus"]=new V({name:"Operation Vindictus",desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)

The bits are all around us. The daemons that hold the Node together can manifest themselves in many different ways.

D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",baseDifficulty:75e3,reqdRank:35e4,rankGain:2e4,rankLoss:2e4,hpLoss:2e4,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75}}),J["Operation Daedalus"]=new V({name:"Operation Daedalus",desc:"Yesterday we obeyed kings and bent our neck to emperors. Today we kneel only to truth.",baseDifficulty:8e4,reqdRank:4e5,rankGain:4e4,rankLoss:1e4,hpLoss:1e5,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.75}})}(),this.initializeDomElementRefs(),e.new&&this.create()}X.prototype.prestige=function(){this.resetAction();var e=c.Factions.Bladeburners;this.rank>=25&&Object(u.joinFaction)(e)},X.prototype.create=function(){this.contracts.Tracking=new Y({name:"Tracking",desc:"Identify and locate Synthoids. This contract involves reconnaissance and information-gathering ONLY. Do NOT engage. Stealth is of the utmost importance.

Successfully completing Tracking contracts will slightly improve your Synthoid population estimate for whatever city you are currently in.",baseDifficulty:125,difficultyFac:1.02,rewardFac:1.041,rankGain:.3,hpLoss:.5,count:Object(C.getRandomInt)(25,150),countGrowth:Object(C.getRandomInt)(5,75)/10,weights:{hack:0,str:.05,def:.05,dex:.35,agi:.35,cha:.1,int:.05},decays:{hack:0,str:.91,def:.91,dex:.91,agi:.91,cha:.9,int:1},isStealth:!0}),this.contracts["Bounty Hunter"]=new Y({name:"Bounty Hunter",desc:"Hunt down and capture fugitive Synthoids. These Synthoids are wanted alive.

Successfully completing a Bounty Hunter contract will lower the population in your current city, and will also increase its chaos level.",baseDifficulty:250,difficultyFac:1.04,rewardFac:1.085,rankGain:.9,hpLoss:1,count:Object(C.getRandomInt)(5,150),countGrowth:Object(C.getRandomInt)(5,75)/10,weights:{hack:0,str:.15,def:.15,dex:.25,agi:.25,cha:.1,int:.1},decays:{hack:0,str:.91,def:.91,dex:.91,agi:.91,cha:.8,int:.9},isKill:!0}),this.contracts.Retirement=new Y({name:"Retirement",desc:"Hunt down and retire (kill) rogue Synthoids.

Successfully completing a Retirement contract will lower the population in your current city, and will also increase its chaos level.",baseDifficulty:200,difficultyFac:1.03,rewardFac:1.065,rankGain:.6,hpLoss:1,count:Object(C.getRandomInt)(5,150),countGrowth:Object(C.getRandomInt)(5,75)/10,weights:{hack:0,str:.2,def:.2,dex:.2,agi:.2,cha:.1,int:.1},decays:{hack:0,str:.91,def:.91,dex:.91,agi:.91,cha:.8,int:.9},isKill:!0}),this.operations.Investigation=new z({name:"Investigation",desc:"As a field agent, investigate and identify Synthoid populations, movements, and operations.

Successful Investigation ops will increase the accuracy of your synthoid data.

You will NOT lose HP from failed Investigation ops.",baseDifficulty:400,difficultyFac:1.03,rewardFac:1.07,reqdRank:25,rankGain:2.2,rankLoss:.2,count:Object(C.getRandomInt)(1,100),countGrowth:Object(C.getRandomInt)(10,40)/10,weights:{hack:.25,str:.05,def:.05,dex:.2,agi:.1,cha:.25,int:.1},decays:{hack:.85,str:.9,def:.9,dex:.9,agi:.9,cha:.7,int:.9},isStealth:!0}),this.operations["Undercover Operation"]=new z({name:"Undercover Operation",desc:"Conduct undercover operations to identify hidden and underground Synthoid communities and organizations.

Successful Undercover ops will increase the accuracy of your synthoid data.",baseDifficulty:500,difficultyFac:1.04,rewardFac:1.09,reqdRank:100,rankGain:4.4,rankLoss:.4,hpLoss:2,count:Object(C.getRandomInt)(1,100),countGrowth:Object(C.getRandomInt)(10,40)/10,weights:{hack:.2,str:.05,def:.05,dex:.2,agi:.2,cha:.2,int:.1},decays:{hack:.8,str:.9,def:.9,dex:.9,agi:.9,cha:.7,int:.9},isStealth:!0}),this.operations["Sting Operation"]=new z({name:"Sting Operation",desc:"Conduct a sting operation to bait and capture particularly notorious Synthoid criminals.",baseDifficulty:650,difficultyFac:1.04,rewardFac:1.095,reqdRank:500,rankGain:5.5,rankLoss:.5,hpLoss:2.5,count:Object(C.getRandomInt)(1,150),countGrowth:Object(C.getRandomInt)(3,40)/10,weights:{hack:.25,str:.05,def:.05,dex:.25,agi:.1,cha:.2,int:.1},decays:{hack:.8,str:.85,def:.85,dex:.85,agi:.85,cha:.7,int:.9},isStealth:!0}),this.operations.Raid=new z({name:"Raid",desc:"Lead an assault on a known Synthoid community. Note that there must be an existing Synthoid community in your current city in order for this Operation to be successful",baseDifficulty:800,difficultyFac:1.045,rewardFac:1.1,reqdRank:3e3,rankGain:55,rankLoss:2.5,hpLoss:50,count:Object(C.getRandomInt)(1,150),countGrowth:Object(C.getRandomInt)(2,40)/10,weights:{hack:.1,str:.2,def:.2,dex:.2,agi:.2,cha:0,int:.1},decays:{hack:.7,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.9},isKill:!0}),this.operations["Stealth Retirement Operation"]=new z({name:"Stealth Retirement Operation",desc:"Lead a covert operation to retire Synthoids. The objective is to complete the task without drawing any attention. Stealth and discretion are key.",baseDifficulty:1e3,difficultyFac:1.05,rewardFac:1.11,reqdRank:2e4,rankGain:22,rankLoss:2,hpLoss:10,count:Object(C.getRandomInt)(1,150),countGrowth:Object(C.getRandomInt)(1,20)/10,weights:{hack:.1,str:.1,def:.1,dex:.3,agi:.3,cha:0,int:.1},decays:{hack:.7,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.9},isStealth:!0,isKill:!0}),this.operations.Assassination=new z({name:"Assassination",desc:"Assassinate Synthoids that have been identified as important, high-profile social and political leaders in the Synthoid communities.",baseDifficulty:1500,difficultyFac:1.06,rewardFac:1.14,reqdRank:5e4,rankGain:44,rankLoss:4,hpLoss:5,count:Object(C.getRandomInt)(1,150),countGrowth:Object(C.getRandomInt)(1,20)/10,weights:{hack:.1,str:.1,def:.1,dex:.3,agi:.3,cha:0,int:.1},decays:{hack:.6,str:.8,def:.8,dex:.8,agi:.8,cha:0,int:.8},isStealth:!0,isKill:!0})},X.prototype.storeCycles=function(e=1){this.storedCycles+=e},X.prototype.process=function(){if(!1===p.b&&this.blackops.hasOwnProperty("Operation Daedalus"))return Object(p.a)(m.Player.bitNodeN);if(!1===r.Augmentations[a.AugmentationNames.BladesSimulacrum].owned&&m.Player.isWorking){if(this.action.type!==$.Idle){let e="Your Bladeburner action was cancelled because you started doing something else.";this.automateEnabled&&(e+="

Your automation was disabled as well. You will have to re-enable it through the Bladeburner console",this.automateEnabled=!1),Object(_.dialogBoxCreate)(e)}this.resetAction()}if(this.stamina<=0&&(this.log("Your Bladeburner action was cancelled because your stamina hit 0"),this.resetAction()),this.storedCycles>=5){var e=Math.floor(this.storedCycles/5);for(var t in e=Math.min(e,5),this.storedCycles-=5*e,this.calculateMaxStamina(),this.stamina+=this.calculateStaminaGainPerSecond()*e,this.stamina=Math.min(this.maxStamina,this.stamina),this.contracts)if(this.contracts.hasOwnProperty(t)){var n=this.contracts[t];n.count+=e*n.countGrowth/480}for(var i in this.operations)if(this.operations.hasOwnProperty(i)){var o=this.operations[i];o.count+=e*o.countGrowth/480}for(var s=0;s=this.automateThreshHigh&&(this.action.name===this.automateActionHigh.name&&this.action.type===this.automateActionHigh.type||(this.action=new q({type:this.automateActionHigh.type,name:this.automateActionHigh.name}),this.startAction(this.action)))),h.routing.isOn(h.Page.Bladeburner)&&this.updateContent()}},X.prototype.calculateMaxStamina=function(){const e=m.Player.agility*this.skillMultipliers.effAgi;let t=(Math.pow(e,.8)+this.staminaBonus)*this.skillMultipliers.stamina*m.Player.bladeburner_max_stamina_mult;if(this.maxStamina!==t){const e=this.maxStamina;this.maxStamina=t,this.stamina=this.maxStamina*this.stamina/e}if(isNaN(t))throw new Error("Max Stamina calculated to be NaN in Bladeburner.calculateMaxStamina()")},X.prototype.calculateStaminaGainPerSecond=function(){var e=m.Player.agility*this.skillMultipliers.effAgi;return(.0085+this.maxStamina/7e4)*Math.pow(e,.17)*(this.skillMultipliers.stamina*m.Player.bladeburner_stamina_gain_mult)},X.prototype.calculateStaminaPenalty=function(){return Math.min(1,this.stamina/(.5*this.maxStamina))},X.prototype.changeRank=function(e){if(isNaN(e))throw new Error("NaN passed into Bladeburner.changeRank()");this.rank+=e,this.rank<0&&(this.rank=0),this.maxRank=Math.max(this.rank,this.maxRank);if(Object(c.factionExists)("Bladeburners")){var t=c.Factions.Bladeburners;if(!(t instanceof l.Faction))throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");if(t.isMember){var n=1+t.favor/100;t.playerReputation+=2*e*m.Player.faction_rep_mult*n}}var r=3*(this.totalSkillPoints+1);if(this.maxRank>=r){var a=Math.floor((this.maxRank-r)/3+1);this.skillPoints+=a,this.totalSkillPoints+=a}},X.prototype.getCurrentCity=function(){var e=this.cities[this.city];if(!(e instanceof j))throw new Error("Bladeburner.getCurrentCity() did not properly return a City object");return e},X.prototype.resetSkillMultipliers=function(){this.skillMultipliers={successChanceAll:1,successChanceStealth:1,successChanceKill:1,successChanceContract:1,successChanceOperation:1,successChanceEstimate:1,actionTime:1,effHack:1,effStr:1,effDef:1,effDex:1,effAgi:1,effCha:1,effInt:1,stamina:1,money:1,expGain:1,weaponAbility:1,gunAbility:1}},X.prototype.updateSkillMultipliers=function(){for(var e in this.resetSkillMultipliers(),this.skills)if(this.skills.hasOwnProperty(e)){var t=U[e];if(null==t)throw new Error("Could not find Skill Object for: "+e);var n=this.skills[e];if(null==n||n<=0)continue;for(var r=Object.keys(this.skillMultipliers),a=0;a=this.actionTimeToComplete?this.completeAction():void 0}},X.prototype.completeAction=function(){switch(this.action.type){case $.Contract:case $.Operation:try{var e=this.action.type===$.Operation;if(null==(_=this.getActionObject(this.action)))throw new Error("Failed to get Contract/Operation Object for: "+this.action.name);var t=_.getDifficulty(),n=Math.pow(t,.28)+t/650,r=Math.pow(_.rewardFac,_.level-1);if(this.stamina-=.285*n,this.stamina<0&&(this.stamina=0),_.attempt(this)){this.gainActionStats(_,!0),++_.successes,--_.count;var a=0;if(e||(a=25e4*r*this.skillMultipliers.money,m.Player.gainMoney(a),m.Player.recordMoneySource(a,"bladeburner")),e?_.setMaxLevel(2.5):_.setMaxLevel(3),_.rankGain){var s=Object(b.addOffset)(_.rankGain*r*i.BitNodeMultipliers.BladeburnerRank,10);this.changeRank(s),e&&this.logging.ops?this.log(_.name+" successfully completed! Gained "+Object(f.formatNumber)(s,3)+" rank"):!e&&this.logging.contracts&&this.log(_.name+" contract successfully completed! Gained "+Object(f.formatNumber)(s,3)+" rank and "+d.numeralWrapper.format(a,"$0.000a"))}e?this.completeOperation(!0):this.completeContract(!0)}else{this.gainActionStats(_,!1),++_.failures;var l=0,c=0;_.rankLoss&&(l=Object(b.addOffset)(_.rankLoss*r,10),this.changeRank(-1*l)),_.hpLoss&&(c=_.hpLoss*n,c=Math.ceil(Object(b.addOffset)(c,10)),this.hpLost+=c,m.Player.takeDamage(c)&&(++this.numHosp,this.moneyLost+=o.CONSTANTS.HospitalCostPerHp*m.Player.max_hp));var u="";l>0&&(u+="Lost "+Object(f.formatNumber)(l,3)+" rank."),c>0&&(u+="Took "+Object(f.formatNumber)(c,0)+" damage."),e&&this.logging.ops?this.log(_.name+" failed! "+u):!e&&this.logging.contracts&&this.log(_.name+" contract failed! "+u),e?this.completeOperation(!1):this.completeContract(!1)}_.autoLevel&&(_.level=_.maxLevel),this.startAction(this.action)}catch(e){Object(k.exceptionAlert)(e)}break;case $.BlackOp:case $.BlackOperation:try{var _;if(null==(_=this.getActionObject(this.action))||!(_ instanceof V))throw new Error("Failed to get BlackOperation Object for: "+this.action.name);t=_.getDifficulty(),n=Math.pow(t,.28)+t/650;this.stamina-=.285*n,this.stamina<0&&(this.stamina=0);var g,y=_.teamCount;if(_.attempt(this)){this.gainActionStats(_,!0),_.count=0,this.blackops[_.name]=!0;var E=0;if(_.rankGain&&(E=Object(b.addOffset)(_.rankGain*i.BitNodeMultipliers.BladeburnerRank,10),this.changeRank(E)),g=Math.ceil(y/2),"Operation Daedalus"===_.name)return this.resetAction(),Object(p.a)(m.Player.bitNodeN);h.routing.isOn(h.Page.Bladeburner)&&this.createActionAndSkillsContent(),this.logging.blackops&&this.log(_.name+" successful! Gained "+Object(f.formatNumber)(E,1)+" rank")}else{this.gainActionStats(_,!1);var v=0;c=0;_.rankLoss&&(v=Object(b.addOffset)(_.rankLoss,10),this.changeRank(-1*v)),_.hpLoss&&(c=_.hpLoss*n,c=Math.ceil(Object(b.addOffset)(c,10)),m.Player.takeDamage(c)&&(++this.numHosp,this.moneyLost+=o.CONSTANTS.HospitalCostPerHp*m.Player.max_hp)),g=Math.floor(y),this.logging.blackops&&this.log(_.name+" failed! Lost "+Object(f.formatNumber)(v,1)+" rank and took "+Object(f.formatNumber)(c,0)+" damage")}if(this.resetAction(),y>=1){var P=Object(C.getRandomInt)(1,g);this.teamSize-=P,this.teamLost+=P,this.logging.blackops&&this.log("You lost "+Object(f.formatNumber)(P,0)+" team members during "+_.name)}}catch(e){Object(k.exceptionAlert)(e)}break;case $.Training:this.stamina-=.1425;var T=30*m.Player.strength_exp_mult,S=30*m.Player.defense_exp_mult,O=30*m.Player.dexterity_exp_mult,M=30*m.Player.agility_exp_mult,x=.04*this.skillMultipliers.stamina;m.Player.gainStrengthExp(T),m.Player.gainDefenseExp(S),m.Player.gainDexterityExp(O),m.Player.gainAgilityExp(M),this.staminaBonus+=x,this.logging.general&&this.log("Training completed. Gained: "+Object(f.formatNumber)(T,1)+" str exp, "+Object(f.formatNumber)(S,1)+" def exp, "+Object(f.formatNumber)(O,1)+" dex exp, "+Object(f.formatNumber)(M,1)+" agi exp, "+Object(f.formatNumber)(x,3)+" max stamina"),this.startAction(this.action);break;case $.FieldAnalysis:case $["Field Analysis"]:var w=.04*Math.pow(m.Player.hacking_skill,.3)+.04*Math.pow(m.Player.intelligence,.9)+.02*Math.pow(m.Player.charisma,.3);if(w*=m.Player.bladeburner_analysis_mult,isNaN(w)||w<0)throw new Error("Field Analysis Effectiveness calculated to be NaN or negative");var A=20*m.Player.hacking_exp_mult,R=20*m.Player.charisma_exp_mult;m.Player.gainHackingExp(A),m.Player.gainIntelligenceExp(.001),m.Player.gainCharismaExp(R),this.changeRank(.1*i.BitNodeMultipliers.BladeburnerRank),this.getCurrentCity().improvePopulationEstimateByPercentage(w*this.skillMultipliers.successChanceEstimate),this.logging.general&&this.log("Field analysis completed. Gained 0.1 rank, "+Object(f.formatNumber)(A,1)+" hacking exp, and "+Object(f.formatNumber)(R,1)+" charisma exp"),this.startAction(this.action);break;case $.Recruitment:var N=this.getRecruitmentSuccessChance();if(Math.random()=1){n=e?Math.ceil(r/2):Math.floor(r);var a=Object(C.getRandomInt)(0,n);this.teamSize-=a,this.teamLost+=a,this.logging.ops&&a>0&&this.log("Lost "+Object(f.formatNumber)(a,0)+" team members during this "+t.name)}var i=this.getCurrentCity();switch(t.name){case"Investigation":e?(i.improvePopulationEstimateByPercentage(.4*this.skillMultipliers.successChanceEstimate),Math.random()<.02*this.skillMultipliers.successChanceEstimate&&i.improveCommunityEstimate(1)):this.triggerPotentialMigration(this.city,.1);break;case"Undercover Operation":e?(i.improvePopulationEstimateByPercentage(.8*this.skillMultipliers.successChanceEstimate),Math.random()<.02*this.skillMultipliers.successChanceEstimate&&i.improveCommunityEstimate(1)):this.triggerPotentialMigration(this.city,.15);break;case"Sting Operation":e&&i.changePopulationByPercentage(-.1,{changeEstEqually:!0,nonZero:!0}),i.changeChaosByCount(.1);break;case"Raid":if(e)i.changePopulationByPercentage(-1,{changeEstEqually:!0,nonZero:!0}),--i.comms,--i.commsEst;else{var o=Object(C.getRandomInt)(-10,-5)/10;i.changePopulationByPercentage(o,{nonZero:!0})}i.changeChaosByPercentage(Object(C.getRandomInt)(1,5));break;case"Stealth Retirement Operation":e&&i.changePopulationByPercentage(-.5,{changeEstEqually:!0,nonZero:!0}),i.changeChaosByPercentage(Object(C.getRandomInt)(-3,-1));break;case"Assassination":e&&i.changePopulationByCount(-1,{estChange:-1}),i.changeChaosByPercentage(Object(C.getRandomInt)(-5,5));break;default:throw new Error("Invalid Action name in completeOperation: "+this.action.name)}},X.prototype.getRecruitmentTime=function(){var e=m.Player.charisma*this.skillMultipliers.effCha,t=Math.pow(e,.81)+e/90;return Math.max(10,Math.round(300-t))},X.prototype.getRecruitmentSuccessChance=function(){return Math.pow(m.Player.charisma,.45)/(this.teamSize+1)},X.prototype.getDiplomacyEffectiveness=function(){return(100-(Math.pow(m.Player.charisma,.045)+m.Player.charisma/1e3))/100},X.prototype.gainActionStats=function(e,t){var n=e.getDifficulty(),r=Math.pow(n,.28)+n/650,a=this.actionTimeToComplete,i=t?1:.5,o=1*a*i*r,s=.001*a*i*r;const l=this.skillMultipliers.expGain;m.Player.gainHackingExp(o*e.weights.hack*m.Player.hacking_exp_mult*l),m.Player.gainStrengthExp(o*e.weights.str*m.Player.strength_exp_mult*l),m.Player.gainDefenseExp(o*e.weights.def*m.Player.defense_exp_mult*l),m.Player.gainDexterityExp(o*e.weights.dex*m.Player.dexterity_exp_mult*l),m.Player.gainAgilityExp(o*e.weights.agi*m.Player.agility_exp_mult*l),m.Player.gainCharismaExp(o*e.weights.cha*m.Player.charisma_exp_mult*l),m.Player.gainIntelligenceExp(s*e.weights.int*l)},X.prototype.randomEvent=function(){var e=Math.random(),t=D[Object(C.getRandomInt)(0,5)],n=this.cities[t];if(!(n instanceof j))throw new Error("sourceCity was not a City object in Bladeburner.randomEvent()");for(var r=D[Object(C.getRandomInt)(0,5)];r===t;)r=D[Object(C.getRandomInt)(0,5)];var a=this.cities[r];if(!(n instanceof j&&a instanceof j))throw new Error("sourceCity/destCity was not a City object in Bladeburner.randomEvent()");if(e<=.05){++n.comms;var i=Object(C.getRandomInt)(10,20)/100,o=Math.round(n.pop*i);n.pop+=o,this.logging.events&&this.log("Intelligence indicates that a new Synthoid community was formed in a city")}else if(e<=.1)if(n.comms<=0){++n.comms;i=Object(C.getRandomInt)(10,20)/100,o=Math.round(n.pop*i);n.pop+=o,this.logging.events&&this.log("Intelligence indicates that a new Synthoid community was formed in a city")}else{--n.comms,++a.comms;i=Object(C.getRandomInt)(10,20)/100,o=Math.round(n.pop*i);n.pop-=o,a.pop+=o,this.logging.events&&this.log("Intelligence indicates that a Synthoid community migrated from "+t+" to some other city")}else if(e<=.3){i=Object(C.getRandomInt)(8,24)/100,o=Math.round(n.pop*i);n.pop+=o,this.logging.events&&this.log("Intelligence indicates that the Synthoid population of "+t+" just changed significantly")}else if(e<=.5)this.triggerMigration(t),this.logging.events&&this.log("Intelligence indicates that a large number of Synthoids migrated from "+t+" to some other city");else if(e<=.7)n.chaos+=1,n.chaos*=1+Object(C.getRandomInt)(5,20)/100,this.logging.events&&this.log("Tensions between Synthoids and humans lead to riots in "+t+"! Chaos increased");else if(e<=.9){i=Object(C.getRandomInt)(8,20)/100,o=Math.round(n.pop*i);n.pop-=o,this.logging.events&&this.log("Intelligence indicates that the Synthoid population of "+t+" just changed significantly")}},X.prototype.triggerPotentialMigration=function(e,t){(null==t||isNaN(t))&&console.error("Invalid 'chance' parameter passed into Bladeburner.triggerPotentialMigration()"),t>1&&(t/=100),Math.random()0&&(i*=Object(C.getRandomInt)(2,4),--r.comms,++n.comms);var o=Math.round(r.pop*i);r.pop-=o,n.pop+=o};let Q={};X.prototype.initializeDomElementRefs=function(){Q={bladeburnerDiv:null,overviewConsoleParentDiv:null,overviewDiv:null,actionAndSkillsDiv:null,currentTab:null,consoleDiv:null,consoleTable:null,consoleInputRow:null,consoleInputCell:null,consoleInputHeader:null,consoleInput:null,overviewRank:null,overviewStamina:null,overviewStaminaHelpTip:null,overviewGen1:null,overviewEstPop:null,overviewEstPopHelpTip:null,overviewEstComms:null,overviewChaos:null,overviewSkillPoints:null,overviewBonusTime:null,overviewAugSuccessMult:null,overviewAugMaxStaminaMult:null,overviewAugStaminaGainMult:null,overviewAugAnalysisMult:null,actionsAndSkillsDesc:null,actionsAndSkillsList:null,generalActions:{},contracts:{},operations:{},blackops:{},skills:{},skillPointsDisplay:null}},X.prototype.createContent=function(){Q.bladeburnerDiv=Object(M.createElement)("div",{id:"bladeburner-container",position:"fixed",class:"generic-menupage-container"}),Q.overviewConsoleParentDiv=Object(M.createElement)("div",{height:"60%",display:"block",position:"relative"}),Q.overviewDiv=Object(M.createElement)("div",{width:"30%",display:"inline-block",border:"1px solid white"}),Q.actionAndSkillsDiv=Object(M.createElement)("div",{height:"60%",width:"70%",display:"block",border:"1px solid white",margin:"6px",padding:"6px"}),Q.currentTab="general",this.createOverviewContent(),this.createActionAndSkillsContent(),Q.consoleDiv=Object(M.createElement)("div",{class:"bladeburner-console-div",clickListener:()=>(Q.consoleInput instanceof Element&&Q.consoleInput.focus(),!1)}),Q.consoleTable=Object(M.createElement)("table",{class:"bladeburner-console-table"}),Q.consoleInputRow=Object(M.createElement)("tr",{class:"bladeburner-console-input-row",id:"bladeubrner-console-input-row"}),Q.consoleInputCell=Object(M.createElement)("td",{class:"bladeburner-console-input-cell"}),Q.consoleInputHeader=Object(M.createElement)("pre",{innerText:"> "}),Q.consoleInput=Object(M.createElement)("input",{type:"text",class:"bladeburner-console-input",tabIndex:1,onfocus:()=>{Q.consoleInput.value=Q.consoleInput.value}}),Q.consoleInputCell.appendChild(Q.consoleInputHeader),Q.consoleInputCell.appendChild(Q.consoleInput),Q.consoleInputRow.appendChild(Q.consoleInputCell),Q.consoleTable.appendChild(Q.consoleInputRow),Q.consoleDiv.appendChild(Q.consoleTable),Q.overviewConsoleParentDiv.appendChild(Q.overviewDiv),Q.overviewConsoleParentDiv.appendChild(Q.consoleDiv),Q.bladeburnerDiv.appendChild(Q.overviewConsoleParentDiv),Q.bladeburnerDiv.appendChild(Q.actionAndSkillsDiv);const e=Object(M.createElement)("div");if(e.innerHTML=`${R}= This action requires stealth, ${N} = This action involves retirement`,Q.bladeburnerDiv.appendChild(e),document.getElementById("entire-game-container").appendChild(Q.bladeburnerDiv),0===this.consoleLogs.length)this.postToConsole("Bladeburner Console BETA"),this.postToConsole("Type 'help' to see console commands");else for(let e=0;e{Object(_.dialogBoxCreate)("Performing actions will use up your stamina.

Your max stamina is determined primarily by your agility stat.

Your stamina gain rate is determined by both your agility and your max stamina. Higher max stamina leads to a higher gain rate.

Once your stamina falls below 50% of its max value, it begins to negatively affect the success rate of your contracts/operations. This penalty is shown in the overview panel. If the penalty is 15%, then this means your success rate would be multipled by 85% (100 - 15).

Your max stamina and stamina gain rate can also be increased by training, or through skills and Augmentation upgrades.")}}),Q.overviewGen1=Object(M.createElement)("p",{display:"block"}),Q.overviewEstPop=Object(M.createElement)("p",{innerText:"Est. Synthoid Population: ",display:"inline-block",tooltip:"This is your Bladeburner division's estimate of how many Synthoids exist in your current city."}),Q.overviewEstPopHelpTip=Object(M.createElement)("div",{innerText:"?",class:"help-tip",clickListener:()=>{Object(_.dialogBoxCreate)("The success rate of your contracts/operations depends on the population of Synthoids in your current city. The success rate that is shown to you is only an estimate, and it is based on your Synthoid population estimate.

Therefore, it is important that this Synthoid population estimate is accurate so that you have a better idea of your success rate for contracts/operations. Certain actions will increase the accuracy of your population estimate.

The Synthoid populations of cities can change due to your actions or random events. If random events occur, they will be logged in the Bladeburner Console.")}}),Q.overviewEstComms=Object(M.createElement)("p",{innerText:"Est. Synthoid Communities: ",display:"inline-block",tooltip:"This is your Bladeburner divison's estimate of how many Synthoid communities exist in your current city."}),Q.overviewChaos=Object(M.createElement)("p",{innerText:"City Chaos: ",display:"inline-block",tooltip:"The city's chaos level due to tensions and conflicts between humans and Synthoids. Having too high of a chaos level can make contracts and operations harder."}),Q.overviewBonusTime=Object(M.createElement)("p",{innerText:"Bonus time: ",display:"inline-block",tooltip:"You gain bonus time while offline or when the game is inactive (e.g. when the tab is throttled by browser). Bonus time makes the Bladeburner mechanic progress faster, up to 5x the normal speed."}),Q.overviewSkillPoints=Object(M.createElement)("p",{display:"block"}),Q.overviewAugSuccessMult=Object(M.createElement)("p",{display:"block"}),Q.overviewAugMaxStaminaMult=Object(M.createElement)("p",{display:"block"}),Q.overviewAugStaminaGainMult=Object(M.createElement)("p",{display:"block"}),Q.overviewAugAnalysisMult=Object(M.createElement)("p",{display:"block"}),Q.overviewDiv.appendChild(Q.overviewRank),Object(O.appendLineBreaks)(Q.overviewDiv,1),Q.overviewDiv.appendChild(Q.overviewStamina),Q.overviewDiv.appendChild(Q.overviewStaminaHelpTip),Q.overviewDiv.appendChild(Q.overviewGen1),Q.overviewDiv.appendChild(Q.overviewEstPop),Q.overviewDiv.appendChild(Q.overviewEstPopHelpTip),Object(O.appendLineBreaks)(Q.overviewDiv,1),Q.overviewDiv.appendChild(Q.overviewEstComms),Object(O.appendLineBreaks)(Q.overviewDiv,1),Q.overviewDiv.appendChild(Q.overviewChaos),Object(O.appendLineBreaks)(Q.overviewDiv,2),Q.overviewDiv.appendChild(Q.overviewBonusTime),Q.overviewDiv.appendChild(Q.overviewSkillPoints),Object(O.appendLineBreaks)(Q.overviewDiv,1),Q.overviewDiv.appendChild(Q.overviewAugSuccessMult),Q.overviewDiv.appendChild(Q.overviewAugMaxStaminaMult),Q.overviewDiv.appendChild(Q.overviewAugStaminaGainMult),Q.overviewDiv.appendChild(Q.overviewAugAnalysisMult),Object(O.appendLineBreaks)(Q.overviewDiv,1),Q.overviewDiv.appendChild(Object(M.createElement)("a",{innerHTML:"Travel",class:"a-link-button",display:"inline-block",clickListener:()=>{var e="bladeburner-travel-popup-cancel-btn",t=[];t.push(Object(M.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(A.removeElementById)(e),!1)})),t.push(Object(M.createElement)("p",{innerText:"Travel to a different city for your Bladeburner activities. This does not cost any money. The city you are in for your Bladeburner duties does not affect your location in the game otherwise"}));for(var n=0;n(n.city=D[r],Object(A.removeElementById)(e),n.updateOverviewContent(),!1)}))}(this,n);Object(x.createPopup)(e,t)}}));if(Object(c.factionExists)("Bladeburners")){var e=c.Factions.Bladeburners;if(!(e instanceof l.Faction))throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");Q.overviewDiv.appendChild(Object(M.createElement)("a",{innerText:"Faction",class:"a-link-button",display:"inline-block",tooltip:"Apply to the Bladeburner Faction, or go to the faction page if you are already a member",clickListener:()=>(e.isMember?(s.Engine.loadFactionContent(),Object(u.displayFactionContent)("Bladeburners")):this.rank>=25?(Object(u.joinFaction)(e),Object(_.dialogBoxCreate)("Congratulations! You were accepted into the Bladeburners faction"),Object(S.removeChildrenFromElement)(Q.overviewDiv),this.createOverviewContent()):Object(_.dialogBoxCreate)("You need a rank of 25 to join the Bladeburners Faction!"),!1)}))}Q.overviewDiv.appendChild(Object(M.createElement)("br")),Q.overviewDiv.appendChild(Object(M.createElement)("br")),this.updateOverviewContent()},X.prototype.createActionAndSkillsContent=function(){null==Q.currentTab&&(Q.currentTab="general"),Object(S.removeChildrenFromElement)(Q.actionAndSkillsDiv),Object(E.clearObject)(Q.generalActions),Object(E.clearObject)(Q.contracts),Object(E.clearObject)(Q.operations),Object(E.clearObject)(Q.blackops),Object(E.clearObject)(Q.skills);for(var e=Q.currentTab.toLowerCase(),t=["General","Contracts","Operations","BlackOps","Skills"],n=0;n(Q.currentTab=e[t].toLowerCase(),n.createActionAndSkillsContent(),!1)}))}(t,n,this,e);switch(Q.actionsAndSkillsDesc=Object(M.createElement)("p",{display:"block",margin:"4px",padding:"4px"}),Object(S.removeChildrenFromElement)(Q.actionsAndSkillsList),Q.actionsAndSkillsList=Object(M.createElement)("ul"),e){case"general":this.createGeneralActionsContent();break;case"contracts":this.createContractsContent();break;case"operations":this.createOperationsContent();break;case"blackops":this.createBlackOpsContent();break;case"skills":this.createSkillsContent();break;default:throw new Error("Invalid value for DomElems.currentTab in Bladeburner.createActionAndSkillsContent")}this.updateContent(),Q.actionAndSkillsDiv.appendChild(Q.actionsAndSkillsDesc),Q.actionAndSkillsDiv.appendChild(Q.actionsAndSkillsList)},X.prototype.createGeneralActionsContent=function(){if(null==Q.actionsAndSkillsList||null==Q.actionsAndSkillsDesc)throw new Error("Bladeburner.createGeneralActionsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in Q.actionsAndSkillsDesc.innerText="These are generic actions that will assist you in your Bladeburner duties. They will not affect your Bladeburner rank in any way.",K)K.hasOwnProperty(e)&&(Q.generalActions[e]=Object(M.createElement)("div",{class:"bladeburner-action",name:e}),Q.actionsAndSkillsList.appendChild(Q.generalActions[e]))},X.prototype.createContractsContent=function(){if(null==Q.actionsAndSkillsList||null==Q.actionsAndSkillsDesc)throw new Error("Bladeburner.createContractsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in Q.actionsAndSkillsDesc.innerHTML="Complete contracts in order to increase your Bladeburner rank and earn money. Failing a contract will cause you to lose HP, which can lead to hospitalization.

You can unlock higher-level contracts by successfully completing them. Higher-level contracts are more difficult, but grant more rank, experience, and money.",this.contracts)this.contracts.hasOwnProperty(e)&&(Q.contracts[e]=Object(M.createElement)("div",{class:"bladeburner-action",name:e}),Q.actionsAndSkillsList.appendChild(Q.contracts[e]))},X.prototype.createOperationsContent=function(){if(null==Q.actionsAndSkillsList||null==Q.actionsAndSkillsDesc)throw new Error("Bladeburner.createOperationsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");for(var e in Q.actionsAndSkillsDesc.innerHTML="Carry out operations for the Bladeburner division. Failing an operation will reduce your Bladeburner rank. It will also cause you to lose HP, which can lead to hospitalization. In general, operations are harder and more punishing than contracts, but are also more rewarding.

Operations can affect the chaos level and Synthoid population of your current city. The exact effects vary between different Operations.

For operations, you can use a team. You must first recruit team members. Having a larger team will improves your chances of success.

You can unlock higher-level operations by successfully completing them. Higher-level operations are more difficult, but grant more rank and experience.",this.operations)this.operations.hasOwnProperty(e)&&(Q.operations[e]=Object(M.createElement)("div",{class:"bladeburner-action",name:e}),Q.actionsAndSkillsList.appendChild(Q.operations[e]))},X.prototype.createBlackOpsContent=function(){if(null==Q.actionsAndSkillsList||null==Q.actionsAndSkillsDesc)throw new Error("Bladeburner.createBlackOpsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");Q.actionsAndSkillsDesc.innerHTML="Black Operations (Black Ops) are special, one-time covert operations. Each Black Op must be unlocked successively by completing the one before it.

Your ultimate goal to climb through the ranks of Bladeburners is to complete all of the Black Ops.

Like normal operations, you may use a team for Black Ops. Failing a black op will incur heavy HP and rank losses.";var e=[];for(var t in J)J.hasOwnProperty(t)&&e.push(J[t]);e.sort(function(e,t){return e.reqdRank-t.reqdRank});for(var n=e.length-1;n>=0;--n)null==this.blackops[[e[n].name]]&&0!==n&&null==this.blackops[[e[n-1].name]]||(Q.blackops[e[n].name]=Object(M.createElement)("div",{class:"bladeburner-action",name:e[n].name}),Q.actionsAndSkillsList.appendChild(Q.blackops[e[n].name]))},X.prototype.createSkillsContent=function(){if(null==Q.actionsAndSkillsList||null==Q.actionsAndSkillsDesc)throw new Error("Bladeburner.createSkillsContent called with either DomElems.actionsAndSkillsList or DomElems.actionsAndSkillsDesc = null");Q.actionsAndSkillsDesc.innerHTML="You will gain one skill point every 3 ranks.

Note that when upgrading a skill, the benefit for that skill is additive. However, the effects of different skills with each other is multiplicative.

";for(var e=Object.keys(this.skillMultipliers),t=0;t";break;case"successChanceStealth":Q.actionsAndSkillsDesc.innerHTML+="Stealth Success Chance: x"+n+"
";break;case"successChanceKill":Q.actionsAndSkillsDesc.innerHTML+="Retirement Success Chance: x"+n+"
";break;case"successChanceContract":Q.actionsAndSkillsDesc.innerHTML+="Contract Success Chance: x"+n+"
";break;case"successChanceOperation":Q.actionsAndSkillsDesc.innerHTML+="Operation Success Chance: x"+n+"
";break;case"successChanceEstimate":Q.actionsAndSkillsDesc.innerHTML+="Synthoid Data Estimate: x"+n+"
";break;case"actionTime":Q.actionsAndSkillsDesc.innerHTML+="Action Time: x"+n+"
";break;case"effHack":Q.actionsAndSkillsDesc.innerHTML+="Hacking Skill: x"+n+"
";break;case"effStr":Q.actionsAndSkillsDesc.innerHTML+="Strength: x"+n+"
";break;case"effDef":Q.actionsAndSkillsDesc.innerHTML+="Defense: x"+n+"
";break;case"effDex":Q.actionsAndSkillsDesc.innerHTML+="Dexterity: x"+n+"
";break;case"effAgi":Q.actionsAndSkillsDesc.innerHTML+="Agility: x"+n+"
";break;case"effCha":Q.actionsAndSkillsDesc.innerHTML+="Charisma: x"+n+"
";break;case"effInt":Q.actionsAndSkillsDesc.innerHTML+="Intelligence: x"+n+"
";break;case"stamina":Q.actionsAndSkillsDesc.innerHTML+="Stamina: x"+n+"
";break;case"money":Q.actionsAndSkillsDesc.innerHTML+="Contract Money: x"+n+"
";break;case"expGain":Q.actionsAndSkillsDesc.innerHTML+="Exp Gain: x"+n+"
";break;case"weaponAbility":case"gunAbility":break;default:console.warn(`Unrecognized SkillMult Key: ${e[t]}`)}}for(var r in Q.skillPointsDisplay=Object(M.createElement)("p",{innerHTML:"
Skill Points: "+Object(f.formatNumber)(this.skillPoints,0)+""}),Q.actionAndSkillsDiv.appendChild(Q.skillPointsDisplay),U)U.hasOwnProperty(r)&&(Q.skills[r]=Object(M.createElement)("div",{class:"bladeburner-action",name:r}),Q.actionsAndSkillsList.appendChild(Q.skills[r]))},X.prototype.updateContent=function(){this.updateOverviewContent(),this.updateActionAndSkillsContent()},X.prototype.updateOverviewContent=function(){h.routing.isOn(h.Page.Bladeburner)&&(Q.overviewRank.childNodes[0].nodeValue="Rank: "+Object(f.formatNumber)(this.rank,2),Q.overviewStamina.innerText="Stamina: "+Object(f.formatNumber)(this.stamina,3)+" / "+Object(f.formatNumber)(this.maxStamina,3),Q.overviewGen1.innerHTML="Stamina Penalty: "+Object(f.formatNumber)(100*(1-this.calculateStaminaPenalty()),1)+"%

Team Size: "+Object(f.formatNumber)(this.teamSize,0)+"
Team Members Lost: "+Object(f.formatNumber)(this.teamLost,0)+"

Num Times Hospitalized: "+this.numHosp+"
Money Lost From Hospitalizations: "+d.numeralWrapper.format(this.moneyLost,"$0.000a")+"

Current City: "+this.city+"
",Q.overviewEstPop.childNodes[0].nodeValue="Est. Synthoid Population: "+d.numeralWrapper.format(this.getCurrentCity().popEst,"0.000a"),Q.overviewEstComms.childNodes[0].nodeValue="Est. Synthoid Communities: "+Object(f.formatNumber)(this.getCurrentCity().comms,0),Q.overviewChaos.childNodes[0].nodeValue="City Chaos: "+Object(f.formatNumber)(this.getCurrentCity().chaos),Q.overviewSkillPoints.innerText="Skill Points: "+Object(f.formatNumber)(this.skillPoints,0),Q.overviewBonusTime.childNodes[0].nodeValue="Bonus time: "+Object(f.convertTimeMsToTimeElapsedString)(this.storedCycles/5*1e3),Q.overviewAugSuccessMult.innerText="Aug. Success Chance Mult: "+Object(f.formatNumber)(100*m.Player.bladeburner_success_chance_mult,1)+"%",Q.overviewAugMaxStaminaMult.innerText="Aug. Max Stamina Mult: "+Object(f.formatNumber)(100*m.Player.bladeburner_max_stamina_mult,1)+"%",Q.overviewAugStaminaGainMult.innerText="Aug. Stamina Gain Mult: "+Object(f.formatNumber)(100*m.Player.bladeburner_stamina_gain_mult,1)+"%",Q.overviewAugAnalysisMult.innerText="Aug. Field Analysis Mult: "+Object(f.formatNumber)(100*m.Player.bladeburner_analysis_mult,1)+"%")},X.prototype.updateActionAndSkillsContent=function(){switch(null==Q.currentTab&&(Q.currentTab="general"),Q.currentTab.toLowerCase()){case"general":for(var e=Object.keys(Q.generalActions),t=0;t";var d=Object.keys(Q.skills);for(t=0;t(this.action.type=$[t.name],this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)}));Object(O.appendLineBreaks)(e,2),e.appendChild(Object(M.createElement)("pre",{innerHTML:t.desc,display:"inline-block"}))},X.prototype.updateContractsUIElement=function(e,t){Object(S.removeChildrenFromElement)(e);var n=e.classList.contains(B),r=t.getSuccessChance(this,{est:!0});if(e.appendChild(Object(M.createElement)("h2",{innerText:n?t.name+" (IN PROGRESS - "+Object(f.formatNumber)(this.actionTimeCurrent,0)+" / "+Object(f.formatNumber)(this.actionTimeToComplete,0)+")":t.name,display:"inline-block"})),n){var a=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(M.createElement)("p",{display:"block",innerText:Object(v.createProgressBarText)({progress:a})}))}else e.appendChild(Object(M.createElement)("a",{innerText:"Start",class:"a-link-button",padding:"3px",margin:"3px",clickListener:()=>(this.action.type=$.Contract,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)}));var i=t.level>=t.maxLevel;Object(O.appendLineBreaks)(e,2),e.appendChild(Object(M.createElement)("pre",{display:"inline-block",innerText:"Level: "+t.level+" / "+t.maxLevel,tooltip:t.getSuccessesNeededForNextLevel(3)+" successes needed for next level"})),e.appendChild(Object(M.createElement)("a",{class:i?"a-link-button-inactive":"a-link-button",innerHTML:"↑",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the contract":"",display:"inline",clickListener:()=>(++t.level,n&&this.startAction(this.action),this.updateContractsUIElement(e,t),!1)})),e.appendChild(Object(M.createElement)("a",{class:t.level<=1?"a-link-button-inactive":"a-link-button",innerHTML:"↓",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the contract":"",display:"inline",clickListener:()=>(--t.level,n&&this.startAction(this.action),this.updateContractsUIElement(e,t),!1)}));var o=t.getActionTime(this);Object(O.appendLineBreaks)(e,2),e.appendChild(Object(M.createElement)("pre",{display:"inline-block",innerHTML:t.desc+"\n\n"+`Estimated success chance: ${Object(f.formatNumber)(100*r,1)}% ${t.isStealth?R:""}${t.isKill?N:""}\n`+"Time Required (s): "+Object(f.formatNumber)(o,0)+"\nContracts remaining: "+Math.floor(t.count)+"\nSuccesses: "+t.successes+"\nFailures: "+t.failures})),e.appendChild(Object(M.createElement)("br"));var s="bladeburner-"+t.name+"-autolevel-checkbox";e.appendChild(Object(M.createElement)("label",{for:s,innerText:"Autolevel",color:"white",tooltip:"Automatically increase contract level when possible"}));const l=Object(M.createElement)("div",{class:"bbcheckbox"}),c=Object(M.createElement)("input",{type:"checkbox",id:s,checked:t.autoLevel,changeListener:()=>{t.autoLevel=c.checked}}),u=Object(M.createElement)("label",{for:s});l.appendChild(c),l.appendChild(u),e.appendChild(l)},X.prototype.updateOperationsUIElement=function(e,t){Object(S.removeChildrenFromElement)(e);var n=e.classList.contains(B),r=t.getSuccessChance(this,{est:!0});if(e.appendChild(Object(M.createElement)("h2",{innerText:n?t.name+" (IN PROGRESS - "+Object(f.formatNumber)(this.actionTimeCurrent,0)+" / "+Object(f.formatNumber)(this.actionTimeToComplete,0)+")":t.name,display:"inline-block"})),n){var a=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(M.createElement)("p",{display:"block",innerText:Object(v.createProgressBarText)({progress:a})}))}else e.appendChild(Object(M.createElement)("a",{innerText:"Start",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>(this.action.type=$.Operation,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)})),e.appendChild(Object(M.createElement)("a",{innerText:"Set Team Size (Curr Size: "+Object(f.formatNumber)(t.teamCount,0)+")",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>{var n="bladeburner-operation-set-team-size-popup",r=Object(M.createElement)("p",{innerText:"Enter the amount of team members you would like to take on these operations. If you do not have the specified number of team members, then as many as possible will be used. Note that team members may be lost during operations."}),a=Object(M.createElement)("input",{type:"number",placeholder:"Team Members"}),i=Object(M.createElement)("a",{innerText:"Confirm",class:"a-link-button",clickListener:()=>{var r=Math.round(parseFloat(a.value));return isNaN(r)?Object(_.dialogBoxCreate)("Invalid value entered for number of Team Members (must be numeric)"):(t.teamCount=r,this.updateOperationsUIElement(e,t)),Object(A.removeElementById)(n),!1}}),o=Object(M.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(A.removeElementById)(n),!1)});Object(x.createPopup)(n,[r,a,i,o])}}));var i=t.level>=t.maxLevel;Object(O.appendLineBreaks)(e,2),e.appendChild(Object(M.createElement)("pre",{display:"inline-block",innerText:"Level: "+t.level+" / "+t.maxLevel,tooltip:t.getSuccessesNeededForNextLevel(2.5)+" successes needed for next level"})),e.appendChild(Object(M.createElement)("a",{class:i?"a-link-button-inactive":"a-link-button",innerHTML:"↑",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the Operation":"",display:"inline",clickListener:()=>(++t.level,n&&this.startAction(this.action),this.updateOperationsUIElement(e,t),!1)})),e.appendChild(Object(M.createElement)("a",{class:t.level<=1?"a-link-button-inactive":"a-link-button",innerHTML:"↓",padding:"2px",margin:"2px",tooltip:n?"WARNING: changing the level will restart the Operation":"",display:"inline",clickListener:()=>(--t.level,n&&this.startAction(this.action),this.updateOperationsUIElement(e,t),!1)}));t.getDifficulty();var o=t.getActionTime(this);Object(O.appendLineBreaks)(e,2),e.appendChild(Object(M.createElement)("pre",{display:"inline-block",innerHTML:t.desc+"\n\n"+`Estimated success chance: ${Object(f.formatNumber)(100*r,1)}% ${t.isStealth?R:""}${t.isKill?N:""}\n`+"Time Required(s): "+Object(f.formatNumber)(o,0)+"\nOperations remaining: "+Math.floor(t.count)+"\nSuccesses: "+t.successes+"\nFailures: "+t.failures})),e.appendChild(Object(M.createElement)("br"));var s="bladeburner-"+t.name+"-autolevel-checkbox";e.appendChild(Object(M.createElement)("label",{for:s,innerText:"Autolevel",color:"white",tooltip:"Automatically increase operation level when possible"}));const l=Object(M.createElement)("div",{class:"bbcheckbox"}),c=Object(M.createElement)("input",{type:"checkbox",id:s,checked:t.autoLevel,changeListener:()=>{t.autoLevel=c.checked}}),u=Object(M.createElement)("label",{for:s});l.appendChild(c),l.appendChild(u),e.appendChild(l)},X.prototype.updateBlackOpsUIElement=function(e,t){Object(S.removeChildrenFromElement)(e);var n=e.classList.contains(B),r=null!=this.blackops[t.name],a=t.getSuccessChance(this,{est:!0}),i=(t.getDifficulty(),t.getActionTime(this)),o=this.rank>=t.reqdRank;if(r)e.appendChild(Object(M.createElement)("h2",{innerText:t.name+" (COMPLETED)",display:"block"}));else{if(e.appendChild(Object(M.createElement)("h2",{innerText:n?t.name+" (IN PROGRESS - "+Object(f.formatNumber)(this.actionTimeCurrent,0)+" / "+Object(f.formatNumber)(this.actionTimeToComplete,0)+")":t.name,display:"inline-block"})),n){var s=this.actionTimeCurrent/this.actionTimeToComplete;e.appendChild(Object(M.createElement)("p",{display:"block",innerText:Object(v.createProgressBarText)({progress:s})}))}else e.appendChild(Object(M.createElement)("a",{innerText:"Start",margin:"3px",padding:"3px",class:o?"a-link-button":"a-link-button-inactive",clickListener:()=>(this.action.type=$.BlackOperation,this.action.name=t.name,this.startAction(this.action),this.updateActionAndSkillsContent(),!1)})),e.appendChild(Object(M.createElement)("a",{innerText:"Set Team Size (Curr Size: "+Object(f.formatNumber)(t.teamCount,0)+")",class:"a-link-button",margin:"3px",padding:"3px",clickListener:()=>{var n="bladeburner-operation-set-team-size-popup",r=Object(M.createElement)("p",{innerText:"Enter the amount of team members you would like to take on this BlackOp. If you do not have the specified number of team members, then as many as possible will be used. Note that team members may be lost during operations."}),a=Object(M.createElement)("input",{type:"number",placeholder:"Team Members"}),i=Object(M.createElement)("a",{innerText:"Confirm",class:"a-link-button",clickListener:()=>{var r=Math.round(parseFloat(a.value));return isNaN(r)?Object(_.dialogBoxCreate)("Invalid value entered for number of Team Members (must be numeric)"):(t.teamCount=r,this.updateBlackOpsUIElement(e,t)),Object(A.removeElementById)(n),!1}}),o=Object(M.createElement)("a",{innerText:"Cancel",class:"a-link-button",clickListener:()=>(Object(A.removeElementById)(n),!1)});Object(x.createPopup)(n,[r,a,i,o])}}));Object(O.appendLineBreaks)(e,2),e.appendChild(Object(M.createElement)("p",{display:"inline-block",innerHTML:"
"+t.desc+"

"})),e.appendChild(Object(M.createElement)("p",{display:"block",color:o?"white":"red",innerHTML:"Required Rank: "+Object(f.formatNumber)(t.reqdRank,0)+"
"})),e.appendChild(Object(M.createElement)("p",{display:"inline-block",innerHTML:`Estimated Success Chance: ${Object(f.formatNumber)(100*a,1)}% ${t.isStealth?R:""}${t.isKill?N:""}\n`+"Time Required(s): "+Object(f.formatNumber)(i,0)}))}},X.prototype.updateSkillsUIElement=function(e,t){Object(S.removeChildrenFromElement)(e);var n=t.name,r=0;this.skills[n]&&!isNaN(this.skills[n])&&(r=this.skills[n]);var a=t.calculateCost(r);e.appendChild(Object(M.createElement)("h2",{innerText:t.name+" (Lvl "+r+")",display:"inline-block"}));var i=this.skillPoints>=a,o=!!t.maxLvl&&r>=t.maxLvl;e.appendChild(Object(M.createElement)("a",{innerText:"Level",display:"inline-block",class:i&&!o?"a-link-button":"a-link-button-inactive",margin:"3px",padding:"3px",clickListener:()=>{if(!(this.skillPoints100&&this.consoleLogs.shift()),null!=t&&null!=Q.consoleDiv&&(e("#bladeubrner-console-input-row").before(''+t+""),Q.consoleTable.childNodes.length>100&&Q.consoleTable.removeChild(Q.consoleTable.firstChild),this.updateConsoleScroll())},X.prototype.updateConsoleScroll=function(){Q.consoleDiv.scrollTop=Q.consoleDiv.scrollHeight},X.prototype.resetConsoleInput=function(){Q.consoleInput.value=""},X.prototype.clearConsole=function(){for(;Q.consoleTable.childNodes.length>1;)Q.consoleTable.removeChild(Q.consoleTable.firstChild);this.consoleLogs.length=0},X.prototype.log=function(e){this.postToConsole(`[${Object(P.getTimestamp)()}] ${e}`)},X.prototype.executeConsoleCommands=function(e){try{this.consoleHistory[this.consoleHistory.length-1]!=e&&(this.consoleHistory.push(e),this.consoleHistory.length>50&&this.consoleHistory.splice(0,1)),L=this.consoleHistory.length;for(var t=e.split(";"),n=0;n"))}},X.prototype.executeLogConsoleCommand=function(e){if(e.length<3)return this.postToConsole("Invalid usage of log command: log [enable/disable] [action/event]"),void this.postToConsole("Use 'help log' for more details and examples");var t=!0;switch(e[1].toLowerCase().includes("d")&&(t=!1),e[2].toLowerCase()){case"general":case"gen":this.logging.general=t,this.log("Logging "+(t?"enabled":"disabled")+" for general actions");break;case"contract":case"contracts":this.logging.contracts=t,this.log("Logging "+(t?"enabled":"disabled")+" for Contracts");break;case"ops":case"op":case"operations":case"operation":this.logging.ops=t,this.log("Logging "+(t?"enabled":"disabled")+" for Operations");break;case"blackops":case"blackop":case"black operations":case"black operation":this.logging.blackops=t,this.log("Logging "+(t?"enabled":"disabled")+" for BlackOps");break;case"event":case"events":this.logging.events=t,this.log("Logging "+(t?"enabled":"disabled")+" for events");break;case"all":this.logging.general=t,this.logging.contracts=t,this.logging.ops=t,this.logging.blackops=t,this.logging.events=t,this.log("Logging "+(t?"enabled":"disabled")+" for everything");break;default:this.postToConsole("Invalid action/event type specified: "+e[2]),this.postToConsole("Examples of valid action/event identifiers are: [general, contracts, ops, blackops, events]")}},X.prototype.executeSkillConsoleCommand=function(e){switch(e.length){case 1:this.postToConsole("Invalid usage of 'skill' console command: skill [action] [name]"),this.postToConsole("Use 'help skill' for more info");break;case 2:if("list"===e[1].toLowerCase()){this.postToConsole("Skills: ");for(var t=Object.keys(U),n=0;n=c?(this.skillPoints-=c,this.upgradeSkill(r),this.log(r.name+" upgraded to Level "+this.skills[s]),this.createActionAndSkillsContent()):this.postToConsole("You do not have enough Skill Points to upgrade this. You need "+Object(f.formatNumber)(c,0))}else this.postToConsole("Invalid usage of 'skill' console command: skill [action] [name]"),this.postToConsole("Use 'help skill' for more info");break;default:this.postToConsole("Invalid usage of 'skill' console command: skill [action] [name]"),this.postToConsole("Use 'help skill' for more info")}},X.prototype.executeStartConsoleCommand=function(e){if(3!==e.length)return this.postToConsole("Invalid usage of 'start' console command: start [type] [name]"),void this.postToConsole("Use 'help start' for more info");var t=e[2];switch(e[1].toLowerCase()){case"general":case"gen":null!=K[t]?(this.action.type=$[t],this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid action name specified: "+e[2]);break;case"contract":case"contracts":null!=this.contracts[t]?(this.action.type=$.Contract,this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid contract name specified: "+e[2]);break;case"ops":case"op":case"operations":case"operation":null!=this.operations[t]?(this.action.type=$.Operation,this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid Operation name specified: "+e[2]);break;case"blackops":case"blackop":case"black operations":case"black operation":null!=J[t]?(this.action.type=$.BlackOperation,this.action.name=t,this.startAction(this.action),this.updateActionAndSkillsContent()):this.postToConsole("Invalid BlackOp name specified: "+e[2]);break;default:this.postToConsole("Invalid action/event type specified: "+e[1]),this.postToConsole("Examples of valid action/event identifiers are: [general, contract, op, blackop]")}},X.prototype.getActionIdFromTypeAndName=function(e="",t=""){if(""===e||""===t)return null;var n=new q,r=e.toLowerCase().trim(),a=t.toLowerCase().trim();switch(r){case"contract":case"contracts":case"contr":return n.type=$.Contract,this.contracts.hasOwnProperty(t)?(n.name=t,n):null;case"operation":case"operations":case"op":case"ops":return n.type=$.Operation,this.operations.hasOwnProperty(t)?(n.name=t,n):null;case"blackoperation":case"black operation":case"black operations":case"black op":case"black ops":case"blackop":case"blackops":return n.type=$.BlackOp,J.hasOwnProperty(t)?(n.name=t,n):null;case"general":case"general action":case"gen":break;default:return null}if(r.startsWith("gen")){switch(a){case"training":n.type=$.Training,n.name="Training";break;case"recruitment":case"recruit":n.type=$.Recruitment,n.name="Recruitment";break;case"field analysis":case"fieldanalysis":n.type=$["Field Analysis"],n.name="Field Analysis";break;case"diplomacy":n.type=$.Diplomacy,n.name="Diplomacy";break;case"hyperbolic regeneration chamber":n.type=$["Hyperbolic Regeneration Chamber"],n.name="Hyperbolic Regeneration Chamber";break;default:return null}return n}},X.prototype.getTypeAndNameFromActionId=function(e){var t={};let n=Object.keys($);for(let r=0;rthis.rank)return n.log(`Failed to start Black Op ${a.name} due to insufficient rank`),!1;if(null!=this.blackops[a.name])return n.log(`Failed to start Black Op ${a.name} because its already been completed`),!1;var i=[];for(const e in J)J.hasOwnProperty(e)&&i.push(e);i.sort(function(e,t){return J[e].reqdRank-J[t].reqdRank});let e=i.indexOf(a.name);if(-1===e)return n.log("ERROR: Invalid Black Operation name passed into bladeburner.startAction(). Note that this name is case-sensitive & whitespace-sensitive"),!1;if(e>0&&null==this.blackops[i[e-1]])return n.log(`ERROR: Cannot attempt Black Operation ${a.name} because you have not done the preceding one`),!1}try{return this.startAction(a),n.shouldLog("startAction")&&n.log("Starting bladeburner action with type "+e+" and name "+t),!0}catch(r){return this.resetAction(),n.log("ERROR: bladeburner.startAction() failed to start action of type "+e+" due to invalid name: "+t+"Note that this name is case-sensitive and whitespace-sensitive"),!1}},X.prototype.getActionTimeNetscriptFn=function(e,t,n){var r="ERROR: bladeburner.getActionTime() failed due to an invalid action specified. Type: "+e+", Name: "+t+". Note that for contracts and operations, the name of the operation is case-sensitive.",a=this.getActionIdFromTypeAndName(e,t);if(null==a)return n.log(r),-1;var i=this.getActionObject(a);if(null==i)return n.log(r),-1;switch(a.type){case $.Contract:case $.Operation:case $.BlackOp:case $.BlackOperation:return i.getActionTime(this);case $.Training:case $["Field Analysis"]:case $.FieldAnalysis:return 30;case $.Recruitment:return this.getRecruitmentTime();default:return n.log(r),-1}},X.prototype.getActionEstimatedSuccessChanceNetscriptFn=function(e,t,n){var r="ERROR: bladeburner.getActionEstimatedSuccessChance() failed due to an invalid action specified. Type: "+e+", Name: "+t+". Note that for contracts and operations, the name of the operation is case-sensitive.",a=this.getActionIdFromTypeAndName(e,t);if(null==a)return n.log(r),-1;var i=this.getActionObject(a);if(null==i)return n.log(r),-1;switch(a.type){case $.Contract:case $.Operation:case $.BlackOp:case $.BlackOperation:return i.getSuccessChance(this,{est:!0});case $.Training:case $["Field Analysis"]:case $.FieldAnalysis:return 1;case $.Recruitment:return this.getRecruitmentSuccessChance();default:return n.log(r),-1}},X.prototype.getActionCountRemainingNetscriptFn=function(e,t,n){var r="ERROR: bladeburner.getActionCountRemaining() failed due to an invalid action specified. Type: "+e+", Name: "+t+". Note that for contracts and operations, the name of the operation is case-sensitive.",a=this.getActionIdFromTypeAndName(e,t);if(null==a)return n.log(r),-1;var i=this.getActionObject(a);if(null==i)return n.log(r),-1;switch(a.type){case $.Contract:case $.Operation:return Math.floor(i.count);case $.BlackOp:case $.BlackOperation:return null!=this.blackops[t]?0:1;case $.Training:case $["Field Analysis"]:case $.FieldAnalysis:return 1/0;default:return n.log(r),-1}},X.prototype.getSkillLevelNetscriptFn=function(e,t){var n="ERROR: bladeburner.getSkillLevel() failed due to an invalid skill specified: "+e+". Note that the name of the skill is case-sensitive";return""===e?-1:U.hasOwnProperty(e)?null==this.skills[e]?0:this.skills[e]:(t.log(n),-1)},X.prototype.getSkillUpgradeCostNetscriptFn=function(e,t){var n="ERROR: bladeburner.getSkillUpgradeCostNetscriptFn() failed due to an invalid skill specified: "+e+". Note that the name of the skill is case-sensitive";if(""===e)return-1;if(!U.hasOwnProperty(e))return t.log(n),-1;var r=U[e];return null==this.skills[e]?r.calculateCost(0):r.calculateCost(this.skills[e])},X.prototype.upgradeSkillNetscriptFn=function(e,t){var n="ERROR: bladeburner.upgradeSkill() failed due to an invalid skill specified: "+e+". Note that the name of the skill is case-sensitive";if(!U.hasOwnProperty(e))return t.log(n),!1;var r=U[e],a=0;this.skills[e]&&!isNaN(this.skills[e])&&(a=this.skills[e]);var i=r.calculateCost(a);return r.maxLvl&&a>=r.maxLvl?(t.shouldLog("upgradeSkill")&&t.log(`bladeburner.upgradeSkill() failed because ${e} is already maxed`),!1):this.skillPoints=25?(Object(u.joinFaction)(t),e.shouldLog("joinBladeburnerFaction")&&e.log("Joined Bladeburners Faction"),h.routing.isOn(h.Page.Bladeburner)&&(Object(S.removeChildrenFromElement)(Q.overviewDiv),this.createOverviewContent()),!0):(e.shouldLog("joinBladeburnerFaction")&&e.log("Failed to join Bladeburners Faction because you do not have the required 25 rank"),!1))},X.prototype.toJSON=function(){return Object(g.Generic_toJSON)("Bladeburner",this)},X.fromJSON=function(e){return Object(g.Generic_fromJSON)(X,e.data)},g.Reviver.constructors.Bladeburner=X}).call(this,n(83))},function(e,t,n){"use strict";n.d(t,"c",function(){return O}),n.d(t,"f",function(){return M}),n.d(t,"e",function(){return T}),n.d(t,"d",function(){return k}),n.d(t,"a",function(){return P}),n.d(t,"b",function(){return S});var r=n(15),a=n(10),i=n(124),o=n(4),s=n(305),l=n(18),c=n(6),u=n(13),m=(n(57),n(0)),p=n(114),h=n(89),d=(n(113),n(101),n(110),n(51),n(17),n(11)),_=n(8),g=(n(201),n(16),n(7),n(105)),y=(n(3),n(46),n(42),n(1)),f=n.n(y),b=n(50),E=n.n(b);function v(e){var t=e.name;a.Augmentations[t]=e}function k(){for(var e in u.Factions)u.Factions.hasOwnProperty(e)&&(u.Factions[e].augmentations=[]);Object(g.clearObject)(a.Augmentations);const t=new r.Augmentation({name:o.AugmentationNames.HemoRecirculator,moneyCost:9e6,repCost:4e3,info:"A heart implant that greatly increases the body's ability to effectively use and pump blood.

This augmentation increases all of the player's combat stats by 8%.",strength_mult:1.08,defense_mult:1.08,agility_mult:1.08,dexterity_mult:1.08});t.addToFactions(["Tetrads","The Dark Army","The Syndicate"]),S(o.AugmentationNames.HemoRecirculator)&&delete a.Augmentations[o.AugmentationNames.HemoRecirculator],v(t);const n=new r.Augmentation({name:o.AugmentationNames.Targeting1,moneyCost:3e6,repCost:2e3,info:"This cranial implant is embedded within the player's inner ear structure and optic nerves. It regulates and enhances the user's balance and hand-eye coordination. It is also capable of augmenting reality by projecting digital information directly onto the retina. These enhancements allow the player to better lock-on and keep track of enemies.

This augmentation increases the player's dexterity by 10%.",dexterity_mult:1.1});n.addToFactions(["Slum Snakes","The Dark Army","The Syndicate","Sector-12","Volhaven","Ishima","OmniTek Incorporated","KuaiGong International","Blade Industries"]),S(o.AugmentationNames.Targeting1)&&delete a.Augmentations[o.AugmentationNames.Targeting1],v(n);const i=new r.Augmentation({name:o.AugmentationNames.Targeting2,moneyCost:85e5,repCost:3500,info:"This is an upgrade of the Augmented Targeting I cranial implant, which is capable of augmenting reality and enhances the user's balance and hand-eye coordination.

This augmentation increases the player's dexterity by 20%.",prereqs:[o.AugmentationNames.Targeting1],dexterity_mult:1.2});i.addToFactions(["The Dark Army","The Syndicate","Sector-12","Volhaven","Ishima","OmniTek Incorporated","KuaiGong International","Blade Industries"]),S(o.AugmentationNames.Targeting2)&&delete a.Augmentations[o.AugmentationNames.Targeting2],v(i);const s=new r.Augmentation({name:o.AugmentationNames.Targeting3,moneyCost:23e6,repCost:11e3,info:"This is an upgrade of the Augmented Targeting II cranial implant, which is capable of augmenting reality and enhances the user's balance and hand-eye coordination.

This augmentation increases the player's dexterity by 30%.",prereqs:[o.AugmentationNames.Targeting2],dexterity_mult:1.3});s.addToFactions(["The Dark Army","The Syndicate","OmniTek Incorporated","KuaiGong International","Blade Industries","The Covenant"]),S(o.AugmentationNames.Targeting3)&&delete a.Augmentations[o.AugmentationNames.Targeting3],v(s);const p=new r.Augmentation({name:o.AugmentationNames.SyntheticHeart,moneyCost:575e6,repCost:3e5,info:"This advanced artificial heart, created from plasteel and graphene, is capable of pumping more blood at much higher efficiencies than a normal human heart.

This augmentation increases the player's agility and strength by 50%.",agility_mult:1.5,strength_mult:1.5});p.addToFactions(["KuaiGong International","Fulcrum Secret Technologies","Speakers for the Dead","NWO","The Covenant","Daedalus","Illuminati"]),S(o.AugmentationNames.SyntheticHeart)&&delete a.Augmentations[o.AugmentationNames.SyntheticHeart],v(p);const h=new r.Augmentation({name:o.AugmentationNames.SynfibrilMuscle,repCost:175e3,moneyCost:225e6,info:"The myofibrils in human muscles are injected with special chemicals that react with the proteins inside the myofibrils, altering their underlying structure. The end result is muscles that are stronger and more elastic. Scientists have named these artificially enhanced units 'synfibrils'.

This augmentation increases the player's strength and defense by 30%.",strength_mult:1.3,defense_mult:1.3});h.addToFactions(["KuaiGong International","Fulcrum Secret Technologies","Speakers for the Dead","NWO","The Covenant","Daedalus","Illuminati","Blade Industries"]),S(o.AugmentationNames.SynfibrilMuscle)&&delete a.Augmentations[o.AugmentationNames.SynfibrilMuscle],v(h);const d=new r.Augmentation({name:o.AugmentationNames.CombatRib1,repCost:3e3,moneyCost:475e4,info:"The human body's ribs are replaced with artificial ribs that automatically and continuously release cognitive and performance-enhancing drugs into the bloodstream, improving the user's abilities in combat.

This augmentation increases the player's strength and defense by 10%.",strength_mult:1.1,defense_mult:1.1});d.addToFactions(["Slum Snakes","The Dark Army","The Syndicate","Sector-12","Volhaven","Ishima","OmniTek Incorporated","KuaiGong International","Blade Industries"]),S(o.AugmentationNames.CombatRib1)&&delete a.Augmentations[o.AugmentationNames.CombatRib1],v(d);const _=new r.Augmentation({name:o.AugmentationNames.CombatRib2,repCost:7500,moneyCost:13e6,info:"This is an upgrade to the Combat Rib I augmentation, and is capable of releasing even more potent combat-enhancing drugs into the bloodstream.

This augmentation increases the player's strength and defense by 14%.",prereqs:[o.AugmentationNames.CombatRib1],strength_mult:1.14,defense_mult:1.14});_.addToFactions(["The Dark Army","The Syndicate","Sector-12","Volhaven","Ishima","OmniTek Incorporated","KuaiGong International","Blade Industries"]),S(o.AugmentationNames.CombatRib2)&&delete a.Augmentations[o.AugmentationNames.CombatRib2],v(_);const y=new r.Augmentation({name:o.AugmentationNames.CombatRib3,repCost:14e3,moneyCost:24e6,info:"This is an upgrade to the Combat Rib II augmentation, and is capable of releasing even more potent combat-enhancing drugs into the bloodstream

.This augmentation increases the player's strength and defense by 18%.",prereqs:[o.AugmentationNames.CombatRib2],strength_mult:1.18,defense_mult:1.18});y.addToFactions(["The Dark Army","The Syndicate","OmniTek Incorporated","KuaiGong International","Blade Industries","The Covenant"]),S(o.AugmentationNames.CombatRib3)&&delete a.Augmentations[o.AugmentationNames.CombatRib3],v(y);const f=new r.Augmentation({name:o.AugmentationNames.NanofiberWeave,repCost:15e3,moneyCost:25e6,info:"Synthetic nanofibers are woven into the skin's extracellular matrix using electrospinning. This improves the skin's ability to regenerate itself and protect the body from external stresses and forces.

This augmentation increases the player's strength and defense by 20%.",strength_mult:1.2,defense_mult:1.2});f.addToFactions(["Tian Di Hui","The Syndicate","The Dark Army","Speakers for the Dead","Blade Industries","Fulcrum Secret Technologies","OmniTek Incorporated"]),S(o.AugmentationNames.NanofiberWeave)&&delete a.Augmentations[o.AugmentationNames.NanofiberWeave],v(f);const b=new r.Augmentation({name:o.AugmentationNames.SubdermalArmor,repCost:35e4,moneyCost:65e7,info:"The NEMEAN Subdermal Weave is a thin, light-weight, graphene plating that houses a dilatant fluid. The material is implanted underneath the skin, and is the most advanced form of defensive enhancement that has ever been created. The dilatant fluid, despite being thin and light, is extremely effective at stopping piercing blows and reducing blunt trauma. The properties of graphene allow the plating to mitigate damage from any fire-related or electrical traumas.

This augmentation increases the player's defense by 120%.",defense_mult:2.2});b.addToFactions(["The Syndicate","Fulcrum Secret Technologies","Illuminati","Daedalus","The Covenant"]),S(o.AugmentationNames.SubdermalArmor)&&delete a.Augmentations[o.AugmentationNames.SubdermalArmor],v(b);const E=new r.Augmentation({name:o.AugmentationNames.WiredReflexes,repCost:500,moneyCost:5e5,info:"Synthetic nerve-enhancements are injected into all major parts of the somatic nervous system, supercharging the body's ability to send signals through neurons. This results in increased reflex speed.

This augmentation increases the player's agility and dexterity by 5%.",agility_mult:1.05,dexterity_mult:1.05});E.addToFactions(["Tian Di Hui","Slum Snakes","Sector-12","Volhaven","Aevum","Ishima","The Syndicate","The Dark Army","Speakers for the Dead"]),S(o.AugmentationNames.WiredReflexes)&&delete a.Augmentations[o.AugmentationNames.WiredReflexes],v(E);const k=new r.Augmentation({name:o.AugmentationNames.GrapheneBoneLacings,repCost:45e4,moneyCost:85e7,info:"A graphene-based material is grafted and fused into the user's bones, significantly increasing their density and tensile strength.

This augmentation increases the player's strength and defense by 70%.",strength_mult:1.7,defense_mult:1.7});k.addToFactions(["Fulcrum Secret Technologies","The Covenant"]),S(o.AugmentationNames.GrapheneBoneLacings)&&delete a.Augmentations[o.AugmentationNames.GrapheneBoneLacings],v(k);const P=new r.Augmentation({name:o.AugmentationNames.BionicSpine,repCost:18e3,moneyCost:25e6,info:"An artificial spine created from plasteel and carbon fibers that completely replaces the organic spine. Not only is the Bionic Spine physically stronger than a human spine, but it is also capable of digitally stimulating and regulating the neural signals that are sent and received by the spinal cord. This results in greatly improved senses and reaction speeds.

This augmentation increases all of the player's combat stats by 15%.",strength_mult:1.15,defense_mult:1.15,agility_mult:1.15,dexterity_mult:1.15});P.addToFactions(["Speakers for the Dead","The Syndicate","KuaiGong International","OmniTek Incorporated","Blade Industries"]),S(o.AugmentationNames.BionicSpine)&&delete a.Augmentations[o.AugmentationNames.BionicSpine],v(P);const T=new r.Augmentation({name:o.AugmentationNames.GrapheneBionicSpine,repCost:65e4,moneyCost:12e8,info:"An upgrade to the Bionic Spine augmentation. It fuses the implant with an advanced graphene material to make it much stronger and lighter.

This augmentation increases all of the player's combat stats by 60%.",prereqs:[o.AugmentationNames.BionicSpine],strength_mult:1.6,defense_mult:1.6,agility_mult:1.6,dexterity_mult:1.6});T.addToFactions(["Fulcrum Secret Technologies","ECorp"]),S(o.AugmentationNames.GrapheneBionicSpine)&&delete a.Augmentations[o.AugmentationNames.GrapheneBionicSpine],v(T);const O=new r.Augmentation({name:o.AugmentationNames.BionicLegs,repCost:6e4,moneyCost:75e6,info:"Cybernetic legs created from plasteel and carbon fibers that completely replace the user's organic legs.

This augmentation increases the player's agility by 60%.",agility_mult:1.6});O.addToFactions(["Speakers for the Dead","The Syndicate","KuaiGong International","OmniTek Incorporated","Blade Industries"]),S(o.AugmentationNames.BionicLegs)&&delete a.Augmentations[o.AugmentationNames.BionicLegs],v(O);const M=new r.Augmentation({name:o.AugmentationNames.GrapheneBionicLegs,repCost:3e5,moneyCost:9e8,info:"An upgrade to the Bionic Legs augmentation. It fuses the implant with an advanced graphene material to make it much stronger and lighter.

This augmentation increases the player's agility by 150%.",prereqs:[o.AugmentationNames.BionicLegs],agility_mult:2.5});M.addToFactions(["MegaCorp","ECorp","Fulcrum Secret Technologies"]),S(o.AugmentationNames.GrapheneBionicLegs)&&delete a.Augmentations[o.AugmentationNames.GrapheneBionicLegs],v(M);const x=new r.Augmentation({name:o.AugmentationNames.SpeechProcessor,repCost:3e3,moneyCost:1e7,info:"A cochlear implant with an embedded computer that analyzes incoming speech. The embedded computer processes characteristics of incoming speech, such as tone and inflection, to pick up on subtle cues and aid in social interactions.

This augmentation increases the player's charisma by 20%.",charisma_mult:1.2});x.addToFactions(["Tian Di Hui","Chongqing","Sector-12","New Tokyo","Aevum","Ishima","Volhaven","Silhouette"]),S(o.AugmentationNames.SpeechProcessor)&&delete a.Augmentations[o.AugmentationNames.SpeechProcessor],v(x);const w=new r.Augmentation({name:o.AugmentationNames.TITN41Injection,repCost:1e4,moneyCost:38e6,info:"TITN is a series of viruses that targets and alters the sequences of human DNA in genes that control personality. The TITN-41 strain alters these genes so that the subject becomes more outgoing and socialable.

This augmentation increases the player's charisma and charisma experience gain rate by 15%.",charisma_mult:1.15,charisma_exp_mult:1.15});w.addToFactions(["Silhouette"]),S(o.AugmentationNames.TITN41Injection)&&delete a.Augmentations[o.AugmentationNames.TITN41Injection],v(w);const A=new r.Augmentation({name:o.AugmentationNames.EnhancedSocialInteractionImplant,repCost:15e4,moneyCost:275e6,info:"A cranial implant that greatly assists in the user's ability to analyze social situations and interactions. The system uses a wide variety of factors such as facial expression, body language, and the voice's tone/inflection to determine the best course of action during socialsituations. The implant also uses deep learning software to continuously learn new behaviorpatterns and how to best respond.

This augmentation increases the player's charisma and charisma experience gain rate by 60%.",charisma_mult:1.6,charisma_exp_mult:1.6});A.addToFactions(["Bachman & Associates","NWO","Clarke Incorporated","OmniTek Incorporated","Four Sigma"]),S(o.AugmentationNames.EnhancedSocialInteractionImplant)&&delete a.Augmentations[o.AugmentationNames.EnhancedSocialInteractionImplant],v(A);const R=new r.Augmentation({name:o.AugmentationNames.BitWire,repCost:1500,moneyCost:2e6,info:"A small brain implant embedded in the cerebrum. This regulates and improves the brain's computing capabilities.

This augmentation increases the player's hacking skill by 5%.",hacking_mult:1.05});R.addToFactions(["CyberSec","NiteSec"]),S(o.AugmentationNames.BitWire)&&delete a.Augmentations[o.AugmentationNames.BitWire],v(R);const N=new r.Augmentation({name:o.AugmentationNames.ArtificialBioNeuralNetwork,repCost:11e4,moneyCost:6e8,info:"A network consisting of millions of nanoprocessors is embedded into the brain. The network is meant to mimick the way a biological brain solves a problem, which each nanoprocessor acting similar to the way a neuron would in a neural network. However, these nanoprocessors are programmed to perform computations much faster than organic neurons, allowing its user to solve much more complex problems at a much faster rate.

This augmentation:
Increases the player's hacking speed by 3%.
Increases the amount of money the player's gains from hacking by 15%.
Increases the player's hacking skill by 12%.",hacking_speed_mult:1.03,hacking_money_mult:1.15,hacking_mult:1.12});N.addToFactions(["BitRunners","Fulcrum Secret Technologies"]),S(o.AugmentationNames.ArtificialBioNeuralNetwork)&&delete a.Augmentations[o.AugmentationNames.ArtificialBioNeuralNetwork],v(N);const D=new r.Augmentation({name:o.AugmentationNames.ArtificialSynapticPotentiation,repCost:2500,moneyCost:16e6,info:"The body is injected with a chemical that artificially induces synaptic potentiation, otherwise known as the strengthening of synapses. This results in a enhanced cognitive abilities.

This augmentation:
Increases the player's hacking speed by 2%
Increases the player's hacking chance by 5%.
Increases the player's hacking experience gain rate by 5%.",hacking_speed_mult:1.02,hacking_chance_mult:1.05,hacking_exp_mult:1.05});D.addToFactions(["The Black Hand","NiteSec"]),S(o.AugmentationNames.ArtificialSynapticPotentiation)&&delete a.Augmentations[o.AugmentationNames.ArtificialSynapticPotentiation],v(D);const I=new r.Augmentation({name:o.AugmentationNames.EnhancedMyelinSheathing,repCost:4e4,moneyCost:275e6,info:"Electrical signals are used to induce a new, artificial form of myelinogensis in the human body. This process results in the proliferation of new, synthetic myelin sheaths in the nervous system. These myelin sheaths can propogate neuro-signals much faster than their organic counterparts, leading to greater processing speeds and better brain function.

This augmentation:
Increases the player's hacking speed by 3%.
Increases the player's hacking skill by 8%.
Increases the player's hacking experience gain rate by 10%.",hacking_speed_mult:1.03,hacking_exp_mult:1.1,hacking_mult:1.08});I.addToFactions(["Fulcrum Secret Technologies","BitRunners","The Black Hand"]),S(o.AugmentationNames.EnhancedMyelinSheathing)&&delete a.Augmentations[o.AugmentationNames.EnhancedMyelinSheathing],v(I);const B=new r.Augmentation({name:o.AugmentationNames.SynapticEnhancement,repCost:800,moneyCost:15e5,info:"A small cranial implant that continuously uses weak electric signals to stimulate the brain and induce stronger synaptic activity. This improves the user's cognitive abilities.

This augmentation increases the player's hacking speed by 3%.",hacking_speed_mult:1.03});B.addToFactions(["CyberSec"]),S(o.AugmentationNames.SynapticEnhancement)&&delete a.Augmentations[o.AugmentationNames.SynapticEnhancement],v(B);const L=new r.Augmentation({name:o.AugmentationNames.NeuralRetentionEnhancement,repCost:8e3,moneyCost:5e7,info:"Chemical injections are used to permanently alter and strengthen the brain's neuronal circuits, strengthening its ability to retain information.

This augmentation increases the player's hacking experience gain rate by 25%.",hacking_exp_mult:1.25});L.addToFactions(["NiteSec"]),S(o.AugmentationNames.NeuralRetentionEnhancement)&&delete a.Augmentations[o.AugmentationNames.NeuralRetentionEnhancement],v(L);const W=new r.Augmentation({name:o.AugmentationNames.DataJack,repCost:45e3,moneyCost:9e7,info:"A brain implant that provides an interface for direct, wireless communication between a computer's main memory and the mind. This implant allows the user to not only access a computer's memory, but also alter and delete it.

This augmentation increases the amount of money the player gains from hacking by 25%.",hacking_money_mult:1.25});W.addToFactions(["BitRunners","The Black Hand","NiteSec","Chongqing","New Tokyo"]),S(o.AugmentationNames.DataJack)&&delete a.Augmentations[o.AugmentationNames.DataJack],v(W);const j=new r.Augmentation({name:o.AugmentationNames.ENM,repCost:6e3,moneyCost:5e7,info:"A thin device embedded inside the arm containing a wireless module capable of connecting to nearby networks. Once connected, the Netburner Module is capable of capturing and processing all of the traffic on that network. By itself, the Embedded Netburner Module does not do much, but a variety of very powerful upgrades can be installed that allow you to fully control the traffic on a network.

This augmentation increases the player's hacking skill by 8%.",hacking_mult:1.08});j.addToFactions(["BitRunners","The Black Hand","NiteSec","ECorp","MegaCorp","Fulcrum Secret Technologies","NWO","Blade Industries"]),S(o.AugmentationNames.ENM)&&delete a.Augmentations[o.AugmentationNames.ENM],v(j);const F=new r.Augmentation({name:o.AugmentationNames.ENMCore,repCost:1e5,moneyCost:5e8,info:"The Core library is an implant that upgrades the firmware of the Embedded Netburner Module. This upgrade allows the Embedded Netburner Module to generate its own data on a network.

This augmentation:
Increases the player's hacking speed by 3%.
Increases the amount of money the player gains from hacking by 10%.
Increases the player's chance of successfully performing a hack by 3%.
Increases the player's hacking experience gain rate by 7%.
Increases the player's hacking skill by 7%.",prereqs:[o.AugmentationNames.ENM],hacking_speed_mult:1.03,hacking_money_mult:1.1,hacking_chance_mult:1.03,hacking_exp_mult:1.07,hacking_mult:1.07});F.addToFactions(["BitRunners","The Black Hand","ECorp","MegaCorp","Fulcrum Secret Technologies","NWO","Blade Industries"]),S(o.AugmentationNames.ENMCore)&&delete a.Augmentations[o.AugmentationNames.ENMCore],v(F);const U=new r.Augmentation({name:o.AugmentationNames.ENMCoreV2,repCost:4e5,moneyCost:9e8,info:"The Core V2 library is an implant that upgrades the firmware of the Embedded Netburner Module. This upgraded firmware allows the Embedded Netburner Module to control the information on a network by re-routing traffic, spoofing IP addresses, or altering the data inside network packets.

This augmentation:
Increases the player's hacking speed by 5%.
Increases the amount of money the player gains from hacking by 30%.
Increases the player's chance of successfully performing a hack by 5%.
Increases the player's hacking experience gain rate by 15%.
Increases the player's hacking skill by 8%.",prereqs:[o.AugmentationNames.ENMCore],hacking_speed_mult:1.05,hacking_money_mult:1.3,hacking_chance_mult:1.05,hacking_exp_mult:1.15,hacking_mult:1.08});U.addToFactions(["BitRunners","ECorp","MegaCorp","Fulcrum Secret Technologies","NWO","Blade Industries","OmniTek Incorporated","KuaiGong International"]),S(o.AugmentationNames.ENMCoreV2)&&delete a.Augmentations[o.AugmentationNames.ENMCoreV2],v(U);const H=new r.Augmentation({name:o.AugmentationNames.ENMCoreV3,repCost:7e5,moneyCost:15e8,info:"The Core V3 library is an implant that upgrades the firmware of the Embedded Netburner Module. This upgraded firmware allows the Embedded Netburner Module to seamlessly inject code into any device on a network.

This augmentation:
Increases the player's hacking speed by 5%.
Increases the amount of money the player gains from hacking by 40%.
Increases the player's chance of successfully performing a hack by 10%.
Increases the player's hacking experience gain rate by 25%.
Increases the player's hacking skill by 10%.",prereqs:[o.AugmentationNames.ENMCoreV2],hacking_speed_mult:1.05,hacking_money_mult:1.4,hacking_chance_mult:1.1,hacking_exp_mult:1.25,hacking_mult:1.1});H.addToFactions(["ECorp","MegaCorp","Fulcrum Secret Technologies","NWO","Daedalus","The Covenant","Illuminati"]),S(o.AugmentationNames.ENMCoreV3)&&delete a.Augmentations[o.AugmentationNames.ENMCoreV3],v(H);const G=new r.Augmentation({name:o.AugmentationNames.ENMAnalyzeEngine,repCost:25e4,moneyCost:12e8,info:"Installs the Analyze Engine for the Embedded Netburner Module, which is a CPU cluster that vastly outperforms the Netburner Module's native single-core processor.

This augmentation increases the player's hacking speed by 10%.",prereqs:[o.AugmentationNames.ENM],hacking_speed_mult:1.1});G.addToFactions(["ECorp","MegaCorp","Fulcrum Secret Technologies","NWO","Daedalus","The Covenant","Illuminati"]),S(o.AugmentationNames.ENMAnalyzeEngine)&&delete a.Augmentations[o.AugmentationNames.ENMAnalyzeEngine],v(G);const K=new r.Augmentation({name:o.AugmentationNames.ENMDMA,repCost:4e5,moneyCost:14e8,info:"This implant installs a Direct Memory Access (DMA) controller into the Embedded Netburner Module. This allows the Module to send and receive data directly to and from the main memory of devices on a network.

This augmentation:
Increases the amount of money the player gains from hacking by 40%.
Increases the player's chance of successfully performing a hack by 20%.",prereqs:[o.AugmentationNames.ENM],hacking_money_mult:1.4,hacking_chance_mult:1.2});K.addToFactions(["ECorp","MegaCorp","Fulcrum Secret Technologies","NWO","Daedalus","The Covenant","Illuminati"]),S(o.AugmentationNames.ENMDMA)&&delete a.Augmentations[o.AugmentationNames.ENMDMA],v(K);const $=new r.Augmentation({name:o.AugmentationNames.Neuralstimulator,repCost:2e4,moneyCost:6e8,info:"A cranial implant that intelligently stimulates certain areas of the brain in order to improve cognitive functions.

This augmentation:
Increases the player's hacking speed by 2%.
Increases the player's chance of successfully performing a hack by 10%.
Increases the player's hacking experience gain rate by 12%.",hacking_speed_mult:1.02,hacking_chance_mult:1.1,hacking_exp_mult:1.12});$.addToFactions(["The Black Hand","Chongqing","Sector-12","New Tokyo","Aevum","Ishima","Volhaven","Bachman & Associates","Clarke Incorporated","Four Sigma"]),S(o.AugmentationNames.Neuralstimulator)&&delete a.Augmentations[o.AugmentationNames.Neuralstimulator],v($);const q=new r.Augmentation({name:o.AugmentationNames.NeuralAccelerator,repCost:8e4,moneyCost:35e7,info:"A microprocessor that accelerates the processing speed of biological neural networks. This is a cranial implant that is embedded inside the brain.

This augmentation:
Increases the player's hacking skill by 10%.
Increases the player's hacking experience gain rate by 15%.
Increases the amount of money the player gains from hacking by 20%.",hacking_mult:1.1,hacking_exp_mult:1.15,hacking_money_mult:1.2});q.addToFactions(["BitRunners"]),S(o.AugmentationNames.NeuralAccelerator)&&delete a.Augmentations[o.AugmentationNames.NeuralAccelerator],v(q);const Y=new r.Augmentation({name:o.AugmentationNames.CranialSignalProcessorsG1,repCost:4e3,moneyCost:14e6,info:"The first generation of Cranial Signal Processors. Cranial Signal Processors are a set of specialized microprocessors that are attached to neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations so that the brain doesn't have to.

This augmentation:
Increases the player's hacking speed by 1%.
Increases the player's hacking skill by 5%.",hacking_speed_mult:1.01,hacking_mult:1.05});Y.addToFactions(["CyberSec"]),S(o.AugmentationNames.CranialSignalProcessorsG1)&&delete a.Augmentations[o.AugmentationNames.CranialSignalProcessorsG1],v(Y);const z=new r.Augmentation({name:o.AugmentationNames.CranialSignalProcessorsG2,repCost:7500,moneyCost:25e6,info:"The second generation of Cranial Signal Processors. Cranial Signal Processors are a set of specialized microprocessors that are attached to neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations so that the brain doesn't have to.

This augmentation:
Increases the player's hacking speed by 2%.
Increases the player's chance of successfully performing a hack by 5%.
Increases the player's hacking skill by 7%.",prereqs:[o.AugmentationNames.CranialSignalProcessorsG1],hacking_speed_mult:1.02,hacking_chance_mult:1.05,hacking_mult:1.07});z.addToFactions(["CyberSec","NiteSec"]),S(o.AugmentationNames.CranialSignalProcessorsG2)&&delete a.Augmentations[o.AugmentationNames.CranialSignalProcessorsG2],v(z);const V=new r.Augmentation({name:o.AugmentationNames.CranialSignalProcessorsG3,repCost:2e4,moneyCost:11e7,info:"The third generation of Cranial Signal Processors. Cranial Signal Processors are a set of specialized microprocessors that are attached to neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations so that the brain doesn't have to.

This augmentation:
Increases the player's hacking speed by 2%.
Increases the amount of money the player gains from hacking by 15%.
Increases the player's hacking skill by 9%.",prereqs:[o.AugmentationNames.CranialSignalProcessorsG2],hacking_speed_mult:1.02,hacking_money_mult:1.15,hacking_mult:1.09});V.addToFactions(["NiteSec","The Black Hand","BitRunners"]),S(o.AugmentationNames.CranialSignalProcessorsG3)&&delete a.Augmentations[o.AugmentationNames.CranialSignalProcessorsG3],v(V);const J=new r.Augmentation({name:o.AugmentationNames.CranialSignalProcessorsG4,repCost:5e4,moneyCost:22e7,info:"The fourth generation of Cranial Signal Processors. Cranial Signal Processors are a set of specialized microprocessors that are attached to neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations so that the brain doesn't have to.

This augmentation:
Increases the player's hacking speed by 2%.
Increases the amount of money the player gains from hacking by 20%.
Increases the amount of money the player can inject into servers using grow() by 25%.",prereqs:[o.AugmentationNames.CranialSignalProcessorsG3],hacking_speed_mult:1.02,hacking_money_mult:1.2,hacking_grow_mult:1.25});J.addToFactions(["The Black Hand","BitRunners"]),S(o.AugmentationNames.CranialSignalProcessorsG4)&&delete a.Augmentations[o.AugmentationNames.CranialSignalProcessorsG4],v(J);const X=new r.Augmentation({name:o.AugmentationNames.CranialSignalProcessorsG5,repCost:1e5,moneyCost:45e7,info:"The fifth generation of Cranial Signal Processors. Cranial Signal Processors are a set of specialized microprocessors that are attached to neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations so that the brain doesn't have to.

This augmentation:
Increases the player's hacking skill by 30%.
Increases the amount of money the player gains from hacking by 25%.
Increases the amount of money the player can inject into servers using grow() by 75%.",prereqs:[o.AugmentationNames.CranialSignalProcessorsG4],hacking_mult:1.3,hacking_money_mult:1.25,hacking_grow_mult:1.75});X.addToFactions(["BitRunners"]),S(o.AugmentationNames.CranialSignalProcessorsG5)&&delete a.Augmentations[o.AugmentationNames.CranialSignalProcessorsG5],v(X);const Q=new r.Augmentation({name:o.AugmentationNames.NeuronalDensification,repCost:75e3,moneyCost:275e6,info:"The brain is surgically re-engineered to have increased neuronal density by decreasing the neuron gap junction. Then, the body is genetically modified to enhance the production and capabilities of its neural stem cells.

This augmentation:
Increases the player's hacking skill by 15%.
Increases the player's hacking experience gain rate by 10%.
Increases the player's hacking speed by 3%.",hacking_mult:1.15,hacking_exp_mult:1.1,hacking_speed_mult:1.03});Q.addToFactions(["Clarke Incorporated"]),S(o.AugmentationNames.NeuronalDensification)&&delete a.Augmentations[o.AugmentationNames.NeuronalDensification],v(Q);const Z=new r.Augmentation({name:o.AugmentationNames.NuoptimalInjectorImplant,repCost:2e3,moneyCost:4e6,info:"This torso implant automatically injects nootropic supplements into the bloodstream to improve memory, increase focus, and provide other cognitive enhancements.

This augmentation increases the amount of reputation the player gains when working for a company by 20%.",company_rep_mult:1.2});Z.addToFactions(["Tian Di Hui","Volhaven","New Tokyo","Chongqing","Ishima","Clarke Incorporated","Four Sigma","Bachman & Associates"]),S(o.AugmentationNames.NuoptimalInjectorImplant)&&delete a.Augmentations[o.AugmentationNames.NuoptimalInjectorImplant],v(Z);const ee=new r.Augmentation({name:o.AugmentationNames.SpeechEnhancement,repCost:1e3,moneyCost:25e5,info:"An advanced neural implant that improves your speaking abilities, making you more convincing and likable in conversations and overall improving your social interactions.

This augmentation:
Increases the player's charisma by 10%.
Increases the amount of reputation the player gains when working for a company by 10%.",company_rep_mult:1.1,charisma_mult:1.1});ee.addToFactions(["Tian Di Hui","Speakers for the Dead","Four Sigma","KuaiGong International","Clarke Incorporated","Bachman & Associates"]),S(o.AugmentationNames.SpeechEnhancement)&&delete a.Augmentations[o.AugmentationNames.SpeechEnhancement],v(ee);const te=new r.Augmentation({name:o.AugmentationNames.FocusWire,repCost:3e4,moneyCost:18e7,info:"A cranial implant that stops procrastination by blocking specific neural pathways in the brain.

This augmentation:
Increases all experience gains by 5%.
Increases the amount of money the player gains from working by 20%.
Increases the amount of reputation the player gains when working for a company by 10%.",hacking_exp_mult:1.05,strength_exp_mult:1.05,defense_exp_mult:1.05,dexterity_exp_mult:1.05,agility_exp_mult:1.05,charisma_exp_mult:1.05,company_rep_mult:1.1,work_money_mult:1.2});te.addToFactions(["Bachman & Associates","Clarke Incorporated","Four Sigma","KuaiGong International"]),S(o.AugmentationNames.FocusWire)&&delete a.Augmentations[o.AugmentationNames.FocusWire],v(te);const ne=new r.Augmentation({name:o.AugmentationNames.PCDNI,repCost:15e4,moneyCost:75e7,info:"Installs a Direct-Neural Interface jack into your arm that is compatible with most computers. Connecting to a computer through this jack allows you to interface with it using the brain's electrochemical signals.

This augmentation:
Increases the amount of reputation the player gains when working for a company by 30%.
Increases the player's hacking skill by 8%.",company_rep_mult:1.3,hacking_mult:1.08});ne.addToFactions(["Four Sigma","OmniTek Incorporated","ECorp","Blade Industries"]),S(o.AugmentationNames.PCDNI)&&delete a.Augmentations[o.AugmentationNames.PCDNI],v(ne);const re=new r.Augmentation({name:o.AugmentationNames.PCDNIOptimizer,repCost:2e5,moneyCost:9e8,info:"This is a submodule upgrade to the PC Direct-Neural Interface augmentation. It improves the performance of the interface and gives the user more control options to the connected computer.

This augmentation:
Increases the amount of reputation the player gains when working for a company by 75%.
Increases the player's hacking skill by 10%.",prereqs:[o.AugmentationNames.PCDNI],company_rep_mult:1.75,hacking_mult:1.1});re.addToFactions(["Fulcrum Secret Technologies","ECorp","Blade Industries"]),S(o.AugmentationNames.PCDNIOptimizer)&&delete a.Augmentations[o.AugmentationNames.PCDNIOptimizer],v(re);const ae=new r.Augmentation({name:o.AugmentationNames.PCDNINeuralNetwork,repCost:6e5,moneyCost:15e8,info:"This is an additional installation that upgrades the functionality of the PC Direct-Neural Interface augmentation. When connected to a computer, The NeuroNet Injector upgrade allows the user to use his/her own brain's processing power to aid the computer in computational tasks.

This augmentation:
Increases the amount of reputation the player gains when working for a company by 100%.
Increases the player's hacking skill by 10%.
Increases the player's hacking speed by 5%.",prereqs:[o.AugmentationNames.PCDNI],company_rep_mult:2,hacking_mult:1.1,hacking_speed_mult:1.05});ae.addToFactions(["Fulcrum Secret Technologies"]),S(o.AugmentationNames.PCDNINeuralNetwork)&&delete a.Augmentations[o.AugmentationNames.PCDNINeuralNetwork],v(ae);const ie=new r.Augmentation({name:o.AugmentationNames.ADRPheromone1,repCost:1500,moneyCost:35e5,info:"The body is genetically re-engineered so that it produces the ADR-V1 pheromone, an artificial pheromone discovered by scientists. The ADR-V1 pheromone, when excreted, triggers feelings of admiration and approval in other people.

This augmentation:
Increases the amount of reputation the player gains when working for a company by 10%
Increases the amount of reputation the player gains for a faction by 10%.",company_rep_mult:1.1,faction_rep_mult:1.1});ie.addToFactions(["Tian Di Hui","The Syndicate","NWO","MegaCorp","Four Sigma"]),S(o.AugmentationNames.ADRPheromone1)&&delete a.Augmentations[o.AugmentationNames.ADRPheromone1],v(ie);const oe=new r.Augmentation({name:o.AugmentationNames.ADRPheromone2,repCost:25e3,moneyCost:11e7,info:"The body is genetically re-engineered so that it produces the ADR-V2 pheromone, which is similar to but more potent than ADR-V1. This pheromone, when excreted, triggers feelings of admiration, approval, and respect in others.

This augmentation:
Increases the amount of reputation the player gains for a faction and company by 20%.",company_rep_mult:1.2,faction_rep_mult:1.2});oe.addToFactions(["Silhouette","Four Sigma","Bachman & Associates","Clarke Incorporated"]),S(o.AugmentationNames.ADRPheromone2)&&delete a.Augmentations[o.AugmentationNames.ADRPheromone2],v(oe);const se=new r.Augmentation({name:o.AugmentationNames.ShadowsSimulacrum,repCost:15e3,moneyCost:8e7,info:"A crude but functional matter phase-shifter module that is embedded in the brainstem and cerebellum. This augmentation was developed by criminal organizations and allows the user to project and control holographic simulacrums within a large radius. These simulacrums are commonly used for espionage and surveillance work.

This augmentation:
Increases the amount of reputation the player gains when working for a faction or company by 15%.",company_rep_mult:1.15,faction_rep_mult:1.15});se.addToFactions(["The Syndicate","The Dark Army","Speakers for the Dead"]),S(o.AugmentationNames.ShadowsSimulacrum)&&delete a.Augmentations[o.AugmentationNames.ShadowsSimulacrum],v(se);const le=new r.Augmentation({name:o.AugmentationNames.HacknetNodeCPUUpload,repCost:1500,moneyCost:22e5,info:"Uploads the architecture and design details of a Hacknet Node's CPU into the brain. This allows the user to engineer custom hardware and software for the Hacknet Node that provides better performance.

This augmentation:
Increases the amount of money produced by Hacknet Nodes by 15%.
Decreases the cost of purchasing a Hacknet Node by 15%.",hacknet_node_money_mult:1.15,hacknet_node_purchase_cost_mult:.85});le.addToFactions(["Netburners"]),S(o.AugmentationNames.HacknetNodeCPUUpload)&&delete a.Augmentations[o.AugmentationNames.HacknetNodeCPUUpload],v(le);const ce=new r.Augmentation({name:o.AugmentationNames.HacknetNodeCacheUpload,repCost:1e3,moneyCost:11e5,info:"Uploads the architecture and design details of a Hacknet Node's main-memory cache into the brain. This allows the user to engineer custom cache hardware for the Hacknet Node that offers better performance.

This augmentation:
Increases the amount of money produced by Hacknet Nodes by 10%.
Decreases the cost of leveling up a Hacknet Node by 15%.",hacknet_node_money_mult:1.1,hacknet_node_level_cost_mult:.85});ce.addToFactions(["Netburners"]),S(o.AugmentationNames.HacknetNodeCacheUpload)&&delete a.Augmentations[o.AugmentationNames.HacknetNodeCacheUpload],v(ce);const ue=new r.Augmentation({name:o.AugmentationNames.HacknetNodeNICUpload,repCost:750,moneyCost:9e5,info:"Uploads the architecture and design details of a Hacknet Node's Network Interface Card (NIC) into the brain. This allows the user to engineer a custom NIC for the Hacknet Node that offers better performance.

This augmentation:
Increases the amount of money produced by Hacknet Nodes by 10%.
Decreases the cost of purchasing a Hacknet Node by 10%.",hacknet_node_money_mult:1.1,hacknet_node_purchase_cost_mult:.9});ue.addToFactions(["Netburners"]),S(o.AugmentationNames.HacknetNodeNICUpload)&&delete a.Augmentations[o.AugmentationNames.HacknetNodeNICUpload],v(ue);const me=new r.Augmentation({name:o.AugmentationNames.HacknetNodeKernelDNI,repCost:3e3,moneyCost:8e6,info:"Installs a Direct-Neural Interface jack into the arm that is capable of connecting to a Hacknet Node. This lets the user access and manipulate the Node's kernel using the mind's electrochemical signals.

This augmentation increases the amount of money produced by Hacknet Nodes by 25%.",hacknet_node_money_mult:1.25});me.addToFactions(["Netburners"]),S(o.AugmentationNames.HacknetNodeKernelDNI)&&delete a.Augmentations[o.AugmentationNames.HacknetNodeKernelDNI],v(me);const pe=new r.Augmentation({name:o.AugmentationNames.HacknetNodeCoreDNI,repCost:5e3,moneyCost:12e6,info:"Installs a Direct-Neural Interface jack into the arm that is capable of connecting to a Hacknet Node. This lets the user access and manipulate the Node's processing logic using the mind's electrochemical signals.

This augmentation increases the amount of money produced by Hacknet Nodes by 45%.",hacknet_node_money_mult:1.45});pe.addToFactions(["Netburners"]),S(o.AugmentationNames.HacknetNodeCoreDNI)&&delete a.Augmentations[o.AugmentationNames.HacknetNodeCoreDNI],v(pe);const he=new r.Augmentation({name:o.AugmentationNames.NeuroFluxGovernor,repCost:500,moneyCost:75e4,info:"A device that is embedded in the back of the neck. The NeuroFlux Governor monitors and regulates nervous impulses coming to and from the spinal column, essentially 'governing' the body. By doing so, it improves the functionality of the body's nervous system.

This is a special augmentation because it can be leveled up infinitely. Each level of this augmentation increases ALL of the player's multipliers by 1%.",hacking_chance_mult:1.01,hacking_speed_mult:1.01,hacking_money_mult:1.01,hacking_grow_mult:1.01,hacking_mult:1.01,strength_mult:1.01,defense_mult:1.01,dexterity_mult:1.01,agility_mult:1.01,charisma_mult:1.01,hacking_exp_mult:1.01,strength_exp_mult:1.01,defense_exp_mult:1.01,dexterity_exp_mult:1.01,agility_exp_mult:1.01,charisma_exp_mult:1.01,company_rep_mult:1.01,faction_rep_mult:1.01,crime_money_mult:1.01,crime_success_mult:1.01,hacknet_node_money_mult:1.01,hacknet_node_purchase_cost_mult:.99,hacknet_node_ram_cost_mult:.99,hacknet_node_core_cost_mult:.99,hacknet_node_level_cost_mult:.99,work_money_mult:1.01});let de=0;for(let e=0;e
This augmentation increases the player's experience gain rate for all stats by 10%.",hacking_exp_mult:1.1,strength_exp_mult:1.1,defense_exp_mult:1.1,dexterity_exp_mult:1.1,agility_exp_mult:1.1,charisma_exp_mult:1.1});ye.addToFactions(["CyberSec"]),S(o.AugmentationNames.Neurotrainer1)&&delete a.Augmentations[o.AugmentationNames.Neurotrainer1],v(ye);const fe=new r.Augmentation({name:o.AugmentationNames.Neurotrainer2,repCost:4e3,moneyCost:9e6,info:"A decentralized cranial implant that improves the brain's ability to learn. This is a more powerful version of the Neurotrainer I augmentation, but it does not require Neurotrainer I to be installed as a prerequisite.

This augmentation increases the player's experience gain rate for all stats by 15%.",hacking_exp_mult:1.15,strength_exp_mult:1.15,defense_exp_mult:1.15,dexterity_exp_mult:1.15,agility_exp_mult:1.15,charisma_exp_mult:1.15});fe.addToFactions(["BitRunners","NiteSec"]),S(o.AugmentationNames.Neurotrainer2)&&delete a.Augmentations[o.AugmentationNames.Neurotrainer2],v(fe);const be=new r.Augmentation({name:o.AugmentationNames.Neurotrainer3,repCost:1e4,moneyCost:26e6,info:"A decentralized cranial implant that improves the brain's ability to learn. This is a more powerful version of the Neurotrainer I and Neurotrainer II augmentation, but it does not require either of them to be installed as a prerequisite.

This augmentation increases the player's experience gain rate for all stats by 20%.",hacking_exp_mult:1.2,strength_exp_mult:1.2,defense_exp_mult:1.2,dexterity_exp_mult:1.2,agility_exp_mult:1.2,charisma_exp_mult:1.2});be.addToFactions(["NWO","Four Sigma"]),S(o.AugmentationNames.Neurotrainer3)&&delete a.Augmentations[o.AugmentationNames.Neurotrainer3],v(be);const Ee=new r.Augmentation({name:o.AugmentationNames.Hypersight,repCost:6e4,moneyCost:55e7,info:"A bionic eye implant that grants sight capabilities far beyond those of a natural human. Embedded circuitry within the implant provides the ability to detect heat and movement through solid objects such as wells, thus providing 'x-ray vision'-like capabilities.

This augmentation:
Increases the player's dexterity by 40%.
Increases the player's hacking speed by 3%.
Increases the amount of money the player gains from hacking by 10%.",dexterity_mult:1.4,hacking_speed_mult:1.03,hacking_money_mult:1.1});Ee.addToFactions(["Blade Industries","KuaiGong International"]),S(o.AugmentationNames.Hypersight)&&delete a.Augmentations[o.AugmentationNames.Hypersight],v(Ee);const ve=new r.Augmentation({name:o.AugmentationNames.LuminCloaking1,repCost:600,moneyCost:1e6,info:"A skin implant that reinforces the skin with highly-advanced synthetic cells. These cells, when powered, have a negative refractive index. As a result, they bend light around the skin, making the user much harder to see from the naked eye.

This augmentation:
Increases the player's agility by 5%
Increases the amount of money the player gains from crimes by 10%.",agility_mult:1.05,crime_money_mult:1.1});ve.addToFactions(["Slum Snakes","Tetrads"]),S(o.AugmentationNames.LuminCloaking1)&&delete a.Augmentations[o.AugmentationNames.LuminCloaking1],v(ve);const ke=new r.Augmentation({name:o.AugmentationNames.LuminCloaking2,repCost:2e3,moneyCost:6e6,info:"This is a more advanced version of the LuminCloaking-V2 augmentation. This skin implant reinforces the skin with highly-advanced synthetic cells. These cells, when powered, are capable of not only bending light but also of bending heat, making the user more resilient as well as stealthy.

This augmentation:
Increases the player's agility by 10%
Increases the player's defense by 10%
Increases the amount of money the player gains from crimes by 25%.",prereqs:[o.AugmentationNames.LuminCloaking1],agility_mult:1.1,defense_mult:1.1,crime_money_mult:1.25});ke.addToFactions(["Slum Snakes","Tetrads"]),S(o.AugmentationNames.LuminCloaking2)&&delete a.Augmentations[o.AugmentationNames.LuminCloaking2],v(ke);const Ce=new r.Augmentation({name:o.AugmentationNames.SmartSonar,repCost:9e3,moneyCost:15e6,info:"A cochlear implant that helps the player detect and locate enemies using sound propagation.

This augmentation:
Increases the player's dexterity by 10%.
Increases the player's dexterity experience gain rate by 15%.
Increases the amount of money the player gains from crimes by 25%.",dexterity_mult:1.1,dexterity_exp_mult:1.15,crime_money_mult:1.25});Ce.addToFactions(["Slum Snakes"]),S(o.AugmentationNames.SmartSonar)&&delete a.Augmentations[o.AugmentationNames.SmartSonar],v(Ce);const Pe=new r.Augmentation({name:o.AugmentationNames.PowerRecirculator,repCost:1e4,moneyCost:36e6,info:"The body's nerves are attached with polypyrrole nanocircuits that are capable of capturing wasted energy (in the form of heat) and converting it back into usable power.

This augmentation:
Increases all of the player's stats by 5%.
Increases the player's experience gain rate for all stats by 10%.",hacking_mult:1.05,strength_mult:1.05,defense_mult:1.05,dexterity_mult:1.05,agility_mult:1.05,charisma_mult:1.05,hacking_exp_mult:1.1,strength_exp_mult:1.1,defense_exp_mult:1.1,dexterity_exp_mult:1.1,agility_exp_mult:1.1,charisma_exp_mult:1.1});Pe.addToFactions(["Tetrads","The Dark Army","The Syndicate","NWO"]),S(o.AugmentationNames.PowerRecirculator)&&delete a.Augmentations[o.AugmentationNames.PowerRecirculator],v(Pe);const Te=new r.Augmentation({name:o.AugmentationNames.QLink,repCost:75e4,moneyCost:5e12,info:"A brain implant that wirelessly connects you to the Illuminati's quantum supercomputer, allowing you to access and use its incredible computing power.

This augmentation:
Increases the player's hacking skill by 75%.
Increases the player's hacking speed by 100%.
Increases the player's chance of successfully performing a hack by 150%.
Increases the amount of money the player gains from hacking by 300%.",hacking_mult:1.75,hacking_speed_mult:2,hacking_chance_mult:2.5,hacking_money_mult:4});Te.addToFactions(["Illuminati"]),S(o.AugmentationNames.QLink)&&delete a.Augmentations[o.AugmentationNames.QLink],v(Te);const Se=new r.Augmentation({name:o.AugmentationNames.TheRedPill,repCost:1e6,moneyCost:0,info:"It's time to leave the cave."});Se.addToFactions(["Daedalus"]),S(o.AugmentationNames.TheRedPill)&&delete a.Augmentations[o.AugmentationNames.TheRedPill],v(Se);const Oe=new r.Augmentation({name:o.AugmentationNames.SPTN97,repCost:5e5,moneyCost:975e6,info:"The SPTN-97 gene is injected into the genome. The SPTN-97 gene is an artificially-synthesized gene that was developed by DARPA to create super-soldiers through genetic modification. The gene was outlawed in 2056.

This augmentation:
Increases all of the player's combat stats by 75%.
Increases the player's hacking skill by 15%.",strength_mult:1.75,defense_mult:1.75,dexterity_mult:1.75,agility_mult:1.75,hacking_mult:1.15});Oe.addToFactions(["The Covenant"]),S(o.AugmentationNames.SPTN97)&&delete a.Augmentations[o.AugmentationNames.SPTN97],v(Oe);const Me=new r.Augmentation({name:o.AugmentationNames.HiveMind,repCost:6e5,moneyCost:11e8,info:"A brain implant developed by ECorp. They do not reveal what exactly the implant does, but they promise that it will greatly enhance your abilities.",hacking_grow_mult:3});Me.addToFactions(["ECorp"]),S(o.AugmentationNames.HiveMind)&&delete a.Augmentations[o.AugmentationNames.HiveMind],v(Me);const xe=new r.Augmentation({name:o.AugmentationNames.CordiARCReactor,repCost:45e4,moneyCost:1e9,info:"The thoracic cavity is equipped with a small chamber designed to hold and sustain hydrogen plasma. The plasma is used to generate fusion power through nuclear fusion, providing limitless amount of clean energy for the body.

This augmentation:
Increases all of the player's combat stats by 35%.
Increases all of the player's combat stat experience gain rate by 35%.",strength_mult:1.35,defense_mult:1.35,dexterity_mult:1.35,agility_mult:1.35,strength_exp_mult:1.35,defense_exp_mult:1.35,dexterity_exp_mult:1.35,agility_exp_mult:1.35});xe.addToFactions(["MegaCorp"]),S(o.AugmentationNames.CordiARCReactor)&&delete a.Augmentations[o.AugmentationNames.CordiARCReactor],v(xe);const we=new r.Augmentation({name:o.AugmentationNames.SmartJaw,repCost:15e4,moneyCost:55e7,info:"A bionic jaw that contains advanced hardware and software capable of psychoanalyzing and profiling the personality of others using optical imaging software.

This augmentation:
Increases the player's charisma by 50%.
Increases the player's charisma experience gain rate by 50%.
Increases the amount of reputation the player gains for a company by 25%.
Increases the amount of reputation the player gains for a faction by 25%.",charisma_mult:1.5,charisma_exp_mult:1.5,company_rep_mult:1.25,faction_rep_mult:1.25});we.addToFactions(["Bachman & Associates"]),S(o.AugmentationNames.SmartJaw)&&delete a.Augmentations[o.AugmentationNames.SmartJaw],v(we);const Ae=new r.Augmentation({name:o.AugmentationNames.Neotra,repCost:225e3,moneyCost:575e6,info:"A highly-advanced techno-organic drug that is injected into the skeletal and integumentary system. The drug permanently modifies the DNA of the body's skin and bone cells, granting them the ability to repair and restructure themselves.

This augmentation increases the player's strength and defense by 55%.",strength_mult:1.55,defense_mult:1.55});Ae.addToFactions(["Blade Industries"]),S(o.AugmentationNames.Neotra)&&delete a.Augmentations[o.AugmentationNames.Neotra],v(Ae);const Re=new r.Augmentation({name:o.AugmentationNames.Xanipher,repCost:35e4,moneyCost:85e7,info:"A concoction of advanced nanobots that is orally ingested into the body. These nanobots induce physiological change and significantly improve the body's functionining in all aspects.

This augmentation:
Increases all of the player's stats by 20%.
Increases the player's experience gain rate for all stats by 15%.",hacking_mult:1.2,strength_mult:1.2,defense_mult:1.2,dexterity_mult:1.2,agility_mult:1.2,charisma_mult:1.2,hacking_exp_mult:1.15,strength_exp_mult:1.15,defense_exp_mult:1.15,dexterity_exp_mult:1.15,agility_exp_mult:1.15,charisma_exp_mult:1.15});Re.addToFactions(["NWO"]),S(o.AugmentationNames.Xanipher)&&delete a.Augmentations[o.AugmentationNames.Xanipher],v(Re);const Ne=new r.Augmentation({name:o.AugmentationNames.nextSENS,repCost:175e3,moneyCost:385e6,info:"The body is genetically re-engineered to maintain a state of negligible senescence, preventing the body from deteriorating with age.

This augmentation increases all of the player's stats by 20%.",hacking_mult:1.2,strength_mult:1.2,defense_mult:1.2,dexterity_mult:1.2,agility_mult:1.2,charisma_mult:1.2});Ne.addToFactions(["Clarke Incorporated"]),S(o.AugmentationNames.nextSENS)&&delete a.Augmentations[o.AugmentationNames.nextSENS],v(Ne);const De=new r.Augmentation({name:o.AugmentationNames.OmniTekInfoLoad,repCost:25e4,moneyCost:575e6,info:"OmniTek's data and information repository is uploaded into your brain, enhancing your programming and hacking abilities.

This augmentation:
Increases the player's hacking skill by 20%.
Increases the player's hacking experience gain rate by 25%.",hacking_mult:1.2,hacking_exp_mult:1.25});De.addToFactions(["OmniTek Incorporated"]),S(o.AugmentationNames.OmniTekInfoLoad)&&delete a.Augmentations[o.AugmentationNames.OmniTekInfoLoad],v(De);const Ie=new r.Augmentation({name:o.AugmentationNames.PhotosyntheticCells,repCost:225e3,moneyCost:55e7,info:"Chloroplasts are added to epidermal stem cells and are applied to the body using a skin graft. The result is photosynthetic skin cells, allowing users to generate their own energy and nutrition using solar power.

This augmentation increases the player's strength, defense, and agility by 40%.",strength_mult:1.4,defense_mult:1.4,agility_mult:1.4});Ie.addToFactions(["KuaiGong International"]),S(o.AugmentationNames.PhotosyntheticCells)&&delete a.Augmentations[o.AugmentationNames.PhotosyntheticCells],v(Ie);const Be=new r.Augmentation({name:o.AugmentationNames.Neurolink,repCost:35e4,moneyCost:875e6,info:"A brain implant that provides a high-bandwidth, direct neural link between your mind and BitRunners' data servers, which reportedly contain the largest database of hacking tools and information in the world.

This augmentation:
Increases the player's hacking skill by 15%.
Increases the player's hacking experience gain rate by 20%.
Increases the player's chance of successfully performing a hack by 10%.
Increases the player's hacking speed by 5%.
Lets the player start with the FTPCrack.exe and relaySMTP.exe programs after a reset.",hacking_mult:1.15,hacking_exp_mult:1.2,hacking_chance_mult:1.1,hacking_speed_mult:1.05});Be.addToFactions(["BitRunners"]),S(o.AugmentationNames.Neurolink)&&delete a.Augmentations[o.AugmentationNames.Neurolink],v(Be);const Le=new r.Augmentation({name:o.AugmentationNames.TheBlackHand,repCost:4e4,moneyCost:11e7,info:"A highly advanced bionic hand. This prosthetic not only enhances strength and dexterity but it is also embedded with hardware and firmware that lets the user connect to, access and hack devices and machines just by touching them.

This augmentation:
Increases the player's strength and dexterity by 15%.
Increases the player's hacking skill by 10%.
Increases the player's hacking speed by 2%.
Increases the amount of money the player gains from hacking by 10%.",strength_mult:1.15,dexterity_mult:1.15,hacking_mult:1.1,hacking_speed_mult:1.02,hacking_money_mult:1.1});Le.addToFactions(["The Black Hand"]),S(o.AugmentationNames.TheBlackHand)&&delete a.Augmentations[o.AugmentationNames.TheBlackHand],v(Le);const We=new r.Augmentation({name:o.AugmentationNames.CRTX42AA,repCost:18e3,moneyCost:45e6,info:"The CRTX42-AA gene is injected into the genome. The CRTX42-AA is an artificially-synthesized gene that targets the visual and prefrontal cortex and improves cognitive abilities.

This augmentation:
Improves the player's hacking skill by 8%.
Improves the player's hacking experience gain rate by 15%.",hacking_mult:1.08,hacking_exp_mult:1.15});We.addToFactions(["NiteSec"]),S(o.AugmentationNames.CRTX42AA)&&delete a.Augmentations[o.AugmentationNames.CRTX42AA],v(We);const je=new r.Augmentation({name:o.AugmentationNames.Neuregen,repCost:15e3,moneyCost:75e6,info:"A drug that genetically modifies the neurons in the brain. The result is that these neurons never die and continuously regenerate and strengthen themselves.

This augmentation increases the player's hacking experience gain rate by 40%.",hacking_exp_mult:1.4});je.addToFactions(["Chongqing"]),S(o.AugmentationNames.Neuregen)&&delete a.Augmentations[o.AugmentationNames.Neuregen],v(je);const Fe=new r.Augmentation({name:o.AugmentationNames.CashRoot,repCost:5e3,moneyCost:25e6,info:"A collection of digital assets saved on a small chip. The chip is implanted into your wrist. A small jack in the chip allows you to connect it to a computer and upload the assets.

This augmentation:
Lets the player start with $1,000,000 after a reset.
Lets the player start with the BruteSSH.exe program after a reset."});Fe.addToFactions(["Sector-12"]),S(o.AugmentationNames.CashRoot)&&delete a.Augmentations[o.AugmentationNames.CashRoot],v(Fe);const Ue=new r.Augmentation({name:o.AugmentationNames.NutriGen,repCost:2500,moneyCost:5e5,info:"A thermo-powered artificial nutrition generator. Endogenously synthesizes glucose, amino acids, and vitamins and redistributes them across the body. The device is powered by the body's naturally wasted energy in the form of heat.

This augmentation:
Increases the player's experience gain rate for all combat stats by 20%.",strength_exp_mult:1.2,defense_exp_mult:1.2,dexterity_exp_mult:1.2,agility_exp_mult:1.2});Ue.addToFactions(["New Tokyo"]),S(o.AugmentationNames.NutriGen)&&delete a.Augmentations[o.AugmentationNames.NutriGen],v(Ue);const He=new r.Augmentation({name:o.AugmentationNames.INFRARet,repCost:3e3,moneyCost:6e6,info:"A retina implant consisting of a tiny chip that sits behind the retina. This implant lets people visually detect infrared radiation.

This augmentation:
Increases the player's crime success rate by 25%.
Increases the amount of money the player gains from crimes by 10%.
Increases the player's dexterity by 10%.",crime_success_mult:1.25,crime_money_mult:1.1,dexterity_mult:1.1});He.addToFactions(["Ishima"]),S(o.AugmentationNames.INFRARet)&&delete a.Augmentations[o.AugmentationNames.INFRARet],v(He);const Ge=new r.Augmentation({name:o.AugmentationNames.DermaForce,repCost:6e3,moneyCost:1e7,info:"A synthetic skin is grafted onto the body. The skin consists of millions of nanobots capable of projecting high-density muon beams, creating an energy barrier around the user.

This augmentation increases the player's defense by 40%.",defense_mult:1.4});Ge.addToFactions(["Volhaven"]),S(o.AugmentationNames.DermaForce)&&delete a.Augmentations[o.AugmentationNames.DermaForce],v(Ge);const Ke=new r.Augmentation({name:o.AugmentationNames.GrapheneBrachiBlades,repCost:9e4,moneyCost:5e8,info:"An upgrade to the BrachiBlades augmentation. It infuses the retractable blades with an advanced graphene material to make them much stronger and lighter.

This augmentation:
Increases the player's strength and defense by 40%.
Increases the player's crime success rate by 10%.
Increases the amount of money the player gains from crimes by 30%.",prereqs:[o.AugmentationNames.BrachiBlades],strength_mult:1.4,defense_mult:1.4,crime_success_mult:1.1,crime_money_mult:1.3});Ke.addToFactions(["Speakers for the Dead"]),S(o.AugmentationNames.GrapheneBrachiBlades)&&delete a.Augmentations[o.AugmentationNames.GrapheneBrachiBlades],v(Ke);const $e=new r.Augmentation({name:o.AugmentationNames.GrapheneBionicArms,repCost:2e5,moneyCost:75e7,info:"An upgrade to the Bionic Arms augmentation. It infuses the prosthetic arms with an advanced graphene material to make them much stronger and lighter.

This augmentation increases the player's strength and dexterity by 85%.",prereqs:[o.AugmentationNames.BionicArms],strength_mult:1.85,dexterity_mult:1.85});$e.addToFactions(["The Dark Army"]),S(o.AugmentationNames.GrapheneBionicArms)&&delete a.Augmentations[o.AugmentationNames.GrapheneBionicArms],v($e);const qe=new r.Augmentation({name:o.AugmentationNames.BrachiBlades,repCost:5e3,moneyCost:18e6,info:"A set of retractable plasteel blades are implanted in the arm, underneath the skin.

This augmentation:
Increases the player's strength and defense by 15%.
Increases the player's crime success rate by 10%.
Increases the amount of money the player gains from crimes by 15%.",strength_mult:1.15,defense_mult:1.15,crime_success_mult:1.1,crime_money_mult:1.15});qe.addToFactions(["The Syndicate"]),S(o.AugmentationNames.BrachiBlades)&&delete a.Augmentations[o.AugmentationNames.BrachiBlades],v(qe);const Ye=new r.Augmentation({name:o.AugmentationNames.BionicArms,repCost:25e3,moneyCost:55e6,info:"Cybernetic arms created from plasteel and carbon fibers that completely replace the user's organic arms.

This augmentation increases the user's strength and dexterity by 30%.",strength_mult:1.3,dexterity_mult:1.3});Ye.addToFactions(["Tetrads"]),S(o.AugmentationNames.BionicArms)&&delete a.Augmentations[o.AugmentationNames.BionicArms],v(Ye);const ze=new r.Augmentation({name:o.AugmentationNames.SNA,repCost:2500,moneyCost:6e6,info:"A cranial implant that affects the user's personality, making them better at negotiation in social situations.

This augmentation:
Increases the amount of money the player earns at a company by 10%.
Increases the amount of reputation the player gains when working for a company or faction by 15%.",work_money_mult:1.1,company_rep_mult:1.15,faction_rep_mult:1.15});ze.addToFactions(["Tian Di Hui"]),S(o.AugmentationNames.SNA)&&delete a.Augmentations[o.AugmentationNames.SNA],v(ze);if(Object(u.factionExists)("Bladeburners")){const e=new r.Augmentation({name:o.AugmentationNames.EsperEyewear,repCost:500,moneyCost:33e6,info:"Ballistic-grade protective and retractable eyewear that was designed specially for Bladeburner units. This is implanted by installing a mechanical frame in the skull's orbit. This frame interfaces with the brain and allows the user to automatically extrude and extract the eyewear. The eyewear protects against debris, shrapnel, laser, flash, and gas. It is also embedded with a data processing chip that can be programmed to display an AR HUD and assist the user in field missions.

This augmentation:
Increases the player's success chance in Bladeburner contracts/operations by 3%.
Increases the player's dexterity by 5%.",bladeburner_success_chance_mult:1.03,dexterity_mult:1.05,isSpecial:!0});e.addToFactions(["Bladeburners"]),C(e);const t=new r.Augmentation({name:o.AugmentationNames.EMS4Recombination,repCost:1e3,moneyCost:55e6,info:"A DNA recombination of the EMS-4 Gene. This genetic engineering technique was originally used on Bladeburners during the Synthoid uprising to induce wakefulness and concentration, suppress fear, reduce empathy, and improve reflexes and memory-recall among other things.

This augmentation:
Increases the player's sucess chance in Bladeburner contracts/operations by 3%.
Increases the player's effectiveness in Bladeburner Field Analysis by 5%.
Increases the player's Bladeburner stamina gain rate by 2%.",bladeburner_success_chance_mult:1.03,bladeburner_analysis_mult:1.05,bladeburner_stamina_gain_mult:1.02,isSpecial:!0});t.addToFactions(["Bladeburners"]),C(t);const n=new r.Augmentation({name:o.AugmentationNames.OrionShoulder,repCost:2500,moneyCost:11e7,info:"A bionic shoulder augmentation for the right shoulder. Using cybernetics, the ORION-MKIV shoulder enhances the strength and dexterity of the user's right arm. It also provides protection due to its crystallized graphene plating.

This augmentation:
Increases the player's defense by 5%.
Increases the player's strength and dexterity by 5%.
Increases the player's success chance in Bladeburner contracts/operations by 4%.",defense_mult:1.05,strength_mult:1.05,dexterity_mult:1.05,bladeburner_success_chance_mult:1.04,isSpecial:!0});n.addToFactions(["Bladeburners"]),C(n);const a=new r.Augmentation({name:o.AugmentationNames.HyperionV1,repCost:5e3,moneyCost:55e7,info:"A pair of mini plasma cannons embedded into the hands. The Hyperion is capable of rapidly firing bolts of high-density plasma. The weapon is meant to be used against augmented enemies as the ionized nature of the plasma disrupts the electrical systems of Augmentations. However, it can also be effective against non-augmented enemies due to its high temperature and concussive force.

This augmentation:
Increases the player's success chance in Bladeburner contracts/operations by 6%.",bladeburner_success_chance_mult:1.06,isSpecial:!0});a.addToFactions(["Bladeburners"]),C(a);const i=new r.Augmentation({name:o.AugmentationNames.HyperionV2,repCost:1e4,moneyCost:11e8,info:"A pair of mini plasma cannons embedded into the hands. This augmentation is more advanced and powerful than the original V1 model. This V2 model is more power-efficiency, more accurate, and can fire plasma bolts at a much higher velocity than the V1 model.

This augmentation:
Increases the player's success chance in Bladeburner contracts/operations by 8%.",prereqs:[o.AugmentationNames.HyperionV1],bladeburner_success_chance_mult:1.08,isSpecial:!0});i.addToFactions(["Bladeburners"]),C(i);const s=new r.Augmentation({name:o.AugmentationNames.GolemSerum,repCost:12500,moneyCost:22e8,info:"A serum that permanently enhances many aspects of a human's capabilities, including strength, speed, immune system performance, and mitochondrial efficiency. The serum was originally developed by the Chinese military in an attempt to create super soldiers.

This augmentation:
Increases all of the player's combat stats by 7%.
Increases the player's Bladeburner stamina gain rate by 5%.
",strength_mult:1.07,defense_mult:1.07,dexterity_mult:1.07,agility_mult:1.07,bladeburner_stamina_gain_mult:1.05,isSpecial:!0});s.addToFactions(["Bladeburners"]),C(s);const l=new r.Augmentation({name:o.AugmentationNames.VangelisVirus,repCost:7500,moneyCost:55e7,info:"A synthetic symbiotic virus that is injected into the human brain tissue. The Vangelis virus heightens the senses and focus of its host, and also enhances its intuition.

This augmentation:
Increases the player's effectiveness in Bladeburner Field Analysis by 10%.
Increases the player's success chance in Bladeburner contracts/operations by 4%.
Increases the player's dexterity experience gain rate by 10%.",dexterity_exp_mult:1.1,bladeburner_analysis_mult:1.1,bladeburner_success_chance_mult:1.04,isSpecial:!0});l.addToFactions(["Bladeburners"]),C(l);const c=new r.Augmentation({name:o.AugmentationNames.VangelisVirus3,repCost:15e3,moneyCost:22e8,info:"An improved version of Vangelis, a synthetic symbiotic virus that is injected into the human brain tissue. On top of the benefits of the original virus, this also grants an accelerated healing factor and enhanced agility/reflexes.

This augmentation:
Increases the player's effectiveness in Bladeburner Field Analysis by 15%.
Increases the player's defense and dexterity experience gain rate by 10%.
Increases the player's success chance in Bladeburner contracts/operations by 5%.",prereqs:[o.AugmentationNames.VangelisVirus],defense_exp_mult:1.1,dexterity_exp_mult:1.1,bladeburner_analysis_mult:1.15,bladeburner_success_chance_mult:1.05,isSpecial:!0});c.addToFactions(["Bladeburners"]),C(c);const u=new r.Augmentation({name:o.AugmentationNames.INTERLINKED,repCost:1e4,moneyCost:11e8,info:"The DNA is genetically modified to enhance the human's body extracellular matrix (ECM). This improves the ECM's ability to structurally support the body and grants heightened strength and durability.

This augmentation:
Increases the player's experience gain rate for all combat stats by 5%.
Increases the player's Bladeburner max stamina by 10%.",strength_exp_mult:1.05,defense_exp_mult:1.05,dexterity_exp_mult:1.05,agility_exp_mult:1.05,bladeburner_max_stamina_mult:1.1,isSpecial:!0});u.addToFactions(["Bladeburners"]),C(u);const m=new r.Augmentation({name:o.AugmentationNames.BladeRunner,repCost:8e3,moneyCost:165e7,info:"A cybernetic foot augmentation that was specially created for Bladeburners during the Synthoid Uprising. The organic musculature of the human foot is enhanced with flexible carbon nanotube matrices that are controlled by intelligent servo-motors.

This augmentation:
Increases the player's agility by 5%.
Increases the player's Bladeburner max stamina by 5%.
Increases the player's Bladeburner stamina gain rate by 5%.
",agility_mult:1.05,bladeburner_max_stamina_mult:1.05,bladeburner_stamina_gain_mult:1.05,isSpecial:!0});m.addToFactions(["Bladeburners"]),C(m);const p=new r.Augmentation({name:o.AugmentationNames.BladeArmor,repCost:5e3,moneyCost:275e6,info:"A powered exoskeleton suit (exosuit) designed as armor for Bladeburner units. This exoskeleton is incredibly adaptable and can protect the wearer from blunt, piercing, concussive, thermal, chemical, and electric trauma. It also enhances the user's strength and agility.

This augmentation:
Increases all of the player's combat stats by 4%.
Increases the player's Bladeburner stamina gain rate by 2%.
Increases the player's success chance in Bladeburner contracts/operations by 3%.",strength_mult:1.04,defense_mult:1.04,dexterity_mult:1.04,agility_mult:1.04,bladeburner_stamina_gain_mult:1.02,bladeburner_success_chance_mult:1.03,isSpecial:!0});p.addToFactions(["Bladeburners"]),C(p);const h=new r.Augmentation({name:o.AugmentationNames.BladeArmorPowerCells,repCost:7500,moneyCost:55e7,info:"Upgrades the BLADE-51b Tesla Armor with Ion Power Cells, which are capable of more efficiently storing and using power.

This augmentation:
Increases the player's success chance in Bladeburner contracts/operations by 5%.
Increases the player's Bladeburner stamina gain rate by 2%.
Increases the player's Bladeburner max stamina by 5%.",prereqs:[o.AugmentationNames.BladeArmor],bladeburner_success_chance_mult:1.05,bladeburner_stamina_gain_mult:1.02,bladeburner_max_stamina_mult:1.05,isSpecial:!0});h.addToFactions(["Bladeburners"]),C(h);const d=new r.Augmentation({name:o.AugmentationNames.BladeArmorEnergyShielding,repCost:8500,moneyCost:11e8,info:"Upgrades the BLADE-51b Tesla Armor with a plasma energy propulsion system that is capable of projecting an energy shielding force field.

This augmentation:
Increases the player's defense by 5%.
Increases the player's success chance in Bladeburner contracts/operations by 6%.",prereqs:[o.AugmentationNames.BladeArmor],defense_mult:1.05,bladeburner_success_chance_mult:1.06,isSpecial:!0});d.addToFactions(["Bladeburners"]),C(d);const _=new r.Augmentation({name:o.AugmentationNames.BladeArmorUnibeam,repCost:12500,moneyCost:33e8,info:"Upgrades the BLADE-51b Tesla Armor with a concentrated deuterium-fluoride laser weapon. It's precision an accuracy makes it useful for quickly neutralizing threats while keeping casualties to a minimum.

This augmentation:
Increases the player's success chance in Bladeburner contracts/operations by 8%.",prereqs:[o.AugmentationNames.BladeArmor],bladeburner_success_chance_mult:1.08,isSpecial:!0});_.addToFactions(["Bladeburners"]),C(_);const g=new r.Augmentation({name:o.AugmentationNames.BladeArmorOmnibeam,repCost:25e3,moneyCost:55e8,info:"Upgrades the BLADE-51b Tesla Armor Unibeam augmentation to use multiple-fiber system. The upgraded weapon uses multiple fiber laser modules that combine together to form a single, more powerful beam of up to 2000MW.

This augmentation:
Increases the player's success chance in Bladeburner contracts/operations by 10%.",prereqs:[o.AugmentationNames.BladeArmorUnibeam],bladeburner_success_chance_mult:1.1,isSpecial:!0});g.addToFactions(["Bladeburners"]),C(g);const y=new r.Augmentation({name:o.AugmentationNames.BladeArmorIPU,repCost:6e3,moneyCost:22e7,info:"Upgrades the BLADE-51b Tesla Armor with an AI Information Processing Unit that was specially designed to analyze Synthoid related data and information.

This augmentation:
Increases the player's effectiveness in Bladeburner Field Analysis by 15%.
Increases the player's success chance in Bladeburner contracts/operations by 2%.",prereqs:[o.AugmentationNames.BladeArmor],bladeburner_analysis_mult:1.15,bladeburner_success_chance_mult:1.02,isSpecial:!0});y.addToFactions(["Bladeburners"]),C(y);const f=new r.Augmentation({name:o.AugmentationNames.BladesSimulacrum,repCost:500,moneyCost:3e10,info:"A highly-advanced matter phase-shifter module that is embedded in the brainstem and cerebellum. This augmentation allows the user to project and control a holographic simulacrum within an extremely large radius. These specially-modified holograms were specially weaponized by Bladeburner units to be used against Synthoids.

This augmentation allows you to perform Bladeburner actions and other actions (such as working, commiting crimes, etc.) at the same time.",isSpecial:!0});f.addToFactions(["Bladeburners"]),C(f)}for(var e in ge=Math.pow(c.CONSTANTS.MultipleAugMultiplier,m.Player.queuedAugmentations.length),a.Augmentations)a.Augmentations.hasOwnProperty(e)&&(a.Augmentations[e].baseCost*=ge);m.Player.reapplyAllAugmentations()}function C(e){if(!(e instanceof r.Augmentation))throw new Error("Invalid argument 'newAugObject' passed into resetAugmentation");var t=e.name;S(t)&&delete a.Augmentations[t],v(e)}function P(e,t=!1){a.Augmentations[e.name].owned=!0;const n=a.Augmentations[e.name];for(const e in n.mults)null==m.Player[e]?console.warn(`Augmentation has unrecognized multiplier property: ${e}`):m.Player[e]*=n.mults[e];if(e.name===o.AugmentationNames.NeuroFluxGovernor&&!t){a.Augmentations[e.name].level=e.level;for(let t=0;t"):console.error(`Invalid augmentation: ${m.Player.queuedAugmentations[t].name}`)}m.Player.queuedAugmentations=[],Object(_.dialogBoxCreate)("You slowly drift to sleep as scientists put you under in order to install the following Augmentations:
"+e+"
You wake up in your home...you feel different..."),Object(p.a)()}function S(e){return a.Augmentations.hasOwnProperty(e)}function O(e){d.routing.isOn(d.Page.Augmentations)&&e instanceof HTMLElement&&E.a.render(f.a.createElement(s.AugmentationsRoot,{exportGameFn:h.b.exportGame.bind(h.b),installAugmentationsFn:T}),e)}function M(e){return(e instanceof r.Augmentation?e.name:e)===o.AugmentationNames.NeuroFluxGovernor}},function(module,__webpack_exports__,__webpack_require__){"use strict";(function($){__webpack_require__.d(__webpack_exports__,"b",function(){return postNetburnerText}),__webpack_require__.d(__webpack_exports__,"a",function(){return Terminal});var _Terminal_DirectoryHelpers__WEBPACK_IMPORTED_MODULE_0__=__webpack_require__(74),_Terminal_DirectoryHelpers__WEBPACK_IMPORTED_MODULE_0___default=__webpack_require__.n(_Terminal_DirectoryHelpers__WEBPACK_IMPORTED_MODULE_0__),_Terminal_determineAllPossibilitiesForTabCompletion__WEBPACK_IMPORTED_MODULE_1__=__webpack_require__(274),_Terminal_determineAllPossibilitiesForTabCompletion__WEBPACK_IMPORTED_MODULE_1___default=__webpack_require__.n(_Terminal_determineAllPossibilitiesForTabCompletion__WEBPACK_IMPORTED_MODULE_1__),_Terminal_HelpText__WEBPACK_IMPORTED_MODULE_2__=__webpack_require__(180),_Terminal_HelpText__WEBPACK_IMPORTED_MODULE_2___default=__webpack_require__.n(_Terminal_HelpText__WEBPACK_IMPORTED_MODULE_2__),_Terminal_tabCompletion__WEBPACK_IMPORTED_MODULE_3__=__webpack_require__(273),_Terminal_tabCompletion__WEBPACK_IMPORTED_MODULE_3___default=__webpack_require__.n(_Terminal_tabCompletion__WEBPACK_IMPORTED_MODULE_3__),_Alias__WEBPACK_IMPORTED_MODULE_4__=__webpack_require__(62),_Alias__WEBPACK_IMPORTED_MODULE_4___default=__webpack_require__.n(_Alias__WEBPACK_IMPORTED_MODULE_4__),_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_5__=__webpack_require__(18),_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_5___default=__webpack_require__.n(_BitNode_BitNodeMultipliers__WEBPACK_IMPORTED_MODULE_5__),_CodingContracts__WEBPACK_IMPORTED_MODULE_6__=__webpack_require__(45),_CodingContracts__WEBPACK_IMPORTED_MODULE_6___default=__webpack_require__.n(_CodingContracts__WEBPACK_IMPORTED_MODULE_6__),_Constants__WEBPACK_IMPORTED_MODULE_7__=__webpack_require__(6),_Constants__WEBPACK_IMPORTED_MODULE_7___default=__webpack_require__.n(_Constants__WEBPACK_IMPORTED_MODULE_7__),_Programs_Programs__WEBPACK_IMPORTED_MODULE_8__=__webpack_require__(31),_Programs_Programs__WEBPACK_IMPORTED_MODULE_8___default=__webpack_require__.n(_Programs_Programs__WEBPACK_IMPORTED_MODULE_8__),_DarkWeb_DarkWeb__WEBPACK_IMPORTED_MODULE_9__=__webpack_require__(208),_DarkWeb_DarkWebItems__WEBPACK_IMPORTED_MODULE_10__=__webpack_require__(97),_DarkWeb_DarkWebItems__WEBPACK_IMPORTED_MODULE_10___default=__webpack_require__.n(_DarkWeb_DarkWebItems__WEBPACK_IMPORTED_MODULE_10__),_engine__WEBPACK_IMPORTED_MODULE_11__=__webpack_require__(12),_Fconf_Fconf__WEBPACK_IMPORTED_MODULE_12__=__webpack_require__(125),_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__=__webpack_require__(33),_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13___default=__webpack_require__.n(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__),_Hacking__WEBPACK_IMPORTED_MODULE_14__=__webpack_require__(54),_Hacknet_HacknetServer__WEBPACK_IMPORTED_MODULE_15__=__webpack_require__(32),_Hacknet_HacknetServer__WEBPACK_IMPORTED_MODULE_15___default=__webpack_require__.n(_Hacknet_HacknetServer__WEBPACK_IMPORTED_MODULE_15__),_InteractiveTutorial__WEBPACK_IMPORTED_MODULE_16__=__webpack_require__(38),_Literature__WEBPACK_IMPORTED_MODULE_17__=__webpack_require__(127),_Message_Message__WEBPACK_IMPORTED_MODULE_18__=__webpack_require__(64),_Message_Message__WEBPACK_IMPORTED_MODULE_18___default=__webpack_require__.n(_Message_Message__WEBPACK_IMPORTED_MODULE_18__),_Message_MessageHelpers__WEBPACK_IMPORTED_MODULE_19__=__webpack_require__(66),_NetscriptWorker__WEBPACK_IMPORTED_MODULE_20__=__webpack_require__(57),_Netscript_killWorkerScript__WEBPACK_IMPORTED_MODULE_21__=__webpack_require__(65),_Netscript_killWorkerScript__WEBPACK_IMPORTED_MODULE_21___default=__webpack_require__.n(_Netscript_killWorkerScript__WEBPACK_IMPORTED_MODULE_21__),_Netscript_WorkerScriptStartStopEventEmitter__WEBPACK_IMPORTED_MODULE_22__=__webpack_require__(100),_Netscript_WorkerScriptStartStopEventEmitter__WEBPACK_IMPORTED_MODULE_22___default=__webpack_require__.n(_Netscript_WorkerScriptStartStopEventEmitter__WEBPACK_IMPORTED_MODULE_22__),_Player__WEBPACK_IMPORTED_MODULE_23__=__webpack_require__(0),_RedPill__WEBPACK_IMPORTED_MODULE_24__=__webpack_require__(78),_Script_RunningScript__WEBPACK_IMPORTED_MODULE_25__=__webpack_require__(113),_Script_RunningScript__WEBPACK_IMPORTED_MODULE_25___default=__webpack_require__.n(_Script_RunningScript__WEBPACK_IMPORTED_MODULE_25__),_Script_RunningScriptHelpers__WEBPACK_IMPORTED_MODULE_26__=__webpack_require__(170),_Script_RunningScriptHelpers__WEBPACK_IMPORTED_MODULE_26___default=__webpack_require__.n(_Script_RunningScriptHelpers__WEBPACK_IMPORTED_MODULE_26__),_Script_ScriptHelpers__WEBPACK_IMPORTED_MODULE_27__=__webpack_require__(71),_Script_ScriptHelpersTS__WEBPACK_IMPORTED_MODULE_28__=__webpack_require__(60),_Script_ScriptHelpersTS__WEBPACK_IMPORTED_MODULE_28___default=__webpack_require__.n(_Script_ScriptHelpersTS__WEBPACK_IMPORTED_MODULE_28__),_Server_AllServers__WEBPACK_IMPORTED_MODULE_29__=__webpack_require__(19),_Server_AllServers__WEBPACK_IMPORTED_MODULE_29___default=__webpack_require__.n(_Server_AllServers__WEBPACK_IMPORTED_MODULE_29__),_Server_Server__WEBPACK_IMPORTED_MODULE_30__=__webpack_require__(110),_Server_Server__WEBPACK_IMPORTED_MODULE_30___default=__webpack_require__.n(_Server_Server__WEBPACK_IMPORTED_MODULE_30__),_Server_ServerHelpers__WEBPACK_IMPORTED_MODULE_31__=__webpack_require__(21),_Server_ServerHelpers__WEBPACK_IMPORTED_MODULE_31___default=__webpack_require__.n(_Server_ServerHelpers__WEBPACK_IMPORTED_MODULE_31__),_Settings_Settings__WEBPACK_IMPORTED_MODULE_32__=__webpack_require__(17),_Settings_Settings__WEBPACK_IMPORTED_MODULE_32___default=__webpack_require__.n(_Settings_Settings__WEBPACK_IMPORTED_MODULE_32__),_Server_SpecialServerIps__WEBPACK_IMPORTED_MODULE_33__=__webpack_require__(36),_Server_SpecialServerIps__WEBPACK_IMPORTED_MODULE_33___default=__webpack_require__.n(_Server_SpecialServerIps__WEBPACK_IMPORTED_MODULE_33__),_TextFile__WEBPACK_IMPORTED_MODULE_34__=__webpack_require__(94),_TextFile__WEBPACK_IMPORTED_MODULE_34___default=__webpack_require__.n(_TextFile__WEBPACK_IMPORTED_MODULE_34__),_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_35__=__webpack_require__(63),_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_35___default=__webpack_require__.n(_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_35__),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__=__webpack_require__(11),_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36___default=__webpack_require__.n(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_37__=__webpack_require__(2),_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_37___default=__webpack_require__.n(_ui_numeralFormat__WEBPACK_IMPORTED_MODULE_37__),_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__=__webpack_require__(25),_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38___default=__webpack_require__.n(_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__),_utils_helpers_addOffset__WEBPACK_IMPORTED_MODULE_39__=__webpack_require__(86),_utils_helpers_addOffset__WEBPACK_IMPORTED_MODULE_39___default=__webpack_require__.n(_utils_helpers_addOffset__WEBPACK_IMPORTED_MODULE_39__),_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_40__=__webpack_require__(46),_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_40___default=__webpack_require__.n(_utils_helpers_isString__WEBPACK_IMPORTED_MODULE_40__),_utils_helpers_arrayToString__WEBPACK_IMPORTED_MODULE_41__=__webpack_require__(81),_utils_helpers_arrayToString__WEBPACK_IMPORTED_MODULE_41___default=__webpack_require__.n(_utils_helpers_arrayToString__WEBPACK_IMPORTED_MODULE_41__),_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_42__=__webpack_require__(150),_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_42___default=__webpack_require__.n(_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_42__),_utils_LogBox__WEBPACK_IMPORTED_MODULE_43__=__webpack_require__(104),_utils_LogBox__WEBPACK_IMPORTED_MODULE_43___default=__webpack_require__.n(_utils_LogBox__WEBPACK_IMPORTED_MODULE_43__),_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_44__=__webpack_require__(43),_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_44___default=__webpack_require__.n(_utils_YesNoBox__WEBPACK_IMPORTED_MODULE_44__),_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_45__=__webpack_require__(5),_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_45___default=__webpack_require__.n(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_45__),autosize__WEBPACK_IMPORTED_MODULE_46__=__webpack_require__(272),autosize__WEBPACK_IMPORTED_MODULE_46___default=__webpack_require__.n(autosize__WEBPACK_IMPORTED_MODULE_46__),jszip__WEBPACK_IMPORTED_MODULE_47__=__webpack_require__(271),jszip__WEBPACK_IMPORTED_MODULE_47___default=__webpack_require__.n(jszip__WEBPACK_IMPORTED_MODULE_47__),file_saver__WEBPACK_IMPORTED_MODULE_48__=__webpack_require__(270),file_saver__WEBPACK_IMPORTED_MODULE_48___default=__webpack_require__.n(file_saver__WEBPACK_IMPORTED_MODULE_48__);function postNetburnerText(){Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_45__.post)("Bitburner v"+_Constants__WEBPACK_IMPORTED_MODULE_7__.CONSTANTS.Version)}function isNumber(e){return"string"==typeof e&&(!isNaN(e)&&!isNaN(parseFloat(e)))}$(document).keydown(function(e){if(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.routing.isOn(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.Page.Terminal)){var t=document.getElementById("terminal-input-text-box");if(null==t||e.ctrlKey||e.shiftKey||Terminal.contractOpen||t.focus(),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.ENTER){e.preventDefault();const n=t.value,r=Terminal.currDir;Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_45__.post)("["+(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_TIMESTAMPS?Object(_utils_helpers_getTimestamp__WEBPACK_IMPORTED_MODULE_42__.getTimestamp)()+" ":"")+_Player__WEBPACK_IMPORTED_MODULE_23__.Player.getCurrentServer().hostname+` ~${r}]> ${n}`),n.length>0&&(Terminal.resetTerminalInput(),Terminal.executeCommands(n))}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.C&&e.ctrlKey&&(_engine__WEBPACK_IMPORTED_MODULE_11__.Engine._actionInProgress?(Object(_ui_postToTerminal__WEBPACK_IMPORTED_MODULE_45__.post)("Cancelling..."),_engine__WEBPACK_IMPORTED_MODULE_11__.Engine._actionInProgress=!1,Terminal.finishAction(!0)):_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_BASH_HOTKEYS&&Terminal.resetTerminalInput()),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.L&&e.ctrlKey&&(e.preventDefault(),Terminal.executeCommand("clear")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.UPARROW||_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.P&&e.ctrlKey){if(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.preventDefault(),null==t)return;var n=Terminal.commandHistoryIndex;if(0==(a=Terminal.commandHistory.length))return;(n<0||n>a)&&(Terminal.commandHistoryIndex=a),0!=n&&--Terminal.commandHistoryIndex;var r=Terminal.commandHistory[Terminal.commandHistoryIndex];t.value=r,Object(_utils_SetTimeoutRef__WEBPACK_IMPORTED_MODULE_35__.setTimeoutRef)(function(){t.selectionStart=t.selectionEnd=1e4},0)}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.DOWNARROW||_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.M&&e.ctrlKey){if(_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_BASH_HOTKEYS&&e.preventDefault(),null==t)return;var a;n=Terminal.commandHistoryIndex;if(0==(a=Terminal.commandHistory.length))return;if((n<0||n>a)&&(Terminal.commandHistoryIndex=a),n==a||n==a-1)Terminal.commandHistoryIndex=a,t.value="";else{++Terminal.commandHistoryIndex;r=Terminal.commandHistory[Terminal.commandHistoryIndex];t.value=r}}if(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.TAB){if(e.preventDefault(),null==t)return;let n=t.value;if(""==n)return;const r=n.lastIndexOf(";");-1!==r&&(n=n.slice(r+1));const a=(n=(n=n.trim()).replace(/\s\s+/g," ")).split(" ");let i=a.length-2;i<-1&&(i=0);const o=Object(_Terminal_determineAllPossibilitiesForTabCompletion__WEBPACK_IMPORTED_MODULE_1__.determineAllPossibilitiesForTabCompletion)(_Player__WEBPACK_IMPORTED_MODULE_23__.Player,n,i,Terminal.currDir);if(0==o.length)return;let s="",l="";if(0==a.length)return;1==a.length?l=a[0]:2==a.length?(l=a[0],s=a[1]):3==a.length?(l=a[0]+" "+a[1],s=a[2]):(s=a.pop(),l=a.join(" ")),Object(_Terminal_tabCompletion__WEBPACK_IMPORTED_MODULE_3__.tabCompletion)(l,s,o),t.focus()}_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.ENABLE_BASH_HOTKEYS&&(e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.A&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("home")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.E&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("end")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.B&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("prevchar")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.B&&e.altKey&&(e.preventDefault(),Terminal.moveTextCursor("prevword")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.F&&e.ctrlKey&&(e.preventDefault(),Terminal.moveTextCursor("nextchar")),e.keyCode===_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.F&&e.altKey&&(e.preventDefault(),Terminal.moveTextCursor("nextword")),e.keyCode!==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.H&&e.keyCode!==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.D||!e.ctrlKey||(Terminal.modifyInput("backspace"),e.preventDefault()))}});let terminalCtrlPressed=!1,shiftKeyPressed=!1;$(document).ready(function(){_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.routing.isOn(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.Page.Terminal)&&$(".terminal-input").focus()}),$(document).keydown(function(e){if(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.routing.isOn(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.Page.Terminal))if(e.which==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.CTRL)terminalCtrlPressed=!0;else if(e.shiftKey)shiftKeyPressed=!0;else if(terminalCtrlPressed||shiftKeyPressed||Terminal.contractOpen);else{var t=document.getElementById("terminal-input-text-box");null!=t&&t.focus(),terminalCtrlPressed=!1,shiftKeyPressed=!1}}),$(document).keyup(function(e){_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.routing.isOn(_ui_navigationTracking__WEBPACK_IMPORTED_MODULE_36__.Page.Terminal)&&(e.which==_utils_helpers_keyCodes__WEBPACK_IMPORTED_MODULE_38__.KEY.CTRL&&(terminalCtrlPressed=!1),e.shiftKey&&(shiftKeyPressed=!1))});let Terminal={hackFlag:!1,analyzeFlag:!1,actionStarted:!1,actionTime:0,commandHistory:[],commandHistoryIndex:0,contractOpen:!1,currDir:"/",resetTerminalInput:function(){const e=Terminal.currDir;_Fconf_FconfSettings__WEBPACK_IMPORTED_MODULE_13__.FconfSettings.WRAP_INPUT?(document.getElementById("terminal-input-td").innerHTML=`
[${_Player__WEBPACK_IMPORTED_MODULE_23__.Player.getCurrentServer().hostname} ~${e}]$
`+'",v.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var xe=s.documentElement,we=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ke=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function Ae(){return!1}function _e(){try{return s.activeElement}catch(e){}}function Se(e,t,n,r,i,o){var s,a;if("object"==typeof t){for(a in"string"!=typeof n&&(r=r||n,n=void 0),t)Se(e,a,n,r,t[a],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ae;else if(!i)return e;return 1===o&&(s=i,(i=function(e){return k().off(e),s.apply(this,arguments)}).guid=s.guid||(s.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}k.event={global:{},add:function(e,t,n,r,i){var o,s,a,l,u,c,h,d,f,p,g,m=Z.get(e);if(m)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(xe,i),n.guid||(n.guid=k.guid++),(l=m.events)||(l=m.events={}),(s=m.handle)||(s=m.handle=function(t){return void 0!==k&&k.event.triggered!==t.type?k.event.dispatch.apply(e,arguments):void 0}),u=(t=(t||"").match(j)||[""]).length;u--;)f=g=(a=ke.exec(t[u])||[])[1],p=(a[2]||"").split(".").sort(),f&&(h=k.event.special[f]||{},f=(i?h.delegateType:h.bindType)||f,h=k.event.special[f]||{},c=k.extend({type:f,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:p.join(".")},o),(d=l[f])||((d=l[f]=[]).delegateCount=0,h.setup&&!1!==h.setup.call(e,r,p,s)||e.addEventListener&&e.addEventListener(f,s)),h.add&&(h.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,c):d.push(c),k.event.global[f]=!0)},remove:function(e,t,n,r,i){var o,s,a,l,u,c,h,d,f,p,g,m=Z.hasData(e)&&Z.get(e);if(m&&(l=m.events)){for(u=(t=(t||"").match(j)||[""]).length;u--;)if(f=g=(a=ke.exec(t[u])||[])[1],p=(a[2]||"").split(".").sort(),f){for(h=k.event.special[f]||{},d=l[f=(r?h.delegateType:h.bindType)||f]||[],a=a[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),s=o=d.length;o--;)c=d[o],!i&&g!==c.origType||n&&n.guid!==c.guid||a&&!a.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(d.splice(o,1),c.selector&&d.delegateCount--,h.remove&&h.remove.call(e,c));s&&!d.length&&(h.teardown&&!1!==h.teardown.call(e,p,m.handle)||k.removeEvent(e,f,m.handle),delete l[f])}else for(f in l)k.event.remove(e,f+t[u],n,r,!0);k.isEmptyObject(l)&&Z.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,s,a=k.event.fix(e),l=new Array(arguments.length),u=(Z.get(this,"events")||{})[a.type]||[],c=k.event.special[a.type]||{};for(l[0]=a,t=1;t=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==e.type||!0!==u.disabled)){for(o=[],s={},n=0;n-1:k.find(i,this,null,[u]).length),s[i]&&o.push(r);o.length&&a.push({elem:u,handlers:o})}return u=this,l\x20\t\r\n\f]*)[^>]*)\/>/gi,De=/\s*$/g;function Be(e,t){return T(e,"table")&&T(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Me(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Pe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Re(e,t){var n,r,i,o,s,a,l,u;if(1===t.nodeType){if(Z.hasData(e)&&(o=Z.access(e),s=Z.set(t,o),u=o.events))for(i in delete s.handle,s.events={},u)for(n=0,r=u[i].length;n1&&"string"==typeof p&&!v.checkClone&&Te.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),Ie(o,t,n,r)});if(d&&(o=(i=be(t,e[0].ownerDocument,!1,e,r)).firstChild,1===i.childNodes.length&&(i=o),o||r)){for(a=(s=k.map(me(i,"script"),Me)).length;h")},clone:function(e,t,n){var r,i,o,s,a=e.cloneNode(!0),l=k.contains(e.ownerDocument,e);if(!(v.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(s=me(a),r=0,i=(o=me(e)).length;r0&&ve(s,!l&&me(e,"script")),a},cleanData:function(e){for(var t,n,r,i=k.event.special,o=0;void 0!==(n=e[o]);o++)if(X(n)){if(t=n[Z.expando]){if(t.events)for(r in t.events)i[r]?k.event.remove(n,r):k.removeEvent(n,r,t.handle);n[Z.expando]=void 0}n[J.expando]&&(n[J.expando]=void 0)}}}),k.fn.extend({detach:function(e){return je(this,e,!0)},remove:function(e){return je(this,e)},text:function(e){return U(this,function(e){return void 0===e?k.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Ie(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Be(this,e).appendChild(e)})},prepend:function(){return Ie(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Be(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Ie(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(k.cleanData(me(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return k.clone(this,e,t)})},html:function(e){return U(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!De.test(e)&&!ge[(fe.exec(e)||["",""])[1].toLowerCase()]){e=k.htmlPrefilter(e);try{for(;n=0&&(l+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-l-a-.5))),l}function Je(e,t,n){var r=$e(e),i=ze(e,t,r),o="border-box"===k.css(e,"boxSizing",!1,r),s=o;if(Ne.test(i)){if(!n)return i;i="auto"}return s=s&&(v.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===k.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],s=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),s,r,i)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}k.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=ze(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,s,a=Y(t),l=Ue.test(t),u=e.style;if(l||(t=Xe(a)),s=k.cssHooks[t]||k.cssHooks[a],void 0===n)return s&&"get"in s&&void 0!==(i=s.get(e,!1,r))?i:u[t];"string"===(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=le(e,t,i),o="number"),null!=n&&n==n&&("number"===o&&(n+=i&&i[3]||(k.cssNumber[a]?"":"px")),v.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),s&&"set"in s&&void 0===(n=s.set(e,n,r))||(l?u.setProperty(t,n):u[t]=n))}},css:function(e,t,n,r){var i,o,s,a=Y(t);return Ue.test(t)||(t=Xe(a)),(s=k.cssHooks[t]||k.cssHooks[a])&&"get"in s&&(i=s.get(e,!0,n)),void 0===i&&(i=ze(e,t,r)),"normal"===i&&t in Ke&&(i=Ke[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),k.each(["height","width"],function(e,t){k.cssHooks[t]={get:function(e,n,r){if(n)return!Ve.test(k.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,t,r):ae(e,Ge,function(){return Je(e,t,r)})},set:function(e,n,r){var i,o=$e(e),s="border-box"===k.css(e,"boxSizing",!1,o),a=r&&Ze(e,t,r,s,o);return s&&v.scrollboxSize()===o.position&&(a-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),a&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=k.css(e,t)),Qe(0,n,a)}}}),k.cssHooks.marginLeft=He(v.reliableMarginLeft,function(e,t){if(t)return(parseFloat(ze(e,"marginLeft"))||e.getBoundingClientRect().left-ae(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),k.each({margin:"",padding:"",border:"Width"},function(e,t){k.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(k.cssHooks[e+t].set=Qe)}),k.fn.extend({css:function(e,t){return U(this,function(e,t,n){var r,i,o={},s=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;s1)}}),k.Tween=et,et.prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||k.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(k.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=k.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}},et.prototype.init.prototype=et.prototype,et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=k.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){k.fx.step[e.prop]?k.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[k.cssProps[e.prop]]&&!k.cssHooks[e.prop]?e.elem[e.prop]=e.now:k.style(e.elem,e.prop,e.now+e.unit)}}},et.propHooks.scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},k.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},k.fx=et.prototype.init,k.fx.step={};var tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){nt&&(!1===s.hidden&&n.requestAnimationFrame?n.requestAnimationFrame(ot):n.setTimeout(ot,k.fx.interval),k.fx.tick())}function st(){return n.setTimeout(function(){tt=void 0}),tt=Date.now()}function at(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(ut.tweeners[t]||[]).concat(ut.tweeners["*"]),o=0,s=i.length;o1)},removeAttr:function(e){return this.each(function(){k.removeAttr(this,e)})}}),k.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return void 0===e.getAttribute?k.prop(e,t,n):(1===o&&k.isXMLDoc(e)||(i=k.attrHooks[t.toLowerCase()]||(k.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void k.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=k.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!v.radioValue&&"radio"===t&&T(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(j);if(i&&1===e.nodeType)for(;n=i[r++];)e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?k.removeAttr(e,n):e.setAttribute(n,n),n}},k.each(k.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||k.find.attr;ht[t]=function(e,t,r){var i,o,s=t.toLowerCase();return r||(o=ht[s],ht[s]=i,i=null!=n(e,t,r)?s:null,ht[s]=o),i}});var dt=/^(?:input|select|textarea|button)$/i,ft=/^(?:a|area)$/i;function pt(e){return(e.match(j)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(j)||[]}k.fn.extend({prop:function(e,t){return U(this,k.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[k.propFix[e]||e]})}}),k.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&k.isXMLDoc(e)||(t=k.propFix[t]||t,i=k.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=k.find.attr(e,"tabindex");return t?parseInt(t,10):dt.test(e.nodeName)||ft.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),v.optSelected||(k.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),k.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){k.propFix[this.toLowerCase()]=this}),k.fn.extend({addClass:function(e){var t,n,r,i,o,s,a,l=0;if(y(e))return this.each(function(t){k(this).addClass(e.call(this,t,gt(this)))});if((t=mt(e)).length)for(;n=this[l++];)if(i=gt(n),r=1===n.nodeType&&" "+pt(i)+" "){for(s=0;o=t[s++];)r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(a=pt(r))&&n.setAttribute("class",a)}return this},removeClass:function(e){var t,n,r,i,o,s,a,l=0;if(y(e))return this.each(function(t){k(this).removeClass(e.call(this,t,gt(this)))});if(!arguments.length)return this.attr("class","");if((t=mt(e)).length)for(;n=this[l++];)if(i=gt(n),r=1===n.nodeType&&" "+pt(i)+" "){for(s=0;o=t[s++];)for(;r.indexOf(" "+o+" ")>-1;)r=r.replace(" "+o+" "," ");i!==(a=pt(r))&&n.setAttribute("class",a)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):y(e)?this.each(function(n){k(this).toggleClass(e.call(this,n,gt(this),t),t)}):this.each(function(){var t,i,o,s;if(r)for(i=0,o=k(this),s=mt(e);t=s[i++];)o.hasClass(t)?o.removeClass(t):o.addClass(t);else void 0!==e&&"boolean"!==n||((t=gt(this))&&Z.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":Z.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;for(t=" "+e+" ";n=this[r++];)if(1===n.nodeType&&(" "+pt(gt(n))+" ").indexOf(t)>-1)return!0;return!1}});var vt=/\r/g;k.fn.extend({val:function(e){var t,n,r,i=this[0];return arguments.length?(r=y(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,k(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=k.map(i,function(e){return null==e?"":e+""})),(t=k.valHooks[this.type]||k.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))})):i?(t=k.valHooks[i.type]||k.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(vt,""):null==n?"":n:void 0}}),k.extend({valHooks:{option:{get:function(e){var t=k.find.attr(e,"value");return null!=t?t:pt(k.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,s="select-one"===e.type,a=s?null:[],l=s?o+1:i.length;for(r=o<0?l:s?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),k.each(["radio","checkbox"],function(){k.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=k.inArray(k(e).val(),t)>-1}},v.checkOn||(k.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),v.focusin="onfocusin"in n;var yt=/^(?:focusinfocus|focusoutblur)$/,bt=function(e){e.stopPropagation()};k.extend(k.event,{trigger:function(e,t,r,i){var o,a,l,u,c,h,d,f,g=[r||s],m=p.call(e,"type")?e.type:e,v=p.call(e,"namespace")?e.namespace.split("."):[];if(a=f=l=r=r||s,3!==r.nodeType&&8!==r.nodeType&&!yt.test(m+k.event.triggered)&&(m.indexOf(".")>-1&&(m=(v=m.split(".")).shift(),v.sort()),c=m.indexOf(":")<0&&"on"+m,(e=e[k.expando]?e:new k.Event(m,"object"==typeof e&&e)).isTrigger=i?2:3,e.namespace=v.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+v.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=r),t=null==t?[e]:k.makeArray(t,[e]),d=k.event.special[m]||{},i||!d.trigger||!1!==d.trigger.apply(r,t))){if(!i&&!d.noBubble&&!b(r)){for(u=d.delegateType||m,yt.test(u+m)||(a=a.parentNode);a;a=a.parentNode)g.push(a),l=a;l===(r.ownerDocument||s)&&g.push(l.defaultView||l.parentWindow||n)}for(o=0;(a=g[o++])&&!e.isPropagationStopped();)f=a,e.type=o>1?u:d.bindType||m,(h=(Z.get(a,"events")||{})[e.type]&&Z.get(a,"handle"))&&h.apply(a,t),(h=c&&a[c])&&h.apply&&X(a)&&(e.result=h.apply(a,t),!1===e.result&&e.preventDefault());return e.type=m,i||e.isDefaultPrevented()||d._default&&!1!==d._default.apply(g.pop(),t)||!X(r)||c&&y(r[m])&&!b(r)&&((l=r[c])&&(r[c]=null),k.event.triggered=m,e.isPropagationStopped()&&f.addEventListener(m,bt),r[m](),e.isPropagationStopped()&&f.removeEventListener(m,bt),k.event.triggered=void 0,l&&(r[c]=l)),e.result}},simulate:function(e,t,n){var r=k.extend(new k.Event,n,{type:e,isSimulated:!0});k.event.trigger(r,null,t)}}),k.fn.extend({trigger:function(e,t){return this.each(function(){k.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return k.event.trigger(e,t,n,!0)}}),v.focusin||k.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){k.event.simulate(t,e.target,k.event.fix(e))};k.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=Z.access(r,t);i||r.addEventListener(e,n,!0),Z.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=Z.access(r,t)-1;i?Z.access(r,t,i):(r.removeEventListener(e,n,!0),Z.remove(r,t))}}});var xt=n.location,wt=Date.now(),Ct=/\?/;k.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new n.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||k.error("Invalid XML: "+e),t};var kt=/\[\]$/,Et=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,_t=/^(?:input|select|textarea|keygen)/i;function St(e,t,n,r){var i;if(Array.isArray(t))k.each(t,function(t,i){n||kt.test(e)?r(e,i):St(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==C(t))r(e,t);else for(i in t)St(e+"["+i+"]",t[i],n,r)}k.param=function(e,t){var n,r=[],i=function(e,t){var n=y(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!k.isPlainObject(e))k.each(e,function(){i(this.name,this.value)});else for(n in e)St(n,e[n],t,i);return r.join("&")},k.fn.extend({serialize:function(){return k.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=k.prop(this,"elements");return e?k.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!k(this).is(":disabled")&&_t.test(this.nodeName)&&!At.test(e)&&(this.checked||!de.test(e))}).map(function(e,t){var n=k(this).val();return null==n?null:Array.isArray(n)?k.map(n,function(e){return{name:t.name,value:e.replace(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}});var Ft=/%20/g,Dt=/#.*$/,Tt=/([?&])_=[^&]*/,Lt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Bt=/^(?:GET|HEAD)$/,Mt=/^\/\//,Pt={},Rt={},Ot="*/".concat("*"),It=s.createElement("a");function jt(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(j)||[];if(y(n))for(;r=o[i++];)"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function Nt(e,t,n,r){var i={},o=e===Rt;function s(a){var l;return i[a]=!0,k.each(e[a]||[],function(e,a){var u=a(t,n,r);return"string"!=typeof u||o||i[u]?o?!(l=u):void 0:(t.dataTypes.unshift(u),s(u),!1)}),l}return s(t.dataTypes[0])||!i["*"]&&s("*")}function $t(e,t){var n,r,i=k.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&k.extend(!0,e,r),e}It.href=xt.href,k.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:xt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(xt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Ot,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":k.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,k.ajaxSettings),t):$t(k.ajaxSettings,e)},ajaxPrefilter:jt(Pt),ajaxTransport:jt(Rt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var r,i,o,a,l,u,c,h,d,f,p=k.ajaxSetup({},t),g=p.context||p,m=p.context&&(g.nodeType||g.jquery)?k(g):k.event,v=k.Deferred(),y=k.Callbacks("once memory"),b=p.statusCode||{},x={},w={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!a)for(a={};t=Lt.exec(o);)a[t[1].toLowerCase()]=t[2];t=a[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?o:null},setRequestHeader:function(e,t){return null==c&&(e=w[e.toLowerCase()]=w[e.toLowerCase()]||e,x[e]=t),this},overrideMimeType:function(e){return null==c&&(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)b[t]=[b[t],e[t]];return this},abort:function(e){var t=e||C;return r&&r.abort(t),A(0,t),this}};if(v.promise(E),p.url=((e||p.url||xt.href)+"").replace(Mt,xt.protocol+"//"),p.type=t.method||t.type||p.method||p.type,p.dataTypes=(p.dataType||"*").toLowerCase().match(j)||[""],null==p.crossDomain){u=s.createElement("a");try{u.href=p.url,u.href=u.href,p.crossDomain=It.protocol+"//"+It.host!=u.protocol+"//"+u.host}catch(e){p.crossDomain=!0}}if(p.data&&p.processData&&"string"!=typeof p.data&&(p.data=k.param(p.data,p.traditional)),Nt(Pt,p,t,E),c)return E;for(d in(h=k.event&&p.global)&&0==k.active++&&k.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Bt.test(p.type),i=p.url.replace(Dt,""),p.hasContent?p.data&&p.processData&&0===(p.contentType||"").indexOf("application/x-www-form-urlencoded")&&(p.data=p.data.replace(Ft,"+")):(f=p.url.slice(i.length),p.data&&(p.processData||"string"==typeof p.data)&&(i+=(Ct.test(i)?"&":"?")+p.data,delete p.data),!1===p.cache&&(i=i.replace(Tt,"$1"),f=(Ct.test(i)?"&":"?")+"_="+wt+++f),p.url=i+f),p.ifModified&&(k.lastModified[i]&&E.setRequestHeader("If-Modified-Since",k.lastModified[i]),k.etag[i]&&E.setRequestHeader("If-None-Match",k.etag[i])),(p.data&&p.hasContent&&!1!==p.contentType||t.contentType)&&E.setRequestHeader("Content-Type",p.contentType),E.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Ot+"; q=0.01":""):p.accepts["*"]),p.headers)E.setRequestHeader(d,p.headers[d]);if(p.beforeSend&&(!1===p.beforeSend.call(g,E,p)||c))return E.abort();if(C="abort",y.add(p.complete),E.done(p.success),E.fail(p.error),r=Nt(Rt,p,t,E)){if(E.readyState=1,h&&m.trigger("ajaxSend",[E,p]),c)return E;p.async&&p.timeout>0&&(l=n.setTimeout(function(){E.abort("timeout")},p.timeout));try{c=!1,r.send(x,A)}catch(e){if(c)throw e;A(-1,e)}}else A(-1,"No Transport");function A(e,t,s,a){var u,d,f,x,w,C=t;c||(c=!0,l&&n.clearTimeout(l),r=void 0,o=a||"",E.readyState=e>0?4:0,u=e>=200&&e<300||304===e,s&&(x=function(e,t,n){for(var r,i,o,s,a=e.contents,l=e.dataTypes;"*"===l[0];)l.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in a)if(a[i]&&a[i].test(r)){l.unshift(i);break}if(l[0]in n)o=l[0];else{for(i in n){if(!l[0]||e.converters[i+" "+l[0]]){o=i;break}s||(s=i)}o=o||s}if(o)return o!==l[0]&&l.unshift(o),n[o]}(p,E,s)),x=function(e,t,n,r){var i,o,s,a,l,u={},c=e.dataTypes.slice();if(c[1])for(s in e.converters)u[s.toLowerCase()]=e.converters[s];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!l&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),l=o,o=c.shift())if("*"===o)o=l;else if("*"!==l&&l!==o){if(!(s=u[l+" "+o]||u["* "+o]))for(i in u)if((a=i.split(" "))[1]===o&&(s=u[l+" "+a[0]]||u["* "+a[0]])){!0===s?s=u[i]:!0!==u[i]&&(o=a[0],c.unshift(a[1]));break}if(!0!==s)if(s&&e.throws)t=s(t);else try{t=s(t)}catch(e){return{state:"parsererror",error:s?e:"No conversion from "+l+" to "+o}}}return{state:"success",data:t}}(p,x,E,u),u?(p.ifModified&&((w=E.getResponseHeader("Last-Modified"))&&(k.lastModified[i]=w),(w=E.getResponseHeader("etag"))&&(k.etag[i]=w)),204===e||"HEAD"===p.type?C="nocontent":304===e?C="notmodified":(C=x.state,d=x.data,u=!(f=x.error))):(f=C,!e&&C||(C="error",e<0&&(e=0))),E.status=e,E.statusText=(t||C)+"",u?v.resolveWith(g,[d,C,E]):v.rejectWith(g,[E,C,f]),E.statusCode(b),b=void 0,h&&m.trigger(u?"ajaxSuccess":"ajaxError",[E,p,u?d:f]),y.fireWith(g,[E,C]),h&&(m.trigger("ajaxComplete",[E,p]),--k.active||k.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return k.get(e,t,n,"json")},getScript:function(e,t){return k.get(e,void 0,t,"script")}}),k.each(["get","post"],function(e,t){k[t]=function(e,n,r,i){return y(n)&&(i=i||r,r=n,n=void 0),k.ajax(k.extend({url:e,type:t,dataType:i,data:n,success:r},k.isPlainObject(e)&&e))}}),k._evalUrl=function(e){return k.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},k.fn.extend({wrapAll:function(e){var t;return this[0]&&(y(e)&&(e=e.call(this[0])),t=k(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstElementChild;)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return y(e)?this.each(function(t){k(this).wrapInner(e.call(this,t))}):this.each(function(){var t=k(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=y(e);return this.each(function(n){k(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){k(this).replaceWith(this.childNodes)}),this}}),k.expr.pseudos.hidden=function(e){return!k.expr.pseudos.visible(e)},k.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},k.ajaxSettings.xhr=function(){try{return new n.XMLHttpRequest}catch(e){}};var Wt={0:200,1223:204},zt=k.ajaxSettings.xhr();v.cors=!!zt&&"withCredentials"in zt,v.ajax=zt=!!zt,k.ajaxTransport(function(e){var t,r;if(v.cors||zt&&!e.crossDomain)return{send:function(i,o){var s,a=e.xhr();if(a.open(e.type,e.url,e.async,e.username,e.password),e.xhrFields)for(s in e.xhrFields)a[s]=e.xhrFields[s];for(s in e.mimeType&&a.overrideMimeType&&a.overrideMimeType(e.mimeType),e.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest"),i)a.setRequestHeader(s,i[s]);t=function(e){return function(){t&&(t=r=a.onload=a.onerror=a.onabort=a.ontimeout=a.onreadystatechange=null,"abort"===e?a.abort():"error"===e?"number"!=typeof a.status?o(0,"error"):o(a.status,a.statusText):o(Wt[a.status]||a.status,a.statusText,"text"!==(a.responseType||"text")||"string"!=typeof a.responseText?{binary:a.response}:{text:a.responseText},a.getAllResponseHeaders()))}},a.onload=t(),r=a.onerror=a.ontimeout=t("error"),void 0!==a.onabort?a.onabort=r:a.onreadystatechange=function(){4===a.readyState&&n.setTimeout(function(){t&&r()})},t=t("abort");try{a.send(e.hasContent&&e.data||null)}catch(e){if(t)throw e}},abort:function(){t&&t()}}}),k.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),k.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return k.globalEval(e),e}}}),k.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),k.ajaxTransport("script",function(e){var t,n;if(e.crossDomain)return{send:function(r,i){t=k("