mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-10 01:33:54 +01:00
commit
7afc7d5c78
@ -137,7 +137,7 @@ module.exports = {
|
|||||||
"no-ex-assign": ["off"],
|
"no-ex-assign": ["off"],
|
||||||
"no-extra-boolean-cast": ["error"],
|
"no-extra-boolean-cast": ["error"],
|
||||||
"no-extra-parens": ["off"],
|
"no-extra-parens": ["off"],
|
||||||
"no-extra-semi": ["off"],
|
"no-extra-semi": ["error"],
|
||||||
"no-eval": ["off"],
|
"no-eval": ["off"],
|
||||||
"no-extend-native": ["off"],
|
"no-extend-native": ["off"],
|
||||||
"no-extra-bind": ["error"],
|
"no-extra-bind": ["error"],
|
||||||
@ -166,12 +166,12 @@ module.exports = {
|
|||||||
"no-label-var": ["error"],
|
"no-label-var": ["error"],
|
||||||
"no-labels": ["off"],
|
"no-labels": ["off"],
|
||||||
"no-lone-blocks": ["error"],
|
"no-lone-blocks": ["error"],
|
||||||
"no-lonely-if": ["off"],
|
"no-lonely-if": ["error"],
|
||||||
"no-loop-func": ["off"],
|
"no-loop-func": ["off"],
|
||||||
"no-magic-numbers": ["off"],
|
"no-magic-numbers": ["off"],
|
||||||
"no-mixed-operators": ["off"],
|
"no-mixed-operators": ["off"],
|
||||||
"no-mixed-requires": ["error"],
|
"no-mixed-requires": ["error"],
|
||||||
"no-mixed-spaces-and-tabs": ["off"],
|
"no-mixed-spaces-and-tabs": ["error"],
|
||||||
"no-multi-assign": ["off"],
|
"no-multi-assign": ["off"],
|
||||||
"no-multi-spaces": ["off"],
|
"no-multi-spaces": ["off"],
|
||||||
"no-multi-str": ["error"],
|
"no-multi-str": ["error"],
|
||||||
@ -253,7 +253,7 @@ module.exports = {
|
|||||||
"no-use-before-define": ["off"],
|
"no-use-before-define": ["off"],
|
||||||
"no-useless-call": ["off"],
|
"no-useless-call": ["off"],
|
||||||
"no-useless-computed-key": ["error"],
|
"no-useless-computed-key": ["error"],
|
||||||
"no-useless-concat": ["off"],
|
"no-useless-concat": ["error"],
|
||||||
"no-useless-constructor": ["error"],
|
"no-useless-constructor": ["error"],
|
||||||
"no-useless-escape": ["off"],
|
"no-useless-escape": ["off"],
|
||||||
"no-useless-rename": [
|
"no-useless-rename": [
|
||||||
|
89
dist/vendor.bundle.js
vendored
89
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/vendor.bundle.js.map
vendored
2
dist/vendor.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
@ -6,10 +6,8 @@ Intelligence is a :ref:`stat <gameplay_stats>` that is unlocked by having
|
|||||||
:ref:`Source-File 5 <gameplay_sourcefiles>` (i.e. Destroying BitNode-5).
|
:ref:`Source-File 5 <gameplay_sourcefiles>` (i.e. Destroying BitNode-5).
|
||||||
|
|
||||||
Intelligence is unique because it is permanent and persistent. It never gets reset
|
Intelligence is unique because it is permanent and persistent. It never gets reset
|
||||||
back to 1. However, gaining Intelligence experience is extremely slow. The methods
|
back to 1. However, gaining Intelligence experience is extremely slow. It is a stat
|
||||||
of gaining Intelligence exp is also hidden. You won't know when you gain
|
that gradually builds up as you continue to play the game.
|
||||||
experience and how much. It is a stat that gradually builds up as you continue
|
|
||||||
to play the game.
|
|
||||||
|
|
||||||
Intelligence will boost your production for many actions in the game, including:
|
Intelligence will boost your production for many actions in the game, including:
|
||||||
|
|
||||||
|
@ -21,23 +21,19 @@ can be used to check how much RAM a server has.
|
|||||||
|
|
||||||
Identifying Servers
|
Identifying Servers
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
A server is identified by two properties: its IP address and its hostname.
|
A server is identified by its hostname.
|
||||||
An IP address is a 32-bit number represented in dot-decimal notation.
|
A hostname is a label assigned to a server.
|
||||||
For example, "56.1.5.0" and "86.5.1.0" might be two IP addresses
|
|
||||||
you see in the game. A hostname is a label assigned to a server.
|
|
||||||
A hostname will usually give you a general idea of what the server
|
A hostname will usually give you a general idea of what the server
|
||||||
is. For example, the company Nova Medical might have a server with
|
is. For example, the company Nova Medical might have a server with
|
||||||
the hostname "nova-med".
|
the hostname "nova-med".
|
||||||
|
|
||||||
Hostnames and IP addresses are unique. This means that if one
|
Hostnames are unique. This means that if one
|
||||||
server has the IP address "1.1.1.1" and the hostname
|
server has the the hostname "some-server", then no other server
|
||||||
"some-server", then no other server in the game can have that
|
in the game can have that that hostname.
|
||||||
IP address or that hostname.
|
|
||||||
|
|
||||||
There are many :ref:`Netscript Functions <netscriptfunctions>`
|
There are many :ref:`Netscript Functions <netscriptfunctions>`
|
||||||
and :ref:`terminal` commands in the game
|
and :ref:`terminal` commands in the game
|
||||||
that will require you to target a specific server. This is done using
|
that will require you to target a specific server by hostname.
|
||||||
either the IP address or the hostname of the server.
|
|
||||||
|
|
||||||
Player-owned Servers
|
Player-owned Servers
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -230,7 +230,7 @@ connect
|
|||||||
|
|
||||||
$ connect [hostname/ip]
|
$ connect [hostname/ip]
|
||||||
|
|
||||||
Connect to a remote server. The hostname or IP address of the remote server must
|
Connect to a remote server. The hostname of the remote server must
|
||||||
be given as the argument to this command. Note that only servers that are immediately
|
be given as the argument to this command. Note that only servers that are immediately
|
||||||
adjacent to the current server in the network can be connected to. To see which
|
adjacent to the current server in the network can be connected to. To see which
|
||||||
servers can be connected to, use the 'scan' command.
|
servers can be connected to, use the 'scan' command.
|
||||||
@ -326,7 +326,7 @@ Then to kill this script the same arguments would have to be used::
|
|||||||
|
|
||||||
$ kill foo.script 50e3 sigma-cosmetics
|
$ kill foo.script 50e3 sigma-cosmetics
|
||||||
|
|
||||||
If you are killing the script using its PID, then the PID argument must be numeric.
|
If you are killing the script using its PID, then the PID argument must be numeric.
|
||||||
|
|
||||||
killall
|
killall
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
@ -533,28 +533,6 @@ Then in order to check its logs with 'tail' the same arguments must be used::
|
|||||||
|
|
||||||
$ tail foo.script 10 50000
|
$ tail foo.script 10 50000
|
||||||
|
|
||||||
theme
|
|
||||||
^^^^^
|
|
||||||
|
|
||||||
$ theme [preset] | [#background #text #highlight]
|
|
||||||
|
|
||||||
Change the color of the game's user interface
|
|
||||||
|
|
||||||
This command can be called with a preset theme. Currently, the supported presets are:
|
|
||||||
|
|
||||||
* default
|
|
||||||
* muted
|
|
||||||
* solarized
|
|
||||||
|
|
||||||
However, you can also specify your own color scheme using hex values.
|
|
||||||
To do so, you must specify three hex color values for the background
|
|
||||||
color, the text color, and the highlight color. These hex values must
|
|
||||||
be preceded by a pound sign (#) and must be either 3 or 6 digits. Example::
|
|
||||||
|
|
||||||
$ theme #ffffff #385 #235012
|
|
||||||
|
|
||||||
A color picker such as Google's can be used to get your desired hex color values
|
|
||||||
|
|
||||||
top
|
top
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
|
@ -337,23 +337,21 @@ async function restoreIfNewerExists(window) {
|
|||||||
let bestMatch;
|
let bestMatch;
|
||||||
if (!steam.data && !disk.data) {
|
if (!steam.data && !disk.data) {
|
||||||
log.info("No data to import");
|
log.info("No data to import");
|
||||||
} else {
|
} else if (!steam.data) {
|
||||||
// We'll just compare using the lastSave field for now.
|
// We'll just compare using the lastSave field for now.
|
||||||
if (!steam.data) {
|
log.debug('Best potential save match: Disk');
|
||||||
log.debug('Best potential save match: Disk');
|
bestMatch = disk;
|
||||||
bestMatch = disk;
|
} else if (!disk.data) {
|
||||||
} else if (!disk.data) {
|
log.debug('Best potential save match: Steam Cloud');
|
||||||
log.debug('Best potential save match: Steam Cloud');
|
bestMatch = steam;
|
||||||
bestMatch = steam;
|
} else if ((steam.data.lastSave >= disk.data.lastSave)
|
||||||
} else if ((steam.data.lastSave >= disk.data.lastSave)
|
|| (steam.data.playtime + lowPlaytime > disk.data.playtime)) {
|
||||||
|| (steam.data.playtime + lowPlaytime > disk.data.playtime)) {
|
// We want to prioritze steam data if the playtime is very close
|
||||||
// We want to prioritze steam data if the playtime is very close
|
log.debug('Best potential save match: Steam Cloud');
|
||||||
log.debug('Best potential save match: Steam Cloud');
|
bestMatch = steam;
|
||||||
bestMatch = steam;
|
} else {
|
||||||
} else {
|
log.debug('Best potential save match: disk');
|
||||||
log.debug('Best potential save match: disk');
|
bestMatch = disk;
|
||||||
bestMatch = disk;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (bestMatch) {
|
if (bestMatch) {
|
||||||
if (bestMatch.data.lastSave > currentData.lastSave + 5000) {
|
if (bestMatch.data.lastSave > currentData.lastSave + 5000) {
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
49
package-lock.json
generated
49
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "bitburner",
|
"name": "bitburner",
|
||||||
"version": "1.4.0",
|
"version": "1.5.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "bitburner",
|
"name": "bitburner",
|
||||||
"version": "1.4.0",
|
"version": "1.5.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "SEE LICENSE IN license.txt",
|
"license": "SEE LICENSE IN license.txt",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -17,9 +17,12 @@
|
|||||||
"@mui/icons-material": "^5.0.3",
|
"@mui/icons-material": "^5.0.3",
|
||||||
"@mui/material": "^5.0.3",
|
"@mui/material": "^5.0.3",
|
||||||
"@mui/styles": "^5.0.1",
|
"@mui/styles": "^5.0.1",
|
||||||
|
"@types/bcrypt": "^5.0.0",
|
||||||
|
"@types/bcryptjs": "^2.4.2",
|
||||||
"acorn": "^8.4.1",
|
"acorn": "^8.4.1",
|
||||||
"acorn-walk": "^8.1.1",
|
"acorn-walk": "^8.1.1",
|
||||||
"arg": "^5.0.0",
|
"arg": "^5.0.0",
|
||||||
|
"bcryptjs": "^2.4.3",
|
||||||
"better-react-mathjax": "^1.0.3",
|
"better-react-mathjax": "^1.0.3",
|
||||||
"clsx": "^1.1.1",
|
"clsx": "^1.1.1",
|
||||||
"date-fns": "^2.25.0",
|
"date-fns": "^2.25.0",
|
||||||
@ -3977,6 +3980,19 @@
|
|||||||
"@babel/types": "^7.3.0"
|
"@babel/types": "^7.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/bcrypt": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/bcryptjs": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ=="
|
||||||
|
},
|
||||||
"node_modules/@types/escodegen": {
|
"node_modules/@types/escodegen": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
||||||
@ -4068,8 +4084,7 @@
|
|||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "16.10.4",
|
"version": "16.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.4.tgz",
|
||||||
"integrity": "sha512-EITwVTX5B4nDjXjGeQAfXOrm+Jn+qNjDmyDRtWoD+wZsl/RDPRTFRKivs4Mt74iOFlLOrE5+Kf+p5yjyhm3+cA==",
|
"integrity": "sha512-EITwVTX5B4nDjXjGeQAfXOrm+Jn+qNjDmyDRtWoD+wZsl/RDPRTFRKivs4Mt74iOFlLOrE5+Kf+p5yjyhm3+cA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/@types/numeral": {
|
"node_modules/@types/numeral": {
|
||||||
"version": "0.0.25",
|
"version": "0.0.25",
|
||||||
@ -5448,6 +5463,11 @@
|
|||||||
"tweetnacl": "^0.14.3"
|
"tweetnacl": "^0.14.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/bcryptjs": {
|
||||||
|
"version": "2.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
|
||||||
|
"integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
|
||||||
|
},
|
||||||
"node_modules/better-react-mathjax": {
|
"node_modules/better-react-mathjax": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-1.0.3.tgz",
|
||||||
@ -25344,6 +25364,19 @@
|
|||||||
"@babel/types": "^7.3.0"
|
"@babel/types": "^7.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/bcrypt": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/bcryptjs": {
|
||||||
|
"version": "2.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.2.tgz",
|
||||||
|
"integrity": "sha512-LiMQ6EOPob/4yUL66SZzu6Yh77cbzJFYll+ZfaPiPPFswtIlA/Fs1MzdKYA7JApHU49zQTbJGX3PDmCpIdDBRQ=="
|
||||||
|
},
|
||||||
"@types/escodegen": {
|
"@types/escodegen": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/escodegen/-/escodegen-0.0.7.tgz",
|
||||||
@ -25435,8 +25468,7 @@
|
|||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "16.10.4",
|
"version": "16.10.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.10.4.tgz",
|
||||||
"integrity": "sha512-EITwVTX5B4nDjXjGeQAfXOrm+Jn+qNjDmyDRtWoD+wZsl/RDPRTFRKivs4Mt74iOFlLOrE5+Kf+p5yjyhm3+cA==",
|
"integrity": "sha512-EITwVTX5B4nDjXjGeQAfXOrm+Jn+qNjDmyDRtWoD+wZsl/RDPRTFRKivs4Mt74iOFlLOrE5+Kf+p5yjyhm3+cA=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"@types/numeral": {
|
"@types/numeral": {
|
||||||
"version": "0.0.25",
|
"version": "0.0.25",
|
||||||
@ -26527,6 +26559,11 @@
|
|||||||
"tweetnacl": "^0.14.3"
|
"tweetnacl": "^0.14.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"bcryptjs": {
|
||||||
|
"version": "2.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
|
||||||
|
"integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms="
|
||||||
|
},
|
||||||
"better-react-mathjax": {
|
"better-react-mathjax": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/better-react-mathjax/-/better-react-mathjax-1.0.3.tgz",
|
||||||
|
@ -17,9 +17,12 @@
|
|||||||
"@mui/icons-material": "^5.0.3",
|
"@mui/icons-material": "^5.0.3",
|
||||||
"@mui/material": "^5.0.3",
|
"@mui/material": "^5.0.3",
|
||||||
"@mui/styles": "^5.0.1",
|
"@mui/styles": "^5.0.1",
|
||||||
|
"@types/bcrypt": "^5.0.0",
|
||||||
|
"@types/bcryptjs": "^2.4.2",
|
||||||
"acorn": "^8.4.1",
|
"acorn": "^8.4.1",
|
||||||
"acorn-walk": "^8.1.1",
|
"acorn-walk": "^8.1.1",
|
||||||
"arg": "^5.0.0",
|
"arg": "^5.0.0",
|
||||||
|
"bcryptjs": "^2.4.3",
|
||||||
"better-react-mathjax": "^1.0.3",
|
"better-react-mathjax": "^1.0.3",
|
||||||
"clsx": "^1.1.1",
|
"clsx": "^1.1.1",
|
||||||
"date-fns": "^2.25.0",
|
"date-fns": "^2.25.0",
|
||||||
|
@ -481,7 +481,16 @@
|
|||||||
"ID": "DEVMENU",
|
"ID": "DEVMENU",
|
||||||
"Name": "Exploit: you're not meant to access this",
|
"Name": "Exploit: you're not meant to access this",
|
||||||
"Description": "Open the dev menu."
|
"Description": "Open the dev menu."
|
||||||
|
},
|
||||||
|
"RAINBOW": {
|
||||||
|
"ID": "RAINBOW",
|
||||||
|
"Name": "Exploit: rainbow",
|
||||||
|
"Description": "Make good use of the rainbow."
|
||||||
|
},
|
||||||
|
"TRUE_RECURSION": {
|
||||||
|
"ID": "TRUE_RECURSION",
|
||||||
|
"Name": "Exploit: true recursion",
|
||||||
|
"Description": "Beat BN1 in megabyteburner 2000."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +553,8 @@ export const achievements: IMap<Achievement> = {
|
|||||||
...achievementData["MAX_CACHE"],
|
...achievementData["MAX_CACHE"],
|
||||||
Icon: "HASHNETCAP",
|
Icon: "HASHNETCAP",
|
||||||
Visible: () => hasAccessToSF(Player, 9),
|
Visible: () => hasAccessToSF(Player, 9),
|
||||||
Condition: () => hasHacknetServers(Player) &&
|
Condition: () =>
|
||||||
|
hasHacknetServers(Player) &&
|
||||||
Player.hashManager.hashes === Player.hashManager.capacity &&
|
Player.hashManager.hashes === Player.hashManager.capacity &&
|
||||||
Player.hashManager.capacity > 0,
|
Player.hashManager.capacity > 0,
|
||||||
},
|
},
|
||||||
@ -729,6 +730,18 @@ export const achievements: IMap<Achievement> = {
|
|||||||
Secret: true,
|
Secret: true,
|
||||||
Condition: () => Player.exploits.includes(Exploit.YoureNotMeantToAccessThis),
|
Condition: () => Player.exploits.includes(Exploit.YoureNotMeantToAccessThis),
|
||||||
},
|
},
|
||||||
|
RAINBOW: {
|
||||||
|
...achievementData["RAINBOW"],
|
||||||
|
Icon: "SF-1",
|
||||||
|
Secret: true,
|
||||||
|
Condition: () => Player.exploits.includes(Exploit.INeedARainbow),
|
||||||
|
},
|
||||||
|
TRUE_RECURSION: {
|
||||||
|
...achievementData["TRUE_RECURSION"],
|
||||||
|
Icon: "SF-1",
|
||||||
|
Secret: true,
|
||||||
|
Condition: () => Player.exploits.includes(Exploit.TrueRecursion),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Steam has a limit of 100 achievement. So these were planned but commented for now.
|
// Steam has a limit of 100 achievement. So these were planned but commented for now.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
import { Exploit } from "../../Exploits/Exploit";
|
||||||
|
|
||||||
const metaBB = "https://bitburner-official.github.io/bitburner-legacy/";
|
const metaBB = "https://bitburner-official.github.io/bitburner-legacy/";
|
||||||
|
|
||||||
@ -10,6 +12,14 @@ const style = {
|
|||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
export function BBCabinetRoot(): React.ReactElement {
|
export function BBCabinetRoot(): React.ReactElement {
|
||||||
|
const player = use.Player();
|
||||||
|
useEffect(() => {
|
||||||
|
window.addEventListener("message", function (this: Window, ev: MessageEvent<boolean>) {
|
||||||
|
if (ev.isTrusted && ev.origin == "https://bitburner-official.github.io" && ev.data) {
|
||||||
|
player.giveExploit(Exploit.TrueRecursion);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const joystick =
|
const joystick =
|
||||||
<>
|
<>
|
||||||
|
@ -148,7 +148,7 @@ function initAugmentations(): void {
|
|||||||
name: AugmentationNames.HemoRecirculator,
|
name: AugmentationNames.HemoRecirculator,
|
||||||
moneyCost: 4.5e7,
|
moneyCost: 4.5e7,
|
||||||
repCost: 1e4,
|
repCost: 1e4,
|
||||||
info: "A heart implant that greatly increases the body's ability to effectively use and pump " + "blood.",
|
info: "A heart implant that greatly increases the body's ability to effectively use and pump blood.",
|
||||||
strength_mult: 1.08,
|
strength_mult: 1.08,
|
||||||
defense_mult: 1.08,
|
defense_mult: 1.08,
|
||||||
agility_mult: 1.08,
|
agility_mult: 1.08,
|
||||||
@ -430,7 +430,7 @@ function initAugmentations(): void {
|
|||||||
repCost: 1.125e6,
|
repCost: 1.125e6,
|
||||||
moneyCost: 4.25e9,
|
moneyCost: 4.25e9,
|
||||||
info:
|
info:
|
||||||
"Graphene is grafted and fused into the skeletal structure, " + "enhancing bone density and tensile strength.",
|
"Graphene is grafted and fused into the skeletal structure, enhancing bone density and tensile strength.",
|
||||||
strength_mult: 1.7,
|
strength_mult: 1.7,
|
||||||
defense_mult: 1.7,
|
defense_mult: 1.7,
|
||||||
});
|
});
|
||||||
@ -1085,7 +1085,7 @@ function initAugmentations(): void {
|
|||||||
name: AugmentationNames.FocusWire,
|
name: AugmentationNames.FocusWire,
|
||||||
repCost: 7.5e4,
|
repCost: 7.5e4,
|
||||||
moneyCost: 9e8,
|
moneyCost: 9e8,
|
||||||
info: "A cranial implant that stops procrastination by blocking specific neural pathways " + "in the brain.",
|
info: "A cranial implant that stops procrastination by blocking specific neural pathways in the brain.",
|
||||||
hacking_exp_mult: 1.05,
|
hacking_exp_mult: 1.05,
|
||||||
strength_exp_mult: 1.05,
|
strength_exp_mult: 1.05,
|
||||||
defense_exp_mult: 1.05,
|
defense_exp_mult: 1.05,
|
||||||
@ -1486,7 +1486,7 @@ function initAugmentations(): void {
|
|||||||
name: AugmentationNames.SmartSonar,
|
name: AugmentationNames.SmartSonar,
|
||||||
repCost: 2.25e4,
|
repCost: 2.25e4,
|
||||||
moneyCost: 7.5e7,
|
moneyCost: 7.5e7,
|
||||||
info: "A cochlear implant that helps the player detect and locate enemies " + "using sound propagation.",
|
info: "A cochlear implant that helps the player detect and locate enemies using sound propagation.",
|
||||||
dexterity_mult: 1.1,
|
dexterity_mult: 1.1,
|
||||||
dexterity_exp_mult: 1.15,
|
dexterity_exp_mult: 1.15,
|
||||||
crime_money_mult: 1.25,
|
crime_money_mult: 1.25,
|
||||||
@ -1703,7 +1703,7 @@ function initAugmentations(): void {
|
|||||||
"The left arm of a legendary BitRunner who ascended beyond this world. " +
|
"The left arm of a legendary BitRunner who ascended beyond this world. " +
|
||||||
"It projects a light blue energy shield that protects the exposed inner parts. " +
|
"It projects a light blue energy shield that protects the exposed inner parts. " +
|
||||||
"Even though it contains no weapons, the advanced tungsten titanium " +
|
"Even though it contains no weapons, the advanced tungsten titanium " +
|
||||||
"alloy increases the users strength to unbelievable levels. The augmentation " +
|
"alloy increases the user's strength to unbelievable levels. The augmentation " +
|
||||||
"gets more powerful over time for seemingly no reason.",
|
"gets more powerful over time for seemingly no reason.",
|
||||||
strength_mult: 2.7,
|
strength_mult: 2.7,
|
||||||
});
|
});
|
||||||
@ -2015,7 +2015,7 @@ function initAugmentations(): void {
|
|||||||
repCost: 6.25e4,
|
repCost: 6.25e4,
|
||||||
moneyCost: 2.75e8,
|
moneyCost: 2.75e8,
|
||||||
info:
|
info:
|
||||||
"Cybernetic arms created from plasteel and carbon fibers that completely replace " + "the user's organic arms.",
|
"Cybernetic arms created from plasteel and carbon fibers that completely replace the user's organic arms.",
|
||||||
strength_mult: 1.3,
|
strength_mult: 1.3,
|
||||||
dexterity_mult: 1.3,
|
dexterity_mult: 1.3,
|
||||||
});
|
});
|
||||||
|
@ -202,8 +202,8 @@ BitNodes["BitNode5"] = new BitNode(
|
|||||||
Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will upgrade its
|
Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will upgrade its
|
||||||
level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. Intelligence is
|
level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. Intelligence is
|
||||||
unique because it is permanent and persistent (it never gets reset back to 1). However gaining Intelligence
|
unique because it is permanent and persistent (it never gets reset back to 1). However gaining Intelligence
|
||||||
experience is much slower than other stats, and it is also hidden (you won't know when you gain experience and how
|
experience is much slower than other stats. Higher Intelligence levels will boost your production for many actions
|
||||||
much). Higher Intelligence levels will boost your production for many actions in the game. <br />
|
in the game. <br />
|
||||||
<br />
|
<br />
|
||||||
In addition, this Source-File will unlock the getBitNodeMultipliers() Netscript function and let you start with
|
In addition, this Source-File will unlock the getBitNodeMultipliers() Netscript function and let you start with
|
||||||
Formulas.exe, and will also raise all of your hacking-related multipliers by:
|
Formulas.exe, and will also raise all of your hacking-related multipliers by:
|
||||||
|
@ -135,7 +135,7 @@ export class Action implements IAction {
|
|||||||
if (this.decays.hasOwnProperty(decay)) {
|
if (this.decays.hasOwnProperty(decay)) {
|
||||||
if (this.decays[decay] > 1) {
|
if (this.decays[decay] > 1) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"Invalid decays when constructing " + "Action " + this.name + ". " + "Decay value cannot be greater than 1",
|
`Invalid decays when constructing Action ${this.name}. Decay value cannot be greater than 1`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ export const Skills: IMap<Skill> = {};
|
|||||||
Skills[SkillNames.BladesIntuition] = new Skill({
|
Skills[SkillNames.BladesIntuition] = new Skill({
|
||||||
name: SkillNames.BladesIntuition,
|
name: SkillNames.BladesIntuition,
|
||||||
desc:
|
desc:
|
||||||
"Each level of this skill increases your success chance " + "for all Contracts, Operations, and BlackOps by 3%",
|
"Each level of this skill increases your success chance for all Contracts, Operations, and BlackOps by 3%",
|
||||||
baseCost: 3,
|
baseCost: 3,
|
||||||
costInc: 2.1,
|
costInc: 2.1,
|
||||||
successChanceAll: 3,
|
successChanceAll: 3,
|
||||||
@ -33,14 +33,14 @@ export const Skills: IMap<Skill> = {};
|
|||||||
});
|
});
|
||||||
Skills[SkillNames.DigitalObserver] = new Skill({
|
Skills[SkillNames.DigitalObserver] = new Skill({
|
||||||
name: SkillNames.DigitalObserver,
|
name: SkillNames.DigitalObserver,
|
||||||
desc: "Each level of this skill increases your success chance in " + "all Operations and BlackOps by 4%",
|
desc: "Each level of this skill increases your success chance in all Operations and BlackOps by 4%",
|
||||||
baseCost: 2,
|
baseCost: 2,
|
||||||
costInc: 2.1,
|
costInc: 2.1,
|
||||||
successChanceOperation: 4,
|
successChanceOperation: 4,
|
||||||
});
|
});
|
||||||
Skills[SkillNames.Tracer] = new Skill({
|
Skills[SkillNames.Tracer] = new Skill({
|
||||||
name: SkillNames.Tracer,
|
name: SkillNames.Tracer,
|
||||||
desc: "Each level of this skill increases your success chance in " + "all Contracts by 4%",
|
desc: "Each level of this skill increases your success chance in all Contracts by 4%",
|
||||||
baseCost: 2,
|
baseCost: 2,
|
||||||
costInc: 2.1,
|
costInc: 2.1,
|
||||||
successChanceContract: 4,
|
successChanceContract: 4,
|
||||||
@ -67,7 +67,7 @@ export const Skills: IMap<Skill> = {};
|
|||||||
});
|
});
|
||||||
Skills[SkillNames.EvasiveSystem] = new Skill({
|
Skills[SkillNames.EvasiveSystem] = new Skill({
|
||||||
name: SkillNames.EvasiveSystem,
|
name: SkillNames.EvasiveSystem,
|
||||||
desc: "Each level of this skill increases your effective " + "dexterity and agility for Bladeburner actions by 4%",
|
desc: "Each level of this skill increases your effective dexterity and agility for Bladeburner actions by 4%",
|
||||||
baseCost: 2,
|
baseCost: 2,
|
||||||
costInc: 2.1,
|
costInc: 2.1,
|
||||||
effDex: 4,
|
effDex: 4,
|
||||||
|
@ -119,17 +119,17 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
|
|||||||
try {
|
try {
|
||||||
tempQty = eval(tempQty);
|
tempQty = eval(tempQty);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("Invalid value or expression for sell price field: " + e);
|
throw new Error("Invalid value or expression for sell quantity field: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tempQty == null || isNaN(parseFloat(tempQty)) || parseFloat(tempQty) < 0) {
|
if (tempQty == null || isNaN(parseFloat(tempQty)) || parseFloat(tempQty) < 0) {
|
||||||
throw new Error("Invalid value or expression for sell price field");
|
throw new Error("Invalid value or expression for sell quantity field");
|
||||||
}
|
}
|
||||||
|
|
||||||
mat.sllman[0] = true;
|
mat.sllman[0] = true;
|
||||||
mat.sllman[1] = q; //Use sanitized input
|
mat.sllman[1] = q; //Use sanitized input
|
||||||
} else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
|
} else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
|
||||||
throw new Error("Invalid value for sell quantity field! Must be numeric or 'MAX'");
|
throw new Error("Invalid value for sell quantity field! Must be numeric or 'PROD' or 'MAX'");
|
||||||
} else {
|
} else {
|
||||||
let q = parseFloat(amt);
|
let q = parseFloat(amt);
|
||||||
if (isNaN(q)) {
|
if (isNaN(q)) {
|
||||||
@ -156,10 +156,10 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
try {
|
try {
|
||||||
temp = eval(temp);
|
temp = eval(temp);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("Invalid value or expression for sell quantity field: " + e);
|
throw new Error("Invalid value or expression for sell price field: " + e);
|
||||||
}
|
}
|
||||||
if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
|
if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
|
||||||
throw new Error("Invalid value or expression for sell quantity field.");
|
throw new Error("Invalid value or expression for sell price field.");
|
||||||
}
|
}
|
||||||
product.sCost = price; //Use sanitized price
|
product.sCost = price; //Use sanitized price
|
||||||
} else {
|
} else {
|
||||||
@ -184,11 +184,11 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
try {
|
try {
|
||||||
temp = eval(temp);
|
temp = eval(temp);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Error("Invalid value or expression for sell price field: " + e);
|
throw new Error("Invalid value or expression for sell quantity field: " + e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
|
if (temp == null || isNaN(parseFloat(temp)) || parseFloat(temp) < 0) {
|
||||||
throw new Error("Invalid value or expression for sell price field");
|
throw new Error("Invalid value or expression for sell quantity field");
|
||||||
}
|
}
|
||||||
if (all) {
|
if (all) {
|
||||||
for (let i = 0; i < cities.length; ++i) {
|
for (let i = 0; i < cities.length; ++i) {
|
||||||
@ -201,7 +201,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
product.sllman[city][1] = qty; //Use sanitized input
|
product.sllman[city][1] = qty; //Use sanitized input
|
||||||
}
|
}
|
||||||
} else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
|
} else if (isNaN(parseFloat(amt)) || parseFloat(amt) < 0) {
|
||||||
throw new Error("Invalid value for sell quantity field! Must be numeric");
|
throw new Error("Invalid value for sell quantity field! Must be numeric or 'PROD' or 'MAX'");
|
||||||
} else {
|
} else {
|
||||||
let qty = parseFloat(amt);
|
let qty = parseFloat(amt);
|
||||||
if (isNaN(qty)) {
|
if (isNaN(qty)) {
|
||||||
@ -218,8 +218,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
product.sllman[city][0] = false;
|
product.sllman[city][0] = false;
|
||||||
product.sllman[city][1] = "";
|
product.sllman[city][1] = "";
|
||||||
}
|
}
|
||||||
} else {
|
} else if (all) {
|
||||||
if (all) {
|
|
||||||
for (let i = 0; i < cities.length; ++i) {
|
for (let i = 0; i < cities.length; ++i) {
|
||||||
const tempCity = cities[i];
|
const tempCity = cities[i];
|
||||||
product.sllman[tempCity][0] = true;
|
product.sllman[tempCity][0] = true;
|
||||||
@ -229,7 +228,6 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
product.sllman[city][0] = true;
|
product.sllman[city][0] = true;
|
||||||
product.sllman[city][1] = qty;
|
product.sllman[city][1] = qty;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,13 +227,13 @@ export function resetIndustryResearchTrees(): void {
|
|||||||
IndustryResearchTrees.Agriculture = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Agriculture = getBaseResearchTreeCopy();
|
||||||
IndustryResearchTrees.Fishing = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Fishing = getBaseResearchTreeCopy();
|
||||||
IndustryResearchTrees.Mining = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Mining = getBaseResearchTreeCopy();
|
||||||
IndustryResearchTrees.Food = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Food = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.Tobacco = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Tobacco = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.Chemical = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Chemical = getBaseResearchTreeCopy();
|
||||||
IndustryResearchTrees.Pharmaceutical = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Pharmaceutical = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.Computer = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Computer = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.Robotics = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Robotics = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.Software = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Software = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.Healthcare = getBaseResearchTreeCopy();
|
IndustryResearchTrees.Healthcare = getProductIndustryResearchTreeCopy();
|
||||||
IndustryResearchTrees.RealEstate = getBaseResearchTreeCopy();
|
IndustryResearchTrees.RealEstate = getProductIndustryResearchTreeCopy();
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ export const researchMetadata: IConstructorParams[] = [
|
|||||||
{
|
{
|
||||||
name: "JoyWire",
|
name: "JoyWire",
|
||||||
cost: 20e3,
|
cost: 20e3,
|
||||||
desc: "A brain implant which is installed in employees, increasing their " + "maximum happiness by 10.",
|
desc: "A brain implant which is installed in employees, increasing their maximum happiness by 10.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Market-TA.I",
|
name: "Market-TA.I",
|
||||||
@ -160,7 +160,7 @@ export const researchMetadata: IConstructorParams[] = [
|
|||||||
{
|
{
|
||||||
name: "sudo.Assist",
|
name: "sudo.Assist",
|
||||||
cost: 15e3,
|
cost: 15e3,
|
||||||
desc: "Develop a virtual assistant AI to handle and manage administrative " + "issues for your corporation.",
|
desc: "Develop a virtual assistant AI to handle and manage administrative issues for your corporation.",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "uPgrade: Capacity.I",
|
name: "uPgrade: Capacity.I",
|
||||||
|
@ -33,8 +33,7 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
|
|||||||
function throwParty(): void {
|
function throwParty(): void {
|
||||||
if (cost === null || isNaN(cost) || cost < 0) {
|
if (cost === null || isNaN(cost) || cost < 0) {
|
||||||
dialogBoxCreate("Invalid value entered");
|
dialogBoxCreate("Invalid value entered");
|
||||||
} else {
|
} else if (!canParty) {
|
||||||
if (!canParty) {
|
|
||||||
dialogBoxCreate("You don't have enough company funds to throw a party!");
|
dialogBoxCreate("You don't have enough company funds to throw a party!");
|
||||||
} else {
|
} else {
|
||||||
const mult = ThrowParty(corp, props.office, cost);
|
const mult = ThrowParty(corp, props.office, cost);
|
||||||
@ -46,7 +45,6 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
|
|||||||
props.rerender();
|
props.rerender();
|
||||||
props.onClose();
|
props.onClose();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function EffectText(): React.ReactElement {
|
function EffectText(): React.ReactElement {
|
||||||
|
@ -19,6 +19,8 @@ export enum Exploit {
|
|||||||
RealityAlteration = "RealityAlteration",
|
RealityAlteration = "RealityAlteration",
|
||||||
N00dles = "N00dles",
|
N00dles = "N00dles",
|
||||||
YoureNotMeantToAccessThis = "YoureNotMeantToAccessThis",
|
YoureNotMeantToAccessThis = "YoureNotMeantToAccessThis",
|
||||||
|
TrueRecursion = "TrueRecursion",
|
||||||
|
INeedARainbow = "INeedARainbow",
|
||||||
// To the players reading this. Yes you're supposed to add EditSaveFile by
|
// To the players reading this. Yes you're supposed to add EditSaveFile by
|
||||||
// editing your save file, yes you could add them all, no we don't care
|
// editing your save file, yes you could add them all, no we don't care
|
||||||
// that's not the point.
|
// that's not the point.
|
||||||
@ -37,6 +39,8 @@ const names: {
|
|||||||
RealityAlteration: "by altering reality to suit your whims.",
|
RealityAlteration: "by altering reality to suit your whims.",
|
||||||
N00dles: "by harnessing the power of the n00dles.",
|
N00dles: "by harnessing the power of the n00dles.",
|
||||||
YoureNotMeantToAccessThis: "by accessing the dev menu.",
|
YoureNotMeantToAccessThis: "by accessing the dev menu.",
|
||||||
|
TrueRecursion: "by truly recursing.",
|
||||||
|
INeedARainbow: "by using the power of the rainbow.",
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ExploitName(exploit: string): string {
|
export function ExploitName(exploit: string): string {
|
||||||
|
@ -117,8 +117,7 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
|||||||
const factionInfo = fac.getInfo();
|
const factionInfo = fac.getInfo();
|
||||||
const hasPrereqs = hasAugmentationPrereqs(aug);
|
const hasPrereqs = hasAugmentationPrereqs(aug);
|
||||||
if (!hasPrereqs) {
|
if (!hasPrereqs) {
|
||||||
const txt =
|
const txt = `You must first purchase or install ${aug.prereqs.join(",")} before you can purchase this one.`;
|
||||||
"You must first purchase or install " + aug.prereqs.join(",") + " before you can " + "purchase this one.";
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
return txt;
|
return txt;
|
||||||
} else {
|
} else {
|
||||||
@ -166,8 +165,7 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
|||||||
|
|
||||||
if (sing) {
|
if (sing) {
|
||||||
return "You purchased " + aug.name;
|
return "You purchased " + aug.name;
|
||||||
} else {
|
} else if (!Settings.SuppressBuyAugmentationConfirmation) {
|
||||||
if (!Settings.SuppressBuyAugmentationConfirmation) {
|
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"You purchased " +
|
"You purchased " +
|
||||||
aug.name +
|
aug.name +
|
||||||
@ -177,7 +175,6 @@ export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = fal
|
|||||||
"augmentations will now be more expensive.",
|
"augmentations will now be more expensive.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"Hmm, something went wrong when trying to purchase an Augmentation. " +
|
"Hmm, something went wrong when trying to purchase an Augmentation. " +
|
||||||
|
@ -28,7 +28,7 @@ type IProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Info text for all options on the UI
|
// Info text for all options on the UI
|
||||||
const gangInfo = "Create and manage a gang for this Faction. Gangs will earn you money and " + "faction reputation";
|
const gangInfo = "Create and manage a gang for this Faction. Gangs will earn you money and faction reputation";
|
||||||
const hackingContractsInfo =
|
const hackingContractsInfo =
|
||||||
"Complete hacking contracts for your faction. " +
|
"Complete hacking contracts for your faction. " +
|
||||||
"Your effectiveness, which determines how much " +
|
"Your effectiveness, which determines how much " +
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
import Box from "@mui/material/Box";
|
|
||||||
import Button from "@mui/material/Button";
|
|
||||||
import Container from "@mui/material/Container";
|
|
||||||
import Paper from "@mui/material/Paper";
|
|
||||||
import TableBody from "@mui/material/TableBody";
|
|
||||||
import TableRow from "@mui/material/TableRow";
|
|
||||||
import Typography from "@mui/material/Typography";
|
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Paper,
|
||||||
|
TableBody,
|
||||||
|
TableRow,
|
||||||
|
Typography
|
||||||
|
} from "@mui/material";
|
||||||
|
|
||||||
|
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { Table, TableCell } from "../../ui/React/Table";
|
import { Table, TableCell } from "../../ui/React/Table";
|
||||||
import { IRouter } from "../../ui/Router";
|
import { IRouter } from "../../ui/Router";
|
||||||
|
|
||||||
import { Faction } from "../Faction";
|
import { Faction } from "../Faction";
|
||||||
import { joinFaction } from "../FactionHelpers";
|
import { joinFaction } from "../FactionHelpers";
|
||||||
import { Factions } from "../Factions";
|
import { Factions } from "../Factions";
|
||||||
@ -51,6 +58,28 @@ export function FactionsRoot(props: IProps): React.ReactElement {
|
|||||||
setRerender((x) => !x);
|
setRerender((x) => !x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getAugsLeft = (faction: Faction, player: IPlayer): number => {
|
||||||
|
const isPlayersGang = player.inGang() && player.getGangName() === faction.name;
|
||||||
|
let augs: string[] = [];
|
||||||
|
|
||||||
|
if (isPlayersGang) {
|
||||||
|
for (const augName of Object.keys(Augmentations)) {
|
||||||
|
if (
|
||||||
|
augName === AugmentationNames.NeuroFluxGovernor ||
|
||||||
|
augName === AugmentationNames.TheRedPill && player.bitNodeN !== 2 ||
|
||||||
|
Augmentations[augName].isSpecial
|
||||||
|
) continue;
|
||||||
|
augs.push(augName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
augs = faction.augmentations.slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
return augs.filter(
|
||||||
|
(augmentation: string) => !player.hasAugmentation(augmentation)
|
||||||
|
).length;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container disableGutters maxWidth="md" sx={{ mx: 0, mb: 10 }}>
|
<Container disableGutters maxWidth="md" sx={{ mx: 0, mb: 10 }}>
|
||||||
<Typography variant="h4">Factions</Typography>
|
<Typography variant="h4">Factions</Typography>
|
||||||
@ -82,11 +111,7 @@ export function FactionsRoot(props: IProps): React.ReactElement {
|
|||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
<Box ml={1} mb={1}>
|
<Box ml={1} mb={1}>
|
||||||
<Button sx={{ width: '100%' }} onClick={() => openFactionAugPage(Factions[faction])}>
|
<Button sx={{ width: '100%' }} onClick={() => openFactionAugPage(Factions[faction])}>
|
||||||
Augmentations Left: {Factions[faction]
|
Augmentations Left: {getAugsLeft(Factions[faction], props.player)}
|
||||||
.augmentations
|
|
||||||
.filter((augmentation: string) =>
|
|
||||||
!props.player.hasAugmentation(augmentation))
|
|
||||||
.length}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
@ -52,21 +52,19 @@ export function SpecialLocation(props: IProps): React.ReactElement {
|
|||||||
if (p.inBladeburner()) {
|
if (p.inBladeburner()) {
|
||||||
// Enter Bladeburner division
|
// Enter Bladeburner division
|
||||||
router.toBladeburner();
|
router.toBladeburner();
|
||||||
} else {
|
} else if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) {
|
||||||
// Apply for Bladeburner division
|
// Apply for Bladeburner division
|
||||||
if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) {
|
p.startBladeburner({new: true});
|
||||||
p.startBladeburner({ new: true });
|
dialogBoxCreate("You have been accepted into the Bladeburner division!");
|
||||||
dialogBoxCreate("You have been accepted into the Bladeburner division!");
|
setRerender((old) => !old);
|
||||||
setRerender((old) => !old);
|
|
||||||
|
|
||||||
const worldHeader = document.getElementById("world-menu-header");
|
const worldHeader = document.getElementById("world-menu-header");
|
||||||
if (worldHeader instanceof HTMLElement) {
|
if (worldHeader instanceof HTMLElement) {
|
||||||
worldHeader.click();
|
worldHeader.click();
|
||||||
worldHeader.click();
|
worldHeader.click();
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dialogBoxCreate("Rejected! Please apply again when you have 100 of each combat stat (str, def, dex, agi)");
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
dialogBoxCreate("Rejected! Please apply again when you have 100 of each combat stat (str, def, dex, agi)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +108,7 @@ export const RamCosts: IMap<any> = {
|
|||||||
hackAnalyzeSecurity: RamCostConstants.ScriptHackAnalyzeRamCost,
|
hackAnalyzeSecurity: RamCostConstants.ScriptHackAnalyzeRamCost,
|
||||||
hackAnalyzeChance: RamCostConstants.ScriptHackAnalyzeRamCost,
|
hackAnalyzeChance: RamCostConstants.ScriptHackAnalyzeRamCost,
|
||||||
sleep: 0,
|
sleep: 0,
|
||||||
|
asleep: 0,
|
||||||
share: 2.4,
|
share: 2.4,
|
||||||
getSharePower: 0.2,
|
getSharePower: 0.2,
|
||||||
grow: RamCostConstants.ScriptGrowRamCost,
|
grow: RamCostConstants.ScriptGrowRamCost,
|
||||||
|
@ -102,7 +102,7 @@ export class WorkerScript {
|
|||||||
scriptRef: RunningScript;
|
scriptRef: RunningScript;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IP Address on which this script is running
|
* hostname on which this script is running
|
||||||
*/
|
*/
|
||||||
hostname: string;
|
hostname: string;
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
throw makeRuntimeRejectMsg(
|
throw makeRuntimeRejectMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
`Invalid scriptArgs argument passed into getRunningScript() from ${callingFnName}(). ` +
|
`Invalid scriptArgs argument passed into getRunningScript() from ${callingFnName}(). ` +
|
||||||
`This is probably a bug. Please report to game developer`,
|
`This is probably a bug. Please report to game developer`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,19 +425,22 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
const helper = {
|
const helper = {
|
||||||
updateDynamicRam: updateDynamicRam,
|
updateDynamicRam: updateDynamicRam,
|
||||||
makeRuntimeErrorMsg: makeRuntimeErrorMsg,
|
makeRuntimeErrorMsg: makeRuntimeErrorMsg,
|
||||||
string: (funcName: string, argName: string, v: any): string => {
|
string: (funcName: string, argName: string, v: unknown): string => {
|
||||||
if (typeof v === "string") return v;
|
if (typeof v === "string") return v;
|
||||||
if (typeof v === "number") return v + ""; // cast to string;
|
if (typeof v === "number") return v + ""; // cast to string;
|
||||||
throw makeRuntimeErrorMsg(funcName, `${argName} should be a string`);
|
throw makeRuntimeErrorMsg(funcName, `${argName} should be a string`);
|
||||||
},
|
},
|
||||||
number: (funcName: string, argName: string, v: any): number => {
|
number: (funcName: string, argName: string, v: unknown): number => {
|
||||||
if (!isNaN(v)) {
|
if (typeof v === "string") {
|
||||||
if (typeof v === "number") return v;
|
const x = parseFloat(v);
|
||||||
if (!isNaN(parseFloat(v))) return parseFloat(v);
|
if (!isNaN(x)) return x; // otherwise it wasn't even a string representing a number.
|
||||||
|
} else if (typeof v === "number") {
|
||||||
|
if (isNaN(v)) throw makeRuntimeErrorMsg(funcName, `${argName} is NaN`);
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
throw makeRuntimeErrorMsg(funcName, `${argName} should be a number`);
|
throw makeRuntimeErrorMsg(funcName, `${argName} should be a number`);
|
||||||
},
|
},
|
||||||
boolean: (v: any): boolean => {
|
boolean: (v: unknown): boolean => {
|
||||||
return !!v; // Just convert it to boolean.
|
return !!v; // Just convert it to boolean.
|
||||||
},
|
},
|
||||||
getServer: safeGetServer,
|
getServer: safeGetServer,
|
||||||
@ -467,7 +470,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
|
|
||||||
const gang = NetscriptGang(Player, workerScript, helper);
|
const gang = NetscriptGang(Player, workerScript, helper);
|
||||||
const sleeve = NetscriptSleeve(Player, workerScript, helper);
|
const sleeve = NetscriptSleeve(Player, workerScript, helper);
|
||||||
const extra = NetscriptExtra(Player, workerScript);
|
const extra = NetscriptExtra(Player, workerScript, helper);
|
||||||
const hacknet = NetscriptHacknet(Player, workerScript, helper);
|
const hacknet = NetscriptHacknet(Player, workerScript, helper);
|
||||||
const stanek = NetscriptStanek(Player, workerScript, helper);
|
const stanek = NetscriptStanek(Player, workerScript, helper);
|
||||||
const bladeburner = NetscriptBladeburner(Player, workerScript, helper);
|
const bladeburner = NetscriptBladeburner(Player, workerScript, helper);
|
||||||
@ -550,6 +553,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return calculatePercentMoneyHacked(server, Player);
|
return calculatePercentMoneyHacked(server, Player);
|
||||||
},
|
},
|
||||||
hackAnalyzeSecurity: function (threads: any): number {
|
hackAnalyzeSecurity: function (threads: any): number {
|
||||||
|
updateDynamicRam("hackAnalyzeSecurity", getRamCost(Player, "hackAnalyzeSecurity"));
|
||||||
return CONSTANTS.ServerFortifyAmount * threads;
|
return CONSTANTS.ServerFortifyAmount * threads;
|
||||||
},
|
},
|
||||||
hackAnalyzeChance: function (hostname: any): any {
|
hackAnalyzeChance: function (hostname: any): any {
|
||||||
@ -564,6 +568,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return calculateHackingChance(server, Player);
|
return calculateHackingChance(server, Player);
|
||||||
},
|
},
|
||||||
sleep: function (time: any): any {
|
sleep: function (time: any): any {
|
||||||
|
updateDynamicRam("sleep", getRamCost(Player, "sleep"));
|
||||||
if (time === undefined) {
|
if (time === undefined) {
|
||||||
throw makeRuntimeErrorMsg("sleep", "Takes 1 argument.");
|
throw makeRuntimeErrorMsg("sleep", "Takes 1 argument.");
|
||||||
}
|
}
|
||||||
@ -573,6 +578,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
asleep: function (time: any): any {
|
asleep: function (time: any): any {
|
||||||
|
updateDynamicRam("asleep", getRamCost(Player, "asleep"));
|
||||||
if (time === undefined) {
|
if (time === undefined) {
|
||||||
throw makeRuntimeErrorMsg("asleep", "Takes 1 argument.");
|
throw makeRuntimeErrorMsg("asleep", "Takes 1 argument.");
|
||||||
}
|
}
|
||||||
@ -650,6 +656,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return numCycleForGrowth(server, Number(growth), Player, cores);
|
return numCycleForGrowth(server, Number(growth), Player, cores);
|
||||||
},
|
},
|
||||||
growthAnalyzeSecurity: function (threads: any): number {
|
growthAnalyzeSecurity: function (threads: any): number {
|
||||||
|
updateDynamicRam("growthAnalyzeSecurity", getRamCost(Player, "growthAnalyzeSecurity"));
|
||||||
return 2 * CONSTANTS.ServerFortifyAmount * threads;
|
return 2 * CONSTANTS.ServerFortifyAmount * threads;
|
||||||
},
|
},
|
||||||
weaken: function (hostname: any, { threads: requestedThreads }: any = {}): any {
|
weaken: function (hostname: any, { threads: requestedThreads }: any = {}): any {
|
||||||
@ -692,7 +699,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
workerScript.log(
|
workerScript.log(
|
||||||
"weaken",
|
"weaken",
|
||||||
() =>
|
() =>
|
||||||
`'${server.hostname}' security level weakened to ${server.hackDifficulty
|
`'${server.hostname}' security level weakened to ${
|
||||||
|
server.hackDifficulty
|
||||||
}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`,
|
}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${numeralWrapper.formatThreads(threads)})`,
|
||||||
);
|
);
|
||||||
workerScript.scriptRef.onlineExpGained += expGain;
|
workerScript.scriptRef.onlineExpGained += expGain;
|
||||||
@ -701,10 +709,12 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
weakenAnalyze: function (threads: any, cores: any = 1): number {
|
weakenAnalyze: function (threads: any, cores: any = 1): number {
|
||||||
|
updateDynamicRam("weakenAnalyze", getRamCost(Player, "weakenAnalyze"));
|
||||||
const coreBonus = 1 + (cores - 1) / 16;
|
const coreBonus = 1 + (cores - 1) / 16;
|
||||||
return CONSTANTS.ServerWeakenAmount * threads * coreBonus * BitNodeMultipliers.ServerWeakenRate;
|
return CONSTANTS.ServerWeakenAmount * threads * coreBonus * BitNodeMultipliers.ServerWeakenRate;
|
||||||
},
|
},
|
||||||
share: function (): Promise<void> {
|
share: function (): Promise<void> {
|
||||||
|
updateDynamicRam("share", getRamCost(Player, "share"));
|
||||||
workerScript.log("share", () => "Sharing this computer.");
|
workerScript.log("share", () => "Sharing this computer.");
|
||||||
const end = StartSharing(workerScript.scriptRef.threads * calculateIntelligenceBonus(Player.intelligence, 2));
|
const end = StartSharing(workerScript.scriptRef.threads * calculateIntelligenceBonus(Player.intelligence, 2));
|
||||||
return netscriptDelay(10000, workerScript).finally(function () {
|
return netscriptDelay(10000, workerScript).finally(function () {
|
||||||
@ -713,21 +723,25 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
getSharePower: function (): number {
|
getSharePower: function (): number {
|
||||||
|
updateDynamicRam("getSharePower", getRamCost(Player, "getSharePower"));
|
||||||
return CalculateShareMult();
|
return CalculateShareMult();
|
||||||
},
|
},
|
||||||
print: function (...args: any[]): void {
|
print: function (...args: any[]): void {
|
||||||
|
updateDynamicRam("print", getRamCost(Player, "print"));
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
throw makeRuntimeErrorMsg("print", "Takes at least 1 argument.");
|
throw makeRuntimeErrorMsg("print", "Takes at least 1 argument.");
|
||||||
}
|
}
|
||||||
workerScript.print(argsToString(args));
|
workerScript.print(argsToString(args));
|
||||||
},
|
},
|
||||||
printf: function (format: string, ...args: any[]): void {
|
printf: function (format: string, ...args: any[]): void {
|
||||||
|
updateDynamicRam("printf", getRamCost(Player, "printf"));
|
||||||
if (typeof format !== "string") {
|
if (typeof format !== "string") {
|
||||||
throw makeRuntimeErrorMsg("printf", "First argument must be string for the format.");
|
throw makeRuntimeErrorMsg("printf", "First argument must be string for the format.");
|
||||||
}
|
}
|
||||||
workerScript.print(vsprintf(format, args));
|
workerScript.print(vsprintf(format, args));
|
||||||
},
|
},
|
||||||
tprint: function (...args: any[]): void {
|
tprint: function (...args: any[]): void {
|
||||||
|
updateDynamicRam("tprint", getRamCost(Player, "tprint"));
|
||||||
if (args.length === 0) {
|
if (args.length === 0) {
|
||||||
throw makeRuntimeErrorMsg("tprint", "Takes at least 1 argument.");
|
throw makeRuntimeErrorMsg("tprint", "Takes at least 1 argument.");
|
||||||
}
|
}
|
||||||
@ -751,6 +765,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
Terminal.print(`${workerScript.scriptRef.filename}: ${str}`);
|
Terminal.print(`${workerScript.scriptRef.filename}: ${str}`);
|
||||||
},
|
},
|
||||||
tprintf: function (format: any, ...args: any): any {
|
tprintf: function (format: any, ...args: any): any {
|
||||||
|
updateDynamicRam("tprintf", getRamCost(Player, "tprintf"));
|
||||||
if (typeof format !== "string") {
|
if (typeof format !== "string") {
|
||||||
throw makeRuntimeErrorMsg("tprintf", "First argument must be string for the format.");
|
throw makeRuntimeErrorMsg("tprintf", "First argument must be string for the format.");
|
||||||
}
|
}
|
||||||
@ -775,9 +790,11 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
Terminal.print(`${str}`);
|
Terminal.print(`${str}`);
|
||||||
},
|
},
|
||||||
clearLog: function (): any {
|
clearLog: function (): any {
|
||||||
|
updateDynamicRam("clearLog", getRamCost(Player, "clearLog"));
|
||||||
workerScript.scriptRef.clearLog();
|
workerScript.scriptRef.clearLog();
|
||||||
},
|
},
|
||||||
disableLog: function (fn: any): any {
|
disableLog: function (fn: any): any {
|
||||||
|
updateDynamicRam("disableLog", getRamCost(Player, "disableLog"));
|
||||||
if (fn === "ALL") {
|
if (fn === "ALL") {
|
||||||
for (fn of Object.keys(possibleLogs)) {
|
for (fn of Object.keys(possibleLogs)) {
|
||||||
workerScript.disableLogs[fn] = true;
|
workerScript.disableLogs[fn] = true;
|
||||||
@ -791,6 +808,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
enableLog: function (fn: any): any {
|
enableLog: function (fn: any): any {
|
||||||
|
updateDynamicRam("enableLog", getRamCost(Player, "enableLog"));
|
||||||
if (fn === "ALL") {
|
if (fn === "ALL") {
|
||||||
for (fn of Object.keys(possibleLogs)) {
|
for (fn of Object.keys(possibleLogs)) {
|
||||||
delete workerScript.disableLogs[fn];
|
delete workerScript.disableLogs[fn];
|
||||||
@ -803,12 +821,14 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
workerScript.log("enableLog", () => `Enabled logging for ${fn}`);
|
workerScript.log("enableLog", () => `Enabled logging for ${fn}`);
|
||||||
},
|
},
|
||||||
isLogEnabled: function (fn: any): any {
|
isLogEnabled: function (fn: any): any {
|
||||||
|
updateDynamicRam("isLogEnabled", getRamCost(Player, "isLogEnabled"));
|
||||||
if (possibleLogs[fn] === undefined) {
|
if (possibleLogs[fn] === undefined) {
|
||||||
throw makeRuntimeErrorMsg("isLogEnabled", `Invalid argument: ${fn}.`);
|
throw makeRuntimeErrorMsg("isLogEnabled", `Invalid argument: ${fn}.`);
|
||||||
}
|
}
|
||||||
return !workerScript.disableLogs[fn];
|
return !workerScript.disableLogs[fn];
|
||||||
},
|
},
|
||||||
getScriptLogs: function (fn: any, hostname: any, ...scriptArgs: any): any {
|
getScriptLogs: function (fn: any, hostname: any, ...scriptArgs: any): any {
|
||||||
|
updateDynamicRam("getScriptLogs", getRamCost(Player, "getScriptLogs"));
|
||||||
const runningScriptObj = getRunningScript(fn, hostname, "getScriptLogs", scriptArgs);
|
const runningScriptObj = getRunningScript(fn, hostname, "getScriptLogs", scriptArgs);
|
||||||
if (runningScriptObj == null) {
|
if (runningScriptObj == null) {
|
||||||
workerScript.log("getScriptLogs", () => getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
|
workerScript.log("getScriptLogs", () => getCannotFindRunningScriptErrorMessage(fn, hostname, scriptArgs));
|
||||||
@ -818,6 +838,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return runningScriptObj.logs.slice();
|
return runningScriptObj.logs.slice();
|
||||||
},
|
},
|
||||||
tail: function (fn: any, hostname: any = workerScript.hostname, ...scriptArgs: any): any {
|
tail: function (fn: any, hostname: any = workerScript.hostname, ...scriptArgs: any): any {
|
||||||
|
updateDynamicRam("tail", getRamCost(Player, "tail"));
|
||||||
let runningScriptObj;
|
let runningScriptObj;
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
runningScriptObj = workerScript.scriptRef;
|
runningScriptObj = workerScript.scriptRef;
|
||||||
@ -1084,6 +1105,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return scriptsRunning;
|
return scriptsRunning;
|
||||||
},
|
},
|
||||||
exit: function (): any {
|
exit: function (): any {
|
||||||
|
updateDynamicRam("exit", getRamCost(Player, "exit"));
|
||||||
workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
|
workerScript.running = false; // Prevent workerScript from "finishing execution naturally"
|
||||||
if (killWorkerScript(workerScript)) {
|
if (killWorkerScript(workerScript)) {
|
||||||
workerScript.log("exit", () => "Exiting...");
|
workerScript.log("exit", () => "Exiting...");
|
||||||
@ -1647,7 +1669,10 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
const cost = getPurchaseServerCost(ram);
|
const cost = getPurchaseServerCost(ram);
|
||||||
if (cost === Infinity) {
|
if (cost === Infinity) {
|
||||||
if (ram > getPurchaseServerMaxRam()) {
|
if (ram > getPurchaseServerMaxRam()) {
|
||||||
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}' must not be greater than getPurchaseServerMaxRam`);
|
workerScript.log(
|
||||||
|
"purchaseServer",
|
||||||
|
() => `Invalid argument: ram='${ram}' must not be greater than getPurchaseServerMaxRam`,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}' must be a positive power of 2`);
|
workerScript.log("purchaseServer", () => `Invalid argument: ram='${ram}' must be a positive power of 2`);
|
||||||
}
|
}
|
||||||
@ -1769,6 +1794,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
writePort: function (port: any, data: any = ""): any {
|
writePort: function (port: any, data: any = ""): any {
|
||||||
|
updateDynamicRam("writePort", getRamCost(Player, "writePort"));
|
||||||
if (typeof data !== "string" && typeof data !== "number") {
|
if (typeof data !== "string" && typeof data !== "number") {
|
||||||
throw makeRuntimeErrorMsg(
|
throw makeRuntimeErrorMsg(
|
||||||
"writePort",
|
"writePort",
|
||||||
@ -1857,6 +1883,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
readPort: function (port: any): any {
|
readPort: function (port: any): any {
|
||||||
|
updateDynamicRam("readPort", getRamCost(Player, "readPort"));
|
||||||
// Read from port
|
// Read from port
|
||||||
const iport = helper.getValidPort("readPort", port);
|
const iport = helper.getValidPort("readPort", port);
|
||||||
const x = iport.read();
|
const x = iport.read();
|
||||||
@ -1916,6 +1943,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
clearPort: function (port: any): any {
|
clearPort: function (port: any): any {
|
||||||
|
updateDynamicRam("clearPort", getRamCost(Player, "clearPort"));
|
||||||
// Clear port
|
// Clear port
|
||||||
const iport = helper.getValidPort("clearPort", port);
|
const iport = helper.getValidPort("clearPort", port);
|
||||||
return iport.clear();
|
return iport.clear();
|
||||||
@ -1964,6 +1992,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return suc;
|
return suc;
|
||||||
},
|
},
|
||||||
getScriptName: function (): any {
|
getScriptName: function (): any {
|
||||||
|
updateDynamicRam("getScriptName", getRamCost(Player, "getScriptName"));
|
||||||
return workerScript.name;
|
return workerScript.name;
|
||||||
},
|
},
|
||||||
getScriptRam: function (scriptname: any, hostname: any = workerScript.hostname): any {
|
getScriptRam: function (scriptname: any, hostname: any = workerScript.hostname): any {
|
||||||
@ -2095,6 +2124,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
nFormat: function (n: any, format: any): any {
|
nFormat: function (n: any, format: any): any {
|
||||||
|
updateDynamicRam("nFormat", getRamCost(Player, "nFormat"));
|
||||||
if (isNaN(n) || isNaN(parseFloat(n)) || typeof format !== "string") {
|
if (isNaN(n) || isNaN(parseFloat(n)) || typeof format !== "string") {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -2102,6 +2132,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return numeralWrapper.format(parseFloat(n), format);
|
return numeralWrapper.format(parseFloat(n), format);
|
||||||
},
|
},
|
||||||
tFormat: function (milliseconds: any, milliPrecision: any = false): any {
|
tFormat: function (milliseconds: any, milliPrecision: any = false): any {
|
||||||
|
updateDynamicRam("tFormat", getRamCost(Player, "tFormat"));
|
||||||
return convertTimeMsToTimeElapsedString(milliseconds, milliPrecision);
|
return convertTimeMsToTimeElapsedString(milliseconds, milliPrecision);
|
||||||
},
|
},
|
||||||
getTimeSinceLastAug: function (): any {
|
getTimeSinceLastAug: function (): any {
|
||||||
@ -2109,17 +2140,20 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return Player.playtimeSinceLastAug;
|
return Player.playtimeSinceLastAug;
|
||||||
},
|
},
|
||||||
alert: function (message: any): void {
|
alert: function (message: any): void {
|
||||||
|
updateDynamicRam("alert", getRamCost(Player, "alert"));
|
||||||
message = argsToString([message]);
|
message = argsToString([message]);
|
||||||
dialogBoxCreate(message);
|
dialogBoxCreate(message);
|
||||||
},
|
},
|
||||||
toast: function (message: any, variant: any = "success", duration: any = 2000): void {
|
toast: function (message: any, variant: any = "success", duration: any = 2000): void {
|
||||||
|
updateDynamicRam("toast", getRamCost(Player, "toast"));
|
||||||
if (!["success", "info", "warning", "error"].includes(variant))
|
if (!["success", "info", "warning", "error"].includes(variant))
|
||||||
throw new Error(`variant must be one of "success", "info", "warning", or "error"`);
|
throw new Error(`variant must be one of "success", "info", "warning", or "error"`);
|
||||||
|
|
||||||
message = argsToString([message]);
|
message = argsToString([message]);
|
||||||
SnackbarEvents.emit(message, variant, duration);
|
SnackbarEvents.emit(message, variant, duration);
|
||||||
},
|
},
|
||||||
prompt: function (txt: any): any {
|
prompt: function (txt: any, options?: { type?: string; options?: string[] }): any {
|
||||||
|
updateDynamicRam("prompt", getRamCost(Player, "prompt"));
|
||||||
if (!isString(txt)) {
|
if (!isString(txt)) {
|
||||||
txt = JSON.stringify(txt);
|
txt = JSON.stringify(txt);
|
||||||
}
|
}
|
||||||
@ -2127,11 +2161,13 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve) {
|
||||||
PromptEvent.emit({
|
PromptEvent.emit({
|
||||||
txt: txt,
|
txt: txt,
|
||||||
|
options,
|
||||||
resolve: resolve,
|
resolve: resolve,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
wget: async function (url: any, target: any, hostname: any = workerScript.hostname): Promise<boolean> {
|
wget: async function (url: any, target: any, hostname: any = workerScript.hostname): Promise<boolean> {
|
||||||
|
updateDynamicRam("wget", getRamCost(Player, "wget"));
|
||||||
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
if (!isScriptFilename(target) && !target.endsWith(".txt")) {
|
||||||
workerScript.log("wget", () => `Invalid target file: '${target}'. Must be a script or text file.`);
|
workerScript.log("wget", () => `Invalid target file: '${target}'. Must be a script or text file.`);
|
||||||
return Promise.resolve(false);
|
return Promise.resolve(false);
|
||||||
@ -2173,7 +2209,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
|
return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
|
||||||
},
|
},
|
||||||
getOwnedSourceFiles: function (): SourceFileLvl[] {
|
getOwnedSourceFiles: function (): SourceFileLvl[] {
|
||||||
helper.updateDynamicRam("getOwnedSourceFiles", getRamCost(Player, "getOwnedSourceFiles"));
|
updateDynamicRam("getOwnedSourceFiles", getRamCost(Player, "getOwnedSourceFiles"));
|
||||||
const res: SourceFileLvl[] = [];
|
const res: SourceFileLvl[] = [];
|
||||||
for (let i = 0; i < Player.sourceFiles.length; ++i) {
|
for (let i = 0; i < Player.sourceFiles.length; ++i) {
|
||||||
res.push({
|
res.push({
|
||||||
@ -2184,7 +2220,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
getPlayer: function (): INetscriptPlayer {
|
getPlayer: function (): INetscriptPlayer {
|
||||||
helper.updateDynamicRam("getPlayer", getRamCost(Player, "getPlayer"));
|
updateDynamicRam("getPlayer", getRamCost(Player, "getPlayer"));
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
hacking: Player.hacking,
|
hacking: Player.hacking,
|
||||||
@ -2273,16 +2309,20 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
jobs: {},
|
jobs: {},
|
||||||
factions: Player.factions.slice(),
|
factions: Player.factions.slice(),
|
||||||
tor: Player.hasTorRouter(),
|
tor: Player.hasTorRouter(),
|
||||||
|
inBladeburner: Player.inBladeburner(),
|
||||||
hasCorporation: Player.hasCorporation(),
|
hasCorporation: Player.hasCorporation(),
|
||||||
};
|
};
|
||||||
Object.assign(data.jobs, Player.jobs);
|
Object.assign(data.jobs, Player.jobs);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
atExit: function (f: any): void {
|
atExit: function (f: any): void {
|
||||||
|
updateDynamicRam("atExit", getRamCost(Player, "atExit"));
|
||||||
if (typeof f !== "function") {
|
if (typeof f !== "function") {
|
||||||
throw makeRuntimeErrorMsg("atExit", "argument should be function");
|
throw makeRuntimeErrorMsg("atExit", "argument should be function");
|
||||||
}
|
}
|
||||||
workerScript.atExit = () => { f(); }; // Wrap the user function to prevent WorkerScript leaking as 'this'
|
workerScript.atExit = () => {
|
||||||
|
f();
|
||||||
|
}; // Wrap the user function to prevent WorkerScript leaking as 'this'
|
||||||
},
|
},
|
||||||
mv: function (host: string, source: string, destination: string): void {
|
mv: function (host: string, source: string, destination: string): void {
|
||||||
updateDynamicRam("mv", getRamCost(Player, "mv"));
|
updateDynamicRam("mv", getRamCost(Player, "mv"));
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||||
import { IPlayer } from "../PersonObjects/IPlayer";
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
import { Exploit } from "../Exploits/Exploit";
|
import { Exploit } from "../Exploits/Exploit";
|
||||||
|
import * as bcrypt from "bcryptjs";
|
||||||
|
import { INetscriptHelper } from "./INetscriptHelper";
|
||||||
|
|
||||||
export interface INetscriptExtra {
|
export interface INetscriptExtra {
|
||||||
heart: {
|
heart: {
|
||||||
@ -9,9 +11,10 @@ export interface INetscriptExtra {
|
|||||||
exploit(): void;
|
exploit(): void;
|
||||||
bypass(doc: Document): void;
|
bypass(doc: Document): void;
|
||||||
alterReality(): void;
|
alterReality(): void;
|
||||||
|
rainbow(guess: string): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript): INetscriptExtra {
|
export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): INetscriptExtra {
|
||||||
return {
|
return {
|
||||||
heart: {
|
heart: {
|
||||||
// Easter egg function
|
// Easter egg function
|
||||||
@ -22,17 +25,18 @@ export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript): INe
|
|||||||
exploit: function (): void {
|
exploit: function (): void {
|
||||||
player.giveExploit(Exploit.UndocumentedFunctionCall);
|
player.giveExploit(Exploit.UndocumentedFunctionCall);
|
||||||
},
|
},
|
||||||
bypass: function (doc: any): void {
|
bypass: function (doc: unknown): void {
|
||||||
// reset both fields first
|
// reset both fields first
|
||||||
doc.completely_unused_field = undefined;
|
const d = doc as any;
|
||||||
|
d.completely_unused_field = undefined;
|
||||||
const real_document: any = document;
|
const real_document: any = document;
|
||||||
real_document.completely_unused_field = undefined;
|
real_document.completely_unused_field = undefined;
|
||||||
// set one to true and check that it affected the other.
|
// set one to true and check that it affected the other.
|
||||||
real_document.completely_unused_field = true;
|
real_document.completely_unused_field = true;
|
||||||
if (doc.completely_unused_field && workerScript.ramUsage === 1.6) {
|
if (d.completely_unused_field && workerScript.ramUsage === 1.6) {
|
||||||
player.giveExploit(Exploit.Bypass);
|
player.giveExploit(Exploit.Bypass);
|
||||||
}
|
}
|
||||||
doc.completely_unused_field = undefined;
|
d.completely_unused_field = undefined;
|
||||||
real_document.completely_unused_field = undefined;
|
real_document.completely_unused_field = undefined;
|
||||||
},
|
},
|
||||||
alterReality: function (): void {
|
alterReality: function (): void {
|
||||||
@ -50,5 +54,17 @@ export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript): INe
|
|||||||
player.giveExploit(Exploit.RealityAlteration);
|
player.giveExploit(Exploit.RealityAlteration);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
rainbow: function (guess: unknown): void {
|
||||||
|
async function tryGuess(): Promise<void> {
|
||||||
|
const verified = await bcrypt.compare(
|
||||||
|
helper.string("rainbow", "guess", guess),
|
||||||
|
"$2a$10$aertxDEkgor8baVtQDZsLuMwwGYmkRM/ohcA6FjmmzIHQeTCsrCcO",
|
||||||
|
);
|
||||||
|
if (verified) {
|
||||||
|
player.giveExploit(Exploit.INeedARainbow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tryGuess();
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -38,40 +38,6 @@ import {
|
|||||||
calculateAscensionPointsGain,
|
calculateAscensionPointsGain,
|
||||||
} from "../Gang/formulas/formulas";
|
} from "../Gang/formulas/formulas";
|
||||||
|
|
||||||
export interface INetscriptFormulas {
|
|
||||||
skills: {
|
|
||||||
calculateSkill(exp: any, mult?: any): any;
|
|
||||||
calculateExp(skill: any, mult?: any): any;
|
|
||||||
};
|
|
||||||
hacking: {
|
|
||||||
hackChance(server: any, player: any): any;
|
|
||||||
hackExp(server: any, player: any): any;
|
|
||||||
hackPercent(server: any, player: any): any;
|
|
||||||
growPercent(server: any, threads: any, player: any, cores?: any): any;
|
|
||||||
hackTime(server: any, player: any): any;
|
|
||||||
growTime(server: any, player: any): any;
|
|
||||||
weakenTime(server: any, player: any): any;
|
|
||||||
};
|
|
||||||
hacknetNodes: {
|
|
||||||
moneyGainRate(level: any, ram: any, cores: any, mult?: any): any;
|
|
||||||
levelUpgradeCost(startingLevel: any, extraLevels?: any, costMult?: any): any;
|
|
||||||
ramUpgradeCost(startingRam: any, extraLevels?: any, costMult?: any): any;
|
|
||||||
coreUpgradeCost(startingCore: any, extraCores?: any, costMult?: any): any;
|
|
||||||
hacknetNodeCost(n: any, mult: any): any;
|
|
||||||
constants(): any;
|
|
||||||
};
|
|
||||||
hacknetServers: {
|
|
||||||
hashGainRate(level: any, ramUsed: any, maxRam: any, cores: any, mult?: any): any;
|
|
||||||
levelUpgradeCost(startingLevel: any, extraLevels?: any, costMult?: any): any;
|
|
||||||
ramUpgradeCost(startingRam: any, extraLevels?: any, costMult?: any): any;
|
|
||||||
coreUpgradeCost(startingCore: any, extraCores?: any, costMult?: any): any;
|
|
||||||
cacheUpgradeCost(startingCache: any, extraCache?: any): any;
|
|
||||||
hashUpgradeCost(upgName: any, level: any): any;
|
|
||||||
hacknetServerCost(n: any, mult: any): any;
|
|
||||||
constants(): any;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IFormulas {
|
export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IFormulas {
|
||||||
const checkFormulasAccess = function (func: string): void {
|
const checkFormulasAccess = function (func: string): void {
|
||||||
if (!player.hasProgram(Programs.Formulas.name)) {
|
if (!player.hasProgram(Programs.Formulas.name)) {
|
||||||
@ -80,63 +46,84 @@ export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
skills: {
|
skills: {
|
||||||
calculateSkill: function (exp: any, mult: any = 1): any {
|
calculateSkill: function (_exp: unknown, _mult: unknown = 1): number {
|
||||||
|
const exp = helper.number("calculateSkill", "exp", _exp);
|
||||||
|
const mult = helper.number("calculateSkill", "mult", _mult);
|
||||||
checkFormulasAccess("skills.calculateSkill");
|
checkFormulasAccess("skills.calculateSkill");
|
||||||
return calculateSkill(exp, mult);
|
return calculateSkill(exp, mult);
|
||||||
},
|
},
|
||||||
calculateExp: function (skill: any, mult: any = 1): any {
|
calculateExp: function (_skill: unknown, _mult: unknown = 1): number {
|
||||||
|
const skill = helper.number("calculateExp", "skill", _skill);
|
||||||
|
const mult = helper.number("calculateExp", "mult", _mult);
|
||||||
checkFormulasAccess("skills.calculateExp");
|
checkFormulasAccess("skills.calculateExp");
|
||||||
return calculateExp(skill, mult);
|
return calculateExp(skill, mult);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hacking: {
|
hacking: {
|
||||||
hackChance: function (server: any, player: any): any {
|
hackChance: function (server: any, player: any): number {
|
||||||
checkFormulasAccess("hacking.hackChance");
|
checkFormulasAccess("hacking.hackChance");
|
||||||
return calculateHackingChance(server, player);
|
return calculateHackingChance(server, player);
|
||||||
},
|
},
|
||||||
hackExp: function (server: any, player: any): any {
|
hackExp: function (server: any, player: any): number {
|
||||||
checkFormulasAccess("hacking.hackExp");
|
checkFormulasAccess("hacking.hackExp");
|
||||||
return calculateHackingExpGain(server, player);
|
return calculateHackingExpGain(server, player);
|
||||||
},
|
},
|
||||||
hackPercent: function (server: any, player: any): any {
|
hackPercent: function (server: any, player: any): number {
|
||||||
checkFormulasAccess("hacking.hackPercent");
|
checkFormulasAccess("hacking.hackPercent");
|
||||||
return calculatePercentMoneyHacked(server, player);
|
return calculatePercentMoneyHacked(server, player);
|
||||||
},
|
},
|
||||||
growPercent: function (server: any, threads: any, player: any, cores: any = 1): any {
|
growPercent: function (server: any, _threads: unknown, player: any, _cores: unknown = 1): number {
|
||||||
|
const threads = helper.number("growPercent", "threads", _threads);
|
||||||
|
const cores = helper.number("growPercent", "cores", _cores);
|
||||||
checkFormulasAccess("hacking.growPercent");
|
checkFormulasAccess("hacking.growPercent");
|
||||||
return calculateServerGrowth(server, threads, player, cores);
|
return calculateServerGrowth(server, threads, player, cores);
|
||||||
},
|
},
|
||||||
hackTime: function (server: any, player: any): any {
|
hackTime: function (server: any, player: any): number {
|
||||||
checkFormulasAccess("hacking.hackTime");
|
checkFormulasAccess("hacking.hackTime");
|
||||||
return calculateHackingTime(server, player) * 1000;
|
return calculateHackingTime(server, player) * 1000;
|
||||||
},
|
},
|
||||||
growTime: function (server: any, player: any): any {
|
growTime: function (server: any, player: any): number {
|
||||||
checkFormulasAccess("hacking.growTime");
|
checkFormulasAccess("hacking.growTime");
|
||||||
return calculateGrowTime(server, player) * 1000;
|
return calculateGrowTime(server, player) * 1000;
|
||||||
},
|
},
|
||||||
weakenTime: function (server: any, player: any): any {
|
weakenTime: function (server: any, player: any): number {
|
||||||
checkFormulasAccess("hacking.weakenTime");
|
checkFormulasAccess("hacking.weakenTime");
|
||||||
return calculateWeakenTime(server, player) * 1000;
|
return calculateWeakenTime(server, player) * 1000;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
hacknetNodes: {
|
hacknetNodes: {
|
||||||
moneyGainRate: function (level: any, ram: any, cores: any, mult: any = 1): any {
|
moneyGainRate: function (_level: unknown, _ram: unknown, _cores: unknown, _mult: unknown = 1): number {
|
||||||
|
const level = helper.number("moneyGainRate", "level", _level);
|
||||||
|
const ram = helper.number("moneyGainRate", "ram", _ram);
|
||||||
|
const cores = helper.number("moneyGainRate", "cores", _cores);
|
||||||
|
const mult = helper.number("moneyGainRate", "mult", _mult);
|
||||||
checkFormulasAccess("hacknetNodes.moneyGainRate");
|
checkFormulasAccess("hacknetNodes.moneyGainRate");
|
||||||
return calculateMoneyGainRate(level, ram, cores, mult);
|
return calculateMoneyGainRate(level, ram, cores, mult);
|
||||||
},
|
},
|
||||||
levelUpgradeCost: function (startingLevel: any, extraLevels: any = 1, costMult: any = 1): any {
|
levelUpgradeCost: function (_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
||||||
|
const startingLevel = helper.number("levelUpgradeCost", "startingLevel", _startingLevel);
|
||||||
|
const extraLevels = helper.number("levelUpgradeCost", "extraLevels", _extraLevels);
|
||||||
|
const costMult = helper.number("levelUpgradeCost", "costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetNodes.levelUpgradeCost");
|
checkFormulasAccess("hacknetNodes.levelUpgradeCost");
|
||||||
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
ramUpgradeCost: function (startingRam: any, extraLevels: any = 1, costMult: any = 1): any {
|
ramUpgradeCost: function (_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
||||||
|
const startingRam = helper.number("ramUpgradeCost", "startingRam", _startingRam);
|
||||||
|
const extraLevels = helper.number("ramUpgradeCost", "extraLevels", _extraLevels);
|
||||||
|
const costMult = helper.number("ramUpgradeCost", "costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetNodes.ramUpgradeCost");
|
checkFormulasAccess("hacknetNodes.ramUpgradeCost");
|
||||||
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
coreUpgradeCost: function (startingCore: any, extraCores: any = 1, costMult: any = 1): any {
|
coreUpgradeCost: function (_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number {
|
||||||
|
const startingCore = helper.number("coreUpgradeCost", "startingCore", _startingCore);
|
||||||
|
const extraCores = helper.number("coreUpgradeCost", "extraCores", _extraCores);
|
||||||
|
const costMult = helper.number("coreUpgradeCost", "costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetNodes.coreUpgradeCost");
|
checkFormulasAccess("hacknetNodes.coreUpgradeCost");
|
||||||
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||||
},
|
},
|
||||||
hacknetNodeCost: function (n: any, mult: any): any {
|
hacknetNodeCost: function (_n: unknown, _mult: unknown): number {
|
||||||
|
const n = helper.number("hacknetNodeCost", "n", _n);
|
||||||
|
const mult = helper.number("hacknetNodeCost", "mult", _mult);
|
||||||
checkFormulasAccess("hacknetNodes.hacknetNodeCost");
|
checkFormulasAccess("hacknetNodes.hacknetNodeCost");
|
||||||
return calculateNodeCost(n, mult);
|
return calculateNodeCost(n, mult);
|
||||||
},
|
},
|
||||||
@ -146,27 +133,51 @@ export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
hacknetServers: {
|
hacknetServers: {
|
||||||
hashGainRate: function (level: any, ramUsed: any, maxRam: any, cores: any, mult: any = 1): any {
|
hashGainRate: function (
|
||||||
|
_level: unknown,
|
||||||
|
_ramUsed: unknown,
|
||||||
|
_maxRam: unknown,
|
||||||
|
_cores: unknown,
|
||||||
|
_mult: unknown = 1,
|
||||||
|
): number {
|
||||||
|
const level = helper.number("hashGainRate", "level", _level);
|
||||||
|
const ramUsed = helper.number("hashGainRate", "ramUsed", _ramUsed);
|
||||||
|
const maxRam = helper.number("hashGainRate", "maxRam", _maxRam);
|
||||||
|
const cores = helper.number("hashGainRate", "cores", _cores);
|
||||||
|
const mult = helper.number("hashGainRate", "mult", _mult);
|
||||||
checkFormulasAccess("hacknetServers.hashGainRate");
|
checkFormulasAccess("hacknetServers.hashGainRate");
|
||||||
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
return HScalculateHashGainRate(level, ramUsed, maxRam, cores, mult);
|
||||||
},
|
},
|
||||||
levelUpgradeCost: function (startingLevel: any, extraLevels: any = 1, costMult: any = 1): any {
|
levelUpgradeCost: function (_startingLevel: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
||||||
|
const startingLevel = helper.number("levelUpgradeCost", "startingLevel", _startingLevel);
|
||||||
|
const extraLevels = helper.number("levelUpgradeCost", "extraLevels", _extraLevels);
|
||||||
|
const costMult = helper.number("levelUpgradeCost", "costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetServers.levelUpgradeCost");
|
checkFormulasAccess("hacknetServers.levelUpgradeCost");
|
||||||
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
ramUpgradeCost: function (startingRam: any, extraLevels: any = 1, costMult: any = 1): any {
|
ramUpgradeCost: function (_startingRam: unknown, _extraLevels: unknown = 1, _costMult: unknown = 1): number {
|
||||||
|
const startingRam = helper.number("ramUpgradeCost", "startingRam", _startingRam);
|
||||||
|
const extraLevels = helper.number("ramUpgradeCost", "extraLevels", _extraLevels);
|
||||||
|
const costMult = helper.number("ramUpgradeCost", "costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetServers.ramUpgradeCost");
|
checkFormulasAccess("hacknetServers.ramUpgradeCost");
|
||||||
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||||
},
|
},
|
||||||
coreUpgradeCost: function (startingCore: any, extraCores: any = 1, costMult: any = 1): any {
|
coreUpgradeCost: function (_startingCore: unknown, _extraCores: unknown = 1, _costMult: unknown = 1): number {
|
||||||
|
const startingCore = helper.number("coreUpgradeCost", "startingCore", _startingCore);
|
||||||
|
const extraCores = helper.number("coreUpgradeCost", "extraCores", _extraCores);
|
||||||
|
const costMult = helper.number("coreUpgradeCost", "costMult", _costMult);
|
||||||
checkFormulasAccess("hacknetServers.coreUpgradeCost");
|
checkFormulasAccess("hacknetServers.coreUpgradeCost");
|
||||||
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||||
},
|
},
|
||||||
cacheUpgradeCost: function (startingCache: any, extraCache: any = 1): any {
|
cacheUpgradeCost: function (_startingCache: unknown, _extraCache: unknown = 1): number {
|
||||||
|
const startingCache = helper.number("cacheUpgradeCost", "startingCache", _startingCache);
|
||||||
|
const extraCache = helper.number("cacheUpgradeCost", "extraCache", _extraCache);
|
||||||
checkFormulasAccess("hacknetServers.cacheUpgradeCost");
|
checkFormulasAccess("hacknetServers.cacheUpgradeCost");
|
||||||
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
return HScalculateCacheUpgradeCost(startingCache, extraCache);
|
||||||
},
|
},
|
||||||
hashUpgradeCost: function (upgName: any, level: any): any {
|
hashUpgradeCost: function (_upgName: unknown, _level: unknown): number {
|
||||||
|
const upgName = helper.string("hashUpgradeCost", "upgName", _upgName);
|
||||||
|
const level = helper.number("hashUpgradeCost", "level", _level);
|
||||||
checkFormulasAccess("hacknetServers.hashUpgradeCost");
|
checkFormulasAccess("hacknetServers.hashUpgradeCost");
|
||||||
const upg = player.hashManager.getUpgrade(upgName);
|
const upg = player.hashManager.getUpgrade(upgName);
|
||||||
if (!upg) {
|
if (!upg) {
|
||||||
@ -177,7 +188,9 @@ export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
}
|
}
|
||||||
return upg.getCost(level);
|
return upg.getCost(level);
|
||||||
},
|
},
|
||||||
hacknetServerCost: function (n: any, mult: any = 1): any {
|
hacknetServerCost: function (_n: unknown, _mult: unknown = 1): number {
|
||||||
|
const n = helper.number("hacknetServerCost", "n", _n);
|
||||||
|
const mult = helper.number("hacknetServerCost", "mult", _mult);
|
||||||
checkFormulasAccess("hacknetServers.hacknetServerCost");
|
checkFormulasAccess("hacknetServers.hacknetServerCost");
|
||||||
return HScalculateServerCost(n, mult);
|
return HScalculateServerCost(n, mult);
|
||||||
},
|
},
|
||||||
@ -203,11 +216,13 @@ export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, h
|
|||||||
checkFormulasAccess("gang.moneyGain");
|
checkFormulasAccess("gang.moneyGain");
|
||||||
return calculateMoneyGain(gang, member, task);
|
return calculateMoneyGain(gang, member, task);
|
||||||
},
|
},
|
||||||
ascensionPointsGain: function (exp: any): number {
|
ascensionPointsGain: function (_exp: unknown): number {
|
||||||
|
const exp = helper.number("ascensionPointsGain", "exp", _exp);
|
||||||
checkFormulasAccess("gang.ascensionPointsGain");
|
checkFormulasAccess("gang.ascensionPointsGain");
|
||||||
return calculateAscensionPointsGain(exp);
|
return calculateAscensionPointsGain(exp);
|
||||||
},
|
},
|
||||||
ascensionMultiplier: function (points: any): number {
|
ascensionMultiplier: function (_points: unknown): number {
|
||||||
|
const points = helper.number("ascensionMultiplier", "points", _points);
|
||||||
checkFormulasAccess("gang.ascensionMultiplier");
|
checkFormulasAccess("gang.ascensionMultiplier");
|
||||||
return calculateAscensionMult(points);
|
return calculateAscensionMult(points);
|
||||||
},
|
},
|
||||||
|
@ -24,10 +24,7 @@ import { Hacknet as IHacknet, NodeStats } from "../ScriptEditor/NetscriptDefinit
|
|||||||
|
|
||||||
export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IHacknet {
|
export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): IHacknet {
|
||||||
// Utility function to get Hacknet Node object
|
// Utility function to get Hacknet Node object
|
||||||
const getHacknetNode = function (i: any, callingFn = ""): HacknetNode | HacknetServer {
|
const getHacknetNode = function (i: number, callingFn = ""): HacknetNode | HacknetServer {
|
||||||
if (isNaN(i)) {
|
|
||||||
throw helper.makeRuntimeErrorMsg(callingFn, "Invalid index specified for Hacknet Node: " + i);
|
|
||||||
}
|
|
||||||
if (i < 0 || i >= player.hacknetNodes.length) {
|
if (i < 0 || i >= player.hacknetNodes.length) {
|
||||||
throw helper.makeRuntimeErrorMsg(callingFn, "Index specified for Hacknet Node is out-of-bounds: " + i);
|
throw helper.makeRuntimeErrorMsg(callingFn, "Index specified for Hacknet Node is out-of-bounds: " + i);
|
||||||
}
|
}
|
||||||
@ -72,7 +69,8 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
|||||||
return getCostOfNextHacknetNode(player);
|
return getCostOfNextHacknetNode(player);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getNodeStats: function (i: any): NodeStats {
|
getNodeStats: function (_i: unknown): NodeStats {
|
||||||
|
const i = helper.number("getNodeStats", "i", _i);
|
||||||
const node = getHacknetNode(i, "getNodeStats");
|
const node = getHacknetNode(i, "getNodeStats");
|
||||||
const hasUpgraded = hasHacknetServers(player);
|
const hasUpgraded = hasHacknetServers(player);
|
||||||
const res: any = {
|
const res: any = {
|
||||||
@ -93,19 +91,27 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
upgradeLevel: function (i: any, n: any): boolean {
|
upgradeLevel: function (_i: unknown, _n: unknown): boolean {
|
||||||
|
const i = helper.number("upgradeLevel", "i", _i);
|
||||||
|
const n = helper.number("upgradeLevel", "n", _n);
|
||||||
const node = getHacknetNode(i, "upgradeLevel");
|
const node = getHacknetNode(i, "upgradeLevel");
|
||||||
return purchaseLevelUpgrade(player, node, n);
|
return purchaseLevelUpgrade(player, node, n);
|
||||||
},
|
},
|
||||||
upgradeRam: function (i: any, n: any): boolean {
|
upgradeRam: function (_i: unknown, _n: unknown): boolean {
|
||||||
|
const i = helper.number("upgradeRam", "i", _i);
|
||||||
|
const n = helper.number("upgradeRam", "n", _n);
|
||||||
const node = getHacknetNode(i, "upgradeRam");
|
const node = getHacknetNode(i, "upgradeRam");
|
||||||
return purchaseRamUpgrade(player, node, n);
|
return purchaseRamUpgrade(player, node, n);
|
||||||
},
|
},
|
||||||
upgradeCore: function (i: any, n: any): boolean {
|
upgradeCore: function (_i: unknown, _n: unknown): boolean {
|
||||||
|
const i = helper.number("upgradeCore", "i", _i);
|
||||||
|
const n = helper.number("upgradeCore", "n", _n);
|
||||||
const node = getHacknetNode(i, "upgradeCore");
|
const node = getHacknetNode(i, "upgradeCore");
|
||||||
return purchaseCoreUpgrade(player, node, n);
|
return purchaseCoreUpgrade(player, node, n);
|
||||||
},
|
},
|
||||||
upgradeCache: function (i: any, n: any): boolean {
|
upgradeCache: function (_i: unknown, _n: unknown): boolean {
|
||||||
|
const i = helper.number("upgradeCache", "i", _i);
|
||||||
|
const n = helper.number("upgradeCache", "n", _n);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -120,19 +126,27 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
|||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
getLevelUpgradeCost: function (i: any, n: any): number {
|
getLevelUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||||
|
const i = helper.number("getLevelUpgradeCost", "i", _i);
|
||||||
|
const n = helper.number("getLevelUpgradeCost", "n", _n);
|
||||||
const node = getHacknetNode(i, "upgradeLevel");
|
const node = getHacknetNode(i, "upgradeLevel");
|
||||||
return node.calculateLevelUpgradeCost(n, player.hacknet_node_level_cost_mult);
|
return node.calculateLevelUpgradeCost(n, player.hacknet_node_level_cost_mult);
|
||||||
},
|
},
|
||||||
getRamUpgradeCost: function (i: any, n: any): number {
|
getRamUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||||
|
const i = helper.number("getRamUpgradeCost", "i", _i);
|
||||||
|
const n = helper.number("getRamUpgradeCost", "n", _n);
|
||||||
const node = getHacknetNode(i, "upgradeRam");
|
const node = getHacknetNode(i, "upgradeRam");
|
||||||
return node.calculateRamUpgradeCost(n, player.hacknet_node_ram_cost_mult);
|
return node.calculateRamUpgradeCost(n, player.hacknet_node_ram_cost_mult);
|
||||||
},
|
},
|
||||||
getCoreUpgradeCost: function (i: any, n: any): number {
|
getCoreUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||||
|
const i = helper.number("getCoreUpgradeCost", "i", _i);
|
||||||
|
const n = helper.number("getCoreUpgradeCost", "n", _n);
|
||||||
const node = getHacknetNode(i, "upgradeCore");
|
const node = getHacknetNode(i, "upgradeCore");
|
||||||
return node.calculateCoreUpgradeCost(n, player.hacknet_node_core_cost_mult);
|
return node.calculateCoreUpgradeCost(n, player.hacknet_node_core_cost_mult);
|
||||||
},
|
},
|
||||||
getCacheUpgradeCost: function (i: any, n: any): number {
|
getCacheUpgradeCost: function (_i: unknown, _n: unknown): number {
|
||||||
|
const i = helper.number("getCacheUpgradeCost", "i", _i);
|
||||||
|
const n = helper.number("getCacheUpgradeCost", "n", _n);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
@ -155,26 +169,30 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript, he
|
|||||||
}
|
}
|
||||||
return player.hashManager.capacity;
|
return player.hashManager.capacity;
|
||||||
},
|
},
|
||||||
hashCost: function (upgName: any): number {
|
hashCost: function (_upgName: unknown): number {
|
||||||
|
const upgName = helper.string("hashCost", "upgName", _upgName);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return Infinity;
|
return Infinity;
|
||||||
}
|
}
|
||||||
|
|
||||||
return player.hashManager.getUpgradeCost(upgName);
|
return player.hashManager.getUpgradeCost(upgName);
|
||||||
},
|
},
|
||||||
spendHashes: function (upgName: any, upgTarget: any): boolean {
|
spendHashes: function (_upgName: unknown, _upgTarget: unknown): boolean {
|
||||||
|
const upgName = helper.string("spendHashes", "upgName", _upgName);
|
||||||
|
const upgTarget = helper.string("spendHashes", "upgTarget", _upgTarget);
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return purchaseHashUpgrade(player, upgName, upgTarget);
|
return purchaseHashUpgrade(player, upgName, upgTarget);
|
||||||
},
|
},
|
||||||
getHashUpgrades: function(): string[] {
|
getHashUpgrades: function (): string[] {
|
||||||
if (!hasHacknetServers(player)) {
|
if (!hasHacknetServers(player)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return Object.values(HashUpgrades).map((upgrade: HashUpgrade) => upgrade.name);
|
return Object.values(HashUpgrades).map((upgrade: HashUpgrade) => upgrade.name);
|
||||||
},
|
},
|
||||||
getHashUpgradeLevel: function (upgName: any): number {
|
getHashUpgradeLevel: function (_upgName: unknown): number {
|
||||||
|
const upgName = helper.string("getHashUpgradeLevel", "upgName", _upgName);
|
||||||
const level = player.hashManager.upgrades[upgName];
|
const level = player.hashManager.upgrades[upgName];
|
||||||
if (level === undefined) {
|
if (level === undefined) {
|
||||||
throw helper.makeRuntimeErrorMsg("hacknet.hashUpgradeLevel", `Invalid Hash Upgrade: ${upgName}`);
|
throw helper.makeRuntimeErrorMsg("hacknet.hashUpgradeLevel", `Invalid Hash Upgrade: ${upgName}`);
|
||||||
|
@ -3,9 +3,9 @@ import { BaseServer } from "../Server/BaseServer";
|
|||||||
export interface INetscriptHelper {
|
export interface INetscriptHelper {
|
||||||
updateDynamicRam(functionName: string, ram: number): void;
|
updateDynamicRam(functionName: string, ram: number): void;
|
||||||
makeRuntimeErrorMsg(functionName: string, message: string): void;
|
makeRuntimeErrorMsg(functionName: string, message: string): void;
|
||||||
string(funcName: string, argName: string, v: any): string;
|
string(funcName: string, argName: string, v: unknown): string;
|
||||||
number(funcName: string, argName: string, v: any): number;
|
number(funcName: string, argName: string, v: unknown): number;
|
||||||
boolean(v: any): boolean;
|
boolean(v: unknown): boolean;
|
||||||
getServer(ip: any, fn: any): BaseServer;
|
getServer(ip: any, fn: any): BaseServer;
|
||||||
checkSingularityAccess(func: string): void;
|
checkSingularityAccess(func: string): void;
|
||||||
hack(hostname: string, manual: boolean): Promise<number>;
|
hack(hostname: string, manual: boolean): Promise<number>;
|
||||||
|
@ -32,9 +32,9 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
|
|||||||
checkStanekAPIAccess("height");
|
checkStanekAPIAccess("height");
|
||||||
return staneksGift.height();
|
return staneksGift.height();
|
||||||
},
|
},
|
||||||
charge: function (arootX: unknown, arootY: unknown): Promise<void> {
|
charge: function (_rootX: unknown, _rootY: unknown): Promise<void> {
|
||||||
const rootX = helper.number("stanek.charge", "rootX", arootX);
|
const rootX = helper.number("stanek.charge", "rootX", _rootX);
|
||||||
const rootY = helper.number("stanek.charge", "rootY", arootY);
|
const rootY = helper.number("stanek.charge", "rootY", _rootY);
|
||||||
|
|
||||||
helper.updateDynamicRam("charge", getRamCost(player, "stanek", "charge"));
|
helper.updateDynamicRam("charge", getRamCost(player, "stanek", "charge"));
|
||||||
checkStanekAPIAccess("charge");
|
checkStanekAPIAccess("charge");
|
||||||
@ -67,11 +67,11 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
|
|||||||
workerScript.log("stanek.clear", () => `Cleared Stanek's Gift.`);
|
workerScript.log("stanek.clear", () => `Cleared Stanek's Gift.`);
|
||||||
staneksGift.clear();
|
staneksGift.clear();
|
||||||
},
|
},
|
||||||
canPlace: function (arootX: unknown, arootY: unknown, arotation: unknown, afragmentId: unknown): boolean {
|
canPlace: function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
||||||
const rootX = helper.number("stanek.canPlace", "rootX", arootX);
|
const rootX = helper.number("stanek.canPlace", "rootX", _rootX);
|
||||||
const rootY = helper.number("stanek.canPlace", "rootY", arootY);
|
const rootY = helper.number("stanek.canPlace", "rootY", _rootY);
|
||||||
const rotation = helper.number("stanek.canPlace", "rotation", arotation);
|
const rotation = helper.number("stanek.canPlace", "rotation", _rotation);
|
||||||
const fragmentId = helper.number("stanek.canPlace", "fragmentId", afragmentId);
|
const fragmentId = helper.number("stanek.canPlace", "fragmentId", _fragmentId);
|
||||||
helper.updateDynamicRam("canPlace", getRamCost(player, "stanek", "canPlace"));
|
helper.updateDynamicRam("canPlace", getRamCost(player, "stanek", "canPlace"));
|
||||||
checkStanekAPIAccess("canPlace");
|
checkStanekAPIAccess("canPlace");
|
||||||
const fragment = FragmentById(fragmentId);
|
const fragment = FragmentById(fragmentId);
|
||||||
@ -79,29 +79,29 @@ export function NetscriptStanek(player: IPlayer, workerScript: WorkerScript, hel
|
|||||||
const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
|
const can = staneksGift.canPlace(rootX, rootY, rotation, fragment);
|
||||||
return can;
|
return can;
|
||||||
},
|
},
|
||||||
place: function (arootX: unknown, arootY: unknown, arotation: unknown, afragmentId: unknown): boolean {
|
place: function (_rootX: unknown, _rootY: unknown, _rotation: unknown, _fragmentId: unknown): boolean {
|
||||||
const rootX = helper.number("stanek.place", "rootX", arootX);
|
const rootX = helper.number("stanek.place", "rootX", _rootX);
|
||||||
const rootY = helper.number("stanek.place", "rootY", arootY);
|
const rootY = helper.number("stanek.place", "rootY", _rootY);
|
||||||
const rotation = helper.number("stanek.place", "rotation", arotation);
|
const rotation = helper.number("stanek.place", "rotation", _rotation);
|
||||||
const fragmentId = helper.number("stanek.place", "fragmentId", afragmentId);
|
const fragmentId = helper.number("stanek.place", "fragmentId", _fragmentId);
|
||||||
helper.updateDynamicRam("place", getRamCost(player, "stanek", "place"));
|
helper.updateDynamicRam("place", getRamCost(player, "stanek", "place"));
|
||||||
checkStanekAPIAccess("place");
|
checkStanekAPIAccess("place");
|
||||||
const fragment = FragmentById(fragmentId);
|
const fragment = FragmentById(fragmentId);
|
||||||
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.place", `Invalid fragment id: ${fragmentId}`);
|
if (!fragment) throw helper.makeRuntimeErrorMsg("stanek.place", `Invalid fragment id: ${fragmentId}`);
|
||||||
return staneksGift.place(rootX, rootY, rotation, fragment);
|
return staneksGift.place(rootX, rootY, rotation, fragment);
|
||||||
},
|
},
|
||||||
get: function (arootX: unknown, arootY: unknown): IActiveFragment | undefined {
|
get: function (_rootX: unknown, _rootY: unknown): IActiveFragment | undefined {
|
||||||
const rootX = helper.number("stanek.get", "rootX", arootX);
|
const rootX = helper.number("stanek.get", "rootX", _rootX);
|
||||||
const rootY = helper.number("stanek.get", "rootY", arootY);
|
const rootY = helper.number("stanek.get", "rootY", _rootY);
|
||||||
helper.updateDynamicRam("get", getRamCost(player, "stanek", "get"));
|
helper.updateDynamicRam("get", getRamCost(player, "stanek", "get"));
|
||||||
checkStanekAPIAccess("get");
|
checkStanekAPIAccess("get");
|
||||||
const fragment = staneksGift.findFragment(rootX, rootY);
|
const fragment = staneksGift.findFragment(rootX, rootY);
|
||||||
if (fragment !== undefined) return fragment.copy();
|
if (fragment !== undefined) return fragment.copy();
|
||||||
return undefined;
|
return undefined;
|
||||||
},
|
},
|
||||||
remove: function (arootX: unknown, arootY: unknown): boolean {
|
remove: function (_rootX: unknown, _rootY: unknown): boolean {
|
||||||
const rootX = helper.number("stanek.remove", "rootX", arootX);
|
const rootX = helper.number("stanek.remove", "rootX", _rootX);
|
||||||
const rootY = helper.number("stanek.remove", "rootY", arootY);
|
const rootY = helper.number("stanek.remove", "rootY", _rootY);
|
||||||
helper.updateDynamicRam("remove", getRamCost(player, "stanek", "remove"));
|
helper.updateDynamicRam("remove", getRamCost(player, "stanek", "remove"));
|
||||||
checkStanekAPIAccess("remove");
|
checkStanekAPIAccess("remove");
|
||||||
return staneksGift.delete(rootX, rootY);
|
return staneksGift.delete(rootX, rootY);
|
||||||
|
@ -34,33 +34,37 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
return stock;
|
return stock;
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
getSymbols: function (): any {
|
getSymbols: function (): string[] {
|
||||||
helper.updateDynamicRam("getSymbols", getRamCost(player, "stock", "getSymbols"));
|
helper.updateDynamicRam("getSymbols", getRamCost(player, "stock", "getSymbols"));
|
||||||
checkTixApiAccess("getSymbols");
|
checkTixApiAccess("getSymbols");
|
||||||
return Object.values(StockSymbols);
|
return Object.values(StockSymbols);
|
||||||
},
|
},
|
||||||
getPrice: function (symbol: any): any {
|
getPrice: function (_symbol: unknown): number {
|
||||||
|
const symbol = helper.string("getPrice", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getPrice", getRamCost(player, "stock", "getPrice"));
|
helper.updateDynamicRam("getPrice", getRamCost(player, "stock", "getPrice"));
|
||||||
checkTixApiAccess("getPrice");
|
checkTixApiAccess("getPrice");
|
||||||
const stock = getStockFromSymbol(symbol, "getPrice");
|
const stock = getStockFromSymbol(symbol, "getPrice");
|
||||||
|
|
||||||
return stock.price;
|
return stock.price;
|
||||||
},
|
},
|
||||||
getAskPrice: function (symbol: any): any {
|
getAskPrice: function (_symbol: unknown): number {
|
||||||
|
const symbol = helper.string("getAskPrice", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getAskPrice", getRamCost(player, "stock", "getAskPrice"));
|
helper.updateDynamicRam("getAskPrice", getRamCost(player, "stock", "getAskPrice"));
|
||||||
checkTixApiAccess("getAskPrice");
|
checkTixApiAccess("getAskPrice");
|
||||||
const stock = getStockFromSymbol(symbol, "getAskPrice");
|
const stock = getStockFromSymbol(symbol, "getAskPrice");
|
||||||
|
|
||||||
return stock.getAskPrice();
|
return stock.getAskPrice();
|
||||||
},
|
},
|
||||||
getBidPrice: function (symbol: any): any {
|
getBidPrice: function (_symbol: unknown): number {
|
||||||
|
const symbol = helper.string("getBidPrice", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getBidPrice", getRamCost(player, "stock", "getBidPrice"));
|
helper.updateDynamicRam("getBidPrice", getRamCost(player, "stock", "getBidPrice"));
|
||||||
checkTixApiAccess("getBidPrice");
|
checkTixApiAccess("getBidPrice");
|
||||||
const stock = getStockFromSymbol(symbol, "getBidPrice");
|
const stock = getStockFromSymbol(symbol, "getBidPrice");
|
||||||
|
|
||||||
return stock.getBidPrice();
|
return stock.getBidPrice();
|
||||||
},
|
},
|
||||||
getPosition: function (symbol: any): any {
|
getPosition: function (_symbol: unknown): [number, number, number, number] {
|
||||||
|
const symbol = helper.string("getPosition", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getPosition", getRamCost(player, "stock", "getPosition"));
|
helper.updateDynamicRam("getPosition", getRamCost(player, "stock", "getPosition"));
|
||||||
checkTixApiAccess("getPosition");
|
checkTixApiAccess("getPosition");
|
||||||
const stock = SymbolToStockMap[symbol];
|
const stock = SymbolToStockMap[symbol];
|
||||||
@ -69,14 +73,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
}
|
}
|
||||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||||
},
|
},
|
||||||
getMaxShares: function (symbol: any): any {
|
getMaxShares: function (_symbol: unknown): number {
|
||||||
|
const symbol = helper.string("getMaxShares", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getMaxShares", getRamCost(player, "stock", "getMaxShares"));
|
helper.updateDynamicRam("getMaxShares", getRamCost(player, "stock", "getMaxShares"));
|
||||||
checkTixApiAccess("getMaxShares");
|
checkTixApiAccess("getMaxShares");
|
||||||
const stock = getStockFromSymbol(symbol, "getMaxShares");
|
const stock = getStockFromSymbol(symbol, "getMaxShares");
|
||||||
|
|
||||||
return stock.maxShares;
|
return stock.maxShares;
|
||||||
},
|
},
|
||||||
getPurchaseCost: function (symbol: any, shares: any, posType: any): any {
|
getPurchaseCost: function (_symbol: unknown, _shares: unknown, _posType: unknown): number {
|
||||||
|
const symbol = helper.string("getPurchaseCost", "symbol", _symbol);
|
||||||
|
let shares = helper.number("getPurchaseCost", "shares", _shares);
|
||||||
|
const posType = helper.string("getPurchaseCost", "posType", _posType);
|
||||||
helper.updateDynamicRam("getPurchaseCost", getRamCost(player, "stock", "getPurchaseCost"));
|
helper.updateDynamicRam("getPurchaseCost", getRamCost(player, "stock", "getPurchaseCost"));
|
||||||
checkTixApiAccess("getPurchaseCost");
|
checkTixApiAccess("getPurchaseCost");
|
||||||
const stock = getStockFromSymbol(symbol, "getPurchaseCost");
|
const stock = getStockFromSymbol(symbol, "getPurchaseCost");
|
||||||
@ -99,7 +107,10 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
getSaleGain: function (symbol: any, shares: any, posType: any): any {
|
getSaleGain: function (_symbol: unknown, _shares: unknown, _posType: unknown): number {
|
||||||
|
const symbol = helper.string("getSaleGain", "symbol", _symbol);
|
||||||
|
let shares = helper.number("getSaleGain", "shares", _shares);
|
||||||
|
const posType = helper.string("getSaleGain", "posType", _posType);
|
||||||
helper.updateDynamicRam("getSaleGain", getRamCost(player, "stock", "getSaleGain"));
|
helper.updateDynamicRam("getSaleGain", getRamCost(player, "stock", "getSaleGain"));
|
||||||
checkTixApiAccess("getSaleGain");
|
checkTixApiAccess("getSaleGain");
|
||||||
const stock = getStockFromSymbol(symbol, "getSaleGain");
|
const stock = getStockFromSymbol(symbol, "getSaleGain");
|
||||||
@ -122,14 +133,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
buy: function (symbol: any, shares: any): any {
|
buy: function (_symbol: unknown, _shares: unknown): number {
|
||||||
|
const symbol = helper.string("buy", "symbol", _symbol);
|
||||||
|
const shares = helper.number("buy", "shares", _shares);
|
||||||
helper.updateDynamicRam("buy", getRamCost(player, "stock", "buy"));
|
helper.updateDynamicRam("buy", getRamCost(player, "stock", "buy"));
|
||||||
checkTixApiAccess("buy");
|
checkTixApiAccess("buy");
|
||||||
const stock = getStockFromSymbol(symbol, "buy");
|
const stock = getStockFromSymbol(symbol, "buy");
|
||||||
const res = buyStock(stock, shares, workerScript, {});
|
const res = buyStock(stock, shares, workerScript, {});
|
||||||
return res ? stock.getAskPrice() : 0;
|
return res ? stock.getAskPrice() : 0;
|
||||||
},
|
},
|
||||||
sell: function (symbol: any, shares: any): any {
|
sell: function (_symbol: unknown, _shares: unknown): number {
|
||||||
|
const symbol = helper.string("sell", "symbol", _symbol);
|
||||||
|
const shares = helper.number("sell", "shares", _shares);
|
||||||
helper.updateDynamicRam("sell", getRamCost(player, "stock", "sell"));
|
helper.updateDynamicRam("sell", getRamCost(player, "stock", "sell"));
|
||||||
checkTixApiAccess("sell");
|
checkTixApiAccess("sell");
|
||||||
const stock = getStockFromSymbol(symbol, "sell");
|
const stock = getStockFromSymbol(symbol, "sell");
|
||||||
@ -137,7 +152,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return res ? stock.getBidPrice() : 0;
|
return res ? stock.getBidPrice() : 0;
|
||||||
},
|
},
|
||||||
short: function (symbol: any, shares: any): any {
|
short: function (_symbol: unknown, _shares: unknown): number {
|
||||||
|
const symbol = helper.string("short", "symbol", _symbol);
|
||||||
|
const shares = helper.number("short", "shares", _shares);
|
||||||
helper.updateDynamicRam("short", getRamCost(player, "stock", "short"));
|
helper.updateDynamicRam("short", getRamCost(player, "stock", "short"));
|
||||||
checkTixApiAccess("short");
|
checkTixApiAccess("short");
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
@ -153,7 +170,9 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return res ? stock.getBidPrice() : 0;
|
return res ? stock.getBidPrice() : 0;
|
||||||
},
|
},
|
||||||
sellShort: function (symbol: any, shares: any): any {
|
sellShort: function (_symbol: unknown, _shares: unknown): number {
|
||||||
|
const symbol = helper.string("sellShort", "symbol", _symbol);
|
||||||
|
const shares = helper.number("sellShort", "shares", _shares);
|
||||||
helper.updateDynamicRam("sellShort", getRamCost(player, "stock", "sellShort"));
|
helper.updateDynamicRam("sellShort", getRamCost(player, "stock", "sellShort"));
|
||||||
checkTixApiAccess("sellShort");
|
checkTixApiAccess("sellShort");
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
@ -169,7 +188,12 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return res ? stock.getAskPrice() : 0;
|
return res ? stock.getAskPrice() : 0;
|
||||||
},
|
},
|
||||||
placeOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any {
|
placeOrder: function (_symbol: unknown, _shares: unknown, _price: unknown, _type: unknown, _pos: unknown): boolean {
|
||||||
|
const symbol = helper.string("placeOrder", "symbol", _symbol);
|
||||||
|
const shares = helper.number("placeOrder", "shares", _shares);
|
||||||
|
const price = helper.number("placeOrder", "price", _price);
|
||||||
|
const type = helper.string("placeOrder", "type", _type);
|
||||||
|
const pos = helper.string("placeOrder", "pos", _pos);
|
||||||
helper.updateDynamicRam("placeOrder", getRamCost(player, "stock", "placeOrder"));
|
helper.updateDynamicRam("placeOrder", getRamCost(player, "stock", "placeOrder"));
|
||||||
checkTixApiAccess("placeOrder");
|
checkTixApiAccess("placeOrder");
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
@ -208,7 +232,18 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
||||||
},
|
},
|
||||||
cancelOrder: function (symbol: any, shares: any, price: any, type: any, pos: any): any {
|
cancelOrder: function (
|
||||||
|
_symbol: unknown,
|
||||||
|
_shares: unknown,
|
||||||
|
_price: unknown,
|
||||||
|
_type: unknown,
|
||||||
|
_pos: unknown,
|
||||||
|
): boolean {
|
||||||
|
const symbol = helper.string("cancelOrder", "symbol", _symbol);
|
||||||
|
const shares = helper.number("cancelOrder", "shares", _shares);
|
||||||
|
const price = helper.number("cancelOrder", "price", _price);
|
||||||
|
const type = helper.string("cancelOrder", "type", _type);
|
||||||
|
const pos = helper.string("cancelOrder", "pos", _pos);
|
||||||
helper.updateDynamicRam("cancelOrder", getRamCost(player, "stock", "cancelOrder"));
|
helper.updateDynamicRam("cancelOrder", getRamCost(player, "stock", "cancelOrder"));
|
||||||
checkTixApiAccess("cancelOrder");
|
checkTixApiAccess("cancelOrder");
|
||||||
if (player.bitNodeN !== 8) {
|
if (player.bitNodeN !== 8) {
|
||||||
@ -290,7 +325,8 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return orders;
|
return orders;
|
||||||
},
|
},
|
||||||
getVolatility: function (symbol: any): any {
|
getVolatility: function (_symbol: unknown): number {
|
||||||
|
const symbol = helper.string("getVolatility", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getVolatility", getRamCost(player, "stock", "getVolatility"));
|
helper.updateDynamicRam("getVolatility", getRamCost(player, "stock", "getVolatility"));
|
||||||
if (!player.has4SDataTixApi) {
|
if (!player.has4SDataTixApi) {
|
||||||
throw helper.makeRuntimeErrorMsg("getVolatility", "You don't have 4S Market Data TIX API Access!");
|
throw helper.makeRuntimeErrorMsg("getVolatility", "You don't have 4S Market Data TIX API Access!");
|
||||||
@ -299,7 +335,8 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
|
|
||||||
return stock.mv / 100; // Convert from percentage to decimal
|
return stock.mv / 100; // Convert from percentage to decimal
|
||||||
},
|
},
|
||||||
getForecast: function (symbol: any): any {
|
getForecast: function (_symbol: unknown): number {
|
||||||
|
const symbol = helper.string("getForecast", "symbol", _symbol);
|
||||||
helper.updateDynamicRam("getForecast", getRamCost(player, "stock", "getForecast"));
|
helper.updateDynamicRam("getForecast", getRamCost(player, "stock", "getForecast"));
|
||||||
if (!player.has4SDataTixApi) {
|
if (!player.has4SDataTixApi) {
|
||||||
throw helper.makeRuntimeErrorMsg("getForecast", "You don't have 4S Market Data TIX API Access!");
|
throw helper.makeRuntimeErrorMsg("getForecast", "You don't have 4S Market Data TIX API Access!");
|
||||||
@ -310,7 +347,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag);
|
stock.b ? (forecast += stock.otlkMag) : (forecast -= stock.otlkMag);
|
||||||
return forecast / 100; // Convert from percentage to decimal
|
return forecast / 100; // Convert from percentage to decimal
|
||||||
},
|
},
|
||||||
purchase4SMarketData: function () {
|
purchase4SMarketData: function (): boolean {
|
||||||
helper.updateDynamicRam("purchase4SMarketData", getRamCost(player, "stock", "purchase4SMarketData"));
|
helper.updateDynamicRam("purchase4SMarketData", getRamCost(player, "stock", "purchase4SMarketData"));
|
||||||
checkTixApiAccess("purchase4SMarketData");
|
checkTixApiAccess("purchase4SMarketData");
|
||||||
|
|
||||||
@ -329,7 +366,7 @@ export function NetscriptStockMarket(player: IPlayer, workerScript: WorkerScript
|
|||||||
workerScript.log("stock.purchase4SMarketData", () => "Purchased 4S Market Data");
|
workerScript.log("stock.purchase4SMarketData", () => "Purchased 4S Market Data");
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
purchase4SMarketDataTixApi: function () {
|
purchase4SMarketDataTixApi: function (): boolean {
|
||||||
helper.updateDynamicRam("purchase4SMarketDataTixApi", getRamCost(player, "stock", "purchase4SMarketDataTixApi"));
|
helper.updateDynamicRam("purchase4SMarketDataTixApi", getRamCost(player, "stock", "purchase4SMarketDataTixApi"));
|
||||||
checkTixApiAccess("purchase4SMarketDataTixApi");
|
checkTixApiAccess("purchase4SMarketDataTixApi");
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ function processNetscript1Imports(code: string, workerScript: WorkerScript): any
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Now we have to generate the code that would create the namespace
|
//Now we have to generate the code that would create the namespace
|
||||||
generatedCode += "var " + namespace + ";\n" + "(function (namespace) {\n";
|
generatedCode += `var ${namespace};\n(function (namespace) {\n`;
|
||||||
|
|
||||||
//Add the function declarations
|
//Add the function declarations
|
||||||
fnDeclarations.forEach((fn: any) => {
|
fnDeclarations.forEach((fn: any) => {
|
||||||
@ -390,7 +390,7 @@ function processNetscript1Imports(code: string, workerScript: WorkerScript): any
|
|||||||
});
|
});
|
||||||
|
|
||||||
//Finish
|
//Finish
|
||||||
generatedCode += "})(" + namespace + " || " + "(" + namespace + " = {}));\n";
|
generatedCode += `})(${namespace} || (" + namespace + " = {}));\n`;
|
||||||
} else {
|
} else {
|
||||||
//import {...} from script
|
//import {...} from script
|
||||||
|
|
||||||
|
@ -363,11 +363,11 @@ export class PlayerObject implements IPlayer {
|
|||||||
this.companyName = ""; // Name of Company. Must match a key value in Companies ma;
|
this.companyName = ""; // Name of Company. Must match a key value in Companies ma;
|
||||||
|
|
||||||
// Servers
|
// Servers
|
||||||
this.currentServer = ""; //IP address of Server currently being accessed through termina;
|
this.currentServer = ""; //hostname of Server currently being accessed through termina;
|
||||||
this.purchasedServers = []; //IP Addresses of purchased server;
|
this.purchasedServers = []; //hostnames of purchased server;
|
||||||
|
|
||||||
// Hacknet Nodes/Servers
|
// Hacknet Nodes/Servers
|
||||||
this.hacknetNodes = []; // Note= For Hacknet Servers, this array holds the IP addresses of the server;
|
this.hacknetNodes = []; // Note= For Hacknet Servers, this array holds the hostnames of the server;
|
||||||
this.hashManager = new HashManager();
|
this.hashManager = new HashManager();
|
||||||
|
|
||||||
//Factions
|
//Factions
|
||||||
@ -483,11 +483,11 @@ export class PlayerObject implements IPlayer {
|
|||||||
// Let's get a hash of some semi-random stuff so we have something unique.
|
// Let's get a hash of some semi-random stuff so we have something unique.
|
||||||
this.identifier = cyrb53(
|
this.identifier = cyrb53(
|
||||||
"I-" +
|
"I-" +
|
||||||
new Date().getTime() +
|
new Date().getTime() +
|
||||||
navigator.userAgent +
|
navigator.userAgent +
|
||||||
window.innerWidth +
|
window.innerWidth +
|
||||||
window.innerHeight +
|
window.innerHeight +
|
||||||
getRandomInt(100, 999),
|
getRandomInt(100, 999),
|
||||||
);
|
);
|
||||||
|
|
||||||
this.init = generalMethods.init;
|
this.init = generalMethods.init;
|
||||||
|
@ -608,11 +608,9 @@ export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
|||||||
if (this.workPartTime(numCycles)) {
|
if (this.workPartTime(numCycles)) {
|
||||||
router.toCity();
|
router.toCity();
|
||||||
}
|
}
|
||||||
} else {
|
} else if (this.work(numCycles)) {
|
||||||
if (this.work(numCycles)) {
|
|
||||||
router.toCity();
|
router.toCity();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1315,9 +1313,7 @@ export function createProgramWork(this: IPlayer, numCycles: number): boolean {
|
|||||||
export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): string {
|
export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): string {
|
||||||
const programName = this.createProgramName;
|
const programName = this.createProgramName;
|
||||||
if (cancelled === false) {
|
if (cancelled === false) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(`You've finished creating ${programName}!<br>The new program can be found on your home computer.`);
|
||||||
"You've finished creating " + programName + "!<br>" + "The new program can be found on your home computer.",
|
|
||||||
);
|
|
||||||
|
|
||||||
this.getHomeComputer().programs.push(programName);
|
this.getHomeComputer().programs.push(programName);
|
||||||
} else {
|
} else {
|
||||||
@ -2244,8 +2240,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
|||||||
if (!(fulcrumSecretServer instanceof Server)) throw new Error("Fulcrum Secret Technologies should be normal server");
|
if (!(fulcrumSecretServer instanceof Server)) throw new Error("Fulcrum Secret Technologies should be normal server");
|
||||||
if (fulcrumSecretServer == null) {
|
if (fulcrumSecretServer == null) {
|
||||||
console.error("Could not find Fulcrum Secret Technologies Server");
|
console.error("Could not find Fulcrum Secret Technologies Server");
|
||||||
} else {
|
} else if (
|
||||||
if (
|
|
||||||
!fulcrumsecrettechonologiesFac.isBanned &&
|
!fulcrumsecrettechonologiesFac.isBanned &&
|
||||||
!fulcrumsecrettechonologiesFac.isMember &&
|
!fulcrumsecrettechonologiesFac.isMember &&
|
||||||
!fulcrumsecrettechonologiesFac.alreadyInvited &&
|
!fulcrumsecrettechonologiesFac.alreadyInvited &&
|
||||||
@ -2254,7 +2249,6 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] {
|
|||||||
) {
|
) {
|
||||||
invitedFactions.push(fulcrumsecrettechonologiesFac);
|
invitedFactions.push(fulcrumsecrettechonologiesFac);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//BitRunners
|
//BitRunners
|
||||||
const bitrunnersFac = Factions["BitRunners"];
|
const bitrunnersFac = Factions["BitRunners"];
|
||||||
|
@ -34,7 +34,32 @@ export function findSleevePurchasableAugs(sleeve: Sleeve, p: IPlayer): Augmentat
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
const validMults = [
|
||||||
|
"hacking_mult",
|
||||||
|
"strength_mult",
|
||||||
|
"defense_mult",
|
||||||
|
"dexterity_mult",
|
||||||
|
"agility_mult",
|
||||||
|
"charisma_mult",
|
||||||
|
"hacking_exp_mult",
|
||||||
|
"strength_exp_mult",
|
||||||
|
"defense_exp_mult",
|
||||||
|
"dexterity_exp_mult",
|
||||||
|
"agility_exp_mult",
|
||||||
|
"charisma_exp_mult",
|
||||||
|
"company_rep_mult",
|
||||||
|
"faction_rep_mult",
|
||||||
|
"crime_money_mult",
|
||||||
|
"crime_success_mult",
|
||||||
|
"work_money_mult",
|
||||||
|
];
|
||||||
|
for (const mult of Object.keys(aug.mults)) {
|
||||||
|
if (validMults.includes(mult)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If player is in a gang, then we return all augs that the player
|
// If player is in a gang, then we return all augs that the player
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { use } from "../../ui/Context";
|
import { find } from "lodash";
|
||||||
import { getAvailableCreatePrograms } from "../ProgramHelpers";
|
|
||||||
|
|
||||||
import { Box, Tooltip, Typography } from "@mui/material";
|
import {
|
||||||
import Button from "@mui/material/Button";
|
Box,
|
||||||
|
Typography,
|
||||||
|
Button,
|
||||||
|
Container,
|
||||||
|
Paper
|
||||||
|
} from "@mui/material";
|
||||||
|
import { Check, Lock, Create } from "@mui/icons-material";
|
||||||
|
|
||||||
|
import { use } from "../../ui/Context";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
|
||||||
|
import { Programs } from "../Programs";
|
||||||
|
|
||||||
export const ProgramsSeen: string[] = [];
|
export const ProgramsSeen: string[] = [];
|
||||||
|
|
||||||
@ -15,7 +25,20 @@ export function ProgramsRoot(): React.ReactElement {
|
|||||||
setRerender((old) => !old);
|
setRerender((old) => !old);
|
||||||
}
|
}
|
||||||
|
|
||||||
const programs = getAvailableCreatePrograms(player);
|
const programs = [...Object.values(Programs)]
|
||||||
|
.filter(prog => {
|
||||||
|
const create = prog.create;
|
||||||
|
if (create === null) return false;
|
||||||
|
if (prog.name === "b1t_flum3.exe") {
|
||||||
|
return create.req(player);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (player.hasProgram(a.name)) return 1;
|
||||||
|
if (player.hasProgram(b.name)) return -1;
|
||||||
|
return (a.create?.level ?? 0) - (b.create?.level ?? 0);
|
||||||
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
programs.forEach((p) => {
|
programs.forEach((p) => {
|
||||||
@ -29,8 +52,27 @@ export function ProgramsRoot(): React.ReactElement {
|
|||||||
return () => clearInterval(id);
|
return () => clearInterval(id);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const getHackingLevelRemaining = (lvl: number): number => {
|
||||||
|
return Math.ceil(Math.max(lvl - (player.hacking + player.intelligence / 2), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
const getProgCompletion = (name: string): number => {
|
||||||
|
const programFile = find(player.getHomeComputer().programs, p => {
|
||||||
|
return (p.startsWith(name) && p.endsWith("%-INC"));
|
||||||
|
});
|
||||||
|
if (!programFile) return -1;
|
||||||
|
|
||||||
|
const res = programFile.split("-");
|
||||||
|
if (res.length != 3) return -1;
|
||||||
|
const percComplete = Number(res[1].slice(0, -1));
|
||||||
|
if (isNaN(percComplete) || percComplete < 0 || percComplete >= 100) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return percComplete;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Container disableGutters maxWidth="lg" sx={{ mx: 0, mb: 10 }}>
|
||||||
<Typography variant="h4">Create program</Typography>
|
<Typography variant="h4">Create program</Typography>
|
||||||
<Typography>
|
<Typography>
|
||||||
This page displays any programs that you are able to create. Writing the code for a program takes time, which
|
This page displays any programs that you are able to create. Writing the code for a program takes time, which
|
||||||
@ -38,30 +80,45 @@ export function ProgramsRoot(): React.ReactElement {
|
|||||||
time. Your progress will be saved and you can continue later.
|
time. Your progress will be saved and you can continue later.
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Box sx={{ display: 'grid', width: 'fit-content' }}>
|
<Box sx={{ display: 'grid', gridTemplateColumns: "repeat(3, 1fr)", my: 1 }}>
|
||||||
{programs.map((program) => {
|
{programs.map((program) => {
|
||||||
const create = program.create;
|
const create = program.create;
|
||||||
if (create === null) return <></>;
|
if (create === null) return <></>;
|
||||||
|
const curCompletion = getProgCompletion(program.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={program.name}>
|
<Box component={Paper} sx={{ p: 1, opacity: player.hasProgram(program.name) ? 0.75 : 1 }} key={program.name}>
|
||||||
<Tooltip title={create.tooltip}>
|
<Typography variant="h6" sx={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
|
||||||
<Button
|
{player.hasProgram(program.name) && <Check sx={{ mr: 1 }} /> ||
|
||||||
sx={{ my: 1 }}
|
(create.req(player) && <Create sx={{ mr: 1 }} /> || <Lock sx={{ mr: 1 }} />)}
|
||||||
onClick={(event) => {
|
{program.name}
|
||||||
if (!event.isTrusted) return;
|
</Typography>
|
||||||
player.startCreateProgramWork(program.name, create.time, create.level);
|
{(!player.hasProgram(program.name) && create.req(player)) && <Button
|
||||||
player.startFocusing();
|
sx={{ my: 1, width: '100%' }}
|
||||||
router.toWork();
|
onClick={(event) => {
|
||||||
}}
|
if (!event.isTrusted) return;
|
||||||
>
|
player.startCreateProgramWork(program.name, create.time, create.level);
|
||||||
{program.name}
|
player.startFocusing();
|
||||||
</Button>
|
router.toWork();
|
||||||
</Tooltip>
|
}}
|
||||||
</React.Fragment>
|
>
|
||||||
|
Create program
|
||||||
|
</Button>}
|
||||||
|
{(player.hasProgram(program.name) || getHackingLevelRemaining(create.level) === 0) ||
|
||||||
|
<Typography color={Settings.theme.hack}>
|
||||||
|
<b>Unlocks in:</b> {getHackingLevelRemaining(create.level)} hacking levels
|
||||||
|
</Typography>}
|
||||||
|
{(curCompletion !== -1) &&
|
||||||
|
<Typography color={Settings.theme.infolight}>
|
||||||
|
<b>Current completion:</b> {curCompletion}%
|
||||||
|
</Typography>}
|
||||||
|
<Typography>
|
||||||
|
{create.tooltip}
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ function giveSourceFile(bitNodeNumber: number): void {
|
|||||||
if (alreadyOwned && ownedSourceFile) {
|
if (alreadyOwned && ownedSourceFile) {
|
||||||
if (ownedSourceFile.lvl >= 3 && ownedSourceFile.n !== 12) {
|
if (ownedSourceFile.lvl >= 3 && ownedSourceFile.n !== 12) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
"The Source-File for the BitNode you just destroyed, " + sourceFile.name + ", " + "is already at max level!",
|
`The Source-File for the BitNode you just destroyed, ${sourceFile.name}, is already at max level!`,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
++ownedSourceFile.lvl;
|
++ownedSourceFile.lvl;
|
||||||
@ -75,12 +75,10 @@ function giveSourceFile(bitNodeNumber: number): void {
|
|||||||
export function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number): void {
|
export function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number): void {
|
||||||
if (!flume) {
|
if (!flume) {
|
||||||
giveSourceFile(destroyedBitNode);
|
giveSourceFile(destroyedBitNode);
|
||||||
} else {
|
} else if (SourceFileFlags[5] === 0 && newBitNode !== 5) {
|
||||||
if (SourceFileFlags[5] === 0 && newBitNode !== 5) {
|
|
||||||
Player.intelligence = 0;
|
Player.intelligence = 0;
|
||||||
Player.intelligence_exp = 0;
|
Player.intelligence_exp = 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (newBitNode === 5 && Player.intelligence === 0) {
|
if (newBitNode === 5 && Player.intelligence === 0) {
|
||||||
Player.intelligence = 1;
|
Player.intelligence = 1;
|
||||||
}
|
}
|
||||||
|
37
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
37
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -94,6 +94,7 @@ interface Player {
|
|||||||
factions: string[];
|
factions: string[];
|
||||||
tor: boolean;
|
tor: boolean;
|
||||||
hasCorporation: boolean;
|
hasCorporation: boolean;
|
||||||
|
inBladeburner: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2784,7 +2785,7 @@ export interface Bladeburner {
|
|||||||
*
|
*
|
||||||
* Note that this is meant to be used for Contracts and Operations.
|
* Note that this is meant to be used for Contracts and Operations.
|
||||||
* This function will return ‘Infinity’ for actions such as Training and Field Analysis.
|
* This function will return ‘Infinity’ for actions such as Training and Field Analysis.
|
||||||
* This function will return 1 for BlackOps not yet completed regardless of wether
|
* This function will return 1 for BlackOps not yet completed regardless of whether
|
||||||
* the player has the required rank to attempt the mission or not.
|
* the player has the required rank to attempt the mission or not.
|
||||||
*
|
*
|
||||||
* @param type - Type of action.
|
* @param type - Type of action.
|
||||||
@ -2824,7 +2825,7 @@ export interface Bladeburner {
|
|||||||
getActionCurrentLevel(type: string, name: string): number;
|
getActionCurrentLevel(type: string, name: string): number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get wether an action is set to autolevel.
|
* Get whether an action is set to autolevel.
|
||||||
* @remarks
|
* @remarks
|
||||||
* RAM cost: 4 GB
|
* RAM cost: 4 GB
|
||||||
*
|
*
|
||||||
@ -5983,19 +5984,25 @@ export interface NS extends Singularity {
|
|||||||
tFormat(milliseconds: number, milliPrecision?: boolean): string;
|
tFormat(milliseconds: number, milliPrecision?: boolean): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompt the player with a Yes/No modal.
|
* Prompt the player with an input modal.
|
||||||
* @remarks
|
* @remarks
|
||||||
* RAM cost: 0 GB
|
* RAM cost: 0 GB
|
||||||
*
|
*
|
||||||
* Prompts the player with a dialog box with two options: “Yes” and “No”.
|
* Prompts the player with a dialog box. If `options.type` is undefined or "boolean",
|
||||||
* This function will return true if the player click “Yes” and false if
|
* the player is shown "Yes" and "No" prompts, which return true and false respectively.
|
||||||
* the player clicks “No”. The script’s execution is halted until the player
|
* Passing a type of "text" will give the player a text field and a value of "select"
|
||||||
* selects one of the options.
|
* will show a drop-down field. Choosing type "select" will require an array or object
|
||||||
|
* to be passed via the `options.choices` property.
|
||||||
|
* The script’s execution is halted until the player selects one of the options.
|
||||||
*
|
*
|
||||||
* @param txt - Text to appear in the prompt dialog box.
|
* @param txt - Text to appear in the prompt dialog box.
|
||||||
* @returns True if the player click “Yes” and false if the player clicks “No”.
|
* @param options - Options to modify the prompt the player is shown.
|
||||||
|
* @returns True if the player click “Yes”; false if the player clicks “No”; or the value entered by the player.
|
||||||
*/
|
*/
|
||||||
prompt(txt: string): Promise<boolean>;
|
prompt(
|
||||||
|
txt: string,
|
||||||
|
options?: { type?: "boolean" | "text" | "select" | undefined; choices?: string[] },
|
||||||
|
): Promise<boolean | string>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open up a message box.
|
* Open up a message box.
|
||||||
@ -6385,12 +6392,12 @@ export interface WarehouseAPI {
|
|||||||
*/
|
*/
|
||||||
buyMaterial(divisionName: string, cityName: string, materialName: string, amt: number): void;
|
buyMaterial(divisionName: string, cityName: string, materialName: string, amt: number): void;
|
||||||
/**
|
/**
|
||||||
* Set material to bulk buy
|
* Set material to bulk buy
|
||||||
* @param divisionName - Name of the division
|
* @param divisionName - Name of the division
|
||||||
* @param cityName - Name of the city
|
* @param cityName - Name of the city
|
||||||
* @param materialName - Name of the material
|
* @param materialName - Name of the material
|
||||||
* @param amt - Amount of material to buy
|
* @param amt - Amount of material to buy
|
||||||
*/
|
*/
|
||||||
bulkPurchase(divisionName: string, cityName: string, materialName: string, amt: number): void;
|
bulkPurchase(divisionName: string, cityName: string, materialName: string, amt: number): void;
|
||||||
/**
|
/**
|
||||||
* Get warehouse data
|
* Get warehouse data
|
||||||
|
@ -17,6 +17,7 @@ import { calculateRamUsage, checkInfiniteLoop } from "../../Script/RamCalculatio
|
|||||||
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
import { RamCalculationErrorCode } from "../../Script/RamCalculationErrorCodes";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
||||||
|
import SearchIcon from "@mui/icons-material/Search";
|
||||||
|
|
||||||
import { NetscriptFunctions } from "../../NetscriptFunctions";
|
import { NetscriptFunctions } from "../../NetscriptFunctions";
|
||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||||
@ -42,7 +43,7 @@ import { PromptEvent } from "../../ui/React/PromptManager";
|
|||||||
import { Modal } from "../../ui/React/Modal";
|
import { Modal } from "../../ui/React/Modal";
|
||||||
|
|
||||||
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
|
import libSource from "!!raw-loader!../NetscriptDefinitions.d.ts";
|
||||||
import { Tooltip } from "@mui/material";
|
import { TextField, Tooltip } from "@mui/material";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
// Map of filename -> code
|
// Map of filename -> code
|
||||||
@ -53,7 +54,7 @@ interface IProps {
|
|||||||
vim: boolean;
|
vim: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: try to removve global symbols
|
// TODO: try to remove global symbols
|
||||||
let symbolsLoaded = false;
|
let symbolsLoaded = false;
|
||||||
let symbols: string[] = [];
|
let symbols: string[] = [];
|
||||||
export function SetupTextEditor(): void {
|
export function SetupTextEditor(): void {
|
||||||
@ -113,6 +114,8 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const vimStatusRef = useRef<HTMLElement>(null);
|
const vimStatusRef = useRef<HTMLElement>(null);
|
||||||
const [vimEditor, setVimEditor] = useState<any>(null);
|
const [vimEditor, setVimEditor] = useState<any>(null);
|
||||||
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
|
const [editor, setEditor] = useState<IStandaloneCodeEditor | null>(null);
|
||||||
|
const [filter, setFilter] = useState("");
|
||||||
|
const [searchExpanded, setSearchExpanded] = useState(false);
|
||||||
|
|
||||||
const [ram, setRAM] = useState("RAM: ???");
|
const [ram, setRAM] = useState("RAM: ???");
|
||||||
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
|
const [ramEntries, setRamEntries] = useState<string[][]>([["???", ""]]);
|
||||||
@ -232,7 +235,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
MonacoVim.VimMode.Vim.mapCommand("gT", "action", "prevTabs", {}, { context: "normal" });
|
MonacoVim.VimMode.Vim.mapCommand("gT", "action", "prevTabs", {}, { context: "normal" });
|
||||||
editor.focus();
|
editor.focus();
|
||||||
});
|
});
|
||||||
} catch {}
|
} catch { }
|
||||||
} else if (!options.vim) {
|
} else if (!options.vim) {
|
||||||
// Whem vim mode is disabled
|
// Whem vim mode is disabled
|
||||||
vimEditor?.dispose();
|
vimEditor?.dispose();
|
||||||
@ -478,7 +481,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
infLoop(newCode);
|
infLoop(newCode);
|
||||||
} catch (err) {}
|
} catch (err) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveScript(scriptToSave: OpenScript): void {
|
function saveScript(scriptToSave: OpenScript): void {
|
||||||
@ -523,7 +526,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const textFile = new TextFile(scriptToSave.fileName, scriptToSave.code);
|
const textFile = new TextFile(scriptToSave.fileName, scriptToSave.code);
|
||||||
server.textFiles.push(textFile);
|
server.textFiles.push(textFile);
|
||||||
} else {
|
} else {
|
||||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + " or text file (.txt)");
|
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or a text file (.txt)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +610,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const textFile = new TextFile(currentScript.fileName, currentScript.code);
|
const textFile = new TextFile(currentScript.fileName, currentScript.code);
|
||||||
server.textFiles.push(textFile);
|
server.textFiles.push(textFile);
|
||||||
} else {
|
} else {
|
||||||
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or " + " or text file (.txt)");
|
dialogBoxCreate("Invalid filename. Must be either a script (.script, .js, or .ns) or a text file (.txt)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -688,7 +691,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex as number].code) {
|
if (serverScriptIndex === -1 || savedScriptCode !== server.scripts[serverScriptIndex as number].code) {
|
||||||
PromptEvent.emit({
|
PromptEvent.emit({
|
||||||
txt: "Do you want to save changes to " + closingScript.fileName + "?",
|
txt: "Do you want to save changes to " + closingScript.fileName + "?",
|
||||||
resolve: (result: boolean) => {
|
resolve: (result: boolean | string) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
// Save changes
|
// Save changes
|
||||||
closingScript.code = savedScriptCode;
|
closingScript.code = savedScriptCode;
|
||||||
@ -745,7 +748,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
"Do you want to overwrite the current editor content with the contents of " +
|
"Do you want to overwrite the current editor content with the contents of " +
|
||||||
openScript.fileName +
|
openScript.fileName +
|
||||||
" on the server? This cannot be undone.",
|
" on the server? This cannot be undone.",
|
||||||
resolve: (result: boolean) => {
|
resolve: (result: boolean | string) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
// Save changes
|
// Save changes
|
||||||
openScript.code = serverScriptCode;
|
openScript.code = serverScriptCode;
|
||||||
@ -787,6 +790,16 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const serverScript = server.scripts.find((s) => s.filename === openScript.fileName);
|
const serverScript = server.scripts.find((s) => s.filename === openScript.fileName);
|
||||||
return serverScript?.code ?? null;
|
return serverScript?.code ?? null;
|
||||||
}
|
}
|
||||||
|
function handleFilterChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setFilter(event.target.value);
|
||||||
|
}
|
||||||
|
function handleExpandSearch(): void {
|
||||||
|
setFilter("")
|
||||||
|
setSearchExpanded(!searchExpanded)
|
||||||
|
}
|
||||||
|
const filteredOpenScripts = Object.values(openScripts).filter(
|
||||||
|
(script) => (script.hostname.includes(filter) || script.fileName.includes(filter))
|
||||||
|
);
|
||||||
|
|
||||||
// Toolbars are roughly 112px:
|
// Toolbars are roughly 112px:
|
||||||
// 8px body margin top
|
// 8px body margin top
|
||||||
@ -797,7 +810,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const editorHeight = dimensions.height - (130 + (options.vim ? 34 : 0));
|
const editorHeight = dimensions.height - (130 + (options.vim ? 34 : 0));
|
||||||
const tabsMaxWidth = 1640;
|
const tabsMaxWidth = 1640;
|
||||||
const tabMargin = 5;
|
const tabMargin = 5;
|
||||||
const tabMaxWidth = openScripts.length ? tabsMaxWidth / openScripts.length - tabMargin : 0;
|
const tabMaxWidth = filteredOpenScripts.length ? tabsMaxWidth / filteredOpenScripts.length - tabMargin : 0;
|
||||||
const tabIconWidth = 25;
|
const tabIconWidth = 25;
|
||||||
const tabTextWidth = tabMaxWidth - tabIconWidth * 2;
|
const tabTextWidth = tabMaxWidth - tabIconWidth * 2;
|
||||||
return (
|
return (
|
||||||
@ -821,23 +834,36 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
overflowX: "scroll",
|
overflowX: "scroll",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{openScripts.map(({ fileName, hostname }, index) => {
|
<Tooltip title={"Search Open Scripts"}>
|
||||||
|
{searchExpanded ?
|
||||||
|
<TextField
|
||||||
|
value={filter}
|
||||||
|
onChange={handleFilterChange}
|
||||||
|
autoFocus
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: <SearchIcon />,
|
||||||
|
spellCheck: false,
|
||||||
|
endAdornment: <CloseIcon onClick={handleExpandSearch} />
|
||||||
|
}}
|
||||||
|
/> : <Button onClick={handleExpandSearch} ><SearchIcon /></Button>}
|
||||||
|
</Tooltip>
|
||||||
|
{filteredOpenScripts.map(({ fileName, hostname }, index) => {
|
||||||
const iconButtonStyle = {
|
const iconButtonStyle = {
|
||||||
maxWidth: `${tabIconWidth}px`,
|
maxWidth: `${tabIconWidth}px`,
|
||||||
minWidth: `${tabIconWidth}px`,
|
minWidth: `${tabIconWidth}px`,
|
||||||
minHeight: "38.5px",
|
minHeight: "38.5px",
|
||||||
maxHeight: "38.5px",
|
maxHeight: "38.5px",
|
||||||
...(currentScript?.fileName === openScripts[index].fileName
|
...(currentScript?.fileName === filteredOpenScripts[index].fileName
|
||||||
? {
|
? {
|
||||||
background: Settings.theme.button,
|
background: Settings.theme.button,
|
||||||
borderColor: Settings.theme.button,
|
borderColor: Settings.theme.button,
|
||||||
color: Settings.theme.primary,
|
color: Settings.theme.primary,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
background: Settings.theme.backgroundsecondary,
|
background: Settings.theme.backgroundsecondary,
|
||||||
borderColor: Settings.theme.backgroundsecondary,
|
borderColor: Settings.theme.backgroundsecondary,
|
||||||
color: Settings.theme.secondary,
|
color: Settings.theme.secondary,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
const scriptTabText = `${hostname}:~/${fileName} ${dirty(index)}`;
|
const scriptTabText = `${hostname}:~/${fileName} ${dirty(index)}`;
|
||||||
@ -870,18 +896,19 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
}}
|
}}
|
||||||
style={{
|
style={{
|
||||||
maxWidth: `${tabTextWidth}px`,
|
maxWidth: `${tabTextWidth}px`,
|
||||||
|
minHeight: '38.5px',
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
...(currentScript?.fileName === openScripts[index].fileName
|
...(currentScript?.fileName === filteredOpenScripts[index].fileName
|
||||||
? {
|
? {
|
||||||
background: Settings.theme.button,
|
background: Settings.theme.button,
|
||||||
borderColor: Settings.theme.button,
|
borderColor: Settings.theme.button,
|
||||||
color: Settings.theme.primary,
|
color: Settings.theme.primary,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
background: Settings.theme.backgroundsecondary,
|
background: Settings.theme.backgroundsecondary,
|
||||||
borderColor: Settings.theme.backgroundsecondary,
|
borderColor: Settings.theme.backgroundsecondary,
|
||||||
color: Settings.theme.secondary,
|
color: Settings.theme.secondary,
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span style={{ overflow: "hidden", direction: "rtl", textOverflow: "ellipsis" }}>
|
<span style={{ overflow: "hidden", direction: "rtl", textOverflow: "ellipsis" }}>
|
||||||
|
@ -78,12 +78,11 @@ export function ipExists(ip: string): boolean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function createUniqueRandomIp(): string {
|
export function createUniqueRandomIp(): string {
|
||||||
const ip = createRandomIp();
|
let ip: string;
|
||||||
|
// Repeat generating ip, until unique one is found
|
||||||
// If the Ip already exists, recurse to create a new one
|
do {
|
||||||
if (ipExists(ip)) {
|
ip = createRandomIp();
|
||||||
return createRandomIp();
|
} while (ipExists(ip));
|
||||||
}
|
|
||||||
|
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ export class BaseServer {
|
|||||||
// Script files on this Server
|
// Script files on this Server
|
||||||
scripts: Script[] = [];
|
scripts: Script[] = [];
|
||||||
|
|
||||||
// Contains the IP Addresses of all servers that are immediately
|
// Contains the hostnames of all servers that are immediately
|
||||||
// reachable from this one
|
// reachable from this one
|
||||||
serversOnNetwork: string[] = [];
|
serversOnNetwork: string[] = [];
|
||||||
|
|
||||||
|
@ -143,11 +143,6 @@ export function SidebarRoot(props: IProps): React.ReactElement {
|
|||||||
const augmentationCount = props.player.queuedAugmentations.length;
|
const augmentationCount = props.player.queuedAugmentations.length;
|
||||||
const invitationsCount = props.player.factionInvitations.filter((f) => !InvitationsSeen.includes(f)).length;
|
const invitationsCount = props.player.factionInvitations.filter((f) => !InvitationsSeen.includes(f)).length;
|
||||||
const programCount = getAvailableCreatePrograms(props.player).length - ProgramsSeen.length;
|
const programCount = getAvailableCreatePrograms(props.player).length - ProgramsSeen.length;
|
||||||
const canCreateProgram =
|
|
||||||
getAvailableCreatePrograms(props.player).length > 0 ||
|
|
||||||
props.player.augmentations.length > 0 ||
|
|
||||||
props.player.queuedAugmentations.length > 0 ||
|
|
||||||
props.player.sourceFiles.length > 0;
|
|
||||||
|
|
||||||
const canOpenFactions =
|
const canOpenFactions =
|
||||||
props.player.factionInvitations.length > 0 ||
|
props.player.factionInvitations.length > 0 ||
|
||||||
@ -439,29 +434,27 @@ export function SidebarRoot(props: IProps): React.ReactElement {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</ListItemText>
|
</ListItemText>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
{canCreateProgram && (
|
<ListItem
|
||||||
<ListItem
|
button
|
||||||
button
|
key={"Create Program"}
|
||||||
key={"Create Program"}
|
className={clsx({
|
||||||
className={clsx({
|
[classes.active]: props.page === Page.CreateProgram,
|
||||||
[classes.active]: props.page === Page.CreateProgram,
|
})}
|
||||||
})}
|
onClick={clickCreateProgram}
|
||||||
onClick={clickCreateProgram}
|
>
|
||||||
>
|
<ListItemIcon>
|
||||||
<ListItemIcon>
|
<Badge badgeContent={programCount > 0 ? programCount : undefined} color="error">
|
||||||
<Badge badgeContent={programCount > 0 ? programCount : undefined} color="error">
|
<Tooltip title={!open ? "Create Program" : ""}>
|
||||||
<Tooltip title={!open ? "Create Program" : ""}>
|
<BugReportIcon color={props.page !== Page.CreateProgram ? "secondary" : "primary"} />
|
||||||
<BugReportIcon color={props.page !== Page.CreateProgram ? "secondary" : "primary"} />
|
</Tooltip>
|
||||||
</Tooltip>
|
</Badge>
|
||||||
</Badge>
|
</ListItemIcon>
|
||||||
</ListItemIcon>
|
<ListItemText>
|
||||||
<ListItemText>
|
<Typography color={props.page !== Page.CreateProgram ? "secondary" : "primary"}>
|
||||||
<Typography color={props.page !== Page.CreateProgram ? "secondary" : "primary"}>
|
Create Program
|
||||||
Create Program
|
</Typography>
|
||||||
</Typography>
|
</ListItemText>
|
||||||
</ListItemText>
|
</ListItem>
|
||||||
</ListItem>
|
|
||||||
)}
|
|
||||||
{canStaneksGift && (
|
{canStaneksGift && (
|
||||||
<ListItem
|
<ListItem
|
||||||
button
|
button
|
||||||
|
@ -66,10 +66,9 @@ SourceFiles["SourceFile5"] = new SourceFile(
|
|||||||
<>
|
<>
|
||||||
This Source-File grants a special new stat called Intelligence. Intelligence is unique because it is permanent and
|
This Source-File grants a special new stat called Intelligence. Intelligence is unique because it is permanent and
|
||||||
persistent (it never gets reset back to 1). However, gaining Intelligence experience is much slower than other
|
persistent (it never gets reset back to 1). However, gaining Intelligence experience is much slower than other
|
||||||
stats, and it is also hidden (you won't know when you gain experience and how much). Higher Intelligence levels
|
stats. Higher Intelligence levels will boost your production for many actions in the game. In addition, this
|
||||||
will boost your production for many actions in the game. In addition, this Source-File will unlock the
|
Source-File will unlock the getBitNodeMultipliers() Netscript function and let you start with Formulas.exe, and
|
||||||
getBitNodeMultipliers() Netscript function and let you start with Formulas.exe, and will raise all of your
|
will raise all of your hacking-related multipliers by:
|
||||||
hacking-related multipliers by:
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
Level 1: 8%
|
Level 1: 8%
|
||||||
|
@ -117,7 +117,7 @@ export function buyStock(
|
|||||||
const resultTxt =
|
const resultTxt =
|
||||||
`Bought ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} for ${numeralWrapper.formatMoney(
|
`Bought ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} for ${numeralWrapper.formatMoney(
|
||||||
totalPrice,
|
totalPrice,
|
||||||
)}. ` + `Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`;
|
)}. Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`;
|
||||||
workerScript.log("stock.buy", () => resultTxt);
|
workerScript.log("stock.buy", () => resultTxt);
|
||||||
} else if (opts.suppressDialog !== true) {
|
} else if (opts.suppressDialog !== true) {
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
|
@ -165,8 +165,7 @@ function executeOrder(order: Order, refs: IProcessOrderRefs): void {
|
|||||||
|
|
||||||
console.error("Could not find the following Order in Order Book: ");
|
console.error("Could not find the following Order in Order Book: ");
|
||||||
console.error(order);
|
console.error(order);
|
||||||
} else {
|
} else if (isBuy) {
|
||||||
if (isBuy) {
|
|
||||||
dialogBoxCreate(
|
dialogBoxCreate(
|
||||||
<>
|
<>
|
||||||
Failed to execute {order.type} for {stock.symbol} @ <Money money={order.price} /> ({pos}). This is most likely
|
Failed to execute {order.type} for {stock.symbol} @ <Money money={order.price} /> ({pos}). This is most likely
|
||||||
@ -174,5 +173,4 @@ function executeOrder(order: Order, refs: IProcessOrderRefs): void {
|
|||||||
</>,
|
</>,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -213,13 +213,11 @@ export class Stock {
|
|||||||
} else {
|
} else {
|
||||||
this.otlkMag -= changeAmt;
|
this.otlkMag -= changeAmt;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (this.b) {
|
||||||
// Forecast decreases
|
// Forecast decreases
|
||||||
if (this.b) {
|
this.otlkMag -= changeAmt;
|
||||||
this.otlkMag -= changeAmt;
|
} else {
|
||||||
} else {
|
this.otlkMag += changeAmt;
|
||||||
this.otlkMag += changeAmt;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.otlkMag = Math.min(this.otlkMag, 50);
|
this.otlkMag = Math.min(this.otlkMag, 50);
|
||||||
|
@ -113,11 +113,9 @@ export function StockTicker(props: IProps): React.ReactElement {
|
|||||||
if (qty > stock.playerShares) {
|
if (qty > stock.playerShares) {
|
||||||
return <>You do not have this many shares in the Long position</>;
|
return <>You do not have this many shares in the Long position</>;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (qty > stock.playerShortShares) {
|
||||||
if (qty > stock.playerShortShares) {
|
|
||||||
return <>You do not have this many shares in the Short position</>;
|
return <>You do not have this many shares in the Short position</>;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const cost = getSellTransactionGain(stock, qty, position);
|
const cost = getSellTransactionGain(stock, qty, position);
|
||||||
if (cost == null) {
|
if (cost == null) {
|
||||||
|
@ -190,7 +190,7 @@ export const HelpTexts: IMap<string[]> = {
|
|||||||
connect: [
|
connect: [
|
||||||
"Usage: connect [hostname]",
|
"Usage: connect [hostname]",
|
||||||
" ",
|
" ",
|
||||||
"Connect to a remote server. The hostname or IP address of the remote server must be given as the argument ",
|
"Connect to a remote server. The hostname of the remote server must be given as the argument ",
|
||||||
"to this command. Note that only servers that are immediately adjacent to the current server in the network can be connected to. To ",
|
"to this command. Note that only servers that are immediately adjacent to the current server in the network can be connected to. To ",
|
||||||
"see which servers can be connected to, use the 'scan' command.",
|
"see which servers can be connected to, use the 'scan' command.",
|
||||||
" ",
|
" ",
|
||||||
|
@ -68,13 +68,11 @@ export function ParseCommand(command: string): (string | number | boolean)[] {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (inQuote === ``) {
|
||||||
if (inQuote === ``) {
|
|
||||||
inQuote = `"`;
|
inQuote = `"`;
|
||||||
} else if (inQuote === `"`) {
|
} else if (inQuote === `"`) {
|
||||||
inQuote = ``;
|
inQuote = ``;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (c === "'") {
|
} else if (c === "'") {
|
||||||
// Single quotes, same thing as above
|
// Single quotes, same thing as above
|
||||||
if (!escaped && prevChar === " ") {
|
if (!escaped && prevChar === " ") {
|
||||||
@ -88,13 +86,11 @@ export function ParseCommand(command: string): (string | number | boolean)[] {
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (inQuote === ``) {
|
||||||
if (inQuote === ``) {
|
|
||||||
inQuote = `'`;
|
inQuote = `'`;
|
||||||
} else if (inQuote === `'`) {
|
} else if (inQuote === `'`) {
|
||||||
inQuote = ``;
|
inQuote = ``;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (c === " " && inQuote === ``) {
|
} else if (c === " " && inQuote === ``) {
|
||||||
const arg = command.substr(start, i - start);
|
const arg = command.substr(start, i - start);
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ export function ls(
|
|||||||
|
|
||||||
function postSegments(segments: string[], style?: any, linked?: boolean): void {
|
function postSegments(segments: string[], style?: any, linked?: boolean): void {
|
||||||
const maxLength = Math.max(...segments.map((s) => s.length)) + 1;
|
const maxLength = Math.max(...segments.map((s) => s.length)) + 1;
|
||||||
const filesPerRow = Math.floor(80 / maxLength);
|
const filesPerRow = Math.ceil(80 / maxLength);
|
||||||
for (let i = 0; i < segments.length; i++) {
|
for (let i = 0; i < segments.length; i++) {
|
||||||
let row = "";
|
let row = "";
|
||||||
for (let col = 0; col < filesPerRow; col++) {
|
for (let col = 0; col < filesPerRow; col++) {
|
||||||
@ -179,13 +179,11 @@ export function ls(
|
|||||||
i--;
|
i--;
|
||||||
if (!style) {
|
if (!style) {
|
||||||
terminal.print(row);
|
terminal.print(row);
|
||||||
} else {
|
} else if (linked) {
|
||||||
if (linked) {
|
|
||||||
terminal.printRaw(<ClickableScriptRow row={row} prefix={prefix} hostname={server.hostname} />);
|
terminal.printRaw(<ClickableScriptRow row={row} prefix={prefix} hostname={server.hostname} />);
|
||||||
} else {
|
} else {
|
||||||
terminal.printRaw(<span style={style}>{row}</span>);
|
terminal.printRaw(<span style={style}>{row}</span>);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,9 @@ export function unalias(
|
|||||||
if (args.length !== 1) {
|
if (args.length !== 1) {
|
||||||
terminal.error("Incorrect usage of unalias name. Usage: unalias [alias]");
|
terminal.error("Incorrect usage of unalias name. Usage: unalias [alias]");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else if (removeAlias(args[0] + "")) {
|
||||||
if (removeAlias(args[0] + "")) {
|
|
||||||
terminal.print(`Removed alias ${args[0]}`);
|
terminal.print(`Removed alias ${args[0]}`);
|
||||||
} else {
|
} else {
|
||||||
terminal.error(`No such alias exists: ${args[0]}`);
|
terminal.error(`No such alias exists: ${args[0]}`);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -66,28 +66,22 @@ export function tabCompletion(
|
|||||||
if (arg === "") {
|
if (arg === "") {
|
||||||
if (longestStartSubstr === command) {
|
if (longestStartSubstr === command) {
|
||||||
return allPossibilities;
|
return allPossibilities;
|
||||||
} else {
|
} else if (semiColonIndex === -1) {
|
||||||
if (semiColonIndex === -1) {
|
|
||||||
// No semicolon, so replace the whole command
|
// No semicolon, so replace the whole command
|
||||||
return longestStartSubstr;
|
return longestStartSubstr;
|
||||||
} else {
|
} else {
|
||||||
// Replace only after the last semicolon
|
// Replace only after the last semicolon
|
||||||
return `${oldValue.slice(0, semiColonIndex + 1)} ${longestStartSubstr}`;
|
return `${oldValue.slice(0, semiColonIndex + 1)} ${longestStartSubstr}`;
|
||||||
}
|
}
|
||||||
}
|
} else if (longestStartSubstr === arg) {
|
||||||
} else {
|
|
||||||
if (longestStartSubstr === arg) {
|
|
||||||
// List all possible options
|
// List all possible options
|
||||||
return allPossibilities;
|
return allPossibilities;
|
||||||
} else {
|
} else if (semiColonIndex == -1) {
|
||||||
if (semiColonIndex == -1) {
|
|
||||||
// No semicolon, so replace the whole command
|
// No semicolon, so replace the whole command
|
||||||
return `${command} ${longestStartSubstr}`;
|
return `${command} ${longestStartSubstr}`;
|
||||||
} else {
|
} else {
|
||||||
// Replace only after the last semicolon
|
// Replace only after the last semicolon
|
||||||
return `${oldValue.slice(0, semiColonIndex + 1)} ${command} ${longestStartSubstr}`;
|
return `${oldValue.slice(0, semiColonIndex + 1)} ${command} ${longestStartSubstr}`;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -640,7 +640,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
|||||||
"of the path, you may only move to adjacent numbers in the row below.",
|
"of the path, you may only move to adjacent numbers in the row below.",
|
||||||
"The triangle is represented as a 2D array of numbers:\n\n",
|
"The triangle is represented as a 2D array of numbers:\n\n",
|
||||||
`${triangle}\n\n`,
|
`${triangle}\n\n`,
|
||||||
"Example: If you are given the following triangle:\n\n" + "[\n",
|
"Example: If you are given the following triangle:\n\n[\n",
|
||||||
" [2],\n",
|
" [2],\n",
|
||||||
" [3,4],\n",
|
" [3,4],\n",
|
||||||
" [6,5,7],\n",
|
" [6,5,7],\n",
|
||||||
|
@ -56,7 +56,7 @@ export function ServerAccordions(props: IProps): React.ReactElement {
|
|||||||
for (const ws of props.workerScripts.values()) {
|
for (const ws of props.workerScripts.values()) {
|
||||||
const server = GetServer(ws.hostname);
|
const server = GetServer(ws.hostname);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
console.warn(`WorkerScript has invalid IP address: ${ws.hostname}`);
|
console.warn(`WorkerScript has invalid hostname: ${ws.hostname}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,9 @@ function Intelligence(): React.ReactElement {
|
|||||||
<TableCell align="right">
|
<TableCell align="right">
|
||||||
<Typography>{numeralWrapper.formatSkill(player.intelligence)} </Typography>
|
<Typography>{numeralWrapper.formatSkill(player.intelligence)} </Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell align="right">
|
||||||
|
<Typography noWrap>({numeralWrapper.formatExp(player.intelligence_exp)} exp)</Typography>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -33,23 +33,34 @@ interface IProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Intelligence(): React.ReactElement {
|
function Intelligence(): React.ReactElement {
|
||||||
|
const theme = useTheme();
|
||||||
const player = use.Player();
|
const player = use.Player();
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
if (player.intelligence === 0) return <></>;
|
if (player.intelligence === 0) return <></>;
|
||||||
|
const progress = player.calculateSkillProgress(player.intelligence_exp);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TableRow>
|
<>
|
||||||
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
|
<TableRow>
|
||||||
<Typography classes={{ root: classes.int }}>Int </Typography>
|
<TableCell component="th" scope="row" classes={{ root: classes.cell }}>
|
||||||
</TableCell>
|
<Typography classes={{ root: classes.int }}>Int </Typography>
|
||||||
<TableCell align="right" classes={{ root: classes.cell }}>
|
</TableCell>
|
||||||
<Typography classes={{ root: classes.int }}>{numeralWrapper.formatSkill(player.intelligence)}</Typography>
|
<TableCell align="right" classes={{ root: classes.cell }}>
|
||||||
</TableCell>
|
<Typography classes={{ root: classes.int }}>{numeralWrapper.formatSkill(player.intelligence)}</Typography>
|
||||||
<TableCell align="right" classes={{ root: classes.cell }}>
|
</TableCell>
|
||||||
<Typography id="overview-int-hook" classes={{ root: classes.int }}>
|
<TableCell align="right" classes={{ root: classes.cell }}>
|
||||||
{/*Hook for player scripts*/}
|
<Typography id="overview-int-hook" classes={{ root: classes.int }}>
|
||||||
</Typography>
|
{/*Hook for player scripts*/}
|
||||||
</TableCell>
|
</Typography>
|
||||||
</TableRow>
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow>
|
||||||
|
{!Settings.DisableOverviewProgressBars && (
|
||||||
|
<StatsProgressOverviewCell progress={progress} color={theme.colors.int} />
|
||||||
|
)}
|
||||||
|
</TableRow>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,54 +3,150 @@ import { EventEmitter } from "../../utils/EventEmitter";
|
|||||||
import { Modal } from "./Modal";
|
import { Modal } from "./Modal";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||||
|
import TextField from "@mui/material/TextField";
|
||||||
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
|
||||||
export const PromptEvent = new EventEmitter<[Prompt]>();
|
export const PromptEvent = new EventEmitter<[Prompt]>();
|
||||||
|
|
||||||
interface Prompt {
|
interface Prompt {
|
||||||
txt: string;
|
txt: string;
|
||||||
resolve: (result: boolean) => void;
|
options?: { type?: string; choices?: string[] };
|
||||||
|
resolve: (result: boolean | string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PromptManager(): React.ReactElement {
|
export function PromptManager(): React.ReactElement {
|
||||||
const [prompt, setPrompt] = useState<Prompt | null>(null);
|
const [prompt, setPrompt] = useState<Prompt | null>(null);
|
||||||
useEffect(
|
useEffect(() => {
|
||||||
() =>
|
return PromptEvent.subscribe((p: Prompt) => {
|
||||||
PromptEvent.subscribe((p: Prompt) => {
|
setPrompt(p);
|
||||||
setPrompt(p);
|
});
|
||||||
}),
|
}, []);
|
||||||
[],
|
|
||||||
);
|
if (prompt === null) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
function close(): void {
|
function close(): void {
|
||||||
if (prompt === null) return;
|
if (prompt === null) return;
|
||||||
prompt.resolve(false);
|
if (["text", "select"].includes(prompt?.options?.type ?? "")) {
|
||||||
|
prompt.resolve("");
|
||||||
|
} else {
|
||||||
|
prompt.resolve(false);
|
||||||
|
}
|
||||||
setPrompt(null);
|
setPrompt(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function yes(): void {
|
const types: { [key: string]: any } = {
|
||||||
if (prompt === null) return;
|
text: PromptMenuText,
|
||||||
prompt.resolve(true);
|
select: PromptMenuSelect,
|
||||||
|
};
|
||||||
|
|
||||||
|
let PromptContent = PromptMenuBoolean;
|
||||||
|
if (prompt?.options?.type) PromptContent = types[prompt?.options?.type];
|
||||||
|
|
||||||
|
const resolve = (value: boolean | string): void => {
|
||||||
|
prompt.resolve(value);
|
||||||
setPrompt(null);
|
setPrompt(null);
|
||||||
}
|
};
|
||||||
function no(): void {
|
|
||||||
if (prompt === null) return;
|
return (
|
||||||
prompt.resolve(false);
|
<Modal open={true} onClose={close}>
|
||||||
setPrompt(null);
|
<Typography>{prompt.txt}</Typography>
|
||||||
}
|
<PromptContent prompt={prompt} resolve={resolve} />
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IContentProps {
|
||||||
|
prompt: Prompt;
|
||||||
|
resolve: (value: boolean | string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
function PromptMenuBoolean({ resolve }: IContentProps): React.ReactElement {
|
||||||
|
const yes = (): void => resolve(true);
|
||||||
|
const no = (): void => resolve(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{prompt != null && (
|
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", paddingTop: "10px" }}>
|
||||||
<Modal open={true} onClose={close}>
|
<Button style={{ marginRight: "auto" }} onClick={yes}>
|
||||||
<pre>
|
Yes
|
||||||
<Typography>{prompt.txt}</Typography>
|
</Button>
|
||||||
</pre>
|
<Button onClick={no}>No</Button>
|
||||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', paddingTop: '10px' }}>
|
</div>
|
||||||
<Button style={{ marginRight: 'auto' }} onClick={yes}>Yes</Button>
|
</>
|
||||||
<Button onClick={no}>No</Button>
|
);
|
||||||
</div>
|
}
|
||||||
</Modal>
|
|
||||||
)}
|
function PromptMenuText({ resolve }: IContentProps): React.ReactElement {
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
|
||||||
|
const submit = (): void => resolve(value);
|
||||||
|
|
||||||
|
const onInput = (event: React.ChangeEvent<HTMLInputElement>): void => {
|
||||||
|
setValue(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void => {
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
if (event.key === "Enter") {
|
||||||
|
event.preventDefault();
|
||||||
|
submit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", paddingTop: "10px" }}>
|
||||||
|
<TextField
|
||||||
|
autoFocus
|
||||||
|
value={value}
|
||||||
|
onInput={onInput}
|
||||||
|
onKeyDown={onKeyDown}
|
||||||
|
style={{ flex: "1 0 auto" }}
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: <Button onClick={submit}>Confirm</Button>,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function PromptMenuSelect({ prompt, resolve }: IContentProps): React.ReactElement {
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
|
||||||
|
const submit = (): void => resolve(value);
|
||||||
|
|
||||||
|
const onChange = (event: SelectChangeEvent<string>): void => {
|
||||||
|
setValue(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getItems = (choices: string[]): React.ReactElement[] => {
|
||||||
|
const content = [];
|
||||||
|
for (const i of choices) {
|
||||||
|
// @ts-ignore
|
||||||
|
content.push(
|
||||||
|
<MenuItem key={i} value={i}>
|
||||||
|
{i}
|
||||||
|
</MenuItem>,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div style={{ display: "flex", alignItems: "center", paddingTop: "10px" }}>
|
||||||
|
<Select onChange={onChange} value={value} style={{ flex: "1 0 auto" }}>
|
||||||
|
{getItems(prompt?.options?.choices || [])}
|
||||||
|
</Select>
|
||||||
|
<Button onClick={submit} disabled={value === ""}>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,8 +17,7 @@ export function validateObject<Type extends Record<string, unknown>, Key extends
|
|||||||
if (paramValidator !== undefined) {
|
if (paramValidator !== undefined) {
|
||||||
if (typeof paramValidator === 'function') {
|
if (typeof paramValidator === 'function') {
|
||||||
paramValidator(obj, key);
|
paramValidator(obj, key);
|
||||||
} else {
|
} else if (paramValidator.func !== undefined) {
|
||||||
if (paramValidator.func !== undefined) {
|
|
||||||
paramValidator.func(obj, validator, key);
|
paramValidator.func(obj, validator, key);
|
||||||
} else {
|
} else {
|
||||||
if ((typeof obj[key]) !== (typeof paramValidator.default)) {
|
if ((typeof obj[key]) !== (typeof paramValidator.default)) {
|
||||||
@ -31,7 +30,6 @@ export function validateObject<Type extends Record<string, unknown>, Key extends
|
|||||||
if (obj[key] > paramValidator.max) obj[key] = paramValidator.max as Type[Key];
|
if (obj[key] > paramValidator.max) obj[key] = paramValidator.max as Type[Key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,9 +94,9 @@ export function v1APIBreak(): void {
|
|||||||
|
|
||||||
if (s.length === 0) continue;
|
if (s.length === 0) continue;
|
||||||
|
|
||||||
txt += `// Detected change ${change[0]}, reason: ${change[1]}` + "\n";
|
txt += `// Detected change ${change[0]}, reason: ${change[1]}\n`;
|
||||||
for (const fl of s) {
|
for (const fl of s) {
|
||||||
txt += `${fl.file}:${fl.line}` + "\n";
|
txt += `${fl.file}:${fl.line}\n`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ async function main(version, versionNumber, changelog) {
|
|||||||
join('\n').replaceAll('`', '\\`');
|
join('\n').replaceAll('`', '\\`');
|
||||||
|
|
||||||
modifiedConstants = modifiedConstants.
|
modifiedConstants = modifiedConstants.
|
||||||
replace(/(^\s*?LatestUpdate:\s`\n)(.*)`,$/ms, `$1${paddedChangelog}\n` + "`,");
|
replace(/(^\s*?LatestUpdate:\s`\n)(.*)`,$/ms, `$1${paddedChangelog}\n\`,`);
|
||||||
}
|
}
|
||||||
await fs.writeFile(appPaths.constants, modifiedConstants);
|
await fs.writeFile(appPaths.constants, modifiedConstants);
|
||||||
console.log(`Modified ${appPaths.constants}`);
|
console.log(`Modified ${appPaths.constants}`);
|
||||||
|
Loading…
Reference in New Issue
Block a user