git branch -d wget-netscritMerge branch 'dev' of https://github.com/danielyxie/bitburner into dev

This commit is contained in:
danielyxie 2018-10-17 21:46:36 -05:00
commit 703b3a646e
25 changed files with 880 additions and 650 deletions

File diff suppressed because one or more lines are too long

100
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -3,6 +3,13 @@
Changelog Changelog
========= =========
v0.40.5 - 10/09/2018
--------------------
* Added codingcontract.getContractType() Netscript function
* Bug Fix: codingcontract.getData() Netscript function now returns arrays by value rather than reference
* Bug Fix: Decreased highest possible data value for 'Find Largest Prime Factor' Coding Contract (to avoid hangs when solving it)
* Bug Fix: Fixed a bug that caused game to freeze during Coding Contract generation
v0.40.4 - 9/29/2018 v0.40.4 - 9/29/2018
------------------- -------------------
* Added new Coding Contracts mechanic. Solve programming problems to earn rewards * Added new Coding Contracts mechanic. Solve programming problems to earn rewards

@ -31,6 +31,20 @@ attempt
:returns: Boolean indicating whether the solution was correct :returns: Boolean indicating whether the solution was correct
getContractType
---------------
.. 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
getDescription getDescription
-------------- --------------

@ -13,6 +13,7 @@ hack
:param string hostname/ip: IP or hostname of the target server to hack :param string hostname/ip: IP or hostname of the target server to hack
:returns: The amount of money stolen if the hack is successful, and zero otherwise :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 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 on your hacking level and the target server's security level. In order to hack a server you must first gain root access
@ -35,6 +36,7 @@ grow
:param string hostname/ip: IP or hostname of the target server to grow :param string hostname/ip: IP or hostname of the target server to grow
:returns: The number by which the money on the server was multiplied for the growth :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 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 level and the target server's security level. When grow() completes, the money available on a target server will be increased by a
@ -57,6 +59,7 @@ weaken
:param string hostname.ip: IP or hostname of the target server to weaken :param string hostname.ip: IP or hostname of the target server to weaken
:returns: The amount by which the target server's security level was decreased. This is equivalent to 0.05 multiplied :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 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 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 depends on your hacking level and the target server's security level. This function lowers the security level of the target
@ -75,6 +78,7 @@ sleep
.. js:function:: sleep(n) .. js:function:: sleep(n)
:param number n: Number of milliseconds to sleep :param number n: Number of milliseconds to sleep
:RAM cost: 0 GB
Suspends the script for n milliseconds. Suspends the script for n milliseconds.
@ -84,6 +88,7 @@ print
.. js:function:: print(x) .. js:function:: print(x)
:param x: Value to be printed :param x: Value to be printed
:RAM cost: 0 GB
Prints a value or a variable to the script's logs. Prints a value or a variable to the script's logs.
@ -93,6 +98,7 @@ tprint
.. js:function:: tprint(x) .. js:function:: tprint(x)
:param x: Value to be printed :param x: Value to be printed
:RAM cost: 0 GB
Prints a value or a variable to the Terminal Prints a value or a variable to the Terminal
@ -101,6 +107,8 @@ clearLog
.. js:function:: clearLog() .. js:function:: clearLog()
:RAM cost: 0 GB
Clears the script's logs Clears the script's logs
disableLog disableLog
@ -109,6 +117,7 @@ disableLog
.. js:function:: disableLog(fn) .. js:function:: disableLog(fn)
:param string fn: Name of function for which to disable logging :param string fn: Name of function for which to disable logging
:RAM cost: 0 GB
Disables logging for the given function. Logging can be disabled for Disables logging for the given function. Logging can be disabled for
all functions by passing 'ALL' as the argument. all functions by passing 'ALL' as the argument.
@ -125,6 +134,7 @@ enableLog
.. js:function:: enableLog(fn) .. js:function:: enableLog(fn)
:param string fn: Name of function for which to enable logging :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 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') as an argument, then it will revert the effects of disableLog('ALL')
@ -135,6 +145,7 @@ isLogEnabled
.. js:function:: isLogEnabled(fn) .. js:function:: isLogEnabled(fn)
:param string fn: Name of function to check :param string fn: Name of function to check
:RAM cost: 0 GB
Returns a boolean indicating whether or not logging is enabled for that Returns a boolean indicating whether or not logging is enabled for that
function (or 'ALL') function (or 'ALL')
@ -144,6 +155,8 @@ getScriptLogs
.. js:function:: getScriptLogs() .. js:function:: getScriptLogs()
:RAM cost: 0 GB
Returns the script's logs. The logs are returned as an array, where each Returns the 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 line is an element in the array. The most recently logged line is at the
end of the array. end of the array.
@ -158,6 +171,7 @@ scan
:param string hostname/ip: IP or hostname of the server to scan :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) :param boolean: Optional boolean specifying whether the function should output hostnames (if true) or IP addresses (if false)
:RAM cost: 0.2 GB
Returns an array containing the hostnames or IPs of all servers that are one node way from the specified target server. The 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. hostnames/IPs in the returned array are strings.
@ -168,6 +182,7 @@ nuke
.. js:function:: nuke(hostname/ip) .. js:function:: nuke(hostname/ip)
:param string hostname/ip: IP or hostname of the target server :param string hostname/ip: IP or hostname of the target server
:RAM cost: 0 GB
Runs the NUKE.exe program on the target server. NUKE.exe must exist on your home computer. Runs the NUKE.exe program on the target server. NUKE.exe must exist on your home computer.
@ -181,6 +196,7 @@ brutessh
.. js:function:: brutessh(hostname/ip) .. js:function:: brutessh(hostname/ip)
:param string hostname/ip: IP or hostname of the target server :param string hostname/ip: IP or hostname of the target server
:RAM cost: 0 GB
Runs the BruteSSH.exe program on the target server. BruteSSH.exe must exist on your home computer. Runs the BruteSSH.exe program on the target server. BruteSSH.exe must exist on your home computer.
@ -194,6 +210,7 @@ ftpcrack
.. js:function:: ftpcrack(hostname/ip) .. js:function:: ftpcrack(hostname/ip)
:param string hostname/ip: IP or hostname of the target server :param string hostname/ip: IP or hostname of the target server
:RAM cost: 0 GB
Runs the FTPCrack.exe program on the target server. FTPCrack.exe must exist on your home computer. Runs the FTPCrack.exe program on the target server. FTPCrack.exe must exist on your home computer.
@ -207,6 +224,7 @@ relaysmtp
.. js:function:: relaysmtp(hostname/ip) .. js:function:: relaysmtp(hostname/ip)
:param string hostname/ip: IP or hostname of the target server :param string hostname/ip: IP or hostname of the target server
:RAM cost: 0 GB
Runs the relaySMTP.exe program on the target server. relaySMTP.exe must exist on your home computer. Runs the relaySMTP.exe program on the target server. relaySMTP.exe must exist on your home computer.
@ -220,6 +238,7 @@ httpworm
.. js:function:: httpworm(hostname/ip) .. js:function:: httpworm(hostname/ip)
:param string hostname/ip: IP or hostname of the target server :param string hostname/ip: IP or hostname of the target server
:RAM cost: 0 GB
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.
@ -233,6 +252,7 @@ sqlinject
.. js:function:: sqlinject(hostname/ip) .. js:function:: sqlinject(hostname/ip)
:param string hostname/ip: IP or hostname of the target server :param string hostname/ip: IP or hostname of the target server
:RAM cost: 0 GB
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.
@ -250,6 +270,7 @@ run
:param args...: :param args...:
Additional arguments to pass into the new script that is being run. Note that if any arguments are being 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. passed into the new script, then the second argument *numThreads* must be filled in with a value.
:RAM cost: 1 GB
Run a script as a separate process. This function can only be used to run scripts located on the current server (the server 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). running the script that calls this function).
@ -282,6 +303,7 @@ exec
:param args...: :param args...:
Additional arguments to pass into the new script that is being run. Note that if any arguments are being 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. 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 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. that it can be used to run a script on any server, instead of just the current server.
@ -311,6 +333,7 @@ spawn
: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...: :param args...:
Additional arguments to pass into the new script that is being run. 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 20 seconds it will execute the newly-specified script. Terminates the current script, and then after a delay of about 20 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. The purpose of this function is to execute a new script without being constrained by the RAM usage of the current one.
@ -330,6 +353,7 @@ kill
:param string script: Filename of the script to kill :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 string hostname/ip: IP or hostname of the server on which to kill the script
:param args...: Arguments to identify which script to kill :param args...: Arguments to identify which script to kill
:RAM cost: 0.5 GB
Kills the script on the target server specified by the script's name and arguments. Remember that scripts 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 are uniquely identified by both their name and arguments. For example, if *foo.script* is run with the argument 1, then this
@ -357,6 +381,7 @@ killall
.. js:function:: killall(hostname/ip) .. js:function:: killall(hostname/ip)
:param string hostname/ip: IP or hostname of the server on which to kill all scripts :param string hostname/ip: IP or hostname of the server on which to kill all scripts
:RAM cost: 0.5 GB
Kills all running scripts on the specified server. This function returns true if any scripts were killed, and 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. false otherwise. In other words, it will return true if there are any scripts running on the target server.
@ -367,6 +392,8 @@ exit
.. js:function:: exit() .. js:function:: exit()
:RAM cost: 0 GB
Terminates the current script immediately Terminates the current script immediately
scp scp
@ -379,6 +406,7 @@ scp
Hostname or IP of the source server, which is the server from which the file will be copied. Hostname or IP 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. 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. :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
Copies a script or literature (.lit) file(s) to another server. The *files* argument can be either a string specifying a 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. single file to copy, or an array of strings specifying multiple files to copy.
@ -405,6 +433,7 @@ ls
:param string hostname/ip: Hostname or IP of the target server :param string hostname/ip: Hostname or IP of the target server
:param string grep: a substring to search for in the filename :param string grep: a substring to search for in the filename
:RAM cost: 0 GB
Returns an array with the filenames of all files on the specified server (as strings). The returned array Returns an array with the filenames of all files on the specified server (as strings). The returned array
is sorted in alphabetic order is sorted in alphabetic order
@ -416,6 +445,7 @@ ps
:param string ip: Hostname or IP address of the target server. :param string ip: Hostname or IP address of the target server.
If not specified, it will be the current server's IP by default If not specified, it will be the current server's IP by default
:RAM cost: 0 GB
Returns an array with general information about all scripts running on the specified 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 target server. The information for each server is given in an object with
@ -443,6 +473,7 @@ hasRootAccess
.. js:function:: hasRootAccess(hostname/ip) .. js:function:: hasRootAccess(hostname/ip)
:param string hostname/ip: Hostname or IP of the target server :param string hostname/ip: Hostname or IP of the target server
:RAM cost: 0.05 GB
Returns a boolean indicating whether or not the player has root access to the specified target server. Returns a boolean indicating whether or not the player has root access to the specified target server.
@ -457,6 +488,8 @@ getHostname
.. js:function:: getHostname() .. js:function:: getHostname()
:RAM cost: 0.05 GB
Returns a string with the hostname of the server that the script is running on Returns a string with the hostname of the server that the script is running on
getHackingLevel getHackingLevel
@ -464,6 +497,8 @@ getHackingLevel
.. js:function:: getHackingLevel() .. js:function:: getHackingLevel()
:RAM cost: 0.05 GB
Returns the player's current hacking level Returns the player's current hacking level
getHackingMultipliers getHackingMultipliers
@ -471,6 +506,8 @@ getHackingMultipliers
.. js:function:: getHackingMultipliers() .. js:function:: getHackingMultipliers()
:RAM cost: 4 GB
Returns an object containing the Player's hacking related multipliers. These multipliers are Returns an object containing the Player's hacking related multipliers. These multipliers are
returned in fractional forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: returned in fractional forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure::
@ -492,6 +529,8 @@ getHacknetMultipliers
.. js:function:: getHacknetMultipliers() .. js:function:: getHacknetMultipliers()
:RAM cost: 4 GB
Returns an object containing the Player's hacknet related multipliers. These multipliers are Returns an object containing the Player's hacknet related multipliers. These multipliers are
returned in fractional forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure:: returned in fractional forms, not percentages (e.g. 1.5 instead of 150%). The object has the following structure::
@ -517,6 +556,7 @@ getServerMoneyAvailable
.. js:function:: getServerMoneyAvailable(hostname/ip) .. js:function:: getServerMoneyAvailable(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the amount of money available on a server. **Running this function on the home computer will return Returns the amount of money available on a server. **Running this function on the home computer will return
the player's money.** the player's money.**
@ -532,6 +572,7 @@ getServerMaxMoney
.. js:function:: getServerMaxMoney(hostname/ip) .. js:function:: getServerMaxMoney(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the maximum amount of money that can be available on a server Returns the maximum amount of money that can be available on a server
@ -541,6 +582,7 @@ getServerGrowth
.. js:function:: getServerGrowth(hostname/ip) .. js:function:: getServerGrowth(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the server's instrinsic "growth parameter". This growth parameter is a number 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 between 1 and 100 that represents how quickly the server's money grows. This parameter affects the
@ -553,6 +595,7 @@ getServerSecurityLevel
.. js:function:: getServerSecurityLevel(hostname/ip) .. js:function:: getServerSecurityLevel(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the security level of the target server. A server's security level is denoted by a number, typically 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). between 1 and 100 (but it can go above 100).
@ -563,6 +606,7 @@ getServerBaseSecurityLevel
.. js:function:: getServerBaseSecurityLevel(hostname/ip) .. js:function:: getServerBaseSecurityLevel(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the base security level of the target server. This is the security level that the server starts out with. 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 This is different than *getServerSecurityLevel()* because *getServerSecurityLevel()* returns the current
@ -575,6 +619,7 @@ getServerMinSecurityLevel
.. js:function:: getServerMinSecurityLevel(hostname/ip) .. js:function:: getServerMinSecurityLevel(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the minimum security level of the target server Returns the minimum security level of the target server
@ -584,6 +629,7 @@ getServerRequiredHackingLevel
.. js:function:: getServerRequiredHackingLevel(hostname/ip) .. js:function:: getServerRequiredHackingLevel(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns the required hacking level of the target server Returns the required hacking level of the target server
@ -593,6 +639,7 @@ getServerNumPortsRequired
.. js:function:: getServerNumPortsRequired(hostname/ip) .. js:function:: getServerNumPortsRequired(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
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.
@ -602,6 +649,7 @@ getServerRam
.. js:function:: getServerRam(hostname/ip) .. js:function:: getServerRam(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns an array with two elements that gives information about a server's memory (RAM). The first 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 element in the array is the amount of RAM that the server has total (in GB). The second element in
@ -619,6 +667,7 @@ serverExists
.. js:function:: serverExists(hostname/ip) .. js:function:: serverExists(hostname/ip)
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 0.1 GB
Returns a boolean denoting whether or not the specified server exists Returns a boolean denoting whether or not the specified server exists
@ -631,6 +680,7 @@ fileExists
:param string hostname/ip: :param string hostname/ip:
Hostname or IP of target server. This is optional. If it is not specified then the 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 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 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")* for scripts is case-sensitive, but for other types of files it is not. For example, *fileExists("brutessh.exe")*
@ -655,6 +705,7 @@ isRunning
:param string filename: Filename of script to check. This is case-sensitive. :param string filename: Filename of script to check. This is case-sensitive.
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:param args...: Arguments to specify/identify which scripts to search for :param args...: Arguments to specify/identify which scripts to search for
:RAM cost: 0.1 GB
Returns a boolean indicating whether the specified script is running on the target server. Remember that a script is 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. uniquely identified by both its name and its arguments.
@ -681,6 +732,8 @@ getNextHacknetNodeCost
.. js:function:: getNextHacknetNodeCost() .. js:function:: getNextHacknetNodeCost()
:RAM cost: 0 GB
Deprecated (no longer usable). See :doc:`netscripthacknetnodeapi` Deprecated (no longer usable). See :doc:`netscripthacknetnodeapi`
purchaseHacknetNode purchaseHacknetNode
@ -688,6 +741,8 @@ purchaseHacknetNode
.. js:function:: purchaseHacknetNode() .. js:function:: purchaseHacknetNode()
:RAM cost: 0 GB
Deprecated (no longer usable). See :doc:`netscripthacknetnodeapi` Deprecated (no longer usable). See :doc:`netscripthacknetnodeapi`
getPurchasedServerCost getPurchasedServerCost
@ -695,6 +750,8 @@ getPurchasedServerCost
.. js:function:: getPurchasedServerCost(ram) .. js:function:: getPurchasedServerCost(ram)
: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) :param number ram: Amount of RAM of a potential purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20)
Returns the cost to purchase a server with the specified amount of *ram*. Returns the cost to purchase a server with the specified amount of *ram*.
@ -712,6 +769,7 @@ purchaseServer
:param string hostname: Hostname of the purchased server :param string hostname: Hostname of the purchased server
:param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20) :param number ram: Amount of RAM of the purchased server. Must be a power of 2 (2, 4, 8, 16, etc.). Maximum value of 1048576 (2^20)
:RAM cost: 2.25 GB
Purchased a server with the specified hostname and amount of RAM. Purchased a server with the specified hostname and amount of RAM.
@ -741,6 +799,7 @@ deleteServer
.. js:function:: deleteServer(hostname) .. js:function:: deleteServer(hostname)
:param string hostname: Hostname of the server to delete :param string hostname: Hostname of the server to delete
:RAM cost: 2.25 GB
Deletes one of your purchased servers, which is specified by its hostname. Deletes one of your purchased servers, which is specified by its hostname.
@ -757,6 +816,7 @@ getPurchasedServers
:param boolean hostname: :param boolean hostname:
Specifies whether hostnames or IP addresses should be returned. If it's true then hostnames will be returned, and if false 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 then IPs will be returned. If this argument is omitted then it is true by default
:RAM cost: 2.25 GB
Returns an array with either the hostnames or IPs 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.
@ -765,6 +825,8 @@ getPurchasedServerLimit
.. js:function:: getPurchasedServerLimit() .. 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
getPurchasedServerMaxRam getPurchasedServerMaxRam
@ -772,6 +834,8 @@ getPurchasedServerMaxRam
.. js:function:: getPurchasedServerMaxRam() .. 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
write write
@ -782,6 +846,7 @@ write
:param string/number port/fn: Port or text file/script that will be written to :param string/number port/fn: Port or text file/script that will be written to
:param string data: Data to write :param string data: Data to write
:param string mode: Defines the write mode. Only valid when writing to text files or scripts. :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) This function can be used to either write data to a port, a text file (.txt), or a script (.script, .js, .ns)
@ -802,6 +867,7 @@ tryWrite
:param number port: Port to be written to :param number port: Port to be written to
:param string data: Data to try to write :param string data: Data to try to write
:returns: True if the data is successfully written to the port, and false otherwise :returns: True if the data is successfully written to the port, and false otherwise
:RAM cost: 1 GB
Attempts to write data to the specified Netscript Port. If the port is full, the data will 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 not be written. Otherwise, the data will be written normally
@ -812,6 +878,7 @@ read
.. js:function:: read(port/fn) .. js:function:: read(port/fn)
:param string/number port/fn: Port or text file to read from :param string/number port/fn: Port or text file to read from
:RAM cost: 1 GB
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)
@ -828,6 +895,7 @@ peek
.. js:function:: peek(port) .. js:function:: peek(port)
:param number port: Port to peek. Must be an integer between 1 and 20 :param number port: Port to peek. Must be an integer between 1 and 20
:RAM cost: 1 GB
This function is used to peek at the data from a port. It returns the first element in the specified 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. without removing that element. If the port is empty, the string "NULL PORT DATA" will be returned.
@ -840,6 +908,7 @@ clear
.. js:function:: clear(port/fn) .. js:function:: clear(port/fn)
:param string/number port/fn: Port or text file to clear :param string/number port/fn: Port or text file to clear
:RAM cost: 1 GB
This function is used to clear data in a `Netscript Ports <http://bitburner.wikia.com/wiki/Netscript_Ports>`_ or a text file. This function is used to clear data in a `Netscript Ports <http://bitburner.wikia.com/wiki/Netscript_Ports>`_ or a text file.
@ -853,6 +922,7 @@ getPortHandle
.. js:function:: getPortHandle(port) .. js:function:: getPortHandle(port)
:param number port: Port number :param number port: Port number
:RAM cost: 10 GB
Get a handle to a Netscript Port. See more details here: :ref:`netscript_ports` Get a handle to a Netscript Port. See more details here: :ref:`netscript_ports`
@ -865,6 +935,7 @@ rm
:param string fn: Filename of file to remove. Must include the extension :param string fn: Filename of file to remove. Must include the extension
:returns: True if it successfully deletes the file, and false otherwise :returns: True if it successfully deletes the file, and false otherwise
:RAM cost: 1 GB
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 message (.msg) files.
@ -875,6 +946,7 @@ scriptRunning
:param string scriptname: Filename of script to check. This is case-sensitive. :param string scriptname: Filename of script to check. This is case-sensitive.
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 1 GB
Returns a boolean indicating whether any instance of the specified script is running on the target server, regardless of Returns a boolean indicating whether any instance of the specified script is running on the target server, regardless of
its arguments. its arguments.
@ -899,6 +971,7 @@ scriptKill
:param string scriptname: Filename of script to kill. This is case-sensitive. :param string scriptname: Filename of script to kill. This is case-sensitive.
:param string hostname/ip: Hostname or IP of target server :param string hostname/ip: Hostname or IP of target server
:RAM cost: 1 GB
Kills all scripts with the specified filename on the target server specified by *hostname/ip*, regardless of arguments. Returns 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. true if one or more scripts were successfully killed, and false if none were.
@ -908,6 +981,8 @@ getScriptName
.. js:function:: getScriptName() .. js:function:: getScriptName()
:RAM cost: 0 GB
Returns the current script name Returns the current script name
getScriptRam getScriptRam
@ -917,6 +992,7 @@ getScriptRam
:param string scriptname: Filename of script. This is case-sensitive. :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 se the current server as the target server. :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 se the current server as the target server.
:RAM cost: 0.1 GB
Returns the amount of RAM required to run the specified script on the target server. Returns Returns the amount of RAM required to run the specified script on the target server. Returns
0 if the script does not exist. 0 if the script does not exist.
@ -928,6 +1004,7 @@ getHackTime
:param string hostname/ip: Hostname or IP of target server :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 :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 *hack()* Netscript function on the target server. Returns the amount of time in seconds it takes to execute the *hack()* Netscript function on the target server.
@ -941,6 +1018,7 @@ getGrowTime
:param string hostname/ip: Hostname or IP of target server :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 :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. Returns the amount of time in seconds it takes to execute the *grow()* Netscript function on the target server.
@ -954,6 +1032,7 @@ getWeakenTime
:param string hostname/ip: Hostname or IP of target server :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 :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. Returns the amount of time in seconds it takes to execute the *weaken()* Netscript function on the target server.
@ -968,6 +1047,7 @@ getScriptIncome
:param string scriptname: Filename of script :param string scriptname: Filename of script
:param string hostname/ip: Server on which script is running :param string hostname/ip: Server on which script is running
:param args...: Arguments that the script is running with :param args...: Arguments that the script is running with
:RAM cost: 0.1 GB
Returns the amount of income the specified script generates while online (when the game is open, does not apply for offline income). 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 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
@ -986,6 +1066,7 @@ getScriptExpGain
:param string scriptname: Filename of script :param string scriptname: Filename of script
:param string hostname/ip: Server on which script is running :param string hostname/ip: Server on which script is running
:param args...: Arguments that the script is running with :param args...: Arguments that the script is running with
:RAM cost: 0.1 GB
Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for offline experience gains). 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. Remember that a script is uniquely identified by both its name and its arguments.
@ -997,6 +1078,8 @@ getTimeSinceLastAug
.. js:function:: getTimeSinceLastAug() .. js:function:: getTimeSinceLastAug()
:RAM cost: 0.05 GB
Returns the amount of time in milliseconds that have passed since you last installed Augmentations Returns the amount of time in milliseconds that have passed since you last installed Augmentations
sprintf sprintf
@ -1004,6 +1087,8 @@ sprintf
.. js:function:: sprintf() .. js:function:: sprintf()
:RAM cost: 0 GB
See `this link <https://github.com/alexei/sprintf.js>`_ for details. See `this link <https://github.com/alexei/sprintf.js>`_ for details.
vsprintf vsprintf
@ -1011,6 +1096,8 @@ vsprintf
.. js:function:: vsprintf() .. js:function:: vsprintf()
:RAM cost: 0 GB
See `this link <https://github.com/alexei/sprintf.js>`_ for details. See `this link <https://github.com/alexei/sprintf.js>`_ for details.
prompt prompt
@ -1019,6 +1106,7 @@ prompt
.. js:function:: prompt(txt) .. js:function:: prompt(txt)
:param string txt: Text to appear in the prompt dialog box :param string txt: Text to appear in the prompt dialog box
:RAM cost: 0 GB
Prompts the player with a dialog box with two options: "Yes" and "No". This function will return true if the player click "Yes" and 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. false if the player clicks "No". The script's execution is halted until the player selects one of the options.
@ -1031,6 +1119,7 @@ wget
:param string url: URL to pull data from :param string url: URL to pull data from
:param string target: Filename to write data to. Must be script or text file :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. :param string ip: Optional hostname/ip of server for target file.
:RAM cost: 0 GB
Retrieves data from a URL and downloads it to a file on the specified server. The data can only 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, be downloaded to a script (.script, .ns, .js) or a text file (.txt). If the file already exists,
@ -1057,4 +1146,6 @@ wget
getFavorToDonate getFavorToDonate
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
:RAM cost: 0.1 GB
Returns the amount of Faction favor required to be able to donate to a faction. Returns the amount of Faction favor required to be able to donate to a faction.

@ -14,7 +14,7 @@ You can use the Singularity Functions in other BitNodes if and only if you have
Source-File 4 will open up additional Singularity Functions that you can use in other BitNodes. If your Source-File 4 is upgraded all the way to Source-File 4 will open up additional Singularity Functions that you can use in other BitNodes. If your Source-File 4 is upgraded all the way to
level 3, then you will be able to access all of the Singularity Functions. level 3, then you will be able to access all of the Singularity Functions.
Note that Singularity Functions require a lot of RAM outside of BitNode-4 (their RAM costs are multiplied by 10 if you are not in BitNode-4) Note that Singularity Functions require twice as much RAM outside of BitNode-4
universityCourse universityCourse
---------------- ----------------

@ -486,58 +486,6 @@
<p id="tutorial-text"> </p> <p id="tutorial-text"> </p>
</div> </div>
<!-- dev menu -->
<div id="dev-menu-container" class="generic-menupage-container">
<p id="dev-menu-text">If you see this menu you can pretty much break the game. It's recommended that you use this menu only to setup a save file appropriate to test a new feature or bug fix.</p>
<p id="dev-menu-text">Generic</p>
<a id="dev-need-money" class="a-link-button">Add $1000t</a>
<a id="dev-need-ram" class="a-link-button">Double home RAM</a>
<p id="dev-menu-text">Augmentation related: </p>
<!-- gets populated with the list of all augments -->
<select id="dev-menu-aug-dropdown" class="dropdown"></select>
<a id="dev-add-aug" class="a-link-button tooltip">Queue Augmentation<span class="tooltiptext">May require save + reload</span></a>
<input id="dev-sf-n" type="number" class="text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<p id="dev-menu-text">Faction related: </p>
<select id="dev-menu-faction-dropdown" class="dropdown"></select>
<a id="dev-add-faction" class="a-link-button tooltip">Receive invite<span class="tooltiptext">May require save + reload</span></a>
<p id="dev-menu-text">Program related: </p>
<select id="dev-menu-connect-dropdown" class="dropdown"></select>
<a id="dev-connect" class="a-link-button tooltip">Connect<span class="tooltiptext">Connect to the target server.</span></a>
<select id="dev-menu-add-program-dropdown" class="dropdown"></select>
<a id="dev-add-program" class="a-link-button tooltip">Add Program<span class="tooltiptext">Add this program to the player home server, won't add the same program twice.</span></a>
<a id="dev-bit-flume" class="a-link-button tooltip">Trigger BitFlume<span class="tooltiptext">Quick escape to change BN, does not give SFs</span></a>
<p id="dev-menu-text">Server related: </p>
<a id="dev-open-all" class="a-link-button tooltip">NUKE + ports all servers<span class="tooltiptext">Opens all ports, nukes all servers, gains root access to everything (still need the appropriate hacking level)</span></a>
<a id="dev-min-security" class="a-link-button tooltip">minimize all servers security<span class="tooltiptext">All servers security will be set to their minimum security</span></a>
<a id="dev-max-money" class="a-link-button tooltip">maximize all servers money<span class="tooltiptext">Set all servers available money to maximum for that server</span></a>
<p id="dev-menu-text">Exp/stats related: </p>
<input id="dev-hacking-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-hacking" class="a-link-button tooltip">add hacking exp<span class="tooltiptext">Add that many hacking experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-strength-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-strength" class="a-link-button tooltip">add strength exp<span class="tooltiptext">Add that many strength experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-defense-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-defense" class="a-link-button tooltip">add defense exp<span class="tooltiptext">Add that many defense experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-dexterity-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-dexterity" class="a-link-button tooltip">add dexterity exp<span class="tooltiptext">Add that many dexterity experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-agility-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-agility" class="a-link-button tooltip">add agility exp<span class="tooltiptext">Add that many agility experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-charisma-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-charisma" class="a-link-button tooltip">add charisma exp<span class="tooltiptext">Add that many charisma experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-intelligence-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-intelligence" class="a-link-button tooltip">add intelligence exp<span class="tooltiptext">Add that many intelligence experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<a id="dev-enable-intelligence" class="a-link-button tooltip"> enable intelligence<span class="tooltiptext">Enables the intelligence stat</span></a>
<a id="dev-disable-intelligence" class="a-link-button tooltip"> disable intelligence<span class="tooltiptext">Disables the intelligence stat</span></a>
</div>
<!-- Location (visiting a location in World) --> <!-- Location (visiting a location in World) -->
<div id="location-container" class="generic-menupage-container"> <div id="location-container" class="generic-menupage-container">
<a id="location-return-to-world-button" class="a-link-button"> Return to World </a> <a id="location-return-to-world-button" class="a-link-button"> Return to World </a>

@ -92,8 +92,9 @@ let NetscriptFunctions =
"installAugmentations|" + "installAugmentations|" +
// TIX API // TIX API
"getStockPrice|getStockPosition|getStockSymbols|buyStock|sellStock|shortStock|sellShort|" + "getStockPrice|getStockPosition|getStockSymbols|buyStock|sellStock|" +
"placeOrder|cancelOrder|" + "shortStock|sellShort|" +
"placeOrder|cancelOrder|getStockVolatility|getStockForecast|" +
// Hacknet Node API // Hacknet Node API
"hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" + "hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" +
@ -112,7 +113,8 @@ let NetscriptFunctions =
"getCityChaos|switchCity|getStamina|joinBladeburnerFaction|getBonusTime|" + "getCityChaos|switchCity|getStamina|joinBladeburnerFaction|getBonusTime|" +
// Coding Contract API // Coding Contract API
"codingcontract|attempt|getData|getDescription|getNumTriesRemaining"; "codingcontract|attempt|getContractType|getData|getDescription|" +
"getNumTriesRemaining";
var NetscriptHighlightRules = function(options) { var NetscriptHighlightRules = function(options) {
var keywordMapper = this.createKeywordMapper({ var keywordMapper = this.createKeywordMapper({

@ -1,8 +1,7 @@
import {BitNodeMultipliers} from "./BitNodeMultipliers"; import {BitNodeMultipliers} from "./BitNodeMultipliers";
import {CONSTANTS} from "./Constants"; import {CONSTANTS} from "./Constants";
import {Engine} from "./engine"; import {Engine} from "./engine";
import {Factions, getNextNeurofluxLevel, import {Factions, factionExists} from "./Faction";
factionExists} from "./Faction";
import {hasBladeburnerSF} from "./NetscriptFunctions"; import {hasBladeburnerSF} from "./NetscriptFunctions";
import {addWorkerScript} from "./NetscriptWorker"; import {addWorkerScript} from "./NetscriptWorker";
import {Player} from "./Player"; import {Player} from "./Player";
@ -1029,9 +1028,25 @@ function initAugmentations() {
"This is a special augmentation because it can be leveled up infinitely. Each level of this augmentation " + "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%." "increases ALL of the player's multipliers by 1%."
}); });
var nextLevel = getNextNeurofluxLevel();
NeuroFluxGovernor.level = nextLevel - 1; // Set the Augmentation's level to the currently-installed level
mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, NeuroFluxGovernor.level); let currLevel = 0;
for (let i = 0; i < Player.augmentations.length; ++i) {
if (Player.augmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
currLevel = Player.augmentations[i].level;
}
}
NeuroFluxGovernor.level = currLevel;
// To set the price/rep req of the NeuroFlux, we have to take into account NeuroFlux
// levels that are purchased but not yet installed
let nextLevel = currLevel;
for (let i = 0; i < Player.queuedAugmentations.length; ++i) {
if (Player.queuedAugmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
++nextLevel;
}
}
mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
NeuroFluxGovernor.baseRepRequirement = 500 * mult * CONSTANTS.AugmentationRepMultiplier * BitNodeMultipliers.AugmentationRepCost; NeuroFluxGovernor.baseRepRequirement = 500 * mult * CONSTANTS.AugmentationRepMultiplier * BitNodeMultipliers.AugmentationRepCost;
NeuroFluxGovernor.baseCost = 750e3 * mult * CONSTANTS.AugmentationCostMultiplier * BitNodeMultipliers.AugmentationMoneyCost; NeuroFluxGovernor.baseCost = 750e3 * mult * CONSTANTS.AugmentationCostMultiplier * BitNodeMultipliers.AugmentationMoneyCost;
if (augmentationExists(AugmentationNames.NeuroFluxGovernor)) { if (augmentationExists(AugmentationNames.NeuroFluxGovernor)) {
@ -2380,7 +2395,7 @@ function applyAugmentation(aug, reapply=false) {
return; return;
} }
if (aug.name == AugmentationNames.NeuroFluxGovernor) { if (aug.name === AugmentationNames.NeuroFluxGovernor) {
for (var i = 0; i < Player.augmentations.length; ++i) { for (var i = 0; i < Player.augmentations.length; ++i) {
if (Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor) { if (Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
//Already have this aug, just upgrade the level //Already have this aug, just upgrade the level

@ -3335,6 +3335,38 @@ Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript
return false; return false;
} }
// Special logic for Black Ops
if (actionId.type === ActionTypes["BlackOp"]) {
// 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`);
return false;
}
// Can't start a BlackOp if you haven't done the one before it
var blackops = [];
for (const nm in BlackOperations) {
if (BlackOperations.hasOwnProperty(nm)) {
blackops.push(nm);
}
}
blackops.sort(function(a, b) {
return (BlackOperations[a].reqdRank - BlackOperations[b].reqdRank); // Sort black ops in intended order
});
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");
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`);
return false;
}
}
try { try {
this.startAction(actionId); this.startAction(actionId);
if (workerScript.shouldLog("startAction")) { if (workerScript.shouldLog("startAction")) {
@ -3436,9 +3468,14 @@ Bladeburner.prototype.getActionCountRemainingNetscriptFn = function(type, name,
switch (actionId.type) { switch (actionId.type) {
case ActionTypes["Contract"]: case ActionTypes["Contract"]:
case ActionTypes["Operation"]: case ActionTypes["Operation"]:
return actionObj.count;
case ActionTypes["BlackOp"]: case ActionTypes["BlackOp"]:
case ActionTypes["BlackOperation"]: case ActionTypes["BlackOperation"]:
return actionObj.count; if (this.blackops[name] != null) {
return 0;
} else {
return 1;
}
case ActionTypes["Training"]: case ActionTypes["Training"]:
case ActionTypes["Field Analysis"]: case ActionTypes["Field Analysis"]:
case ActionTypes["FieldAnalysis"]: case ActionTypes["FieldAnalysis"]:

@ -154,6 +154,10 @@ export class CodingContract {
return CodingContractTypes[this.type].numTries; return CodingContractTypes[this.type].numTries;
} }
getType(): string {
return CodingContractTypes[this.type].name;
}
isSolution(solution: string): boolean { isSolution(solution: string): boolean {
return CodingContractTypes[this.type].solver(this.data, solution); return CodingContractTypes[this.type].solver(this.data, solution);
} }

@ -1,5 +1,5 @@
let CONSTANTS = { let CONSTANTS = {
Version: "0.40.4", Version: "0.40.5",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -48,7 +48,7 @@ let CONSTANTS = {
/* Netscript Constants */ /* Netscript Constants */
//RAM Costs for different commands //RAM Costs for different commands
ScriptBaseRamCost: 1.6, ScriptBaseRamCost: 1.6,
ScriptDomRamCost: 100, ScriptDomRamCost: 25,
ScriptWhileRamCost: 0, ScriptWhileRamCost: 0,
ScriptForRamCost: 0, ScriptForRamCost: 0,
ScriptIfRamCost: 0, ScriptIfRamCost: 0,
@ -91,6 +91,8 @@ let CONSTANTS = {
ScriptSingularityFn2RamCost: 2, ScriptSingularityFn2RamCost: 2,
ScriptSingularityFn3RamCost: 3, ScriptSingularityFn3RamCost: 3,
ScriptSingularityFnRamMult: 2, // Multiplier for RAM cost outside of BN-4
ScriptBladeburnerApiBaseRamCost: 4, ScriptBladeburnerApiBaseRamCost: 4,
NumNetscriptPorts: 20, NumNetscriptPorts: 20,
@ -506,18 +508,20 @@ let CONSTANTS = {
LatestUpdate: LatestUpdate:
` `
v0.40.4 v0.41.0
* Added new Coding Contracts mechanic. Solve programming problems to earn rewards * WARNING: In NetscriptJS, defining a function called print() is no longer possible
* The write() and read() Netscript functions now work on scripts * RAM Cost of accessing the global document object lowered from 100 GB to 25 GB
* Added getStockSymbols() Netscript function to the TIX API (by InfraK) * RAM Cost to use Singularity Functions outside of BitNode-4 lowered by 75%. They now only cost twice as much as they do in BitNode-4
* Added wget() Netscript function * b1t_flum3.exe now takes significantly less time to create
* Added bladeburner.getActionRepGain() function to the Netscript Bladeburner API * Improved number formatting for Player 'work' actions (including crimes, etc.). These numbers should also adhere to locale settings now (by Kline-)
* The getLevelUpgradeCost(), getRamUpgradeCost(), and getCoreUpgradeCost() functions in the Hacknet API now return Infinity if the node is at max level. See documentation * Bug Fix: Calling print() in NetscriptJS no longer brings up the print dialog
* It is now possible to use freely use angled bracket (<, >) and create DOM elements using tprint() * Bug Fix: Fixed a bug that sometimes caused a blank black screen when destroying/resetting/switching BitNodes
* The game's theme colors can now be set through the Terminal configuration (.fconf). * Bug Fix: Netscript calls that throw errors will now no longer cause the 'concurrent calls' error if they are caught in the script. i.e. try/catch should now work properly in scripts
* You can now switch to the old left-hand main menu bar through the Terminal configuration (.fconf) * Bug Fix: Fixed a bug where sometimes the NeuroFlux Governor Augmentation level would be incorrectly calculated when the game was loaded
* Bug Fix: grow() percentage is no longer reported as Infinity when a server's money is grown from 0 to X * Bug Fix: Fixed a bug where calling the scp() Netscript function with invalid hostname/ips would throw an unclear error message
* Bug Fix: Infiltration popup now displays the correct amount of exp gained * Bug Fix: Bladeburner API function getActionCountRemaining() should now work properly for BlackOps
* Bug Fix: Black Ops can no longer be attempted out-of-order or without the required rank via Bladeburner API
* RAM cost for basic Netscript functions added to documentation (by CBJamo)
` `
} }

@ -86,7 +86,7 @@ const Programs = {
level: 1, level: 1,
tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)", tooltip:"This program creates a portal to the BitNode Nexus (allows you to restart and switch BitNodes)",
req: function() {return Player.sourceFiles.length > 0 && Player.hacking_skill >= 1}, req: function() {return Player.sourceFiles.length > 0 && Player.hacking_skill >= 1},
time: CONSTANTS.MillisecondsPerFiveMinutes / 5, time: CONSTANTS.MillisecondsPerFiveMinutes / 20,
}), }),
// special because you can't create it. // special because you can't create it.
Flight: new Program("fl1ght.exe"), Flight: new Program("fl1ght.exe"),

395
src/DevMenu.js Normal file

@ -0,0 +1,395 @@
import {AugmentationNames} from "./Augmentations"
import {Programs} from "./CreateProgram"
import {Factions} from "./Faction";
import {Player} from "./Player";
import {AllServers} from "./Server";
import {Terminal} from "./Terminal";
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
import {createElement} from "../utils/uiHelpers/createElement";
import {removeElementById} from "../utils/uiHelpers/removeElementById";
const devMenuContainerId = "dev-menu-container";
export function createDevMenu() {
if (process.env.NODE_ENV !== "development") {
throw new Error("Cannot create Dev Menu because you are not in a dev build");
}
const devMenuText = createElement("h1", {
display: "block",
innerText: "Development Menu - Only meant to be used for testing/debugging",
});
// Generic
const genericHeader = createElement("h2", {
display: "block",
innerText: "Generic"
});
const addMoney = createElement("button", {
class: "std-button",
clickListener: () => {
Player.gainMoney(1e15);
},
display: "block",
innerText: "Add $1000t",
});
const addRam = createElement("button", {
class: "std-button",
clickListener: () => {
Player.getHomeComputer().maxRam *= 2;
},
display: "block",
innerText: "Double Home Computer RAM",
});
const triggerBitflume = createElement("button", {
class: "std-button",
clickListener: () => {
hackWorldDaemon(Player.bitNodeN, true);
},
innerText: "Trigger BitFlume",
});
const destroyCurrentBitnode = createElement("button", {
class: "std-button",
clickListener: () => {
hackWorldDaemon(Player.bitNodeN);
},
innerText: "Destroy Current BitNode",
tooltip: "Will grant Source-File for the BitNode",
})
// Experience / stats
const statsHeader = createElement("h2", {
display: "block",
innerText: "Experience/Stats"
});
const statsHackingExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsHackingExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsHackingExpInput.value);
Player.gainHackingExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsStrengthExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsStrengthExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsStrengthExpInput.value);
Player.gainStrengthExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsDefenseExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsDefenseExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsDefenseExpInput.value);
Player.gainDefenseExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsDexterityExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsDexterityExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsDexterityExpInput.value);
Player.gainDexterityExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsAgilityExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsAgilityExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsAgilityExpButton.value);
Player.gainAgilityExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsCharismaExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsCharismaExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsCharismaExpInput.value);
Player.gainCharismaExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsIntelligenceExpInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "+/- hacking exp",
type: "number",
});
const statsIntelligenceExpButton = createElement("button", {
class: "std-button",
clickListener: () => {
const exp = parseInt(statsIntelligenceExpInput.value);
Player.gainIntelligenceExp(exp);
Player.updateSkillLevels();
},
display: "block",
innerText: "Add Hacking Exp",
});
const statsEnableIntelligenceButton = createElement("button", {
class: "std-button",
clickListener: () => {
Player.intelligence = 1;
},
innerText: "Enable Intelligence"
});
const statsDisableIntelligenceButton = createElement("button", {
class: "std-button",
clickListener: () => {
Player.intelligence = 0;
},
innerText: "Disable Intelligence"
});
// Factions
const factionsHeader = createElement("h2", {innerText: "Factions"});
const factionsDropdown = createElement("select", {class: "dropdown"});
for (const i in Factions) {
factionsDropdown.options[factionsDropdown.options.length] = new Option(Factions[i].name, Factions[i].name);
}
const factionsAddButton = createElement("button", {
class: "std-button",
clickListener: () => {
const facName = factionsDropdown.options[factionsDropdown.selectedIndex].value;
Player.receiveInvite(facName);
},
innerText: "Receive Invite to Faction",
});
// Augmentations / Source Files
const augmentationsHeader = createElement("h2", {innerText: "Augmentations"});
const augmentationsDropdown = createElement("select", {class: "dropdown"});
for (const i in AugmentationNames) {
const augName = AugmentationNames[i];
augmentationsDropdown.options[augmentationsDropdown.options.length] = new Option(augName, augName);
}
const augmentationsQueueButton = createElement("button", {
class: "std-button",
clickListener: () => {
Player.queueAugmentation(augmentationsDropdown.options[augmentationsDropdown.selectedIndex].value);
},
innerText: "Queue Augmentation",
})
// Programs
const programsHeader = createElement("h2", {innerText: "Programs"});
const programsAddDropdown = createElement("select", {class: "dropdown"});
for (const i in Programs) {
const progName = Programs[i].name;
programsAddDropdown.options[programsAddDropdown.options.length] = new Option(progName, progName);
}
const programsAddButton = createElement("button", {
class: "std-button",
clickListener: () => {
const program = programsAddDropdown.options[programsAddDropdown.selectedIndex].value;
if(!Player.hasProgram(program)) {
Player.getHomeComputer().programs.push(program);
}
},
innerText: "Add Program",
})
// Servers
const serversHeader = createElement("h2", {innerText: "Servers"});
const serversOpenAll = createElement("button", {
class: "std-button",
clickListener: () => {
for (const i in AllServers) {
AllServers[i].hasAdminRights = true;
AllServers[i].sshPortOpen = true;
AllServers[i].ftpPortOpen = true;
AllServers[i].smtpPortOpen = true;
AllServers[i].httpPortOpen = true;
AllServers[i].sqlPortOpen = true;
AllServers[i].openPortCount = 5;
}
},
display: "block",
innerText: "Get Admin Rights to all servers",
});
const serversMinSecurityAll = createElement("button", {
class: "std-button",
clickListener: () => {
for (const i in AllServers) {
AllServers[i].hackDifficulty = AllServers[i].minDifficulty;
}
},
display: "block",
innerText: "Set all servers to min security",
});
const serversMaxMoneyAll = createElement("button", {
class: "std-button",
clickListener: () => {
for (const i in AllServers) {
AllServers[i].moneyAvailable = AllServers[i].moneyMax;
}
},
display: "block",
innerText: "Set all servers to max money",
});
const serversConnectToDropdown = createElement("select", {class: "dropdown"});
for (const i in AllServers) {
const hn = AllServers[i].hostname;
serversConnectToDropdown.options[serversConnectToDropdown.options.length] = new Option(hn, hn);
}
const serversConnectToButton = createElement("button", {
class: "std-button",
clickListener: () => {
const host = serversConnectToDropdown.options[serversConnectToDropdown.selectedIndex].value;
Terminal.connectToServer(host);
},
innerText: "Connect to server",
});
// Add everything to container, then append to main menu
const devMenuContainer = createElement("div", {
class: "generic-menupage-container",
id: devMenuContainerId,
});
const bladeburnerHeader = createElement("h2", {innerText: "Bladeburner"});
const bladeburnerGainRankInput = createElement("input", {
class: "text-input",
display: "block",
placeholder: "Rank to gain (or negative to lose rank)",
type: "number",
});
const bladeburnerGainRankButton = createElement("button", {
class: "std-button",
clickListener: () => {
try {
const rank = parseInt(bladeburnerGainRankInput.value);
Player.bladeburner.changeRank(rank);
} catch(e) {
exceptionAlert(`Failed to change Bladeburner Rank in dev menu: ${e}`);
}
},
display: "block",
innerText: "Gain Bladeburner Rank",
})
devMenuContainer.appendChild(devMenuText);
devMenuContainer.appendChild(genericHeader);
devMenuContainer.appendChild(addMoney);
devMenuContainer.appendChild(addRam);
devMenuContainer.appendChild(triggerBitflume);
devMenuContainer.appendChild(destroyCurrentBitnode);
devMenuContainer.appendChild(statsHeader);
devMenuContainer.appendChild(statsHackingExpInput);
devMenuContainer.appendChild(statsHackingExpButton);
devMenuContainer.appendChild(statsStrengthExpInput);
devMenuContainer.appendChild(statsStrengthExpButton);
devMenuContainer.appendChild(statsDefenseExpInput);
devMenuContainer.appendChild(statsDefenseExpButton);
devMenuContainer.appendChild(statsDexterityExpInput);
devMenuContainer.appendChild(statsDexterityExpButton);
devMenuContainer.appendChild(statsAgilityExpInput);
devMenuContainer.appendChild(statsAgilityExpButton);
devMenuContainer.appendChild(statsCharismaExpInput);
devMenuContainer.appendChild(statsCharismaExpButton);
devMenuContainer.appendChild(statsIntelligenceExpInput);
devMenuContainer.appendChild(statsIntelligenceExpButton);
devMenuContainer.appendChild(statsEnableIntelligenceButton);
devMenuContainer.appendChild(statsDisableIntelligenceButton);
devMenuContainer.appendChild(factionsHeader);
devMenuContainer.appendChild(factionsDropdown);
devMenuContainer.appendChild(factionsAddButton);
devMenuContainer.appendChild(augmentationsHeader);
devMenuContainer.appendChild(augmentationsQueueButton);
devMenuContainer.appendChild(programsHeader);
devMenuContainer.appendChild(programsAddDropdown);
devMenuContainer.appendChild(programsAddButton);
devMenuContainer.appendChild(serversHeader);
devMenuContainer.appendChild(serversOpenAll);
devMenuContainer.appendChild(serversMinSecurityAll);
devMenuContainer.appendChild(serversMaxMoneyAll);
devMenuContainer.appendChild(serversConnectToDropdown);
devMenuContainer.appendChild(serversConnectToButton);
devMenuContainer.appendChild(bladeburnerHeader);
devMenuContainer.appendChild(bladeburnerGainRankInput);
devMenuContainer.appendChild(bladeburnerGainRankButton);
const entireGameContainer = document.getElementById("entire-game-container");
if (entireGameContainer == null) {
throw new Error("Could not find entire-game-container DOM element");
}
entireGameContainer.appendChild(devMenuContainer);
}
export function closeDevMenu() {
removeElementById(devMenuContainerId);
}

@ -734,27 +734,21 @@ function purchaseAugmentation(aug, fac, sing=false) {
} }
function getNextNeurofluxLevel() { function getNextNeurofluxLevel() {
var aug = Augmentations[AugmentationNames.NeuroFluxGovernor]; // Get current Neuroflux level based on Player's augmentations
if (aug == null) { let currLevel = 0;
for (var i = 0; i < Player.augmentations.length; ++i) { for (var i = 0; i < Player.augmentations.length; ++i) {
if (Player.augmentations[i].name == AugmentationNames.NeuroFluxGovernor) { if (Player.augmentations[i].name === AugmentationNames.NeuroFluxGovernor) {
aug = Player.augmentations[i]; currLevel = Player.augmentations[i].level;
}
}
if (aug == null) {
console.log("WARNING: Could not find NeuroFlux Governor aug. This is OK if " +
"it happens during the loading/initialization of the game, but probably " +
"indicates something seriously wrong at other times");
return 1;
} }
} }
var nextLevel = aug.level + 1;
// Account for purchased but uninstalled Augmentations
for (var i = 0; i < Player.queuedAugmentations.length; ++i) { for (var i = 0; i < Player.queuedAugmentations.length; ++i) {
if (Player.queuedAugmentations[i].name == AugmentationNames.NeuroFluxGovernor) { if (Player.queuedAugmentations[i].name == AugmentationNames.NeuroFluxGovernor) {
++nextLevel; ++currLevel;
} }
} }
return nextLevel; return currLevel + 1;
} }
function processPassiveFactionRepGain(numCycles) { function processPassiveFactionRepGain(numCycles) {

@ -1811,7 +1811,7 @@ function initLocationButtons() {
yesBtn.innerHTML = "Purchase"; noBtn.innerHTML = "Cancel"; yesBtn.innerHTML = "Purchase"; noBtn.innerHTML = "Cancel";
yesBtn.addEventListener("click", ()=>{ yesBtn.addEventListener("click", ()=>{
if (Player.money.lt(cost)) { if (Player.money.lt(cost)) {
dialogBoxCreate("You do not have enough mone to purchase an additional CPU Core for your home computer!"); dialogBoxCreate("You do not have enough money to purchase an additional CPU Core for your home computer!");
} else { } else {
Player.loseMoney(cost); Player.loseMoney(cost);
Player.getHomeComputer().cpuCores++; Player.getHomeComputer().cpuCores++;

@ -882,12 +882,12 @@ function NetscriptFunctions(workerScript) {
} }
destServer = getServer(ip2); destServer = getServer(ip2);
if (destServer == null) { if (destServer == null) {
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid hostname/ip passed into scp() command: " + ip); throw makeRuntimeRejectMsg(workerScript, `ERROR: Invalid hostname/ip passed into scp() command: ${ip2}`);
} }
currServ = getServer(ip1); currServ = getServer(ip1);
if (currServ == null) { if (currServ == null) {
throw makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer"); throw makeRuntimeRejectMsg(workerScript, `ERROR: Invalid hostname/ip passed into scp() command: ${ip1}`);
} }
} else if (arguments.length === 2) { //scriptname, destination } else if (arguments.length === 2) { //scriptname, destination
if (scriptname === undefined || ip1 === undefined) { if (scriptname === undefined || ip1 === undefined) {
@ -895,7 +895,7 @@ function NetscriptFunctions(workerScript) {
} }
destServer = getServer(ip1); destServer = getServer(ip1);
if (destServer == null) { if (destServer == null) {
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid hostname/ip passed into scp() command: " + ip); throw makeRuntimeRejectMsg(workerScript, `ERROR: Invalid hostname/ip passed into scp() command: ${ip1}`);
} }
currServ = getServer(workerScript.serverIp); currServ = getServer(workerScript.serverIp);
@ -2313,7 +2313,7 @@ function NetscriptFunctions(workerScript) {
/* Singularity Functions */ /* Singularity Functions */
universityCourse : function(universityName, className) { universityCourse : function(universityName, className) {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("universityCourse", ramCost); return updateStaticRam("universityCourse", ramCost);
} }
@ -2402,7 +2402,7 @@ function NetscriptFunctions(workerScript) {
gymWorkout : function(gymName, stat) { gymWorkout : function(gymName, stat) {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("gymWorkout", ramCost); return updateStaticRam("gymWorkout", ramCost);
} }
@ -2504,7 +2504,7 @@ function NetscriptFunctions(workerScript) {
travelToCity(cityname) { travelToCity(cityname) {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("travelToCity", ramCost); return updateStaticRam("travelToCity", ramCost);
} }
@ -2541,7 +2541,7 @@ function NetscriptFunctions(workerScript) {
purchaseTor() { purchaseTor() {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("purchaseTor", ramCost); return updateStaticRam("purchaseTor", ramCost);
} }
@ -2585,7 +2585,7 @@ function NetscriptFunctions(workerScript) {
}, },
purchaseProgram(programName) { purchaseProgram(programName) {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("purchaseProgram", ramCost); return updateStaticRam("purchaseProgram", ramCost);
} }
@ -2637,7 +2637,7 @@ function NetscriptFunctions(workerScript) {
}, },
getStats : function() { getStats : function() {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getStats", ramCost); return updateStaticRam("getStats", ramCost);
} }
@ -2661,7 +2661,7 @@ function NetscriptFunctions(workerScript) {
}, },
getCharacterInformation : function() { getCharacterInformation : function() {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getCharacterInformation", ramCost); return updateStaticRam("getCharacterInformation", ramCost);
} }
@ -2697,7 +2697,7 @@ function NetscriptFunctions(workerScript) {
}, },
isBusy : function() { isBusy : function() {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("isBusy", ramCost); return updateStaticRam("isBusy", ramCost);
} }
@ -2712,7 +2712,7 @@ function NetscriptFunctions(workerScript) {
}, },
stopAction : function() { stopAction : function() {
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 2; var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 2;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("stopAction", ramCost); return updateStaticRam("stopAction", ramCost);
} }
@ -2734,7 +2734,7 @@ function NetscriptFunctions(workerScript) {
}, },
upgradeHomeRam : function() { upgradeHomeRam : function() {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("upgradeHomeRam", ramCost); return updateStaticRam("upgradeHomeRam", ramCost);
} }
@ -2766,7 +2766,7 @@ function NetscriptFunctions(workerScript) {
}, },
getUpgradeHomeRamCost : function() { getUpgradeHomeRamCost : function() {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 2; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 2;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getUpgradeHomeRamCost", ramCost); return updateStaticRam("getUpgradeHomeRamCost", ramCost);
} }
@ -2782,7 +2782,7 @@ function NetscriptFunctions(workerScript) {
}, },
workForCompany : function() { workForCompany : function() {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("workForCompany", ramCost); return updateStaticRam("workForCompany", ramCost);
} }
@ -2823,7 +2823,7 @@ function NetscriptFunctions(workerScript) {
}, },
applyToCompany : function(companyName, field) { applyToCompany : function(companyName, field) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("applyToCompany", ramCost); return updateStaticRam("applyToCompany", ramCost);
} }
@ -2904,7 +2904,7 @@ function NetscriptFunctions(workerScript) {
}, },
getCompanyRep : function(companyName) { getCompanyRep : function(companyName) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 2; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 2;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getCompanyRep", ramCost); return updateStaticRam("getCompanyRep", ramCost);
} }
@ -2925,7 +2925,7 @@ function NetscriptFunctions(workerScript) {
}, },
getCompanyFavor : function(companyName) { getCompanyFavor : function(companyName) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getCompanyFavor", ramCost); return updateStaticRam("getCompanyFavor", ramCost);
} }
@ -2946,7 +2946,7 @@ function NetscriptFunctions(workerScript) {
}, },
getCompanyFavorGain : function(companyName) { getCompanyFavorGain : function(companyName) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getCompanyFavorGain", ramCost); return updateStaticRam("getCompanyFavorGain", ramCost);
} }
@ -2967,7 +2967,7 @@ function NetscriptFunctions(workerScript) {
}, },
checkFactionInvitations : function() { checkFactionInvitations : function() {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("checkFactionInvitations", ramCost); return updateStaticRam("checkFactionInvitations", ramCost);
} }
@ -2983,7 +2983,7 @@ function NetscriptFunctions(workerScript) {
}, },
joinFaction : function(name) { joinFaction : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("joinFaction", ramCost); return updateStaticRam("joinFaction", ramCost);
} }
@ -3022,7 +3022,7 @@ function NetscriptFunctions(workerScript) {
}, },
workForFaction : function(name, type) { workForFaction : function(name, type) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("workForFaction", ramCost); return updateStaticRam("workForFaction", ramCost);
} }
@ -3122,7 +3122,7 @@ function NetscriptFunctions(workerScript) {
}, },
getFactionRep : function(name) { getFactionRep : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getFactionRep", ramCost); return updateStaticRam("getFactionRep", ramCost);
} }
@ -3143,7 +3143,7 @@ function NetscriptFunctions(workerScript) {
}, },
getFactionFavor : function(name) { getFactionFavor : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getFactionFavor", ramCost); return updateStaticRam("getFactionFavor", ramCost);
} }
@ -3164,7 +3164,7 @@ function NetscriptFunctions(workerScript) {
}, },
getFactionFavorGain: function(name) { getFactionFavorGain: function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost; var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getFactionFavorGain", ramCost); return updateStaticRam("getFactionFavorGain", ramCost);
} }
@ -3185,7 +3185,7 @@ function NetscriptFunctions(workerScript) {
}, },
donateToFaction : function(name, amt) { donateToFaction : function(name, amt) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("donateToFaction", ramCost); return updateStaticRam("donateToFaction", ramCost);
} }
@ -3224,7 +3224,7 @@ function NetscriptFunctions(workerScript) {
}, },
createProgram : function(name) { createProgram : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("createProgram", ramCost); return updateStaticRam("createProgram", ramCost);
} }
@ -3278,7 +3278,7 @@ function NetscriptFunctions(workerScript) {
}, },
commitCrime : function(crimeRoughName) { commitCrime : function(crimeRoughName) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("commitCrime", ramCost); return updateStaticRam("commitCrime", ramCost);
} }
@ -3335,7 +3335,7 @@ function NetscriptFunctions(workerScript) {
}, },
getCrimeChance : function(crimeRoughName) { getCrimeChance : function(crimeRoughName) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getCrimeChance", ramCost); return updateStaticRam("getCrimeChance", ramCost);
} }
@ -3356,7 +3356,7 @@ function NetscriptFunctions(workerScript) {
}, },
getOwnedAugmentations : function(purchased=false) { getOwnedAugmentations : function(purchased=false) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getOwnedAugmentations", ramCost); return updateStaticRam("getOwnedAugmentations", ramCost);
} }
@ -3380,7 +3380,7 @@ function NetscriptFunctions(workerScript) {
}, },
getOwnedSourceFiles : function() { getOwnedSourceFiles : function() {
let ramCost = CONSTANTS.ScriptSingularityFn3RamCost; let ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getOwnedSourceFiles", ramCost); return updateStaticRam("getOwnedSourceFiles", ramCost);
} }
@ -3399,7 +3399,7 @@ function NetscriptFunctions(workerScript) {
}, },
getAugmentationsFromFaction : function(facname) { getAugmentationsFromFaction : function(facname) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getAugmentationsFromFaction", ramCost); return updateStaticRam("getAugmentationsFromFaction", ramCost);
} }
@ -3425,7 +3425,7 @@ function NetscriptFunctions(workerScript) {
}, },
getAugmentationCost : function(name) { getAugmentationCost : function(name) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getAugmentationCost", ramCost); return updateStaticRam("getAugmentationCost", ramCost);
} }
@ -3447,7 +3447,7 @@ function NetscriptFunctions(workerScript) {
}, },
purchaseAugmentation : function(faction, name) { purchaseAugmentation : function(faction, name) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("purchaseAugmentation", ramCost); return updateStaticRam("purchaseAugmentation", ramCost);
} }
@ -3512,7 +3512,7 @@ function NetscriptFunctions(workerScript) {
}, },
installAugmentations : function(cbScript) { installAugmentations : function(cbScript) {
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost; var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
if (Player.bitNodeN !== 4) {ramCost *= 8;} if (Player.bitNodeN !== 4) {ramCost *= CONSTANTS.ScriptSingularityFnRamMult;}
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("installAugmentations", ramCost); return updateStaticRam("installAugmentations", ramCost);
} }
@ -4085,17 +4085,35 @@ function NetscriptFunctions(workerScript) {
return false; return false;
} }
}, },
getContractType : function(fn, ip=workerScript.serverIp) {
if (workerScript.checkingRam) {
return updateStaticRam("getContractType", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
}
updateDynamicRam("getContractType", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
let contract = getCodingContract(fn, ip);
if (contract == null) {
workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`);
return null;
}
return contract.getType();
},
getData : function(fn, ip=workerScript.serverIp) { getData : function(fn, ip=workerScript.serverIp) {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("getData", CONSTANTS.ScriptCodingContractBaseRamCost / 2); return updateStaticRam("getData", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
} }
updateDynamicRam("getData", CONSTANTS.ScriptCodingContractBaseRamCost / 2); updateDynamicRam("getData", CONSTANTS.ScriptCodingContractBaseRamCost / 2);
var contract = getCodingContract(fn, ip); let contract = getCodingContract(fn, ip);
if (contract == null) { if (contract == null) {
workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`); workerScript.log(`ERROR: codingcontract.getData() failed because it could find the specified contract ${fn} on server ${ip}`);
return null; return null;
} }
return contract.getData(); let data = contract.getData();
if (data.constructor === Array) {
// Pass a copy
return data.slice();
} else {
return data;
}
}, },
getDescription : function(fn, ip=workerScript.serverIp) { getDescription : function(fn, ip=workerScript.serverIp) {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {

@ -31,8 +31,6 @@ export async function executeJSScript(scripts = [], workerScript) {
loadedModule = script.module; loadedModule = script.module;
let ns = workerScript.env.vars; let ns = workerScript.env.vars;
//ns.threads = workerScript.threads;
//ns.args = workerScript.args;
try { try {
// TODO: putting await in a non-async function yields unhelpful // TODO: putting await in a non-async function yields unhelpful
@ -75,7 +73,7 @@ export function _getScriptUrls(script, scripts, seen) {
// import {foo} from "blob://<uuid>" // import {foo} from "blob://<uuid>"
// //
// Where the blob URL contains the script content. // Where the blob URL contains the script content.
const transformedCode = script.code.replace(/((?:from|import)\s+(?:'|"))([^'"]+)('|";)/g, let transformedCode = script.code.replace(/((?:from|import)\s+(?:'|"))([^'"]+)('|";)/g,
(unmodified, prefix, filename, suffix) => { (unmodified, prefix, filename, suffix) => {
const isAllowedImport = scripts.some(s => s.filename == filename); const isAllowedImport = scripts.some(s => s.filename == filename);
if (!isAllowedImport) return unmodified; if (!isAllowedImport) return unmodified;
@ -92,6 +90,9 @@ export function _getScriptUrls(script, scripts, seen) {
} }
); );
// We automatically define a print function() in the NetscriptJS module so that
// accidental calls to window.print() do not bring up the "print screen" dialog
transformedCode += `\n\nfunction print() {throw new Error("Invalid call to window.print(). Did you mean to use Netscript's print()?");}`
// If we successfully transformed the code, create a blob url for it and // If we successfully transformed the code, create a blob url for it and
// push that URL onto the top of the stack. // push that URL onto the top of the stack.

@ -14,7 +14,6 @@ import {NetscriptPort} from "./NetscriptPort";
import {AllServers} from "./Server"; import {AllServers} from "./Server";
import {Settings} from "./Settings"; import {Settings} from "./Settings";
//TODO Maybe escodegen might be better?
import {generate} from 'escodegen'; import {generate} from 'escodegen';
import {parse, Node} from "../utils/acorn"; import {parse, Node} from "../utils/acorn";
@ -138,7 +137,18 @@ function startNetscript2Script(workerScript) {
throw workerScript; throw workerScript;
} }
runningFn = propName; runningFn = propName;
let result = f(...args);
// If the function throws an error, clear the runningFn flag first, and then re-throw it
// This allows people to properly catch errors thrown by NS functions without getting
// the concurrent call error above
let result;
try {
result = f(...args);
} catch(e) {
runningFn = null;
throw(e);
}
if (result && result.finally !== undefined) { if (result && result.finally !== undefined) {
return result.finally(function () { return result.finally(function () {
runningFn = null; runningFn = null;

249
src/Player.js Normal file → Executable file

@ -20,17 +20,14 @@ import {AllServers, Server, AddToAllServers} from "./Server";
import {Settings} from "./Settings"; import {Settings} from "./Settings";
import {SpecialServerIps, SpecialServerNames} from "./SpecialServerIps"; import {SpecialServerIps, SpecialServerNames} from "./SpecialServerIps";
import {SourceFiles, applySourceFile} from "./SourceFile"; import {SourceFiles, applySourceFile} from "./SourceFile";
import Decimal from "decimal.js"; import Decimal from "decimal.js";
import {numeralWrapper} from "./ui/numeralFormat"; import {numeralWrapper} from "./ui/numeralFormat";
import {dialogBoxCreate} from "../utils/DialogBox"; import {dialogBoxCreate} from "../utils/DialogBox";
import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners"; import {clearEventListeners} from "../utils/uiHelpers/clearEventListeners";
import {createRandomIp} from "../utils/IPAddress"; import {createRandomIp} from "../utils/IPAddress";
import {Reviver, Generic_toJSON, import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver"; Generic_fromJSON} from "../utils/JSONReviver";
import {formatNumber, import {convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions";
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions";
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle; const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
@ -721,17 +718,17 @@ PlayerObject.prototype.work = function(numCycles) {
var txt = document.getElementById("work-in-progress-text"); var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName + txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
" at " + this.companyName + " (Current Company Reputation: " + " at " + this.companyName + " (Current Company Reputation: " +
formatNumber(companyRep, 0) + ")<br><br>" + numeralWrapper.format(companyRep, '0,0') + ")<br><br>" +
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" + "You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
"You have earned: <br><br>" + "You have earned: <br><br>" +
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " ($" + numeralWrapper.format(this.workMoneyGainRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * CYCLES_PER_SEC, 4) + " / sec) reputation for this company <br><br>" + numeralWrapper.format(this.workRepGained, '0,0.0000') + " (" + numeralWrapper.format(this.workRepGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) reputation for this company <br><br>" +
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br><br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br><br>" +
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br><br> " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br><br> " +
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br><br>" + numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br><br>" +
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " + "You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " +
"but you will only gain half of the reputation you've earned so far." "but you will only gain half of the reputation you've earned so far."
} }
@ -750,14 +747,14 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
this.updateSkillLevels(); this.updateSkillLevels();
var txt = "You earned a total of: <br>" + var txt = "You earned a total of: <br>" +
"$" + formatNumber(this.workMoneyGained, 2) + "<br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
formatNumber(this.workRepGained, 4) + " reputation for the company <br>" + numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation for the company <br>" +
formatNumber(this.workHackExpGained, 4) + " hacking exp <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
formatNumber(this.workStrExpGained, 4) + " strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>"; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
if (cancelled) { if (cancelled) {
txt = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " + txt = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
@ -774,14 +771,14 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
if (sing) { if (sing) {
var res = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " + var res = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
"earned $" + formatNumber(this.workMoneyGained, 2) + ", " + "earned $" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + ", " +
formatNumber(this.workRepGained, 4) + " reputation, " + numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation, " +
formatNumber(this.workHackExpGained, 4) + " hacking exp, " + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
formatNumber(this.workStrExpGained, 4) + " strength exp, " + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp, " +
formatNumber(this.workDefExpGained, 4) + " defense exp, " + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp, " +
formatNumber(this.workDexExpGained, 4) + " dexterity exp, " + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp, " +
formatNumber(this.workAgiExpGained, 4) + " agility exp, and " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp, and " +
formatNumber(this.workChaExpGained, 4) + " charisma exp."; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp.";
this.resetWorkStatus(); this.resetWorkStatus();
return res; return res;
} }
@ -843,17 +840,17 @@ PlayerObject.prototype.workPartTime = function(numCycles) {
var txt = document.getElementById("work-in-progress-text"); var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName + txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
" at " + Player.companyName + " (Current Company Reputation: " + " at " + Player.companyName + " (Current Company Reputation: " +
formatNumber(companyRep, 0) + ")<br><br>" + numeralWrapper.format(companyRep, '0,0') + ")<br><br>" +
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" + "You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
"You have earned: <br><br>" + "You have earned: <br><br>" +
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " ($" + numeralWrapper.format(this.workMoneyGainRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * CYCLES_PER_SEC, 4) + " / sec) reputation for this company <br><br>" + numeralWrapper.format(this.workRepGained, '0,0.0000') + " (" + numeralWrapper.format(this.workRepGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) reputation for this company <br><br>" +
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br><br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br><br>" +
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br><br> " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br><br> " +
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br><br>" + numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br><br>" +
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, <br>" + "You will automatically finish after working for 8 hours. You can cancel earlier if you wish, <br>" +
"and there will be no penalty because this is a part-time job."; "and there will be no penalty because this is a part-time job.";
@ -868,14 +865,14 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
this.updateSkillLevels(); this.updateSkillLevels();
var txt = "You earned a total of: <br>" + var txt = "You earned a total of: <br>" +
"$" + formatNumber(this.workMoneyGained, 2) + "<br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
formatNumber(this.workRepGained, 4) + " reputation for the company <br>" + numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation for the company <br>" +
formatNumber(this.workHackExpGained, 4) + " hacking exp <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
formatNumber(this.workStrExpGained, 4) + " strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>"; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
txt = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br> " + txt; txt = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br> " + txt;
if (!sing) {dialogBoxCreate(txt);} if (!sing) {dialogBoxCreate(txt);}
@ -886,14 +883,14 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
if (sing) { if (sing) {
var res = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " + var res = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
"earned a total of " + "earned a total of " +
"$" + formatNumber(this.workMoneyGained, 2) + ", " + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + ", " +
formatNumber(this.workRepGained, 4) + " reputation, " + numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation, " +
formatNumber(this.workHackExpGained, 4) + " hacking exp, " + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
formatNumber(this.workStrExpGained, 4) + " strength exp, " + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp, " +
formatNumber(this.workDefExpGained, 4) + " defense exp, " + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp, " +
formatNumber(this.workDexExpGained, 4) + " dexterity exp, " + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp, " +
formatNumber(this.workAgiExpGained, 4) + " agility exp, and " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp, and " +
formatNumber(this.workChaExpGained, 4) + " charisma exp"; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp";
this.resetWorkStatus(); this.resetWorkStatus();
return res; return res;
} }
@ -1012,17 +1009,17 @@ PlayerObject.prototype.workForFaction = function(numCycles) {
var txt = document.getElementById("work-in-progress-text"); var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently " + this.currentWorkFactionDescription + " for your faction " + faction.name + txt.innerHTML = "You are currently " + this.currentWorkFactionDescription + " for your faction " + faction.name +
" (Current Faction Reputation: " + formatNumber(faction.playerReputation, 0) + "). <br>" + " (Current Faction Reputation: " + numeralWrapper.format(faction.playerReputation, '0,0') + "). <br>" +
"You have been doing this for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" + "You have been doing this for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
"You have earned: <br><br>" + "You have earned: <br><br>" +
"$" + formatNumber(this.workMoneyGained, 2) + " (" + formatNumber(this.workMoneyGainRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " (" + numeralWrapper.format(this.workMoneyGainRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
formatNumber(this.workRepGained, 4) + " (" + formatNumber(this.workRepGainRate * CYCLES_PER_SEC, 4) + " / sec) reputation for this faction <br><br>" + numeralWrapper.format(this.workRepGained, '0,0.0000') + " (" + numeralWrapper.format(this.workRepGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) reputation for this faction <br><br>" +
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br><br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br><br>" +
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br><br> " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br><br> " +
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br><br>" + numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br><br>" +
"You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br>" + "You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br>" +
"There is no penalty for cancelling earlier."; "There is no penalty for cancelling earlier.";
@ -1038,14 +1035,14 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
var txt = "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " + var txt = "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
"You earned a total of: <br>" + "You earned a total of: <br>" +
"$" + formatNumber(this.workMoneyGained, 2) + "<br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
formatNumber(this.workRepGained, 4) + " reputation for the faction <br>" + numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation for the faction <br>" +
formatNumber(this.workHackExpGained, 4) + " hacking exp <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
formatNumber(this.workStrExpGained, 4) + " strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>"; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
if (!sing) {dialogBoxCreate(txt);} if (!sing) {dialogBoxCreate(txt);}
var mainMenu = document.getElementById("mainmenu-container"); var mainMenu = document.getElementById("mainmenu-container");
@ -1058,13 +1055,13 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
if (sing) { if (sing) {
var res="You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " + var res="You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
"You earned " + "You earned " +
formatNumber(this.workRepGained, 4) + " rep, " + numeralWrapper.format(this.workRepGained, '0,0.0000') + " rep, " +
formatNumber(this.workHackExpGained, 4) + " hacking exp, " + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
formatNumber(this.workStrExpGained, 4) + " str exp, " + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " str exp, " +
formatNumber(this.workDefExpGained, 4) + " def exp, " + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " def exp, " +
formatNumber(this.workDexExpGained, 4) + " dex exp, " + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dex exp, " +
formatNumber(this.workAgiExpGained, 4) + " agi exp, and " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agi exp, and " +
formatNumber(this.workChaExpGained, 4) + " cha exp."; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " cha exp.";
this.resetWorkStatus(); this.resetWorkStatus();
return res; return res;
} }
@ -1350,14 +1347,14 @@ PlayerObject.prototype.takeClass = function(numCycles) {
var txt = document.getElementById("work-in-progress-text"); var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You have been " + className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" + txt.innerHTML = "You have been " + className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
"This has cost you: <br>" + "This has cost you: <br>" +
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyLossRate * CYCLES_PER_SEC, 2) + " / sec) <br><br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " ($" + numeralWrapper.format(this.workMoneyLossRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
"You have gained: <br>" + "You have gained: <br>" +
formatNumber(this.workHackExpGained, 4) + " (" + formatNumber(this.workHackExpGainRate * CYCLES_PER_SEC, 4) + " / sec) hacking exp <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br>" +
formatNumber(this.workStrExpGained, 4) + " (" + formatNumber(this.workStrExpGainRate * CYCLES_PER_SEC, 4) + " / sec) strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " (" + formatNumber(this.workDefExpGainRate * CYCLES_PER_SEC, 4) + " / sec) defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " (" + formatNumber(this.workDexExpGainRate * CYCLES_PER_SEC, 4) + " / sec) dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " (" + formatNumber(this.workAgiExpGainRate * CYCLES_PER_SEC, 4) + " / sec) agility exp <br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br>" +
formatNumber(this.workChaExpGained, 4) + " (" + formatNumber(this.workChaExpGainRate * CYCLES_PER_SEC, 4) + " / sec) charisma exp <br>" + numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br>" +
"You may cancel at any time"; "You may cancel at any time";
} }
@ -1373,14 +1370,14 @@ PlayerObject.prototype.finishClass = function(sing=false) {
this.updateSkillLevels(); this.updateSkillLevels();
var txt = "After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", <br>" + var txt = "After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", <br>" +
"you spent a total of $" + formatNumber(this.workMoneyGained * -1, 2) + ". <br><br>" + "you spent a total of $" + numeralWrapper.format(this.workMoneyGained * -1, '0,0.00') + ". <br><br>" +
"You earned a total of: <br>" + "You earned a total of: <br>" +
formatNumber(this.workHackExpGained, 4) + " hacking exp <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
formatNumber(this.workStrExpGained, 4) + " strength exp <br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
formatNumber(this.workDefExpGained, 4) + " defense exp <br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
formatNumber(this.workDexExpGained, 4) + " dexterity exp <br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
formatNumber(this.workAgiExpGained, 4) + " agility exp <br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
formatNumber(this.workChaExpGained, 4) + " charisma exp<br>"; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
if (!sing) {dialogBoxCreate(txt);} if (!sing) {dialogBoxCreate(txt);}
var mainMenu = document.getElementById("mainmenu-container"); var mainMenu = document.getElementById("mainmenu-container");
@ -1391,14 +1388,14 @@ PlayerObject.prototype.finishClass = function(sing=false) {
Engine.loadLocationContent(); Engine.loadLocationContent();
if (sing) { if (sing) {
var res="After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", " + var res="After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", " +
"you spent a total of $" + formatNumber(this.workMoneyGained * -1, 2) + ". " + "you spent a total of $" + numeralWrapper.format(this.workMoneyGained * -1, '0,0.00') + ". " +
"You earned a total of: " + "You earned a total of: " +
formatNumber(this.workHackExpGained, 3) + " hacking exp, " + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
formatNumber(this.workStrExpGained, 3) + " strength exp, " + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp, " +
formatNumber(this.workDefExpGained, 3) + " defense exp, " + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp, " +
formatNumber(this.workDexExpGained, 3) + " dexterity exp, " + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp, " +
formatNumber(this.workAgiExpGained, 3) + " agility exp, and " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp, and " +
formatNumber(this.workChaExpGained, 3) + " charisma exp"; numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp";
this.resetWorkStatus(); this.resetWorkStatus();
return res; return res;
} }
@ -1489,23 +1486,23 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
if(this.singFnCrimeWorkerScript.disableLogs.ALL == null && this.singFnCrimeWorkerScript.disableLogs.commitCrime == null) { if(this.singFnCrimeWorkerScript.disableLogs.ALL == null && this.singFnCrimeWorkerScript.disableLogs.commitCrime == null) {
this.singFnCrimeWorkerScript.scriptRef.log("Crime successful! Gained " + this.singFnCrimeWorkerScript.scriptRef.log("Crime successful! Gained " +
numeralWrapper.format(this.workMoneyGained, "$0.000a") + ", " + numeralWrapper.format(this.workMoneyGained, "$0.000a") + ", " +
formatNumber(this.workHackExpGained, 3) + " hack exp, " + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hack exp, " +
formatNumber(this.workStrExpGained, 3) + " str exp, " + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " str exp, " +
formatNumber(this.workDefExpGained, 3) + " def exp, " + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " def exp, " +
formatNumber(this.workDexExpGained, 3) + " dex exp, " + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dex exp, " +
formatNumber(this.workAgiExpGained, 3) + " agi exp, " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agi exp, " +
formatNumber(this.workChaExpGained, 3) + " cha exp."); numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " cha exp.");
} }
} else { } else {
dialogBoxCreate("Crime successful! <br><br>" + dialogBoxCreate("Crime successful! <br><br>" +
"You gained:<br>"+ "You gained:<br>"+
"$" + formatNumber(this.workMoneyGained, 2) + "<br>" + "$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
formatNumber(this.workHackExpGained, 4) + " hacking experience <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking experience <br>" +
formatNumber(this.workStrExpGained, 4) + " strength experience<br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength experience<br>" +
formatNumber(this.workDefExpGained, 4) + " defense experience<br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense experience<br>" +
formatNumber(this.workDexExpGained, 4) + " dexterity experience<br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity experience<br>" +
formatNumber(this.workAgiExpGained, 4) + " agility experience<br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility experience<br>" +
formatNumber(this.workChaExpGained, 4) + " charisma experience"); numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma experience");
} }
} else { } else {
@ -1519,22 +1516,22 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
if (this.committingCrimeThruSingFn) { if (this.committingCrimeThruSingFn) {
if(this.singFnCrimeWorkerScript.disableLogs.ALL == null && this.singFnCrimeWorkerScript.disableLogs.commitCrime == null) { if(this.singFnCrimeWorkerScript.disableLogs.ALL == null && this.singFnCrimeWorkerScript.disableLogs.commitCrime == null) {
this.singFnCrimeWorkerScript.scriptRef.log("Crime failed! Gained " + this.singFnCrimeWorkerScript.scriptRef.log("Crime failed! Gained " +
formatNumber(this.workHackExpGained, 3) + " hack exp, " + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hack exp, " +
formatNumber(this.workStrExpGained, 3) + " str exp, " + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " str exp, " +
formatNumber(this.workDefExpGained, 3) + " def exp, " + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " def exp, " +
formatNumber(this.workDexExpGained, 3) + " dex exp, " + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dex exp, " +
formatNumber(this.workAgiExpGained, 3) + " agi exp, " + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agi exp, " +
formatNumber(this.workChaExpGained, 3) + " cha exp."); numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " cha exp.");
} }
} else { } else {
dialogBoxCreate("Crime failed! <br><br>" + dialogBoxCreate("Crime failed! <br><br>" +
"You gained:<br>"+ "You gained:<br>"+
formatNumber(this.workHackExpGained, 4) + " hacking experience <br>" + numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking experience <br>" +
formatNumber(this.workStrExpGained, 4) + " strength experience<br>" + numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength experience<br>" +
formatNumber(this.workDefExpGained, 4) + " defense experience<br>" + numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense experience<br>" +
formatNumber(this.workDexExpGained, 4) + " dexterity experience<br>" + numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity experience<br>" +
formatNumber(this.workAgiExpGained, 4) + " agility experience<br>" + numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility experience<br>" +
formatNumber(this.workChaExpGained, 4) + " charisma experience"); numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma experience");
} }
} }
@ -1912,10 +1909,10 @@ PlayerObject.prototype.reapplyAllAugmentations = function(resetMultipliers=true)
this.augmentations[i].name = "Hacknet Node NIC Architecture Neural-Upload"; this.augmentations[i].name = "Hacknet Node NIC Architecture Neural-Upload";
} }
var augName = this.augmentations[i].name; const augName = this.augmentations[i].name;
var aug = Augmentations[augName]; var aug = Augmentations[augName];
if (aug == null) { if (aug == null) {
console.log("WARNING: Invalid augmentation name"); console.log(`WARNING: Invalid augmentation name in Player.reapplyAllAugmentations(). Aug ${augName} will be skipped`);
continue; continue;
} }
aug.owned = true; aug.owned = true;

@ -18,7 +18,6 @@ import {yesNoBoxCreate, yesNoBoxGetYesButton,
//Returns promise //Returns promise
function writeRedPillLine(line) { function writeRedPillLine(line) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
var container = document.getElementById("red-pill-content"); var container = document.getElementById("red-pill-content");
var pElem = document.createElement("p"); var pElem = document.createElement("p");
container.appendChild(pElem); container.appendChild(pElem);
@ -54,6 +53,10 @@ function writeRedPillLetter(pElem, line, i=0) {
let redPillFlag = false; let redPillFlag = false;
function hackWorldDaemon(currentNodeNumber, flume=false) { function hackWorldDaemon(currentNodeNumber, flume=false) {
// Clear Red Pill screen first
var container = document.getElementById("red-pill-content");
removeChildrenFromElement(container);
redPillFlag = true; redPillFlag = true;
Engine.loadRedPillContent(); Engine.loadRedPillContent();
return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() { return writeRedPillLine("[ERROR] SEMPOOL INVALID").then(function() {
@ -301,7 +304,7 @@ function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode, flume=fa
Player.gainIntelligenceExp(-5); Player.gainIntelligenceExp(-5);
} }
redPillFlag = false; redPillFlag = false;
var container = document.getElementById("red-pill-container"); var container = document.getElementById("red-pill-content");
removeChildrenFromElement(container); removeChildrenFromElement(container);
//Set new Bit Node //Set new Bit Node

6
src/SaveObject.js Normal file → Executable file

@ -24,7 +24,7 @@ import {Reviver, Generic_toJSON,
import {createElement} from "../utils/uiHelpers/createElement"; import {createElement} from "../utils/uiHelpers/createElement";
import {createPopup} from "../utils/uiHelpers/createPopup"; import {createPopup} from "../utils/uiHelpers/createPopup";
import {createStatusText} from "./ui/createStatusText"; import {createStatusText} from "./ui/createStatusText";
import {formatNumber} from "../utils/StringHelperFunctions"; import {numeralWrapper} from "./ui/numeralFormat";
import {removeElementById} from "../utils/uiHelpers/removeElementById"; import {removeElementById} from "../utils/uiHelpers/removeElementById";
import Decimal from "decimal.js"; import Decimal from "decimal.js";
@ -517,8 +517,8 @@ function loadImportedGame(saveObj, saveString) {
Player.lastUpdate = Engine._lastUpdate; Player.lastUpdate = Engine._lastUpdate;
Engine.start(); //Run main game loop and Scripts loop Engine.start(); //Run main game loop and Scripts loop
dialogBoxCreate("While you were offline, your scripts generated <span class='money-gold'>$" + dialogBoxCreate("While you were offline, your scripts generated <span class='money-gold'>$" +
formatNumber(offlineProductionFromScripts, 2) + "</span> and your Hacknet Nodes generated <span class='money-gold'>$" + numeralWrapper.format(offlineProductionFromScripts, '0,0.00') + "</span> and your Hacknet Nodes generated <span class='money-gold'>$" +
formatNumber(offlineProductionFromHacknetNodes, 2) + "</span>"); numeralWrapper.format(offlineProductionFromHacknetNodes, '0,0.00') + "</span>");
return true; return true;
} }

@ -50,7 +50,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
}, },
difficulty: 1, difficulty: 1,
gen: () => { gen: () => {
return getRandomInt(500, 9e9); return getRandomInt(500, 1e9);
}, },
name: "Find Largest Prime Factor", name: "Find Largest Prime Factor",
numTries: 10, numTries: 10,

@ -33,6 +33,7 @@ import {displayCreateProgramContent,
getNumAvailableCreateProgram, getNumAvailableCreateProgram,
initCreateProgramButtons, initCreateProgramButtons,
Programs} from "./CreateProgram"; Programs} from "./CreateProgram";
import {createDevMenu, closeDevMenu} from "./DevMenu";
import {displayFactionContent, joinFaction, import {displayFactionContent, joinFaction,
processPassiveFactionRepGain, Factions, processPassiveFactionRepGain, Factions,
inviteToFaction, initFactions} from "./Faction"; inviteToFaction, initFactions} from "./Faction";
@ -194,41 +195,6 @@ const Engine = {
tutorialFactionsButton: null, tutorialFactionsButton: null,
tutorialAugmentationsButton: null, tutorialAugmentationsButton: null,
tutorialBackButton: null, tutorialBackButton: null,
//Dev menu
devMenuGiveMoney: null,
devMenuGiveRam: null,
devMenuAugDropdown: null,
devMenuAddAug: null,
devMenuTriggerBitFlume: null,
devMenuFactionDropdown: null,
devMenuAddFaction: null,
devMenuOpen: null,
devMenuMinSecurity: null,
devMenuMaxMoney: null,
devMenuConnectDropdown: null,
devMenuConnect: null,
devMenuProgramsDropdown: null,
devMenuAddProgram: null,
devMenuHackingExp: null,
devMenuAddHacking: null,
devMenuStrengthExp: null,
devMenuAddStrength: null,
devMenuDefenseExp: null,
devMenuAddDefense: null,
devMenuDexterityExp: null,
devMenuAddDexterity: null,
devMenuAgilityExp: null,
devMenuAddAgility: null,
devMenuCharismaExp: null,
devMenuAddCharisma: null,
devMenuIntelligenceExp: null,
devMenuAddIntelligence: null,
devMenuEnableIntelligence: null,
devMenuDisableIntelligence: null,
devMenuSFN: null,
devMenuSFLvl: null,
devMenuAddSF: null,
}, },
//Display objects //Display objects
@ -254,7 +220,6 @@ const Engine = {
factionAugmentationsContent: null, factionAugmentationsContent: null,
augmentationsContent: null, augmentationsContent: null,
tutorialContent: null, tutorialContent: null,
devMenuContent: null,
infiltrationContent: null, infiltrationContent: null,
stockMarketContent: null, stockMarketContent: null,
locationContent: null, locationContent: null,
@ -365,8 +330,7 @@ const Engine = {
loadDevMenuContent: function() { loadDevMenuContent: function() {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.devMenuContent.style.display = "block"; createDevMenu();
Engine.displayDevMenuContent();
routing.navigateTo(Page.DevMenu); routing.navigateTo(Page.DevMenu);
document.getElementById("dev-menu-link").classList.add("active"); document.getElementById("dev-menu-link").classList.add("active");
}, },
@ -507,7 +471,6 @@ const Engine = {
Engine.Display.factionAugmentationsContent.style.display = "none"; Engine.Display.factionAugmentationsContent.style.display = "none";
Engine.Display.augmentationsContent.style.display = "none"; Engine.Display.augmentationsContent.style.display = "none";
Engine.Display.tutorialContent.style.display = "none"; Engine.Display.tutorialContent.style.display = "none";
Engine.Display.devMenuContent.style.display = "none";
Engine.Display.locationContent.style.display = "none"; Engine.Display.locationContent.style.display = "none";
Engine.Display.workInProgressContent.style.display = "none"; Engine.Display.workInProgressContent.style.display = "none";
Engine.Display.redPillContent.style.display = "none"; Engine.Display.redPillContent.style.display = "none";
@ -551,6 +514,9 @@ const Engine = {
document.getElementById("bladeburner-menu-link").classList.remove("active"); document.getElementById("bladeburner-menu-link").classList.remove("active");
document.getElementById("corporation-menu-link").classList.remove("active"); document.getElementById("corporation-menu-link").classList.remove("active");
document.getElementById("gang-menu-link").classList.remove("active"); document.getElementById("gang-menu-link").classList.remove("active");
// Close dev menu
closeDevMenu();
}, },
displayCharacterOverviewInfo: function() { displayCharacterOverviewInfo: function() {
@ -844,43 +810,6 @@ const Engine = {
document.getElementById("tutorial-text").style.display = "none"; document.getElementById("tutorial-text").style.display = "none";
}, },
displayDevMenuContent: function() {
Engine.Clickables.devMenuGiveMoney.style.display = "block";
Engine.Clickables.devMenuGiveRam.style.display = "block";
Engine.Clickables.devMenuAugDropdown.style.display = "block";
Engine.Clickables.devMenuAddAug.style.display = "block";
Engine.Clickables.devMenuTriggerBitFlume.style.display = "block";
Engine.Clickables.devMenuFactionDropdown.style.display = "block";
Engine.Clickables.devMenuAddFaction.style.display = "block";
Engine.Clickables.devMenuOpen.style.display = "block";
Engine.Clickables.devMenuMinSecurity.style.display = "block";
Engine.Clickables.devMenuMaxMoney.style.display = "block";
Engine.Clickables.devMenuConnectDropdown.style.display = "block";
Engine.Clickables.devMenuConnect.style.display = "block";
Engine.Clickables.devMenuProgramsDropdown.style.display = "block";
Engine.Clickables.devMenuAddProgram.style.display = "block";
Engine.Clickables.devMenuHackingExp.style.display = "block";
Engine.Clickables.devMenuAddHacking.style.display = "block";
Engine.Clickables.devMenuStrengthExp.style.display = "block";
Engine.Clickables.devMenuAddStrength.style.display = "block";
Engine.Clickables.devMenuDefenseExp.style.display = "block";
Engine.Clickables.devMenuAddDefense.style.display = "block";
Engine.Clickables.devMenuDexterityExp.style.display = "block";
Engine.Clickables.devMenuAddDexterity.style.display = "block";
Engine.Clickables.devMenuAgilityExp.style.display = "block";
Engine.Clickables.devMenuAddAgility.style.display = "block";
Engine.Clickables.devMenuCharismaExp.style.display = "block";
Engine.Clickables.devMenuAddCharisma.style.display = "block";
Engine.Clickables.devMenuIntelligenceExp.style.display = "block";
Engine.Clickables.devMenuAddIntelligence.style.display = "block";
Engine.Clickables.devMenuEnableIntelligence.style.display = "block";
Engine.Clickables.devMenuDisableIntelligence.style.display = "block";
Engine.Clickables.devMenuSFN.style.display = "block";
Engine.Clickables.devMenuSFLvl.style.display = "block";
Engine.Clickables.devMenuAddSF.style.display = "block";
},
//Displays the text when a section of the Tutorial is opened //Displays the text when a section of the Tutorial is opened
displayTutorialPage: function(text) { displayTutorialPage: function(text) {
document.getElementById("tutorial-getting-started-link").style.display = "none"; document.getElementById("tutorial-getting-started-link").style.display = "none";
@ -1169,10 +1098,18 @@ const Engine = {
reward.type = getRandomInt(0, CodingContractRewardType.Money); reward.type = getRandomInt(0, CodingContractRewardType.Money);
// Change type based on certain conditions // Change type based on certain conditions
if (reward.type === CodingContractRewardType.FactionReputation && Player.factions.length === 0) { var factionsThatAllowHacking = Player.factions.filter((fac) => {
try {
return Factions[fac].getInfo().offerHackingWork;
} catch (e) {
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
return false;
}
});
if (reward.type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) {
reward.type = CodingContractRewardType.CompanyReputation; reward.type = CodingContractRewardType.CompanyReputation;
} }
if (reward.type === CodingContractRewardType.FactionReputationAll && Player.factions.length === 0) { if (reward.type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) {
reward.type = CodingContractRewardType.CompanyReputation; reward.type = CodingContractRewardType.CompanyReputation;
} }
if (reward.type === CodingContractRewardType.CompanyReputation && Player.companyName === "") { if (reward.type === CodingContractRewardType.CompanyReputation && Player.companyName === "") {
@ -1183,18 +1120,10 @@ const Engine = {
switch (reward.type) { switch (reward.type) {
case CodingContractRewardType.FactionReputation: case CodingContractRewardType.FactionReputation:
// Get a random faction that player is a part of. That // Get a random faction that player is a part of. That
//faction must allow hacking contracts // faction must allow hacking contracts
var numFactions = Player.factions.length; var numFactions = factionsThatAllowHacking.length;
var randFaction = Player.factions[getRandomInt(0, numFactions - 1)]; var randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)];
try { reward.name = randFaction;
while(Factions[randFaction].getInfo().offerHackingWork !== true) {
randFaction = Player.factions[getRandomInt(0, numFactions - 1)];
}
reward.name = randFaction;
} catch (e) {
exceptionAlert("Failed to find a faction for Coding Contract Generation: " + e);
}
break; break;
case CodingContractRewardType.CompanyReputation: case CodingContractRewardType.CompanyReputation:
if (Player.companyName !== "") { if (Player.companyName !== "") {
@ -1525,9 +1454,6 @@ const Engine = {
Engine.Display.tutorialContent = document.getElementById("tutorial-container"); Engine.Display.tutorialContent = document.getElementById("tutorial-container");
Engine.Display.tutorialContent.style.display = "none"; Engine.Display.tutorialContent.style.display = "none";
Engine.Display.devMenuContent = document.getElementById("dev-menu-container");
Engine.Display.devMenuContent.style.display = "none";
Engine.Display.infiltrationContent = document.getElementById("infiltration-container"); Engine.Display.infiltrationContent = document.getElementById("infiltration-container");
Engine.Display.infiltrationContent.style.display = "none"; Engine.Display.infiltrationContent.style.display = "none";
@ -1614,190 +1540,6 @@ const Engine = {
Engine.Clickables.tutorialBackButton.addEventListener("click", function() { Engine.Clickables.tutorialBackButton.addEventListener("click", function() {
Engine.displayTutorialContent(); Engine.displayTutorialContent();
}); });
// dev menu buttons
Engine.Clickables.devMenuGiveMoney = document.getElementById("dev-need-money");
Engine.Clickables.devMenuGiveMoney.addEventListener("click", function() {
Player.gainMoney(1e15);
});
Engine.Clickables.devMenuGiveRam = document.getElementById("dev-need-ram");
Engine.Clickables.devMenuGiveRam.addEventListener("click", function() {
Player.getHomeComputer().maxRam *= 2;
});
Engine.Clickables.devMenuAugDropdown = document.getElementById("dev-menu-aug-dropdown");
const augDD = Engine.Clickables.devMenuAugDropdown;
for(const i in AugmentationNames) {
augDD.options[augDD.options.length] = new Option(AugmentationNames[i], AugmentationNames[i]);
}
Engine.Clickables.devMenuAddAug = document.getElementById("dev-add-aug");
Engine.Clickables.devMenuAddAug.addEventListener("click", function() {
Player.queueAugmentation(augDD.options[augDD.selectedIndex].value);
});
Engine.Clickables.devMenuTriggerBitFlume = document.getElementById("dev-bit-flume");
Engine.Clickables.devMenuTriggerBitFlume.addEventListener("click", function() {
hackWorldDaemon(Player.bitNodeN, true);
});
Engine.Clickables.devMenuFactionDropdown = document.getElementById("dev-menu-faction-dropdown");
const facDD = Engine.Clickables.devMenuFactionDropdown;
for(const i in Factions) {
facDD.options[facDD.options.length] = new Option(Factions[i].name, Factions[i].name);
}
Engine.Clickables.devMenuAddFaction = document.getElementById("dev-add-faction");
Engine.Clickables.devMenuAddFaction.addEventListener("click", function() {
const factionName = facDD.options[facDD.selectedIndex].value;
Player.receiveInvite(factionName);
});
Engine.Clickables.devMenuOpen = document.getElementById("dev-open-all");
Engine.Clickables.devMenuOpen.addEventListener("click", function() {
for(const i in AllServers) {
AllServers[i].hasAdminRights = true;
AllServers[i].sshPortOpen = true;
AllServers[i].ftpPortOpen = true;
AllServers[i].smtpPortOpen = true;
AllServers[i].httpPortOpen = true;
AllServers[i].sqlPortOpen = true;
AllServers[i].openPortCount = 5;
}
});
Engine.Clickables.devMenuMinSecurity = document.getElementById("dev-min-security");
Engine.Clickables.devMenuMinSecurity.addEventListener("click", function() {
for(const i in AllServers) {
AllServers[i].hackDifficulty = AllServers[i].minDifficulty;
}
});
Engine.Clickables.devMenuMaxMoney = document.getElementById("dev-max-money");
Engine.Clickables.devMenuMaxMoney.addEventListener("click", function() {
for(const i in AllServers) {
AllServers[i].moneyAvailable = AllServers[i].moneyMax;
}
});
Engine.Clickables.devMenuConnectDropdown = document.getElementById("dev-menu-connect-dropdown");
const connectDD = Engine.Clickables.devMenuConnectDropdown;
for(const i in AllServers) {
connectDD.options[connectDD.options.length] = new Option(AllServers[i].hostname, AllServers[i].hostname);
}
Engine.Clickables.devMenuConnect = document.getElementById("dev-connect");
Engine.Clickables.devMenuConnect.addEventListener("click", function() {
const host = connectDD.options[connectDD.selectedIndex].value;
Terminal.connectToServer(host);
});
Engine.Clickables.devMenuProgramsDropdown = document.getElementById("dev-menu-add-program-dropdown");
const programsDD = Engine.Clickables.devMenuProgramsDropdown;
for(const i in Programs) {
programsDD.options[programsDD.options.length] = new Option(Programs[i].name, Programs[i].name);
}
Engine.Clickables.devMenuAddProgram = document.getElementById("dev-add-program");
Engine.Clickables.devMenuAddProgram.addEventListener("click", function() {
const program = programsDD.options[programsDD.selectedIndex].value;
if(!Player.hasProgram(program)) {
Player.getHomeComputer().programs.push(program);
}
});
Engine.Clickables.devMenuHackingExp = document.getElementById("dev-hacking-exp");
Engine.Clickables.devMenuAddHacking = document.getElementById("dev-add-hacking");
Engine.Clickables.devMenuAddHacking.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuHackingExp.value);
Player.gainHackingExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuStrengthExp = document.getElementById("dev-strength-exp");
Engine.Clickables.devMenuAddStrength = document.getElementById("dev-add-strength");
Engine.Clickables.devMenuAddStrength.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuStrengthExp.value);
Player.gainStrengthExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuDefenseExp = document.getElementById("dev-defense-exp");
Engine.Clickables.devMenuAddDefense = document.getElementById("dev-add-defense");
Engine.Clickables.devMenuAddDefense.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuDefenseExp.value);
Player.gainDefenseExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuDexterityExp = document.getElementById("dev-dexterity-exp");
Engine.Clickables.devMenuAddDexterity = document.getElementById("dev-add-dexterity");
Engine.Clickables.devMenuAddDexterity.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuDexterityExp.value);
Player.gainDexterityExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuAgilityExp = document.getElementById("dev-agility-exp");
Engine.Clickables.devMenuAddAgility = document.getElementById("dev-add-agility");
Engine.Clickables.devMenuAddAgility.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuAgilityExp.value);
Player.gainAgilityExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuCharismaExp = document.getElementById("dev-charisma-exp");
Engine.Clickables.devMenuAddCharisma = document.getElementById("dev-add-charisma");
Engine.Clickables.devMenuAddCharisma.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuCharismaExp.value);
Player.gainCharismaExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuIntelligenceExp = document.getElementById("dev-intelligence-exp");
Engine.Clickables.devMenuAddIntelligence = document.getElementById("dev-add-intelligence");
Engine.Clickables.devMenuAddIntelligence.addEventListener("click", function() {
const exp = parseInt(Engine.Clickables.devMenuIntelligenceExp.value);
Player.gainIntelligenceExp(exp);
Player.updateSkillLevels();
});
Engine.Clickables.devMenuEnableIntelligence = document.getElementById("dev-enable-intelligence");
Engine.Clickables.devMenuEnableIntelligence.addEventListener("click", function() {
Player.intelligence = 1;
});
Engine.Clickables.devMenuDisableIntelligence = document.getElementById("dev-disable-intelligence");
Engine.Clickables.devMenuDisableIntelligence.addEventListener("click", function() {
Player.intelligence = 0;
});
Engine.Clickables.devMenuSFN = document.getElementById("dev-sf-n");
Engine.Clickables.devMenuSFLvl = document.getElementById("dev-sf-lvl");
Engine.Clickables.devMenuAddSF = document.getElementById("dev-add-source-file");
Engine.Clickables.devMenuAddSF.addEventListener("click", function() {
const sfN = parseInt(Engine.Clickables.devMenuSFN.value);
const sfLvl = parseInt(Engine.Clickables.devMenuSFLvl.value);
let sfIndex = -1;
for(const i in Player.sourceFiles) {
if(Player.sourceFiles[i].n === sfN) {
sfIndex = i;
break;
}
}
if(sfIndex === -1) { // add fresh source file
Player.sourceFiles.push(new PlayerOwnedSourceFile(sfN, sfLvl));
} else if(sfLvl === 0) { // remove a source file.
if(sfIndex === -1) { // doesn't have it anyway.
return;
}
Player.sourceFiles.splice(sfIndex, 1);
} else { // set source file level
Player.sourceFiles[sfIndex].lvl=sfLvl;
}
});
}, },
/* Initialization */ /* Initialization */
@ -1899,7 +1641,7 @@ const Engine = {
this.classList.toggle("opened"); this.classList.toggle("opened");
const elems = [tutorial, options]; const elems = [tutorial, options];
const links = [tutorialLink, optionsLink]; const links = [tutorialLink, optionsLink];
if(process.env.NODE_ENV === "development") { if (process.env.NODE_ENV === "development") {
elems.push(document.getElementById("dev-tab")); elems.push(document.getElementById("dev-tab"));
links.push(document.getElementById("dev-menu-link")); links.push(document.getElementById("dev-menu-link"));
} }

@ -490,58 +490,6 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
<p id="tutorial-text"> </p> <p id="tutorial-text"> </p>
</div> </div>
<!-- dev menu -->
<div id="dev-menu-container" class="generic-menupage-container">
<p id="dev-menu-text">If you see this menu you can pretty much break the game. It's recommended that you use this menu only to setup a save file appropriate to test a new feature or bug fix.</p>
<p id="dev-menu-text">Generic</p>
<a id="dev-need-money" class="a-link-button">Add $1000t</a>
<a id="dev-need-ram" class="a-link-button">Double home RAM</a>
<p id="dev-menu-text">Augmentation related: </p>
<!-- gets populated with the list of all augments -->
<select id="dev-menu-aug-dropdown" class="dropdown"></select>
<a id="dev-add-aug" class="a-link-button tooltip">Queue Augmentation<span class="tooltiptext">May require save + reload</span></a>
<input id="dev-sf-n" type="number" class="text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<p id="dev-menu-text">Faction related: </p>
<select id="dev-menu-faction-dropdown" class="dropdown"></select>
<a id="dev-add-faction" class="a-link-button tooltip">Receive invite<span class="tooltiptext">May require save + reload</span></a>
<p id="dev-menu-text">Program related: </p>
<select id="dev-menu-connect-dropdown" class="dropdown"></select>
<a id="dev-connect" class="a-link-button tooltip">Connect<span class="tooltiptext">Connect to the target server.</span></a>
<select id="dev-menu-add-program-dropdown" class="dropdown"></select>
<a id="dev-add-program" class="a-link-button tooltip">Add Program<span class="tooltiptext">Add this program to the player home server, won't add the same program twice.</span></a>
<a id="dev-bit-flume" class="a-link-button tooltip">Trigger BitFlume<span class="tooltiptext">Quick escape to change BN, does not give SFs</span></a>
<p id="dev-menu-text">Server related: </p>
<a id="dev-open-all" class="a-link-button tooltip">NUKE + ports all servers<span class="tooltiptext">Opens all ports, nukes all servers, gains root access to everything (still need the appropriate hacking level)</span></a>
<a id="dev-min-security" class="a-link-button tooltip">minimize all servers security<span class="tooltiptext">All servers security will be set to their minimum security</span></a>
<a id="dev-max-money" class="a-link-button tooltip">maximize all servers money<span class="tooltiptext">Set all servers available money to maximum for that server</span></a>
<p id="dev-menu-text">Exp/stats related: </p>
<input id="dev-hacking-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-hacking" class="a-link-button tooltip">add hacking exp<span class="tooltiptext">Add that many hacking experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-strength-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-strength" class="a-link-button tooltip">add strength exp<span class="tooltiptext">Add that many strength experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-defense-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-defense" class="a-link-button tooltip">add defense exp<span class="tooltiptext">Add that many defense experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-dexterity-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-dexterity" class="a-link-button tooltip">add dexterity exp<span class="tooltiptext">Add that many dexterity experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-agility-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-agility" class="a-link-button tooltip">add agility exp<span class="tooltiptext">Add that many agility experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-charisma-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-charisma" class="a-link-button tooltip">add charisma exp<span class="tooltiptext">Add that many charisma experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-intelligence-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-intelligence" class="a-link-button tooltip">add intelligence exp<span class="tooltiptext">Add that many intelligence experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<a id="dev-enable-intelligence" class="a-link-button tooltip"> enable intelligence<span class="tooltiptext">Enables the intelligence stat</span></a>
<a id="dev-disable-intelligence" class="a-link-button tooltip"> disable intelligence<span class="tooltiptext">Disables the intelligence stat</span></a>
</div>
<!-- Location (visiting a location in World) --> <!-- Location (visiting a location in World) -->
<div id="location-container" class="generic-menupage-container"> <div id="location-container" class="generic-menupage-container">
<a id="location-return-to-world-button" class="a-link-button"> Return to World </a> <a id="location-return-to-world-button" class="a-link-button"> Return to World </a>