mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-27 00:17:32 +01:00
commit
4c0d96f572
@ -99,7 +99,6 @@ module.exports = {
|
|||||||
"no-catch-shadow": ["error"],
|
"no-catch-shadow": ["error"],
|
||||||
"no-class-assign": ["error"],
|
"no-class-assign": ["error"],
|
||||||
"no-compare-neg-zero": ["error"],
|
"no-compare-neg-zero": ["error"],
|
||||||
"no-cond-assign": ["off", "except-parens"],
|
|
||||||
"no-confusing-arrow": ["error"],
|
"no-confusing-arrow": ["error"],
|
||||||
"no-console": ["off"],
|
"no-console": ["off"],
|
||||||
"no-const-assign": ["error"],
|
"no-const-assign": ["error"],
|
||||||
|
@ -84,6 +84,28 @@ changes are okay to contribute:
|
|||||||
- Changes that directly affect the game's balance
|
- Changes that directly affect the game's balance
|
||||||
- New gameplay mechanics
|
- New gameplay mechanics
|
||||||
|
|
||||||
|
### How to setup fork properly
|
||||||
|
|
||||||
|
Fork and clone the repo
|
||||||
|
|
||||||
|
```
|
||||||
|
# This will add the game original code as a repo in your local copy
|
||||||
|
$ git remote add danielyxie git@github.com:danielyxie/bitburner.git
|
||||||
|
|
||||||
|
# You can verify you did this right by doing the following command
|
||||||
|
$ git remote show
|
||||||
|
danielyxie
|
||||||
|
origin
|
||||||
|
|
||||||
|
# Then download all the branches from the game. (there might be more branches)
|
||||||
|
$ git fetch danielyxie
|
||||||
|
From github.com:danielyxie/bitburner
|
||||||
|
* [new branch] dev -> danielyxie/dev
|
||||||
|
* [new branch] master -> danielyxie/master
|
||||||
|
|
||||||
|
# Makes sure you always start from `danielyxie/dev` to avoid merge conflicts.
|
||||||
|
```
|
||||||
|
|
||||||
#### Submitting a Pull Request
|
#### Submitting a Pull Request
|
||||||
|
|
||||||
When submitting a pull request with your code contributions, please abide by
|
When submitting a pull request with your code contributions, please abide by
|
||||||
|
40
dist/vendor.bundle.js
vendored
40
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -3,6 +3,109 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
v0.56.0 - 2021-10-11 Trimming the backlog (hydroflame & community)
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
** BREAKING **
|
||||||
|
|
||||||
|
* The 'write' function is now async. This helps when making scripts that write scripts.
|
||||||
|
|
||||||
|
** Terminal **
|
||||||
|
|
||||||
|
* 'grow' and 'weaken' have been added as terminal command. This should help player transition
|
||||||
|
from commands to scripts. The tutorial also talks about it.
|
||||||
|
* 'cp' command added
|
||||||
|
* Improved performance by rate limiting refresh.
|
||||||
|
|
||||||
|
** IP vs Hostname **
|
||||||
|
|
||||||
|
* The game now uses hostname as primary key for it's servers (yeah believe it or not IPs were
|
||||||
|
used until then). This has caused some issues with purchased servers (they couldn't be sold).
|
||||||
|
You might need to soft reset for the game to fully convert itself.
|
||||||
|
|
||||||
|
** Sleeve **
|
||||||
|
|
||||||
|
* Fixed bug where they couldn't train at Volhaven.
|
||||||
|
* No longer consume all bonus time at once, making it look buggy.
|
||||||
|
|
||||||
|
** SF9 **
|
||||||
|
|
||||||
|
* Now boosts hacknet production by 8/12/14%
|
||||||
|
|
||||||
|
** Hacknet Servers **
|
||||||
|
|
||||||
|
* production nerfed by 10%
|
||||||
|
* Max money increase gets weaker above 10t max money
|
||||||
|
|
||||||
|
** Corporation **
|
||||||
|
|
||||||
|
* Warehouse tooltip now also displays the amount of space taken by products.
|
||||||
|
* Changed research box completely to avoid dependency on Treant (Treant is a pita)
|
||||||
|
* All textbox should accept MAX/MP case insensitive.
|
||||||
|
* Fixed export popup not refreshing dropdowns correctly.
|
||||||
|
* Fixed product mku becoming zero
|
||||||
|
* Increased scaling of Wilson to avoid feedback loop.
|
||||||
|
* Can no longer get in debt by buying real estate
|
||||||
|
* Bonus time is consumed faster.
|
||||||
|
|
||||||
|
** Netscript **
|
||||||
|
|
||||||
|
* isBusy takes bitverse and infiltration into account
|
||||||
|
* hospitalize can't be called when in infiltration.
|
||||||
|
* setToCommitCrime now accepts crime rough name instead of perfect name.
|
||||||
|
* disableLog All now works for bladeburner functions.
|
||||||
|
* Fixed netscript port for ns1.
|
||||||
|
|
||||||
|
** Augmentation **
|
||||||
|
|
||||||
|
* Added augmentation to Ti Di Hui that removes penalty for being unfocused.
|
||||||
|
* Neuroflux no longer appears in special factions.
|
||||||
|
|
||||||
|
** Script Editor **
|
||||||
|
|
||||||
|
* Ram check is debounced instead of refreshed every second.
|
||||||
|
* Added the vscode extension documentation to the game (it doesn't work well, thought)
|
||||||
|
* Fixed issue where autocomplete list would grow forever
|
||||||
|
* Added semi-monokai as theme.
|
||||||
|
* Fixed issue where modifying filename would mess it up.
|
||||||
|
* Font size can be changed now.
|
||||||
|
|
||||||
|
** Infiltration **
|
||||||
|
|
||||||
|
* Fixed issue where game controls would become unfocused.
|
||||||
|
|
||||||
|
** Misc. **
|
||||||
|
|
||||||
|
* Fixed loader incorrectly assuming some null values are incorrect.
|
||||||
|
* installBackdoor trigger Bitverse sequence
|
||||||
|
* Some improvements to the theme editor
|
||||||
|
* Improved documentation about where to learn javascript.
|
||||||
|
* Added some instructions for contributors.
|
||||||
|
* Fixed typo in corporation sell shares modal (@Saynt_Garmo)
|
||||||
|
* Fixed pagination being black on black in Active Scripts
|
||||||
|
* Create Script tab renamed to Script Editor
|
||||||
|
* Fixed an issue where corp some textbox wouldn't update when changing city.
|
||||||
|
* Fixed an issue where hacknet online time was always 0.
|
||||||
|
* Netscript function prompt fixed.
|
||||||
|
* Fixed miscalculation in growth.
|
||||||
|
* Script with syntax errors will try to be a tad more helpful.
|
||||||
|
* Corporations can no longer bribe bladeburners.
|
||||||
|
* Augmentation Graphene Branchiblade renamed to Brachi, like the rest of them.
|
||||||
|
* All ram is displayed in GB/TB/PB now.
|
||||||
|
* Game now saves when saving a file, this can be turned off.
|
||||||
|
* Several improvement to log window.
|
||||||
|
* Bladeburner current action returns General type instead of the name of the action.
|
||||||
|
* Bladeburner travel and Sleeve travel respect disable ASCII.
|
||||||
|
* Tutorial fits on small screens.
|
||||||
|
* Import is much slower but more consistent now.
|
||||||
|
* Fix intelligence not updating properly.
|
||||||
|
* Added SF -1: Time Compression
|
||||||
|
* ReadTheDoc theme now matches the game.
|
||||||
|
* Logbox should wrap text better
|
||||||
|
* Logbox behavior should feel better.
|
||||||
|
* Fix font for AutoLink.exe
|
||||||
|
* nerf noodle bar
|
||||||
|
|
||||||
v0.55.0 - 2021-09-20 Material UI (hydroflame & community)
|
v0.55.0 - 2021-09-20 Material UI (hydroflame & community)
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
|
@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.55'
|
version = '0.56'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.55.0'
|
release = '0.56.0'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "bitburner",
|
"name": "bitburner",
|
||||||
"license": "SEE LICENSE IN license.txt",
|
"license": "SEE LICENSE IN license.txt",
|
||||||
"version": "0.53.0",
|
"version": "0.56.0",
|
||||||
"main": "electron-main.js",
|
"main": "electron-main.js",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Daniel Xie"
|
"name": "Daniel Xie"
|
||||||
|
@ -2,25 +2,25 @@ const numSpaces = 4;
|
|||||||
const maxLineLength = 160;
|
const maxLineLength = 160;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"env": {
|
env: {
|
||||||
"es6": true,
|
es6: true,
|
||||||
"node": true
|
node: true,
|
||||||
},
|
},
|
||||||
"extends": "eslint:recommended",
|
extends: "eslint:recommended",
|
||||||
"parserOptions": {
|
parserOptions: {
|
||||||
"ecmaFeatures": {
|
ecmaFeatures: {
|
||||||
"experimentalObjectRestSpread": true
|
experimentalObjectRestSpread: true,
|
||||||
},
|
},
|
||||||
"ecmaVersion": 8,
|
ecmaVersion: 8,
|
||||||
"sourceType": "module"
|
sourceType: "module",
|
||||||
},
|
},
|
||||||
"rules": {
|
rules: {
|
||||||
"accessor-pairs": [
|
"accessor-pairs": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"getWithoutSet": false,
|
getWithoutSet: false,
|
||||||
"setWithoutGet": true
|
setWithoutGet: true,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"array-bracket-newline": ["error"],
|
"array-bracket-newline": ["error"],
|
||||||
"array-bracket-spacing": ["error"],
|
"array-bracket-spacing": ["error"],
|
||||||
@ -33,50 +33,35 @@ module.exports = {
|
|||||||
"block-spacing": ["error"],
|
"block-spacing": ["error"],
|
||||||
"brace-style": ["error"],
|
"brace-style": ["error"],
|
||||||
"callback-return": ["error"],
|
"callback-return": ["error"],
|
||||||
"camelcase": ["error"],
|
camelcase: ["error"],
|
||||||
"capitalized-comments": ["error"],
|
"capitalized-comments": ["error"],
|
||||||
"class-methods-use-this": ["error"],
|
"class-methods-use-this": ["error"],
|
||||||
"comma-dangle": ["error"],
|
"comma-dangle": ["error"],
|
||||||
"comma-spacing": ["error"],
|
"comma-spacing": ["error"],
|
||||||
"comma-style": [
|
"comma-style": ["error", "last"],
|
||||||
"error",
|
complexity: ["error"],
|
||||||
"last"
|
"computed-property-spacing": ["error", "never"],
|
||||||
],
|
|
||||||
"complexity": ["error"],
|
|
||||||
"computed-property-spacing": [
|
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"consistent-return": ["error"],
|
"consistent-return": ["error"],
|
||||||
"consistent-this": ["error"],
|
"consistent-this": ["error"],
|
||||||
"constructor-super": ["error"],
|
"constructor-super": ["error"],
|
||||||
"curly": ["error"],
|
curly: ["error"],
|
||||||
"default-case": ["error"],
|
"default-case": ["error"],
|
||||||
"dot-location": [
|
"dot-location": ["error", "property"],
|
||||||
"error",
|
|
||||||
"property"
|
|
||||||
],
|
|
||||||
"dot-notation": ["error"],
|
"dot-notation": ["error"],
|
||||||
"eol-last": ["error"],
|
"eol-last": ["error"],
|
||||||
"eqeqeq": ["error"],
|
eqeqeq: ["error"],
|
||||||
"for-direction": ["error"],
|
"for-direction": ["error"],
|
||||||
"func-call-spacing": ["error"],
|
"func-call-spacing": ["error"],
|
||||||
"func-name-matching": ["error"],
|
"func-name-matching": ["error"],
|
||||||
"func-names": [
|
"func-names": ["error", "never"],
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"func-style": ["error"],
|
"func-style": ["error"],
|
||||||
"function-paren-newline": ["error"],
|
"function-paren-newline": ["error"],
|
||||||
"generator-star-spacing": [
|
"generator-star-spacing": ["error", "before"],
|
||||||
"error",
|
|
||||||
"before"
|
|
||||||
],
|
|
||||||
"getter-return": [
|
"getter-return": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"allowImplicit": false
|
allowImplicit: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"global-require": ["error"],
|
"global-require": ["error"],
|
||||||
"guard-for-in": ["error"],
|
"guard-for-in": ["error"],
|
||||||
@ -84,52 +69,37 @@ module.exports = {
|
|||||||
"id-blacklist": ["error"],
|
"id-blacklist": ["error"],
|
||||||
"id-length": ["error"],
|
"id-length": ["error"],
|
||||||
"id-match": ["error"],
|
"id-match": ["error"],
|
||||||
"implicit-arrow-linebreak": [
|
"implicit-arrow-linebreak": ["error", "beside"],
|
||||||
"error",
|
indent: [
|
||||||
"beside"
|
|
||||||
],
|
|
||||||
"indent": [
|
|
||||||
"error",
|
"error",
|
||||||
numSpaces,
|
numSpaces,
|
||||||
{
|
{
|
||||||
"SwitchCase": 1
|
SwitchCase: 1,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"init-declarations": ["error"],
|
"init-declarations": ["error"],
|
||||||
"jsx-quotes": ["error"],
|
"jsx-quotes": ["error"],
|
||||||
"key-spacing": ["error"],
|
"key-spacing": ["error"],
|
||||||
"keyword-spacing": ["error"],
|
"keyword-spacing": ["error"],
|
||||||
"line-comment-position": ["error"],
|
"line-comment-position": ["error"],
|
||||||
"linebreak-style": [
|
"linebreak-style": ["error", "windows"],
|
||||||
"error",
|
|
||||||
"windows"
|
|
||||||
],
|
|
||||||
"lines-around-comment": ["error"],
|
"lines-around-comment": ["error"],
|
||||||
"lines-between-class-members": ["error"],
|
"lines-between-class-members": ["error"],
|
||||||
"max-depth": ["error"],
|
"max-depth": ["error"],
|
||||||
"max-len": [
|
"max-len": ["error", maxLineLength],
|
||||||
"error",
|
|
||||||
maxLineLength
|
|
||||||
],
|
|
||||||
"max-lines": [
|
"max-lines": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"skipBlankLines": true,
|
skipBlankLines: true,
|
||||||
"skipComments": true
|
skipComments: true,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"max-nested-callbacks": ["error"],
|
"max-nested-callbacks": ["error"],
|
||||||
"max-params": ["error"],
|
"max-params": ["error"],
|
||||||
"max-statements": ["error"],
|
"max-statements": ["error"],
|
||||||
"max-statements-per-line": ["error"],
|
"max-statements-per-line": ["error"],
|
||||||
"multiline-comment-style": [
|
"multiline-comment-style": ["off", "starred-block"],
|
||||||
"off",
|
"multiline-ternary": ["error", "never"],
|
||||||
"starred-block"
|
|
||||||
],
|
|
||||||
"multiline-ternary": [
|
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"new-cap": ["error"],
|
"new-cap": ["error"],
|
||||||
"new-parens": ["error"],
|
"new-parens": ["error"],
|
||||||
// TODO: configure this...
|
// TODO: configure this...
|
||||||
@ -145,18 +115,15 @@ module.exports = {
|
|||||||
"no-catch-shadow": ["error"],
|
"no-catch-shadow": ["error"],
|
||||||
"no-class-assign": ["error"],
|
"no-class-assign": ["error"],
|
||||||
"no-compare-neg-zero": ["error"],
|
"no-compare-neg-zero": ["error"],
|
||||||
"no-cond-assign": [
|
"no-cond-assign": ["error", "except-parens"],
|
||||||
"error",
|
|
||||||
"except-parens"
|
|
||||||
],
|
|
||||||
"no-confusing-arrow": ["error"],
|
"no-confusing-arrow": ["error"],
|
||||||
"no-console": ["error"],
|
"no-console": ["error"],
|
||||||
"no-const-assign": ["error"],
|
"no-const-assign": ["error"],
|
||||||
"no-constant-condition": [
|
"no-constant-condition": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"checkLoops": false
|
checkLoops: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-continue": ["off"],
|
"no-continue": ["off"],
|
||||||
"no-control-regex": ["error"],
|
"no-control-regex": ["error"],
|
||||||
@ -170,15 +137,15 @@ module.exports = {
|
|||||||
"no-duplicate-imports": [
|
"no-duplicate-imports": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"includeExports": true
|
includeExports: true,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-else-return": ["error"],
|
"no-else-return": ["error"],
|
||||||
"no-empty": [
|
"no-empty": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"allowEmptyCatch": false
|
allowEmptyCatch: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-empty-character-class": ["error"],
|
"no-empty-character-class": ["error"],
|
||||||
"no-empty-function": ["error"],
|
"no-empty-function": ["error"],
|
||||||
@ -194,8 +161,8 @@ module.exports = {
|
|||||||
"error",
|
"error",
|
||||||
"all",
|
"all",
|
||||||
{
|
{
|
||||||
"conditionalAssign": false
|
conditionalAssign: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-extra-semi": ["error"],
|
"no-extra-semi": ["error"],
|
||||||
"no-fallthrough": ["error"],
|
"no-fallthrough": ["error"],
|
||||||
@ -206,20 +173,17 @@ module.exports = {
|
|||||||
"no-implicit-globals": ["error"],
|
"no-implicit-globals": ["error"],
|
||||||
"no-implied-eval": ["error"],
|
"no-implied-eval": ["error"],
|
||||||
"no-inline-comments": ["error"],
|
"no-inline-comments": ["error"],
|
||||||
"no-inner-declarations": [
|
"no-inner-declarations": ["error", "both"],
|
||||||
"error",
|
|
||||||
"both"
|
|
||||||
],
|
|
||||||
"no-invalid-regexp": ["error"],
|
"no-invalid-regexp": ["error"],
|
||||||
"no-invalid-this": ["error"],
|
"no-invalid-this": ["error"],
|
||||||
"no-irregular-whitespace": [
|
"no-irregular-whitespace": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"skipComments": false,
|
skipComments: false,
|
||||||
"skipRegExps": false,
|
skipRegExps: false,
|
||||||
"skipStrings": false,
|
skipStrings: false,
|
||||||
"skipTemplates": false
|
skipTemplates: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-iterator": ["error"],
|
"no-iterator": ["error"],
|
||||||
"no-label-var": ["error"],
|
"no-label-var": ["error"],
|
||||||
@ -230,13 +194,9 @@ module.exports = {
|
|||||||
"no-magic-numbers": [
|
"no-magic-numbers": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"ignore": [
|
ignore: [-1, 0, 1],
|
||||||
-1,
|
ignoreArrayIndexes: true,
|
||||||
0,
|
},
|
||||||
1
|
|
||||||
],
|
|
||||||
"ignoreArrayIndexes": true
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
"no-mixed-operators": ["error"],
|
"no-mixed-operators": ["error"],
|
||||||
"no-mixed-requires": ["error"],
|
"no-mixed-requires": ["error"],
|
||||||
@ -247,8 +207,8 @@ module.exports = {
|
|||||||
"no-multiple-empty-lines": [
|
"no-multiple-empty-lines": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"max": 1
|
max: 1,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-native-reassign": ["error"],
|
"no-native-reassign": ["error"],
|
||||||
"no-negated-condition": ["error"],
|
"no-negated-condition": ["error"],
|
||||||
@ -268,8 +228,8 @@ module.exports = {
|
|||||||
"no-plusplus": [
|
"no-plusplus": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"allowForLoopAfterthoughts": true
|
allowForLoopAfterthoughts: true,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-process-env": ["error"],
|
"no-process-env": ["error"],
|
||||||
"no-process-exit": ["error"],
|
"no-process-exit": ["error"],
|
||||||
@ -283,10 +243,10 @@ module.exports = {
|
|||||||
"no-restricted-properties": [
|
"no-restricted-properties": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"message": "'log' is too general, use an appropriate level when logging.",
|
message: "'log' is too general, use an appropriate level when logging.",
|
||||||
"object": "console",
|
object: "console",
|
||||||
"property": "log"
|
property: "log",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-restricted-syntax": ["error"],
|
"no-restricted-syntax": ["error"],
|
||||||
"no-return-assign": ["error"],
|
"no-return-assign": ["error"],
|
||||||
@ -295,8 +255,8 @@ module.exports = {
|
|||||||
"no-self-assign": [
|
"no-self-assign": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"props": false
|
props: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-self-compare": ["error"],
|
"no-self-compare": ["error"],
|
||||||
"no-sequences": ["error"],
|
"no-sequences": ["error"],
|
||||||
@ -333,10 +293,10 @@ module.exports = {
|
|||||||
"no-useless-rename": [
|
"no-useless-rename": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"ignoreDestructuring": false,
|
ignoreDestructuring: false,
|
||||||
"ignoreExport": false,
|
ignoreExport: false,
|
||||||
"ignoreImport": false
|
ignoreImport: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"no-useless-return": ["error"],
|
"no-useless-return": ["error"],
|
||||||
"no-var": ["error"],
|
"no-var": ["error"],
|
||||||
@ -344,10 +304,7 @@ module.exports = {
|
|||||||
"no-warning-comments": ["error"],
|
"no-warning-comments": ["error"],
|
||||||
"no-whitespace-before-property": ["error"],
|
"no-whitespace-before-property": ["error"],
|
||||||
"no-with": ["error"],
|
"no-with": ["error"],
|
||||||
"nonblock-statement-body-position": [
|
"nonblock-statement-body-position": ["error", "below"],
|
||||||
"error",
|
|
||||||
"below"
|
|
||||||
],
|
|
||||||
"object-curly-newline": ["error"],
|
"object-curly-newline": ["error"],
|
||||||
"object-curly-spacing": ["error"],
|
"object-curly-spacing": ["error"],
|
||||||
"object-property-newline": ["error"],
|
"object-property-newline": ["error"],
|
||||||
@ -355,10 +312,7 @@ module.exports = {
|
|||||||
"one-var": ["off"],
|
"one-var": ["off"],
|
||||||
"one-var-declaration-per-line": ["error"],
|
"one-var-declaration-per-line": ["error"],
|
||||||
"operator-assignment": ["error"],
|
"operator-assignment": ["error"],
|
||||||
"operator-linebreak": [
|
"operator-linebreak": ["error", "none"],
|
||||||
"error",
|
|
||||||
"none"
|
|
||||||
],
|
|
||||||
"padded-blocks": ["off"],
|
"padded-blocks": ["off"],
|
||||||
"padding-line-between-statements": ["error"],
|
"padding-line-between-statements": ["error"],
|
||||||
"prefer-arrow-callback": ["error"],
|
"prefer-arrow-callback": ["error"],
|
||||||
@ -371,24 +325,15 @@ module.exports = {
|
|||||||
"prefer-spread": ["error"],
|
"prefer-spread": ["error"],
|
||||||
"prefer-template": ["error"],
|
"prefer-template": ["error"],
|
||||||
"quote-props": ["error"],
|
"quote-props": ["error"],
|
||||||
"quotes": ["error"],
|
quotes: ["error"],
|
||||||
"radix": [
|
radix: ["error", "as-needed"],
|
||||||
"error",
|
|
||||||
"as-needed"
|
|
||||||
],
|
|
||||||
"require-await": ["error"],
|
"require-await": ["error"],
|
||||||
"require-jsdoc": ["off"],
|
"require-jsdoc": ["off"],
|
||||||
"require-yield": ["error"],
|
"require-yield": ["error"],
|
||||||
"rest-spread-spacing": [
|
"rest-spread-spacing": ["error", "never"],
|
||||||
"error",
|
semi: ["error"],
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"semi": ["error"],
|
|
||||||
"semi-spacing": ["error"],
|
"semi-spacing": ["error"],
|
||||||
"semi-style": [
|
"semi-style": ["error", "last"],
|
||||||
"error",
|
|
||||||
"last"
|
|
||||||
],
|
|
||||||
"sort-imports": ["error"],
|
"sort-imports": ["error"],
|
||||||
"sort-keys": ["error"],
|
"sort-keys": ["error"],
|
||||||
"sort-vars": ["error"],
|
"sort-vars": ["error"],
|
||||||
@ -398,37 +343,25 @@ module.exports = {
|
|||||||
"space-infix-ops": ["error"],
|
"space-infix-ops": ["error"],
|
||||||
"space-unary-ops": ["error"],
|
"space-unary-ops": ["error"],
|
||||||
"spaced-comment": ["error"],
|
"spaced-comment": ["error"],
|
||||||
"strict": ["error"],
|
strict: ["error"],
|
||||||
"switch-colon-spacing": [
|
"switch-colon-spacing": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"after": true,
|
after: true,
|
||||||
"before": false
|
before: false,
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"symbol-description": ["error"],
|
"symbol-description": ["error"],
|
||||||
"template-curly-spacing": ["error"],
|
"template-curly-spacing": ["error"],
|
||||||
"template-tag-spacing": ["error"],
|
"template-tag-spacing": ["error"],
|
||||||
"unicode-bom": [
|
"unicode-bom": ["error", "never"],
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
],
|
|
||||||
"use-isnan": ["error"],
|
"use-isnan": ["error"],
|
||||||
"valid-jsdoc": ["error"],
|
"valid-jsdoc": ["error"],
|
||||||
"valid-typeof": ["error"],
|
"valid-typeof": ["error"],
|
||||||
"vars-on-top": ["error"],
|
"vars-on-top": ["error"],
|
||||||
"wrap-iife": [
|
"wrap-iife": ["error", "any"],
|
||||||
"error",
|
|
||||||
"any"
|
|
||||||
],
|
|
||||||
"wrap-regex": ["error"],
|
"wrap-regex": ["error"],
|
||||||
"yield-star-spacing": [
|
"yield-star-spacing": ["error", "before"],
|
||||||
"error",
|
yoda: ["error", "never"],
|
||||||
"before"
|
},
|
||||||
],
|
|
||||||
"yoda": [
|
|
||||||
"error",
|
|
||||||
"never"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
@ -8,16 +8,18 @@ const path = require("path");
|
|||||||
const exec = require("child_process").exec;
|
const exec = require("child_process").exec;
|
||||||
const semver = require("./semver");
|
const semver = require("./semver");
|
||||||
|
|
||||||
const getPackageJson = () => new Promise((resolve, reject) => {
|
const getPackageJson = () =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
/* eslint-disable-next-line global-require */
|
/* eslint-disable-next-line global-require */
|
||||||
resolve(require(path.resolve(process.cwd(), "package.json")));
|
resolve(require(path.resolve(process.cwd(), "package.json")));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const getEngines = (data) => new Promise((resolve, reject) => {
|
const getEngines = (data) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
let versions = null;
|
let versions = null;
|
||||||
|
|
||||||
if (data.engines) {
|
if (data.engines) {
|
||||||
@ -29,9 +31,10 @@ const getEngines = (data) => new Promise((resolve, reject) => {
|
|||||||
} else {
|
} else {
|
||||||
reject("Missing or improper 'engines' property in 'package.json'");
|
reject("Missing or improper 'engines' property in 'package.json'");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkNpmVersion = (engines) => new Promise((resolve, reject) => {
|
const checkNpmVersion = (engines) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
exec("npm -v", (error, stdout, stderr) => {
|
exec("npm -v", (error, stdout, stderr) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
reject(`Unable to find NPM version\n${stderr}`);
|
reject(`Unable to find NPM version\n${stderr}`);
|
||||||
@ -43,20 +46,25 @@ const checkNpmVersion = (engines) => new Promise((resolve, reject) => {
|
|||||||
if (semver.satisfies(npmVersion, engineVersion)) {
|
if (semver.satisfies(npmVersion, engineVersion)) {
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
reject(`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`);
|
reject(
|
||||||
|
`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkNodeVersion = (engines) => new Promise((resolve, reject) => {
|
const checkNodeVersion = (engines) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
const nodeVersion = process.version.substring(1);
|
const nodeVersion = process.version.substring(1);
|
||||||
|
|
||||||
if (semver.satisfies(nodeVersion, engines.node)) {
|
if (semver.satisfies(nodeVersion, engines.node)) {
|
||||||
resolve(engines);
|
resolve(engines);
|
||||||
} else {
|
} else {
|
||||||
reject(`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`);
|
reject(
|
||||||
|
`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
getPackageJson()
|
getPackageJson()
|
||||||
.then(getEngines)
|
.then(getEngines)
|
||||||
@ -69,5 +77,5 @@ getPackageJson()
|
|||||||
/* eslint-disable no-console, no-process-exit */
|
/* eslint-disable no-console, no-process-exit */
|
||||||
console.error(error);
|
console.error(error);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
@ -444,7 +444,6 @@ function parseComparator(comp, loose) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SemVer {
|
class SemVer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A semantic version.
|
* A semantic version.
|
||||||
* @param {string} version The version.
|
* @param {string} version The version.
|
||||||
@ -488,7 +487,7 @@ class SemVer {
|
|||||||
// Numberify any prerelease numeric ids
|
// Numberify any prerelease numeric ids
|
||||||
if (matches[4]) {
|
if (matches[4]) {
|
||||||
this.prerelease = matches[4].split(".").map((id) => {
|
this.prerelease = matches[4].split(".").map((id) => {
|
||||||
if ((/^[0-9]+$/).test(id)) {
|
if (/^[0-9]+$/.test(id)) {
|
||||||
const num = Number(id);
|
const num = Number(id);
|
||||||
if (num >= 0 && num < MAX_SAFE_INTEGER) {
|
if (num >= 0 && num < MAX_SAFE_INTEGER) {
|
||||||
return num;
|
return num;
|
||||||
@ -532,7 +531,9 @@ class SemVer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch)
|
compareIdentifiers(this.major, other.major) ||
|
||||||
|
compareIdentifiers(this.minor, other.minor) ||
|
||||||
|
compareIdentifiers(this.patch, other.patch)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -572,7 +573,8 @@ class SemVer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const compare = (leftVersion, rightVersion, loose) => new SemVer(leftVersion, loose).compare(new SemVer(rightVersion, loose));
|
const compare = (leftVersion, rightVersion, loose) =>
|
||||||
|
new SemVer(leftVersion, loose).compare(new SemVer(rightVersion, loose));
|
||||||
const gt = (leftVersion, rightVersion, loose) => compare(leftVersion, rightVersion, loose) > 0;
|
const gt = (leftVersion, rightVersion, loose) => compare(leftVersion, rightVersion, loose) > 0;
|
||||||
const lt = (leftVersion, rightVersion, loose) => compare(leftVersion, rightVersion, loose) < 0;
|
const lt = (leftVersion, rightVersion, loose) => compare(leftVersion, rightVersion, loose) < 0;
|
||||||
const eq = (leftVersion, rightVersion, loose) => compare(leftVersion, rightVersion, loose) === 0;
|
const eq = (leftVersion, rightVersion, loose) => compare(leftVersion, rightVersion, loose) === 0;
|
||||||
|
@ -533,6 +533,7 @@ export class Augmentation {
|
|||||||
console.warn(`Invalid Faction object in addToAllFactions(). Key value: ${fac}`);
|
console.warn(`Invalid Faction object in addToAllFactions(). Key value: ${fac}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (facObj.getInfo().special) continue;
|
||||||
facObj.augmentations.push(this.name);
|
facObj.augmentations.push(this.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,114 @@
|
|||||||
import { IMap } from "../../types";
|
export const AugmentationNames: {
|
||||||
|
Targeting1: string;
|
||||||
export const AugmentationNames: IMap<string> = {
|
Targeting2: string;
|
||||||
|
Targeting3: string;
|
||||||
|
SyntheticHeart: string;
|
||||||
|
SynfibrilMuscle: string;
|
||||||
|
CombatRib1: string;
|
||||||
|
CombatRib2: string;
|
||||||
|
CombatRib3: string;
|
||||||
|
NanofiberWeave: string;
|
||||||
|
SubdermalArmor: string;
|
||||||
|
WiredReflexes: string;
|
||||||
|
GrapheneBoneLacings: string;
|
||||||
|
BionicSpine: string;
|
||||||
|
GrapheneBionicSpine: string;
|
||||||
|
BionicLegs: string;
|
||||||
|
GrapheneBionicLegs: string;
|
||||||
|
SpeechProcessor: string;
|
||||||
|
TITN41Injection: string;
|
||||||
|
EnhancedSocialInteractionImplant: string;
|
||||||
|
BitWire: string;
|
||||||
|
ArtificialBioNeuralNetwork: string;
|
||||||
|
ArtificialSynapticPotentiation: string;
|
||||||
|
EnhancedMyelinSheathing: string;
|
||||||
|
SynapticEnhancement: string;
|
||||||
|
NeuralRetentionEnhancement: string;
|
||||||
|
DataJack: string;
|
||||||
|
ENM: string;
|
||||||
|
ENMCore: string;
|
||||||
|
ENMCoreV2: string;
|
||||||
|
ENMCoreV3: string;
|
||||||
|
ENMAnalyzeEngine: string;
|
||||||
|
ENMDMA: string;
|
||||||
|
Neuralstimulator: string;
|
||||||
|
NeuralAccelerator: string;
|
||||||
|
CranialSignalProcessorsG1: string;
|
||||||
|
CranialSignalProcessorsG2: string;
|
||||||
|
CranialSignalProcessorsG3: string;
|
||||||
|
CranialSignalProcessorsG4: string;
|
||||||
|
CranialSignalProcessorsG5: string;
|
||||||
|
NeuronalDensification: string;
|
||||||
|
NeuroreceptorManager: string;
|
||||||
|
NuoptimalInjectorImplant: string;
|
||||||
|
SpeechEnhancement: string;
|
||||||
|
FocusWire: string;
|
||||||
|
PCDNI: string;
|
||||||
|
PCDNIOptimizer: string;
|
||||||
|
PCDNINeuralNetwork: string;
|
||||||
|
PCMatrix: string;
|
||||||
|
ADRPheromone1: string;
|
||||||
|
ADRPheromone2: string;
|
||||||
|
ShadowsSimulacrum: string;
|
||||||
|
HacknetNodeCPUUpload: string;
|
||||||
|
HacknetNodeCacheUpload: string;
|
||||||
|
HacknetNodeNICUpload: string;
|
||||||
|
HacknetNodeKernelDNI: string;
|
||||||
|
HacknetNodeCoreDNI: string;
|
||||||
|
NeuroFluxGovernor: string;
|
||||||
|
Neurotrainer1: string;
|
||||||
|
Neurotrainer2: string;
|
||||||
|
Neurotrainer3: string;
|
||||||
|
Hypersight: string;
|
||||||
|
LuminCloaking1: string;
|
||||||
|
LuminCloaking2: string;
|
||||||
|
HemoRecirculator: string;
|
||||||
|
SmartSonar: string;
|
||||||
|
PowerRecirculator: string;
|
||||||
|
QLink: string;
|
||||||
|
TheRedPill: string;
|
||||||
|
SPTN97: string;
|
||||||
|
HiveMind: string;
|
||||||
|
CordiARCReactor: string;
|
||||||
|
SmartJaw: string;
|
||||||
|
Neotra: string;
|
||||||
|
Xanipher: string;
|
||||||
|
nextSENS: string;
|
||||||
|
OmniTekInfoLoad: string;
|
||||||
|
PhotosyntheticCells: string;
|
||||||
|
Neurolink: string;
|
||||||
|
TheBlackHand: string;
|
||||||
|
UnstableCircadianModulator: string;
|
||||||
|
CRTX42AA: string;
|
||||||
|
Neuregen: string;
|
||||||
|
CashRoot: string;
|
||||||
|
NutriGen: string;
|
||||||
|
INFRARet: string;
|
||||||
|
DermaForce: string;
|
||||||
|
GrapheneBrachiBlades: string;
|
||||||
|
GrapheneBionicArms: string;
|
||||||
|
BrachiBlades: string;
|
||||||
|
BionicArms: string;
|
||||||
|
SNA: string;
|
||||||
|
HydroflameLeftArm: string;
|
||||||
|
EsperEyewear: string;
|
||||||
|
EMS4Recombination: string;
|
||||||
|
OrionShoulder: string;
|
||||||
|
HyperionV1: string;
|
||||||
|
HyperionV2: string;
|
||||||
|
GolemSerum: string;
|
||||||
|
VangelisVirus: string;
|
||||||
|
VangelisVirus3: string;
|
||||||
|
INTERLINKED: string;
|
||||||
|
BladeRunner: string;
|
||||||
|
BladeArmor: string;
|
||||||
|
BladeArmorPowerCells: string;
|
||||||
|
BladeArmorEnergyShielding: string;
|
||||||
|
BladeArmorUnibeam: string;
|
||||||
|
BladeArmorOmnibeam: string;
|
||||||
|
BladeArmorIPU: string;
|
||||||
|
BladesSimulacrum: string;
|
||||||
|
} = {
|
||||||
Targeting1: "Augmented Targeting I",
|
Targeting1: "Augmented Targeting I",
|
||||||
Targeting2: "Augmented Targeting II",
|
Targeting2: "Augmented Targeting II",
|
||||||
Targeting3: "Augmented Targeting III",
|
Targeting3: "Augmented Targeting III",
|
||||||
@ -87,7 +195,7 @@ export const AugmentationNames: IMap<string> = {
|
|||||||
NutriGen: "NutriGen Implant",
|
NutriGen: "NutriGen Implant",
|
||||||
INFRARet: "INFRARET Enhancement",
|
INFRARet: "INFRARET Enhancement",
|
||||||
DermaForce: "DermaForce Particle Barrier",
|
DermaForce: "DermaForce Particle Barrier",
|
||||||
GrapheneBrachiBlades: "Graphene BranchiBlades Upgrade",
|
GrapheneBrachiBlades: "Graphene BrachiBlades Upgrade",
|
||||||
GrapheneBionicArms: "Graphene Bionic Arms Upgrade",
|
GrapheneBionicArms: "Graphene Bionic Arms Upgrade",
|
||||||
BrachiBlades: "BrachiBlades",
|
BrachiBlades: "BrachiBlades",
|
||||||
BionicArms: "Bionic Arms",
|
BionicArms: "Bionic Arms",
|
||||||
|
116
src/Constants.ts
116
src/Constants.ts
@ -114,7 +114,7 @@ export const CONSTANTS: {
|
|||||||
TotalNumBitNodes: number;
|
TotalNumBitNodes: number;
|
||||||
LatestUpdate: string;
|
LatestUpdate: string;
|
||||||
} = {
|
} = {
|
||||||
Version: "0.55.0",
|
Version: "0.56.0",
|
||||||
|
|
||||||
// Speed (in ms) at which the main loop is updated
|
// Speed (in ms) at which the main loop is updated
|
||||||
_idleSpeed: 200,
|
_idleSpeed: 200,
|
||||||
@ -281,31 +281,107 @@ export const CONSTANTS: {
|
|||||||
TotalNumBitNodes: 24,
|
TotalNumBitNodes: 24,
|
||||||
|
|
||||||
LatestUpdate: `
|
LatestUpdate: `
|
||||||
v0.55.0 - 2021-09-20 Material UI (hydroflame & community)
|
v0.56.0 - 2021-10-11 Trimming the backlog (hydroflame & community)
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
|
|
||||||
** Global **
|
** BREAKING **
|
||||||
|
|
||||||
* The game is now 100% in typescript, react, and Material-UI
|
* The 'write' function is now async. This helps when making scripts that write scripts.
|
||||||
|
|
||||||
|
** Terminal **
|
||||||
|
|
||||||
|
* 'grow' and 'weaken' have been added as terminal command. This should help player transition
|
||||||
|
from commands to scripts. The tutorial also talks about it.
|
||||||
|
* 'cp' command added
|
||||||
|
* Improved performance by rate limiting refresh.
|
||||||
|
|
||||||
|
** IP vs Hostname **
|
||||||
|
|
||||||
|
* The game now uses hostname as primary key for it's servers (yeah believe it or not IPs were
|
||||||
|
used until then). This has caused some issues with purchased servers (they couldn't be sold).
|
||||||
|
You might need to soft reset for the game to fully convert itself.
|
||||||
|
|
||||||
|
** Sleeve **
|
||||||
|
|
||||||
|
* Fixed bug where they couldn't train at Volhaven.
|
||||||
|
* No longer consume all bonus time at once, making it look buggy.
|
||||||
|
|
||||||
|
** SF9 **
|
||||||
|
|
||||||
|
* Now boosts hacknet production by 8/12/14%
|
||||||
|
|
||||||
|
** Hacknet Servers **
|
||||||
|
|
||||||
|
* production nerfed by 10%
|
||||||
|
* Max money increase gets weaker above 10t max money
|
||||||
|
|
||||||
|
** Corporation **
|
||||||
|
|
||||||
|
* Warehouse tooltip now also displays the amount of space taken by products.
|
||||||
|
* Changed research box completely to avoid dependency on Treant (Treant is a pita)
|
||||||
|
* All textbox should accept MAX/MP case insensitive.
|
||||||
|
* Fixed export popup not refreshing dropdowns correctly.
|
||||||
|
* Fixed product mku becoming zero
|
||||||
|
* Increased scaling of Wilson to avoid feedback loop.
|
||||||
|
* Can no longer get in debt by buying real estate
|
||||||
|
* Bonus time is consumed faster.
|
||||||
|
|
||||||
|
** Netscript **
|
||||||
|
|
||||||
|
* isBusy takes bitverse and infiltration into account
|
||||||
|
* hospitalize can't be called when in infiltration.
|
||||||
|
* setToCommitCrime now accepts crime rough name instead of perfect name.
|
||||||
|
* disableLog All now works for bladeburner functions.
|
||||||
|
* Fixed netscript port for ns1.
|
||||||
|
|
||||||
|
** Augmentation **
|
||||||
|
|
||||||
|
* Added augmentation to Ti Di Hui that removes penalty for being unfocused.
|
||||||
|
* Neuroflux no longer appears in special factions.
|
||||||
|
|
||||||
|
** Script Editor **
|
||||||
|
|
||||||
|
* Ram check is debounced instead of refreshed every second.
|
||||||
|
* Added the vscode extension documentation to the game (it doesn't work well, thought)
|
||||||
|
* Fixed issue where autocomplete list would grow forever
|
||||||
|
* Added semi-monokai as theme.
|
||||||
|
* Fixed issue where modifying filename would mess it up.
|
||||||
|
* Font size can be changed now.
|
||||||
|
|
||||||
|
** Infiltration **
|
||||||
|
|
||||||
|
* Fixed issue where game controls would become unfocused.
|
||||||
|
|
||||||
** Misc. **
|
** Misc. **
|
||||||
|
|
||||||
* Corporations can no longer bribe special factions
|
* Fixed loader incorrectly assuming some null values are incorrect.
|
||||||
* Infiltration can no longer lose focus of the keyboard.
|
* installBackdoor trigger Bitverse sequence
|
||||||
* Fix terminal line limit
|
* Some improvements to the theme editor
|
||||||
* Added theme editor
|
* Improved documentation about where to learn javascript.
|
||||||
* Theme applies on game load (@Nolshine)
|
* Added some instructions for contributors.
|
||||||
* Sleeves no longer consume all bonus time for some actions
|
* Fixed typo in corporation sell shares modal (@Saynt_Garmo)
|
||||||
* Fix a bug where the autocomlete list would get duplicates
|
* Fixed pagination being black on black in Active Scripts
|
||||||
* Fix tutorial not scaling properly on small screens
|
* Create Script tab renamed to Script Editor
|
||||||
* Import should be more consistent
|
* Fixed an issue where corp some textbox wouldn't update when changing city.
|
||||||
* Typo with 'help' command
|
* Fixed an issue where hacknet online time was always 0.
|
||||||
* Fix infinite loop in casino
|
* Netscript function prompt fixed.
|
||||||
|
* Fixed miscalculation in growth.
|
||||||
|
* Script with syntax errors will try to be a tad more helpful.
|
||||||
|
* Corporations can no longer bribe bladeburners.
|
||||||
|
* Augmentation Graphene Branchiblade renamed to Brachi, like the rest of them.
|
||||||
|
* All ram is displayed in GB/TB/PB now.
|
||||||
|
* Game now saves when saving a file, this can be turned off.
|
||||||
|
* Several improvement to log window.
|
||||||
|
* Bladeburner current action returns General type instead of the name of the action.
|
||||||
|
* Bladeburner travel and Sleeve travel respect disable ASCII.
|
||||||
|
* Tutorial fits on small screens.
|
||||||
|
* Import is much slower but more consistent now.
|
||||||
|
* Fix intelligence not updating properly.
|
||||||
|
* Added SF -1: Time Compression
|
||||||
|
* ReadTheDoc theme now matches the game.
|
||||||
|
* Logbox should wrap text better
|
||||||
|
* Logbox behavior should feel better.
|
||||||
|
* Fix font for AutoLink.exe
|
||||||
* nerf noodle bar
|
* nerf noodle bar
|
||||||
`,
|
`,
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
@ -105,6 +105,7 @@ export function SellMaterial(mat: Material, amt: string, price: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Parse quantity
|
//Parse quantity
|
||||||
|
amt = amt.toUpperCase();
|
||||||
if (amt.includes("MAX") || amt.includes("PROD")) {
|
if (amt.includes("MAX") || amt.includes("PROD")) {
|
||||||
let q = amt.replace(/\s+/g, "");
|
let q = amt.replace(/\s+/g, "");
|
||||||
q = q.replace(/[^-()\d/*+.MAXPROD]/g, "");
|
q = q.replace(/[^-()\d/*+.MAXPROD]/g, "");
|
||||||
@ -168,6 +169,7 @@ export function SellProduct(product: Product, city: string, amt: string, price:
|
|||||||
const cities = Object.keys(Cities);
|
const cities = Object.keys(Cities);
|
||||||
|
|
||||||
// Parse quantity
|
// Parse quantity
|
||||||
|
amt = amt.toUpperCase();
|
||||||
if (amt.includes("MAX") || amt.includes("PROD")) {
|
if (amt.includes("MAX") || amt.includes("PROD")) {
|
||||||
//Dynamically evaluated quantity. First test to make sure its valid
|
//Dynamically evaluated quantity. First test to make sure its valid
|
||||||
let qty = amt.replace(/\s+/g, "");
|
let qty = amt.replace(/\s+/g, "");
|
||||||
@ -372,7 +374,7 @@ export function Research(division: IIndustry, researchName: string): void {
|
|||||||
|
|
||||||
export function ExportMaterial(divisionName: string, cityName: string, material: Material, amt: string): void {
|
export function ExportMaterial(divisionName: string, cityName: string, material: Material, amt: string): void {
|
||||||
// Sanitize amt
|
// Sanitize amt
|
||||||
let sanitizedAmt = amt.replace(/\s+/g, "");
|
let sanitizedAmt = amt.replace(/\s+/g, "").toUpperCase();
|
||||||
sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAX]/g, "");
|
sanitizedAmt = sanitizedAmt.replace(/[^-()\d/*+.MAX]/g, "");
|
||||||
let temp = sanitizedAmt.replace(/MAX/g, "1");
|
let temp = sanitizedAmt.replace(/MAX/g, "1");
|
||||||
try {
|
try {
|
||||||
|
@ -564,7 +564,7 @@ export class Industry implements IIndustry {
|
|||||||
buyAmt = mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
buyAmt = mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles;
|
||||||
|
|
||||||
if (matName == "RealEstate") {
|
if (matName == "RealEstate") {
|
||||||
maxAmt = buyAmt;
|
maxAmt = corporation.funds.toNumber() / mat.bCost;
|
||||||
} else {
|
} else {
|
||||||
maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName]);
|
maxAmt = Math.floor((warehouse.size - warehouse.sizeUsed) / MaterialSizes[matName]);
|
||||||
}
|
}
|
||||||
@ -840,7 +840,7 @@ export class Industry implements IIndustry {
|
|||||||
let sellAmt;
|
let sellAmt;
|
||||||
if (isString(mat.sllman[1])) {
|
if (isString(mat.sllman[1])) {
|
||||||
//Dynamically evaluated
|
//Dynamically evaluated
|
||||||
let tmp = (mat.sllman[1] as string).replace(/MAX/g, maxSell + "");
|
let tmp = (mat.sllman[1] as string).replace(/MAX/g, (maxSell + "").toUpperCase());
|
||||||
tmp = tmp.replace(/PROD/g, mat.prd + "");
|
tmp = tmp.replace(/PROD/g, mat.prd + "");
|
||||||
try {
|
try {
|
||||||
sellAmt = eval(tmp);
|
sellAmt = eval(tmp);
|
||||||
@ -893,7 +893,7 @@ export class Industry implements IIndustry {
|
|||||||
const exp = mat.exp[expI];
|
const exp = mat.exp[expI];
|
||||||
const amtStr = exp.amt.replace(
|
const amtStr = exp.amt.replace(
|
||||||
/MAX/g,
|
/MAX/g,
|
||||||
mat.qty / (CorporationConstants.SecsPerMarketCycle * marketCycles) + "",
|
(mat.qty / (CorporationConstants.SecsPerMarketCycle * marketCycles) + "").toUpperCase(),
|
||||||
);
|
);
|
||||||
let amt = 0;
|
let amt = 0;
|
||||||
try {
|
try {
|
||||||
@ -1201,7 +1201,7 @@ export class Industry implements IIndustry {
|
|||||||
let sellAmt;
|
let sellAmt;
|
||||||
if (product.sllman[city][0] && isString(product.sllman[city][1])) {
|
if (product.sllman[city][0] && isString(product.sllman[city][1])) {
|
||||||
//Sell amount is dynamically evaluated
|
//Sell amount is dynamically evaluated
|
||||||
let tmp = product.sllman[city][1].replace(/MAX/g, maxSell);
|
let tmp = product.sllman[city][1].replace(/MAX/g, (maxSell + "").toUpperCase());
|
||||||
tmp = tmp.replace(/PROD/g, product.data[city][1]);
|
tmp = tmp.replace(/PROD/g, product.data[city][1]);
|
||||||
try {
|
try {
|
||||||
tmp = eval(tmp);
|
tmp = eval(tmp);
|
||||||
|
@ -80,10 +80,20 @@ export function ExpandIndustryTab(props: IProps): React.ReactElement {
|
|||||||
<Typography>Division name:</Typography>
|
<Typography>Division name:</Typography>
|
||||||
|
|
||||||
<Box display="flex" alignItems="center">
|
<Box display="flex" alignItems="center">
|
||||||
<TextField autoFocus={true} value={name} onChange={onNameChange} onKeyDown={onKeyDown} type="text" />
|
<TextField
|
||||||
|
autoFocus={true}
|
||||||
|
value={name}
|
||||||
|
onChange={onNameChange}
|
||||||
|
onKeyDown={onKeyDown}
|
||||||
|
type="text"
|
||||||
|
InputProps={{
|
||||||
|
endAdornment: (
|
||||||
<Button disabled={disabled} sx={{ mx: 1 }} onClick={newIndustry}>
|
<Button disabled={disabled} sx={{ mx: 1 }} onClick={newIndustry}>
|
||||||
Create Division
|
Expand
|
||||||
</Button>
|
</Button>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -43,16 +43,21 @@ export function ExpandNewCity(props: IProps): React.ReactElement {
|
|||||||
Would you like to expand into a new city by opening an office? This would cost{" "}
|
Would you like to expand into a new city by opening an office? This would cost{" "}
|
||||||
<MoneyCost money={CorporationConstants.OfficeInitialCost} corp={corp} />
|
<MoneyCost money={CorporationConstants.OfficeInitialCost} corp={corp} />
|
||||||
</Typography>
|
</Typography>
|
||||||
<Select value={city} onChange={onCityChange}>
|
<Select
|
||||||
|
endAdornment={
|
||||||
|
<Button onClick={expand} disabled={disabled}>
|
||||||
|
Confirm
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
value={city}
|
||||||
|
onChange={onCityChange}
|
||||||
|
>
|
||||||
{possibleCities.map((cityName: string) => (
|
{possibleCities.map((cityName: string) => (
|
||||||
<MenuItem key={cityName} value={cityName}>
|
<MenuItem key={cityName} value={cityName}>
|
||||||
{cityName}
|
{cityName}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Select>
|
</Select>
|
||||||
<Button onClick={expand} disabled={disabled}>
|
|
||||||
Confirm
|
|
||||||
</Button>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,9 @@ export function ExportModal(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onIndustryChange(event: SelectChangeEvent<string>): void {
|
function onIndustryChange(event: SelectChangeEvent<string>): void {
|
||||||
setIndustry(event.target.value);
|
const div = event.target.value;
|
||||||
|
setIndustry(div);
|
||||||
|
setCity(Object.keys(corp.divisions[0].warehouses)[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
@ -30,8 +30,7 @@ export function Augmentations(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function queueAllAugs(): void {
|
function queueAllAugs(): void {
|
||||||
for (const i in AugmentationNames) {
|
for (const augName of Object.keys(AugmentationNames)) {
|
||||||
const augName = AugmentationNames[i];
|
|
||||||
props.player.queueAugmentation(augName);
|
props.player.queueAugmentation(augName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,14 @@ import React from "react";
|
|||||||
import { use } from "../ui/Context";
|
import { use } from "../ui/Context";
|
||||||
import { Exploit } from "./Exploit";
|
import { Exploit } from "./Exploit";
|
||||||
|
|
||||||
|
const getComputedStyle = window.getComputedStyle;
|
||||||
export function Unclickable(): React.ReactElement {
|
export function Unclickable(): React.ReactElement {
|
||||||
const player = use.Player();
|
const player = use.Player();
|
||||||
|
|
||||||
function unclickable(event: React.MouseEvent<HTMLDivElement>): void {
|
function unclickable(event: React.MouseEvent<HTMLDivElement>): void {
|
||||||
if (!event.target || !(event.target instanceof Element)) return;
|
if (!event.target || !(event.target instanceof Element)) return;
|
||||||
const display = window.getComputedStyle(event.target as Element).display;
|
const display = getComputedStyle(event.target as Element).display;
|
||||||
const visibility = window.getComputedStyle(event.target as Element).visibility;
|
const visibility = getComputedStyle(event.target as Element).visibility;
|
||||||
if (display === "none" && visibility === "hidden" && event.isTrusted) player.giveExploit(Exploit.Unclickable);
|
if (display === "none" && visibility === "hidden" && event.isTrusted) player.giveExploit(Exploit.Unclickable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,11 @@ export class FactionInfo {
|
|||||||
*/
|
*/
|
||||||
keep: boolean;
|
keep: boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special faction
|
||||||
|
*/
|
||||||
|
special: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
infoText: JSX.Element,
|
infoText: JSX.Element,
|
||||||
enemies: string[],
|
enemies: string[],
|
||||||
@ -57,6 +62,7 @@ export class FactionInfo {
|
|||||||
offerHackingWork: boolean,
|
offerHackingWork: boolean,
|
||||||
offerFieldWork: boolean,
|
offerFieldWork: boolean,
|
||||||
offerSecurityWork: boolean,
|
offerSecurityWork: boolean,
|
||||||
|
special: boolean,
|
||||||
keep: boolean,
|
keep: boolean,
|
||||||
) {
|
) {
|
||||||
this.infoText = infoText;
|
this.infoText = infoText;
|
||||||
@ -70,6 +76,7 @@ export class FactionInfo {
|
|||||||
this.augmentationPriceMult = 1;
|
this.augmentationPriceMult = 1;
|
||||||
this.augmentationRepRequirementMult = 1;
|
this.augmentationRepRequirementMult = 1;
|
||||||
this.keep = keep;
|
this.keep = keep;
|
||||||
|
this.special = special;
|
||||||
}
|
}
|
||||||
|
|
||||||
offersWork(): boolean {
|
offersWork(): boolean {
|
||||||
@ -96,6 +103,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
Daedalus: new FactionInfo(
|
Daedalus: new FactionInfo(
|
||||||
@ -106,6 +114,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
"The Covenant": new FactionInfo(
|
"The Covenant": new FactionInfo(
|
||||||
@ -124,6 +133,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Megacorporations, each forms its own faction
|
// Megacorporations, each forms its own faction
|
||||||
@ -139,6 +149,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -158,6 +169,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -175,10 +187,11 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true, true),
|
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true, false, true),
|
||||||
|
|
||||||
NWO: new FactionInfo(
|
NWO: new FactionInfo(
|
||||||
(
|
(
|
||||||
@ -193,10 +206,20 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
"Clarke Incorporated": new FactionInfo(<>The Power of the Genome - Unlocked.</>, [], true, true, true, true, true),
|
"Clarke Incorporated": new FactionInfo(
|
||||||
|
<>The Power of the Genome - Unlocked.</>,
|
||||||
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
|
||||||
"OmniTek Incorporated": new FactionInfo(
|
"OmniTek Incorporated": new FactionInfo(
|
||||||
<>Simply put, our mission is to design and build robots that make a difference.</>,
|
<>Simply put, our mission is to design and build robots that make a difference.</>,
|
||||||
@ -205,6 +228,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -220,10 +244,20 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
"KuaiGong International": new FactionInfo(<>Dream big. Work hard. Make history.</>, [], true, true, true, true, true),
|
"KuaiGong International": new FactionInfo(
|
||||||
|
<>Dream big. Work hard. Make history.</>,
|
||||||
|
[],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
|
||||||
// Other Corporations
|
// Other Corporations
|
||||||
"Fulcrum Secret Technologies": new FactionInfo(
|
"Fulcrum Secret Technologies": new FactionInfo(
|
||||||
@ -238,6 +272,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
|
|
||||||
@ -261,6 +296,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
"The Black Hand": new FactionInfo(
|
"The Black Hand": new FactionInfo(
|
||||||
@ -280,6 +316,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
@ -325,6 +362,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
// City factions, essentially governments
|
// City factions, essentially governments
|
||||||
@ -336,8 +374,18 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
|
),
|
||||||
|
Chongqing: new FactionInfo(
|
||||||
|
<>Serve the People.</>,
|
||||||
|
["Sector-12", "Aevum", "Volhaven"],
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
Chongqing: new FactionInfo(<>Serve the People.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true, false),
|
|
||||||
Ishima: new FactionInfo(
|
Ishima: new FactionInfo(
|
||||||
<>The East Asian Order of the Future.</>,
|
<>The East Asian Order of the Future.</>,
|
||||||
["Sector-12", "Aevum", "Volhaven"],
|
["Sector-12", "Aevum", "Volhaven"],
|
||||||
@ -346,6 +394,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
"New Tokyo": new FactionInfo(
|
"New Tokyo": new FactionInfo(
|
||||||
<>Asia's World City.</>,
|
<>Asia's World City.</>,
|
||||||
@ -355,6 +404,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
"Sector-12": new FactionInfo(
|
"Sector-12": new FactionInfo(
|
||||||
<>The City of the Future.</>,
|
<>The City of the Future.</>,
|
||||||
@ -364,6 +414,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
Volhaven: new FactionInfo(
|
Volhaven: new FactionInfo(
|
||||||
<>Benefit, Honor, and Glory.</>,
|
<>Benefit, Honor, and Glory.</>,
|
||||||
@ -373,6 +424,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Criminal Organizations/Gangs
|
// Criminal Organizations/Gangs
|
||||||
@ -384,6 +436,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
"The Dark Army": new FactionInfo(
|
"The Dark Army": new FactionInfo(
|
||||||
@ -394,9 +447,10 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true, false),
|
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true, false, false),
|
||||||
|
|
||||||
Silhouette: new FactionInfo(
|
Silhouette: new FactionInfo(
|
||||||
(
|
(
|
||||||
@ -415,6 +469,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
Tetrads: new FactionInfo(
|
Tetrads: new FactionInfo(
|
||||||
@ -425,14 +480,15 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true, false),
|
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true, false, false),
|
||||||
|
|
||||||
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
|
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
|
||||||
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false, false),
|
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false, false, false),
|
||||||
|
|
||||||
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true, false),
|
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true, false, false),
|
||||||
|
|
||||||
CyberSec: new FactionInfo(
|
CyberSec: new FactionInfo(
|
||||||
(
|
(
|
||||||
@ -448,6 +504,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
false,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Special Factions
|
// Special Factions
|
||||||
@ -466,6 +523,7 @@ export const FactionInfos: IMap<FactionInfo> = {
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
|
true,
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
@ -41,6 +41,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
|
|||||||
if (isPlayersGang) {
|
if (isPlayersGang) {
|
||||||
const augs: string[] = [];
|
const augs: string[] = [];
|
||||||
for (const augName in Augmentations) {
|
for (const augName in Augmentations) {
|
||||||
|
if (augName === AugmentationNames.NeuroFluxGovernor) continue;
|
||||||
const aug = Augmentations[augName];
|
const aug = Augmentations[augName];
|
||||||
if (!aug.isSpecial) {
|
if (!aug.isSpecial) {
|
||||||
augs.push(augName);
|
augs.push(augName);
|
||||||
|
@ -510,7 +510,9 @@ export function purchaseHashUpgrade(player: IPlayer, upgName: string, upgTarget:
|
|||||||
}
|
}
|
||||||
if (!(target instanceof Server)) throw new Error(`'${upgTarget}' is not a normal server.`);
|
if (!(target instanceof Server)) throw new Error(`'${upgTarget}' is not a normal server.`);
|
||||||
|
|
||||||
target.changeMaximumMoney(upg.value, true);
|
const old = target.moneyMax;
|
||||||
|
target.changeMaximumMoney(upg.value);
|
||||||
|
console.log(target.moneyMax / old);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
player.hashManager.refundUpgrade(upgName);
|
player.hashManager.refundUpgrade(upgName);
|
||||||
return false;
|
return false;
|
||||||
|
@ -28,6 +28,7 @@ import { TableCell } from "../../ui/React/Table";
|
|||||||
import TableBody from "@mui/material/TableBody";
|
import TableBody from "@mui/material/TableBody";
|
||||||
import Table from "@mui/material/Table";
|
import Table from "@mui/material/Table";
|
||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
node: HacknetNode;
|
node: HacknetNode;
|
||||||
@ -163,7 +164,7 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
|
|||||||
<Typography>RAM:</Typography>
|
<Typography>RAM:</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography>{node.ram}GB</Typography>
|
<Typography>{numeralWrapper.formatRAM(node.ram)}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Button onClick={upgradeRamOnClick}>{upgradeRamContent}</Button>
|
<Button onClick={upgradeRamOnClick}>{upgradeRamContent}</Button>
|
||||||
|
@ -31,6 +31,7 @@ import { TableCell } from "../../ui/React/Table";
|
|||||||
import TableBody from "@mui/material/TableBody";
|
import TableBody from "@mui/material/TableBody";
|
||||||
import Table from "@mui/material/Table";
|
import Table from "@mui/material/Table";
|
||||||
import TableRow from "@mui/material/TableRow";
|
import TableRow from "@mui/material/TableRow";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
node: HacknetServer;
|
node: HacknetServer;
|
||||||
@ -213,7 +214,7 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
|
|||||||
<Typography>RAM:</Typography>
|
<Typography>RAM:</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Typography>{node.maxRam}GB</Typography>
|
<Typography>{numeralWrapper.formatRAM(node.maxRam)}</Typography>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell>
|
||||||
<Button onClick={upgradeRamOnClick}>{upgradeRamContent}</Button>
|
<Button onClick={upgradeRamOnClick}>{upgradeRamContent}</Button>
|
||||||
|
@ -64,13 +64,21 @@ export function HacknetUpgradeElem(props: IProps): React.ReactElement {
|
|||||||
</Typography>
|
</Typography>
|
||||||
|
|
||||||
<Typography>{upg.desc}</Typography>
|
<Typography>{upg.desc}</Typography>
|
||||||
|
{!upg.hasTargetServer && (
|
||||||
<Button onClick={purchase} disabled={!canPurchase}>
|
<Button onClick={purchase} disabled={!canPurchase}>
|
||||||
Purchase
|
Buy
|
||||||
</Button>
|
</Button>
|
||||||
{level > 0 && effect && <Typography>{effect}</Typography>}
|
|
||||||
{upg.hasTargetServer && (
|
|
||||||
<ServerDropdown value={selectedServer} serverType={ServerType.Foreign} onChange={changeTargetServer} />
|
|
||||||
)}
|
)}
|
||||||
|
{upg.hasTargetServer && (
|
||||||
|
<ServerDropdown
|
||||||
|
purchase={purchase}
|
||||||
|
canPurchase={canPurchase}
|
||||||
|
value={selectedServer}
|
||||||
|
serverType={ServerType.Foreign}
|
||||||
|
onChange={changeTargetServer}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{level > 0 && effect && <Typography>{effect}</Typography>}
|
||||||
</Paper>
|
</Paper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import { purchaseRamForHomeComputer } from "../../Server/ServerPurchases";
|
|||||||
|
|
||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { MathComponent } from "mathjax-react";
|
import { MathComponent } from "mathjax-react";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
p: IPlayer;
|
p: IPlayer;
|
||||||
@ -31,7 +32,8 @@ export function RamButton(props: IProps): React.ReactElement {
|
|||||||
<Tooltip title={<MathComponent tex={String.raw`\large{cost = 3.2 \times 10^3 \times 1.58^{log_2{(ram)}}}`} />}>
|
<Tooltip title={<MathComponent tex={String.raw`\large{cost = 3.2 \times 10^3 \times 1.58^{log_2{(ram)}}}`} />}>
|
||||||
<span>
|
<span>
|
||||||
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
|
<Button disabled={!props.p.canAfford(cost)} onClick={buy}>
|
||||||
Upgrade 'home' RAM ({homeComputer.maxRam}GB -> {homeComputer.maxRam * 2}GB) -
|
Upgrade 'home' RAM ({numeralWrapper.formatRAM(homeComputer.maxRam)} ->
|
||||||
|
{numeralWrapper.formatRAM(homeComputer.maxRam * 2)}) -
|
||||||
<Money money={cost} player={props.p} />
|
<Money money={cost} player={props.p} />
|
||||||
</Button>
|
</Button>
|
||||||
</span>
|
</span>
|
||||||
|
@ -17,6 +17,7 @@ import { getPurchaseServerCost } from "../../Server/ServerPurchases";
|
|||||||
import { Money } from "../../ui/React/Money";
|
import { Money } from "../../ui/React/Money";
|
||||||
import { use } from "../../ui/Context";
|
import { use } from "../../ui/Context";
|
||||||
import { PurchaseServerModal } from "./PurchaseServerModal";
|
import { PurchaseServerModal } from "./PurchaseServerModal";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
interface IServerProps {
|
interface IServerProps {
|
||||||
ram: number;
|
ram: number;
|
||||||
@ -30,7 +31,7 @@ function ServerButton(props: IServerProps): React.ReactElement {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button onClick={() => setOpen(true)} disabled={!player.canAfford(cost)}>
|
<Button onClick={() => setOpen(true)} disabled={!player.canAfford(cost)}>
|
||||||
Purchase {props.ram}GB Server -
|
Purchase {numeralWrapper.formatRAM(props.ram)} Server -
|
||||||
<Money money={cost} player={player} />
|
<Money money={cost} player={player} />
|
||||||
</Button>
|
</Button>
|
||||||
<PurchaseServerModal
|
<PurchaseServerModal
|
||||||
|
@ -10,7 +10,6 @@ import { RunningScript } from "../Script/RunningScript";
|
|||||||
import { GetServer } from "../Server/AllServers";
|
import { GetServer } from "../Server/AllServers";
|
||||||
|
|
||||||
import { compareArrays } from "../utils/helpers/compareArrays";
|
import { compareArrays } from "../utils/helpers/compareArrays";
|
||||||
import { roundToTwo } from "../utils/helpers/roundToTwo";
|
|
||||||
|
|
||||||
export function killWorkerScript(runningScriptObj: RunningScript, hostname: string, rerenderUi?: boolean): boolean;
|
export function killWorkerScript(runningScriptObj: RunningScript, hostname: string, rerenderUi?: boolean): boolean;
|
||||||
export function killWorkerScript(workerScript: WorkerScript): boolean;
|
export function killWorkerScript(workerScript: WorkerScript): boolean;
|
||||||
|
@ -13,13 +13,12 @@ export function netscriptDelay(time: number, workerScript: WorkerScript): Promis
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): string {
|
export function makeRuntimeRejectMsg(workerScript: WorkerScript, msg: string): string {
|
||||||
const lineNum = "";
|
|
||||||
const server = GetServer(workerScript.hostname);
|
const server = GetServer(workerScript.hostname);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
throw new Error(`WorkerScript constructed with invalid server ip: ${workerScript.hostname}`);
|
throw new Error(`WorkerScript constructed with invalid server ip: ${workerScript.hostname}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "|" + server.hostname + "|" + workerScript.name + "|" + msg + lineNum;
|
return "|" + server.hostname + "|" + workerScript.name + "|" + msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveNetscriptRequestedThreads(
|
export function resolveNetscriptRequestedThreads(
|
||||||
|
@ -122,6 +122,7 @@ import { Router } from "./ui/GameRoot";
|
|||||||
import { numeralWrapper } from "./ui/numeralFormat";
|
import { numeralWrapper } from "./ui/numeralFormat";
|
||||||
import { is2DArray } from "./utils/helpers/is2DArray";
|
import { is2DArray } from "./utils/helpers/is2DArray";
|
||||||
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions";
|
||||||
|
import { SpecialServers } from "./Server/data/SpecialServers";
|
||||||
|
|
||||||
import { LogBoxEvents } from "./ui/React/LogBoxManager";
|
import { LogBoxEvents } from "./ui/React/LogBoxManager";
|
||||||
import { arrayToString } from "./utils/helpers/arrayToString";
|
import { arrayToString } from "./utils/helpers/arrayToString";
|
||||||
@ -136,6 +137,7 @@ import { IIndustry } from "./Corporation/IIndustry";
|
|||||||
|
|
||||||
import { Faction } from "./Faction/Faction";
|
import { Faction } from "./Faction/Faction";
|
||||||
import { Augmentation } from "./Augmentation/Augmentation";
|
import { Augmentation } from "./Augmentation/Augmentation";
|
||||||
|
import { Page } from "./ui/Router";
|
||||||
|
|
||||||
import { CodingContract } from "./CodingContracts";
|
import { CodingContract } from "./CodingContracts";
|
||||||
import { Stock } from "./StockMarket/Stock";
|
import { Stock } from "./StockMarket/Stock";
|
||||||
@ -713,7 +715,7 @@ 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, helper);
|
const extra = NetscriptExtra(Player, workerScript);
|
||||||
const hacknet = NetscriptHacknet(Player, workerScript, helper);
|
const hacknet = NetscriptHacknet(Player, workerScript, helper);
|
||||||
|
|
||||||
const functions = {
|
const functions = {
|
||||||
@ -3076,6 +3078,10 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
workerScript.log("installBackdoor", `Successfully installed backdoor on '${server.hostname}'`);
|
workerScript.log("installBackdoor", `Successfully installed backdoor on '${server.hostname}'`);
|
||||||
|
|
||||||
server.backdoorInstalled = true;
|
server.backdoorInstalled = true;
|
||||||
|
|
||||||
|
if (SpecialServers.WorldDaemon === server.hostname) {
|
||||||
|
Router.toBitVerse(false, false);
|
||||||
|
}
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -3239,12 +3245,16 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
hospitalize: function (): any {
|
hospitalize: function (): any {
|
||||||
updateDynamicRam("hospitalize", getRamCost("hospitalize"));
|
updateDynamicRam("hospitalize", getRamCost("hospitalize"));
|
||||||
checkSingularityAccess("hospitalize", 1);
|
checkSingularityAccess("hospitalize", 1);
|
||||||
|
if (Player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse) {
|
||||||
|
workerScript.log("hospitalize", "Cannot go to the hospital because the player is busy.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
return Player.hospitalize();
|
return Player.hospitalize();
|
||||||
},
|
},
|
||||||
isBusy: function (): any {
|
isBusy: function (): any {
|
||||||
updateDynamicRam("isBusy", getRamCost("isBusy"));
|
updateDynamicRam("isBusy", getRamCost("isBusy"));
|
||||||
checkSingularityAccess("isBusy", 1);
|
checkSingularityAccess("isBusy", 1);
|
||||||
return Player.isWorking;
|
return Player.isWorking || Router.page() === Page.Infiltration || Router.page() === Page.BitVerse;
|
||||||
},
|
},
|
||||||
stopAction: function (): any {
|
stopAction: function (): any {
|
||||||
updateDynamicRam("stopAction", getRamCost("stopAction"));
|
updateDynamicRam("stopAction", getRamCost("stopAction"));
|
||||||
@ -3280,7 +3290,9 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
||||||
workerScript.log(
|
workerScript.log(
|
||||||
"upgradeHomeRam",
|
"upgradeHomeRam",
|
||||||
`Purchased additional RAM for home computer! It now has ${homeComputer.maxRam}GB of RAM.`,
|
`Purchased additional RAM for home computer! It now has ${numeralWrapper.formatRAM(
|
||||||
|
homeComputer.maxRam,
|
||||||
|
)} of RAM.`,
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -4170,8 +4182,6 @@ function NetscriptFunctions(workerScript: WorkerScript): NS {
|
|||||||
},
|
},
|
||||||
joinBladeburnerDivision: function (): any {
|
joinBladeburnerDivision: function (): any {
|
||||||
updateDynamicRam("joinBladeburnerDivision", getRamCost("bladeburner", "joinBladeburnerDivision"));
|
updateDynamicRam("joinBladeburnerDivision", getRamCost("bladeburner", "joinBladeburnerDivision"));
|
||||||
const bladeburner = Player.bladeburner;
|
|
||||||
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
|
|
||||||
if (Player.bitNodeN === 7 || SourceFileFlags[7] > 0) {
|
if (Player.bitNodeN === 7 || SourceFileFlags[7] > 0) {
|
||||||
if (Player.bitNodeN === 8) {
|
if (Player.bitNodeN === 8) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { INetscriptHelper } from "./INetscriptHelper";
|
|
||||||
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";
|
||||||
@ -11,7 +10,7 @@ export interface INetscriptExtra {
|
|||||||
bypass(doc: Document): void;
|
bypass(doc: Document): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript, helper: INetscriptHelper): INetscriptExtra {
|
export function NetscriptExtra(player: IPlayer, workerScript: WorkerScript): INetscriptExtra {
|
||||||
return {
|
return {
|
||||||
heart: {
|
heart: {
|
||||||
// Easter egg function
|
// Easter egg function
|
||||||
|
@ -8,6 +8,7 @@ import { WorkerScript } from "../Netscript/WorkerScript";
|
|||||||
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
|
import { findSleevePurchasableAugs } from "../PersonObjects/Sleeve/SleeveHelpers";
|
||||||
import { Augmentations } from "../Augmentation/Augmentations";
|
import { Augmentations } from "../Augmentation/Augmentations";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
|
import { findCrime } from "../Crime/CrimeHelpers";
|
||||||
|
|
||||||
export interface INetscriptSleeve {
|
export interface INetscriptSleeve {
|
||||||
getNumSleeves(): number;
|
getNumSleeves(): number;
|
||||||
@ -87,13 +88,17 @@ export function NetscriptSleeve(
|
|||||||
checkSleeveNumber("setToSynchronize", sleeveNumber);
|
checkSleeveNumber("setToSynchronize", sleeveNumber);
|
||||||
return player.sleeves[sleeveNumber].synchronize(player);
|
return player.sleeves[sleeveNumber].synchronize(player);
|
||||||
},
|
},
|
||||||
setToCommitCrime: function (asleeveNumber: any = 0, acrimeName: any = ""): boolean {
|
setToCommitCrime: function (asleeveNumber: any = 0, aCrimeRoughName: any = ""): boolean {
|
||||||
const sleeveNumber = helper.number("setToCommitCrime", "sleeveNumber", asleeveNumber);
|
const sleeveNumber = helper.number("setToCommitCrime", "sleeveNumber", asleeveNumber);
|
||||||
const crimeName = helper.string("setToUniversityCourse", "crimeName", acrimeName);
|
const crimeRoughName = helper.string("setToCommitCrime", "crimeName", aCrimeRoughName);
|
||||||
helper.updateDynamicRam("setToCommitCrime", getRamCost("sleeve", "setToCommitCrime"));
|
helper.updateDynamicRam("setToCommitCrime", getRamCost("sleeve", "setToCommitCrime"));
|
||||||
checkSleeveAPIAccess("setToCommitCrime");
|
checkSleeveAPIAccess("setToCommitCrime");
|
||||||
checkSleeveNumber("setToCommitCrime", sleeveNumber);
|
checkSleeveNumber("setToCommitCrime", sleeveNumber);
|
||||||
return player.sleeves[sleeveNumber].commitCrime(player, crimeName);
|
const crime = findCrime(crimeRoughName);
|
||||||
|
if (crime === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return player.sleeves[sleeveNumber].commitCrime(player, crime.name);
|
||||||
},
|
},
|
||||||
setToUniversityCourse: function (asleeveNumber: any = 0, auniversityName: any = "", aclassName: any = ""): boolean {
|
setToUniversityCourse: function (asleeveNumber: any = 0, auniversityName: any = "", aclassName: any = ""): boolean {
|
||||||
const sleeveNumber = helper.number("setToUniversityCourse", "sleeveNumber", asleeveNumber);
|
const sleeveNumber = helper.number("setToUniversityCourse", "sleeveNumber", asleeveNumber);
|
||||||
|
@ -124,10 +124,14 @@ function startNetscript2Script(workerScript: WorkerScript): Promise<WorkerScript
|
|||||||
.catch((e) => reject(e));
|
.catch((e) => reject(e));
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
|
if (e instanceof SyntaxError) {
|
||||||
|
workerScript.errorMessage = makeRuntimeRejectMsg(workerScript, e.message + " (sorry we can't be more helpful)");
|
||||||
|
} else {
|
||||||
workerScript.errorMessage = makeRuntimeRejectMsg(
|
workerScript.errorMessage = makeRuntimeRejectMsg(
|
||||||
workerScript,
|
workerScript,
|
||||||
e.message + ((e.stack && "\nstack:\n" + e.stack.toString()) || ""),
|
e.message + ((e.stack && "\nstack:\n" + e.stack.toString()) || ""),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
throw workerScript;
|
throw workerScript;
|
||||||
} else if (isScriptErrorMessage(e)) {
|
} else if (isScriptErrorMessage(e)) {
|
||||||
workerScript.errorMessage = e;
|
workerScript.errorMessage = e;
|
||||||
|
@ -201,6 +201,7 @@ export interface IPlayer {
|
|||||||
inGang(): boolean;
|
inGang(): boolean;
|
||||||
isQualified(company: Company, position: CompanyPosition): boolean;
|
isQualified(company: Company, position: CompanyPosition): boolean;
|
||||||
loseMoney(money: number): void;
|
loseMoney(money: number): void;
|
||||||
|
process(router: IRouter, numCycles?: number): void;
|
||||||
reapplyAllAugmentations(resetMultipliers?: boolean): void;
|
reapplyAllAugmentations(resetMultipliers?: boolean): void;
|
||||||
reapplyAllSourceFiles(): void;
|
reapplyAllSourceFiles(): void;
|
||||||
regenerateHp(amt: number): void;
|
regenerateHp(amt: number): void;
|
||||||
|
@ -245,6 +245,7 @@ export class PlayerObject implements IPlayer {
|
|||||||
getIntelligenceBonus: (weight: number) => number;
|
getIntelligenceBonus: (weight: number) => number;
|
||||||
getCasinoWinnings: () => number;
|
getCasinoWinnings: () => number;
|
||||||
quitJob: (company: string) => void;
|
quitJob: (company: string) => void;
|
||||||
|
process: (router: IRouter, numCycles?: number) => void;
|
||||||
createHacknetServer: () => HacknetServer;
|
createHacknetServer: () => HacknetServer;
|
||||||
startCreateProgramWork: (router: IRouter, programName: string, time: number, reqLevel: number) => void;
|
startCreateProgramWork: (router: IRouter, programName: string, time: number, reqLevel: number) => void;
|
||||||
queueAugmentation: (augmentationName: string) => void;
|
queueAugmentation: (augmentationName: string) => void;
|
||||||
@ -505,6 +506,7 @@ export class PlayerObject implements IPlayer {
|
|||||||
this.getWorkAgiExpGain = generalMethods.getWorkAgiExpGain;
|
this.getWorkAgiExpGain = generalMethods.getWorkAgiExpGain;
|
||||||
this.getWorkChaExpGain = generalMethods.getWorkChaExpGain;
|
this.getWorkChaExpGain = generalMethods.getWorkChaExpGain;
|
||||||
this.getWorkRepGain = generalMethods.getWorkRepGain;
|
this.getWorkRepGain = generalMethods.getWorkRepGain;
|
||||||
|
this.process = generalMethods.process;
|
||||||
this.startCreateProgramWork = generalMethods.startCreateProgramWork;
|
this.startCreateProgramWork = generalMethods.startCreateProgramWork;
|
||||||
this.createProgramWork = generalMethods.createProgramWork;
|
this.createProgramWork = generalMethods.createProgramWork;
|
||||||
this.finishCreateProgramWork = generalMethods.finishCreateProgramWork;
|
this.finishCreateProgramWork = generalMethods.finishCreateProgramWork;
|
||||||
|
@ -77,7 +77,6 @@ export function init(this: IPlayer): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function prestigeAugmentation(this: IPlayer): void {
|
export function prestigeAugmentation(this: IPlayer): void {
|
||||||
const homeComp = this.getHomeComputer();
|
|
||||||
this.currentServer = SpecialServers.Home;
|
this.currentServer = SpecialServers.Home;
|
||||||
|
|
||||||
this.numPeopleKilled = 0;
|
this.numPeopleKilled = 0;
|
||||||
@ -576,6 +575,37 @@ export function startWork(this: IPlayer, router: IRouter, companyName: string):
|
|||||||
router.toWork();
|
router.toWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
||||||
|
// Working
|
||||||
|
if (this.isWorking) {
|
||||||
|
if (this.workType == CONSTANTS.WorkTypeFaction) {
|
||||||
|
if (this.workForFaction(numCycles)) {
|
||||||
|
router.toFaction();
|
||||||
|
}
|
||||||
|
} else if (this.workType == CONSTANTS.WorkTypeCreateProgram) {
|
||||||
|
if (this.createProgramWork(numCycles)) {
|
||||||
|
router.toTerminal();
|
||||||
|
}
|
||||||
|
} else if (this.workType == CONSTANTS.WorkTypeStudyClass) {
|
||||||
|
if (this.takeClass(numCycles)) {
|
||||||
|
router.toCity();
|
||||||
|
}
|
||||||
|
} else if (this.workType == CONSTANTS.WorkTypeCrime) {
|
||||||
|
if (this.commitCrime(numCycles)) {
|
||||||
|
router.toLocation(Locations[LocationName.Slums]);
|
||||||
|
}
|
||||||
|
} else if (this.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
||||||
|
if (this.workPartTime(numCycles)) {
|
||||||
|
router.toCity();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.work(numCycles)) {
|
||||||
|
router.toCity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function cancelationPenalty(this: IPlayer): number {
|
export function cancelationPenalty(this: IPlayer): number {
|
||||||
const server = GetServer(this.companyName);
|
const server = GetServer(this.companyName);
|
||||||
if (server instanceof Server) {
|
if (server instanceof Server) {
|
||||||
|
@ -563,7 +563,6 @@ export class Sleeve extends Person {
|
|||||||
* Resets all parameters used to keep information about the current task
|
* Resets all parameters used to keep information about the current task
|
||||||
*/
|
*/
|
||||||
resetTaskStatus(): void {
|
resetTaskStatus(): void {
|
||||||
console.error("");
|
|
||||||
this.earningsForTask = createTaskTracker();
|
this.earningsForTask = createTaskTracker();
|
||||||
this.gainRatesForTask = createTaskTracker();
|
this.gainRatesForTask = createTaskTracker();
|
||||||
this.currentTask = SleeveTaskType.Idle;
|
this.currentTask = SleeveTaskType.Idle;
|
||||||
|
@ -29,4 +29,5 @@ export function loadPlayer(saveString: string): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Player.exploits = sanitizeExploits(Player.exploits);
|
Player.exploits = sanitizeExploits(Player.exploits);
|
||||||
|
console.log(Player.bladeburner);
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,18 @@ function evaluateVersionCompatibility(ver: string): void {
|
|||||||
|
|
||||||
delete anyPlayer.companyPosition;
|
delete anyPlayer.companyPosition;
|
||||||
}
|
}
|
||||||
|
if (ver < "0.56.0") {
|
||||||
|
for (const q of anyPlayer.queuedAugmentations) {
|
||||||
|
if (q.name === "Graphene BranchiBlades Upgrade") {
|
||||||
|
q.name = "Graphene BrachiBlades Upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const q of anyPlayer.augmentations) {
|
||||||
|
if (q.name === "Graphene BranchiBlades Upgrade") {
|
||||||
|
q.name = "Graphene BrachiBlades Upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadGame(saveString: string): boolean {
|
function loadGame(saveString: string): boolean {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useRef } from "react";
|
import React, { useState, useEffect, useRef, useMemo } from "react";
|
||||||
import Editor from "@monaco-editor/react";
|
import Editor from "@monaco-editor/react";
|
||||||
import * as monaco from "monaco-editor";
|
import * as monaco from "monaco-editor";
|
||||||
type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
type IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
|
||||||
@ -21,6 +21,8 @@ import { NetscriptFunctions } from "../../NetscriptFunctions";
|
|||||||
import { WorkerScript } from "../../Netscript/WorkerScript";
|
import { WorkerScript } from "../../Netscript/WorkerScript";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { iTutorialNextStep, ITutorial, iTutorialSteps } from "../../InteractiveTutorial";
|
import { iTutorialNextStep, ITutorial, iTutorialSteps } from "../../InteractiveTutorial";
|
||||||
|
import { debounce } from "lodash";
|
||||||
|
import { saveObject } from "../../SaveObject";
|
||||||
|
|
||||||
import Button from "@mui/material/Button";
|
import Button from "@mui/material/Button";
|
||||||
import Typography from "@mui/material/Typography";
|
import Typography from "@mui/material/Typography";
|
||||||
@ -84,6 +86,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
const [filename, setFilename] = useState(props.filename ? props.filename : lastFilename);
|
const [filename, setFilename] = useState(props.filename ? props.filename : lastFilename);
|
||||||
const [code, setCode] = useState<string>(props.filename ? props.code : lastCode);
|
const [code, setCode] = useState<string>(props.filename ? props.code : lastCode);
|
||||||
const [ram, setRAM] = useState("RAM: ???");
|
const [ram, setRAM] = useState("RAM: ???");
|
||||||
|
const [updatingRam, setUpdatingRam] = useState(false);
|
||||||
const [optionsOpen, setOptionsOpen] = useState(false);
|
const [optionsOpen, setOptionsOpen] = useState(false);
|
||||||
const [options, setOptions] = useState<Options>({
|
const [options, setOptions] = useState<Options>({
|
||||||
theme: Settings.MonacoTheme,
|
theme: Settings.MonacoTheme,
|
||||||
@ -91,6 +94,15 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
fontSize: Settings.MonacoFontSize,
|
fontSize: Settings.MonacoFontSize,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const debouncedSetRAM = useMemo(
|
||||||
|
() =>
|
||||||
|
debounce((s) => {
|
||||||
|
setRAM(s);
|
||||||
|
setUpdatingRam(false);
|
||||||
|
}, 300),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
// store the last known state in case we need to restart without nano.
|
// store the last known state in case we need to restart without nano.
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.filename === undefined) return;
|
if (props.filename === undefined) return;
|
||||||
@ -165,6 +177,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
for (let i = 0; i < server.scripts.length; i++) {
|
for (let i = 0; i < server.scripts.length; i++) {
|
||||||
if (filename == server.scripts[i].filename) {
|
if (filename == server.scripts[i].filename) {
|
||||||
server.scripts[i].saveScript(filename, code, props.player.currentServer, server.scripts);
|
server.scripts[i].saveScript(filename, code, props.player.currentServer, server.scripts);
|
||||||
|
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
|
||||||
props.router.toTerminal();
|
props.router.toTerminal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -178,6 +191,7 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
for (let i = 0; i < server.textFiles.length; ++i) {
|
for (let i = 0; i < server.textFiles.length; ++i) {
|
||||||
if (server.textFiles[i].fn === filename) {
|
if (server.textFiles[i].fn === filename) {
|
||||||
server.textFiles[i].write(code);
|
server.textFiles[i].write(code);
|
||||||
|
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
|
||||||
props.router.toTerminal();
|
props.router.toTerminal();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -188,6 +202,8 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
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 " + " or text file (.txt)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Settings.SaveGameOnFileSave) saveObject.saveGame();
|
||||||
props.router.toTerminal();
|
props.router.toTerminal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,38 +229,40 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
lastPosition = editorRef.current.getPosition();
|
lastPosition = editorRef.current.getPosition();
|
||||||
}
|
}
|
||||||
setCode(newCode);
|
setCode(newCode);
|
||||||
|
updateRAM(newCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateRAM(): Promise<void> {
|
// calculate it once the first time the file is loaded.
|
||||||
const codeCopy = code + "";
|
useEffect(() => {
|
||||||
|
updateRAM(code);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
async function updateRAM(newCode: string): Promise<void> {
|
||||||
|
setUpdatingRam(true);
|
||||||
|
const codeCopy = newCode + "";
|
||||||
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
const ramUsage = await calculateRamUsage(codeCopy, props.player.getCurrentServer().scripts);
|
||||||
if (ramUsage > 0) {
|
if (ramUsage > 0) {
|
||||||
setRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
debouncedSetRAM("RAM: " + numeralWrapper.formatRAM(ramUsage));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (ramUsage) {
|
switch (ramUsage) {
|
||||||
case RamCalculationErrorCode.ImportError: {
|
case RamCalculationErrorCode.ImportError: {
|
||||||
setRAM("RAM: Import Error");
|
debouncedSetRAM("RAM: Import Error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RamCalculationErrorCode.URLImportError: {
|
case RamCalculationErrorCode.URLImportError: {
|
||||||
setRAM("RAM: HTTP Import Error");
|
debouncedSetRAM("RAM: HTTP Import Error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case RamCalculationErrorCode.SyntaxError:
|
case RamCalculationErrorCode.SyntaxError:
|
||||||
default: {
|
default: {
|
||||||
setRAM("RAM: Syntax Error");
|
debouncedSetRAM("RAM: Syntax Error");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new Promise<void>(() => undefined);
|
return new Promise<void>(() => undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const id = setInterval(updateRAM, 1000);
|
|
||||||
return () => clearInterval(id);
|
|
||||||
}, [code]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
function maybeSave(event: KeyboardEvent): void {
|
function maybeSave(event: KeyboardEvent): void {
|
||||||
if (Settings.DisableHotkeys) return;
|
if (Settings.DisableHotkeys) return;
|
||||||
@ -326,7 +344,9 @@ export function Root(props: IProps): React.ReactElement {
|
|||||||
/>
|
/>
|
||||||
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
|
<Box display="flex" flexDirection="row" sx={{ m: 1 }} alignItems="center">
|
||||||
<Button onClick={beautify}>Beautify</Button>
|
<Button onClick={beautify}>Beautify</Button>
|
||||||
<Typography sx={{ mx: 1 }}>{ram}</Typography>
|
<Typography color={updatingRam ? "secondary" : "primary"} sx={{ mx: 1 }}>
|
||||||
|
{ram}
|
||||||
|
</Typography>
|
||||||
<Button onClick={save}>Save & Close (Ctrl/Cmd + b)</Button>
|
<Button onClick={save}>Save & Close (Ctrl/Cmd + b)</Button>
|
||||||
<Link sx={{ mx: 1 }} target="_blank" href="https://bitburner.readthedocs.io/en/latest/index.html">
|
<Link sx={{ mx: 1 }} target="_blank" href="https://bitburner.readthedocs.io/en/latest/index.html">
|
||||||
<Typography> Netscript Documentation</Typography>
|
<Typography> Netscript Documentation</Typography>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export async function loadThemes(monaco: any): Promise<void> {
|
export async function loadThemes(monaco: { editor: any }): Promise<void> {
|
||||||
monaco.editor.defineTheme("monokai", {
|
monaco.editor.defineTheme("monokai", {
|
||||||
base: "vs-dark",
|
base: "vs-dark",
|
||||||
inherit: true,
|
inherit: true,
|
||||||
|
@ -125,14 +125,16 @@ export class Server extends BaseServer {
|
|||||||
/**
|
/**
|
||||||
* Change this server's maximum money
|
* Change this server's maximum money
|
||||||
* @param n - Value by which to change the server's maximum money
|
* @param n - Value by which to change the server's maximum money
|
||||||
* @param perc - Whether it should be changed by a percentage, or a flat value
|
|
||||||
*/
|
*/
|
||||||
changeMaximumMoney(n: number, perc = false): void {
|
changeMaximumMoney(n: number): void {
|
||||||
if (perc) {
|
const softCap = 10e12;
|
||||||
this.moneyMax *= n;
|
if (this.moneyMax > softCap) {
|
||||||
} else {
|
const aboveCap = this.moneyMax - softCap;
|
||||||
this.moneyMax += n;
|
n = 1 + (n - 1) / Math.log(aboveCap) / Math.log(8);
|
||||||
}
|
}
|
||||||
|
console.log(n);
|
||||||
|
|
||||||
|
this.moneyMax *= n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,6 +68,11 @@ interface IDefaultSettings {
|
|||||||
*/
|
*/
|
||||||
MaxTerminalCapacity: number;
|
MaxTerminalCapacity: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the game when you save any file.
|
||||||
|
*/
|
||||||
|
SaveGameOnFileSave: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the player should be asked to confirm purchasing each and every augmentation.
|
* Whether the player should be asked to confirm purchasing each and every augmentation.
|
||||||
*/
|
*/
|
||||||
@ -168,6 +173,7 @@ export const defaultSettings: IDefaultSettings = {
|
|||||||
MaxLogCapacity: 50,
|
MaxLogCapacity: 50,
|
||||||
MaxPortCapacity: 50,
|
MaxPortCapacity: 50,
|
||||||
MaxTerminalCapacity: 200,
|
MaxTerminalCapacity: 200,
|
||||||
|
SaveGameOnFileSave: true,
|
||||||
SuppressBuyAugmentationConfirmation: false,
|
SuppressBuyAugmentationConfirmation: false,
|
||||||
SuppressFactionInvites: false,
|
SuppressFactionInvites: false,
|
||||||
SuppressHospitalizationPopup: false,
|
SuppressHospitalizationPopup: false,
|
||||||
@ -226,6 +232,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
MaxTerminalCapacity: defaultSettings.MaxTerminalCapacity,
|
MaxTerminalCapacity: defaultSettings.MaxTerminalCapacity,
|
||||||
OwnedAugmentationsOrder: OwnedAugmentationsOrderSetting.AcquirementTime,
|
OwnedAugmentationsOrder: OwnedAugmentationsOrderSetting.AcquirementTime,
|
||||||
PurchaseAugmentationsOrder: PurchaseAugmentationsOrderSetting.Default,
|
PurchaseAugmentationsOrder: PurchaseAugmentationsOrderSetting.Default,
|
||||||
|
SaveGameOnFileSave: defaultSettings.SaveGameOnFileSave,
|
||||||
SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation,
|
SuppressBuyAugmentationConfirmation: defaultSettings.SuppressBuyAugmentationConfirmation,
|
||||||
SuppressFactionInvites: defaultSettings.SuppressFactionInvites,
|
SuppressFactionInvites: defaultSettings.SuppressFactionInvites,
|
||||||
SuppressHospitalizationPopup: defaultSettings.SuppressHospitalizationPopup,
|
SuppressHospitalizationPopup: defaultSettings.SuppressHospitalizationPopup,
|
||||||
@ -234,7 +241,7 @@ export const Settings: ISettings & ISelfInitializer & ISelfLoading = {
|
|||||||
SuppressBladeburnerPopup: defaultSettings.SuppressBladeburnerPopup,
|
SuppressBladeburnerPopup: defaultSettings.SuppressBladeburnerPopup,
|
||||||
MonacoTheme: "vs-dark",
|
MonacoTheme: "vs-dark",
|
||||||
MonacoInsertSpaces: false,
|
MonacoInsertSpaces: false,
|
||||||
MonacoFontSize: 10,
|
MonacoFontSize: 20,
|
||||||
|
|
||||||
theme: {
|
theme: {
|
||||||
primarylight: defaultSettings.theme.primarylight,
|
primarylight: defaultSettings.theme.primarylight,
|
||||||
|
@ -14,6 +14,7 @@ export const TerminalHelpText: string[] = [
|
|||||||
"clear Clear all text on the terminal ",
|
"clear Clear all text on the terminal ",
|
||||||
"cls See 'clear' command ",
|
"cls See 'clear' command ",
|
||||||
"connect [hostname] Connects to a remote server",
|
"connect [hostname] Connects to a remote server",
|
||||||
|
"cp [src] [dst]: Copy a file",
|
||||||
"download [script/text file] Downloads scripts or text files to your computer",
|
"download [script/text file] Downloads scripts or text files to your computer",
|
||||||
"expr [math expression] Evaluate a mathematical expression",
|
"expr [math expression] Evaluate a mathematical expression",
|
||||||
"free Check the machine's memory (RAM) usage",
|
"free Check the machine's memory (RAM) usage",
|
||||||
@ -158,6 +159,7 @@ export const HelpTexts: IMap<string[]> = {
|
|||||||
"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.",
|
||||||
],
|
],
|
||||||
|
cp: ["cp [src] [dst]", " ", "Copy a file on this server. To copy a file to another server use scp."],
|
||||||
download: [
|
download: [
|
||||||
"download [script/text file]",
|
"download [script/text file]",
|
||||||
" ",
|
" ",
|
||||||
|
@ -41,6 +41,7 @@ import { cat } from "./commands/cat";
|
|||||||
import { cd } from "./commands/cd";
|
import { cd } from "./commands/cd";
|
||||||
import { check } from "./commands/check";
|
import { check } from "./commands/check";
|
||||||
import { connect } from "./commands/connect";
|
import { connect } from "./commands/connect";
|
||||||
|
import { cp } from "./commands/cp";
|
||||||
import { download } from "./commands/download";
|
import { download } from "./commands/download";
|
||||||
import { expr } from "./commands/expr";
|
import { expr } from "./commands/expr";
|
||||||
import { free } from "./commands/free";
|
import { free } from "./commands/free";
|
||||||
@ -729,6 +730,7 @@ export class Terminal implements ITerminal {
|
|||||||
clear: () => this.clear(),
|
clear: () => this.clear(),
|
||||||
cls: () => this.clear(),
|
cls: () => this.clear(),
|
||||||
connect: connect,
|
connect: connect,
|
||||||
|
cp: cp,
|
||||||
download: download,
|
download: download,
|
||||||
expr: expr,
|
expr: expr,
|
||||||
free: free,
|
free: free,
|
||||||
|
92
src/Terminal/commands/cp.ts
Normal file
92
src/Terminal/commands/cp.ts
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { ITerminal } from "../ITerminal";
|
||||||
|
import { IRouter } from "../../ui/Router";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
import { BaseServer } from "../../Server/BaseServer";
|
||||||
|
import { isScriptFilename } from "../../Script/isScriptFilename";
|
||||||
|
|
||||||
|
export function cp(
|
||||||
|
terminal: ITerminal,
|
||||||
|
router: IRouter,
|
||||||
|
player: IPlayer,
|
||||||
|
server: BaseServer,
|
||||||
|
args: (string | number)[],
|
||||||
|
): void {
|
||||||
|
try {
|
||||||
|
if (args.length !== 2) {
|
||||||
|
terminal.error("Incorrect usage of cp command. Usage: cp [src] [dst]");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const src = args[0] + "";
|
||||||
|
const dst = args[1] + "";
|
||||||
|
if (src === dst) {
|
||||||
|
terminal.error("src and dst cannot be the same");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const srcExt = src.slice(src.lastIndexOf("."));
|
||||||
|
const dstExt = dst.slice(dst.lastIndexOf("."));
|
||||||
|
if (srcExt !== dstExt) {
|
||||||
|
terminal.error("src and dst must have the same extension.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const filename = terminal.getFilepath(src);
|
||||||
|
if (!isScriptFilename(filename) && !filename.endsWith(".txt")) {
|
||||||
|
terminal.error("cp only works for scripts and .txt files");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scp for txt files
|
||||||
|
if (filename.endsWith(".txt")) {
|
||||||
|
let txtFile = null;
|
||||||
|
for (let i = 0; i < server.textFiles.length; ++i) {
|
||||||
|
if (server.textFiles[i].fn === filename) {
|
||||||
|
txtFile = server.textFiles[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txtFile === null) {
|
||||||
|
return terminal.error("No such file exists!");
|
||||||
|
}
|
||||||
|
|
||||||
|
const tRes = server.writeToTextFile(dst, txtFile.text);
|
||||||
|
if (!tRes.success) {
|
||||||
|
terminal.error("scp failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tRes.overwritten) {
|
||||||
|
terminal.print(`WARNING: ${dst} already exists and will be overwriten`);
|
||||||
|
terminal.print(`${dst} overwritten`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
terminal.print(`${dst} copied`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current script
|
||||||
|
let sourceScript = null;
|
||||||
|
for (let i = 0; i < server.scripts.length; ++i) {
|
||||||
|
if (filename == server.scripts[i].filename) {
|
||||||
|
sourceScript = server.scripts[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sourceScript == null) {
|
||||||
|
terminal.error("cp() failed. No such script exists");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sRes = server.writeToScriptFile(dst, sourceScript.code);
|
||||||
|
if (!sRes.success) {
|
||||||
|
terminal.error(`scp failed`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sRes.overwritten) {
|
||||||
|
terminal.print(`WARNING: ${dst} already exists and will be overwritten`);
|
||||||
|
terminal.print(`${dst} overwritten`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
terminal.print(`${dst} copied`);
|
||||||
|
} catch (e) {
|
||||||
|
terminal.error(e + "");
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ import { startWorkerScript } from "../../NetscriptWorker";
|
|||||||
import { RunningScript } from "../../Script/RunningScript";
|
import { RunningScript } from "../../Script/RunningScript";
|
||||||
import { findRunningScript } from "../../Script/ScriptHelpers";
|
import { findRunningScript } from "../../Script/ScriptHelpers";
|
||||||
import * as libarg from "arg";
|
import * as libarg from "arg";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
export function runScript(
|
export function runScript(
|
||||||
terminal: ITerminal,
|
terminal: ITerminal,
|
||||||
@ -64,8 +65,8 @@ export function runScript(
|
|||||||
"This machine does not have enough RAM to run this script with " +
|
"This machine does not have enough RAM to run this script with " +
|
||||||
numThreads +
|
numThreads +
|
||||||
" threads. Script requires " +
|
" threads. Script requires " +
|
||||||
ramUsage +
|
numeralWrapper.formatRAM(ramUsage) +
|
||||||
"GB of RAM",
|
" of RAM",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ const commands = [
|
|||||||
"clear",
|
"clear",
|
||||||
"cls",
|
"cls",
|
||||||
"connect",
|
"connect",
|
||||||
|
"cp",
|
||||||
"download",
|
"download",
|
||||||
"expr",
|
"expr",
|
||||||
"free",
|
"free",
|
||||||
@ -239,6 +240,13 @@ export function determineAllPossibilitiesForTabCompletion(
|
|||||||
return allPos;
|
return allPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isCommand("cp") && index === 0) {
|
||||||
|
addAllScripts();
|
||||||
|
addAllTextFiles();
|
||||||
|
addAllDirectories();
|
||||||
|
return allPos;
|
||||||
|
}
|
||||||
|
|
||||||
if (isCommand("connect")) {
|
if (isCommand("connect")) {
|
||||||
// All network connections
|
// All network connections
|
||||||
for (let i = 0; i < currServ.serversOnNetwork.length; ++i) {
|
for (let i = 0; i < currServ.serversOnNetwork.length; ++i) {
|
||||||
|
@ -34,8 +34,6 @@ import { updateSourceFileFlags } from "./SourceFile/SourceFileFlags";
|
|||||||
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
|
import { initSymbolToStockMap, processStockPrices } from "./StockMarket/StockMarket";
|
||||||
import { Terminal } from "./Terminal";
|
import { Terminal } from "./Terminal";
|
||||||
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
|
import { Sleeve } from "./PersonObjects/Sleeve/Sleeve";
|
||||||
import { Locations } from "./Locations/Locations";
|
|
||||||
import { LocationName } from "./Locations/data/LocationNames";
|
|
||||||
|
|
||||||
import { Money } from "./ui/React/Money";
|
import { Money } from "./ui/React/Money";
|
||||||
import { Hashes } from "./ui/React/Hashes";
|
import { Hashes } from "./ui/React/Hashes";
|
||||||
@ -91,34 +89,7 @@ const Engine: {
|
|||||||
|
|
||||||
Terminal.process(Router, Player, numCycles);
|
Terminal.process(Router, Player, numCycles);
|
||||||
|
|
||||||
// Working
|
Player.process(Router, numCycles);
|
||||||
if (Player.isWorking) {
|
|
||||||
if (Player.workType == CONSTANTS.WorkTypeFaction) {
|
|
||||||
if (Player.workForFaction(numCycles)) {
|
|
||||||
Router.toFaction();
|
|
||||||
}
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) {
|
|
||||||
if (Player.createProgramWork(numCycles)) {
|
|
||||||
Router.toTerminal();
|
|
||||||
}
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeStudyClass) {
|
|
||||||
if (Player.takeClass(numCycles)) {
|
|
||||||
Router.toCity();
|
|
||||||
}
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeCrime) {
|
|
||||||
if (Player.commitCrime(numCycles)) {
|
|
||||||
Router.toLocation(Locations[LocationName.Slums]);
|
|
||||||
}
|
|
||||||
} else if (Player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
|
||||||
if (Player.workPartTime(numCycles)) {
|
|
||||||
Router.toCity();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Player.work(numCycles)) {
|
|
||||||
Router.toCity();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update stock prices
|
// Update stock prices
|
||||||
if (Player.hasWseAccount) {
|
if (Player.hasWseAccount) {
|
||||||
|
@ -77,6 +77,7 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
|||||||
const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects);
|
const [disableTextEffects, setDisableTextEffects] = useState(Settings.DisableTextEffects);
|
||||||
const [enableBashHotkeys, setEnableBashHotkeys] = useState(Settings.EnableBashHotkeys);
|
const [enableBashHotkeys, setEnableBashHotkeys] = useState(Settings.EnableBashHotkeys);
|
||||||
const [enableTimestamps, setEnableTimestamps] = useState(Settings.EnableTimestamps);
|
const [enableTimestamps, setEnableTimestamps] = useState(Settings.EnableTimestamps);
|
||||||
|
const [saveGameOnFileSave, setSaveGameOnFileSave] = useState(Settings.SaveGameOnFileSave);
|
||||||
|
|
||||||
const [locale, setLocale] = useState(Settings.Locale);
|
const [locale, setLocale] = useState(Settings.Locale);
|
||||||
const [diagnosticOpen, setDiagnosticOpen] = useState(false);
|
const [diagnosticOpen, setDiagnosticOpen] = useState(false);
|
||||||
@ -165,6 +166,10 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
|||||||
setEnableTimestamps(event.target.checked);
|
setEnableTimestamps(event.target.checked);
|
||||||
Settings.EnableTimestamps = event.target.checked;
|
Settings.EnableTimestamps = event.target.checked;
|
||||||
}
|
}
|
||||||
|
function handleSaveGameOnFile(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setSaveGameOnFileSave(event.target.checked);
|
||||||
|
Settings.SaveGameOnFileSave = event.target.checked;
|
||||||
|
}
|
||||||
|
|
||||||
function startImport(): void {
|
function startImport(): void {
|
||||||
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) return;
|
if (!window.File || !window.FileReader || !window.FileList || !window.Blob) return;
|
||||||
@ -505,6 +510,19 @@ export function GameOptionsRoot(props: IProps): React.ReactElement {
|
|||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
|
||||||
|
<ListItem>
|
||||||
|
<FormControlLabel
|
||||||
|
control={<Switch checked={saveGameOnFileSave} onChange={handleSaveGameOnFile} />}
|
||||||
|
label={
|
||||||
|
<Tooltip
|
||||||
|
title={<Typography>Save your game any time a file is saved in the script editor.</Typography>}
|
||||||
|
>
|
||||||
|
<Typography>Save game on file save</Typography>
|
||||||
|
</Tooltip>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</ListItem>
|
||||||
|
|
||||||
<ListItem>
|
<ListItem>
|
||||||
<Tooltip title={<Typography>Sets the locale for displaying numbers.</Typography>}>
|
<Tooltip title={<Typography>Sets the locale for displaying numbers.</Typography>}>
|
||||||
<Typography>Locale </Typography>
|
<Typography>Locale </Typography>
|
||||||
|
@ -11,6 +11,7 @@ import { BaseServer } from "../../Server/BaseServer";
|
|||||||
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
||||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||||
import MenuItem from "@mui/material/MenuItem";
|
import MenuItem from "@mui/material/MenuItem";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
|
||||||
// TODO make this an enum when this gets converted to TypeScript
|
// TODO make this an enum when this gets converted to TypeScript
|
||||||
export const ServerType = {
|
export const ServerType = {
|
||||||
@ -21,6 +22,8 @@ export const ServerType = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
purchase: () => void;
|
||||||
|
canPurchase: boolean;
|
||||||
serverType: number;
|
serverType: number;
|
||||||
onChange: (event: SelectChangeEvent<string>) => void;
|
onChange: (event: SelectChangeEvent<string>) => void;
|
||||||
value: string;
|
value: string;
|
||||||
@ -61,7 +64,16 @@ export function ServerDropdown(props: IProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select sx={{ mx: 1 }} value={props.value} onChange={props.onChange}>
|
<Select
|
||||||
|
startAdornment={
|
||||||
|
<Button onClick={props.purchase} disabled={!props.canPurchase}>
|
||||||
|
Buy
|
||||||
|
</Button>
|
||||||
|
}
|
||||||
|
sx={{ mx: 1 }}
|
||||||
|
value={props.value}
|
||||||
|
onChange={props.onChange}
|
||||||
|
>
|
||||||
{servers}
|
{servers}
|
||||||
</Select>
|
</Select>
|
||||||
);
|
);
|
||||||
|
@ -36,24 +36,16 @@ export function TablePaginationActionsAll(props: TablePaginationActionsProps): R
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
<Box sx={{ flexShrink: 0, ml: 2.5 }}>
|
||||||
<IconButton onClick={handleFirstPageButtonClick} disabled={page === 0} aria-label="first page">
|
<IconButton onClick={handleFirstPageButtonClick} disabled={page === 0}>
|
||||||
{theme.direction === "rtl" ? <LastPageIcon /> : <FirstPageIcon />}
|
{theme.direction === "rtl" ? <LastPageIcon /> : <FirstPageIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton onClick={handleBackButtonClick} disabled={page === 0} aria-label="previous page">
|
<IconButton onClick={handleBackButtonClick} disabled={page === 0}>
|
||||||
{theme.direction === "rtl" ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
|
{theme.direction === "rtl" ? <KeyboardArrowRight /> : <KeyboardArrowLeft />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton onClick={handleNextButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1}>
|
||||||
onClick={handleNextButtonClick}
|
|
||||||
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
|
|
||||||
aria-label="next page"
|
|
||||||
>
|
|
||||||
{theme.direction === "rtl" ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
|
{theme.direction === "rtl" ? <KeyboardArrowLeft /> : <KeyboardArrowRight />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton
|
<IconButton onClick={handleLastPageButtonClick} disabled={page >= Math.ceil(count / rowsPerPage) - 1}>
|
||||||
onClick={handleLastPageButtonClick}
|
|
||||||
disabled={page >= Math.ceil(count / rowsPerPage) - 1}
|
|
||||||
aria-label="last page"
|
|
||||||
>
|
|
||||||
{theme.direction === "rtl" ? <FirstPageIcon /> : <LastPageIcon />}
|
{theme.direction === "rtl" ? <FirstPageIcon /> : <LastPageIcon />}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -276,6 +276,12 @@ export function refreshTheme(): void {
|
|||||||
select: {
|
select: {
|
||||||
color: Settings.theme.primary,
|
color: Settings.theme.primary,
|
||||||
},
|
},
|
||||||
|
selectLabel: {
|
||||||
|
color: Settings.theme.primary,
|
||||||
|
},
|
||||||
|
displayedRows: {
|
||||||
|
color: Settings.theme.primary,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
MuiTab: {
|
MuiTab: {
|
||||||
|
@ -106,6 +106,10 @@ class NumeralFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
formatRAM(n: number): string {
|
formatRAM(n: number): string {
|
||||||
|
if (n < 1e3) return this.format(n, "0.00") + "GB";
|
||||||
|
if (n < 1e6) return this.format(n / 1e3, "0.00") + "TB";
|
||||||
|
if (n < 1e9) return this.format(n / 1e6, "0.00") + "PB";
|
||||||
|
if (n < 1e12) return this.format(n / 1e9, "0.00") + "EB";
|
||||||
return this.format(n, "0.00") + "GB";
|
return this.format(n, "0.00") + "GB";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,8 +12,7 @@ export interface IReviverValue {
|
|||||||
// off to that `fromJSON` fuunction, passing in the value.
|
// off to that `fromJSON` fuunction, passing in the value.
|
||||||
export function Reviver(key: string, value: IReviverValue | null): any {
|
export function Reviver(key: string, value: IReviverValue | null): any {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
console.log("Reviver WRONGLY called with key: " + key + ", and value: " + value);
|
return null;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof value === "object" && typeof value.ctor === "string" && typeof value.data !== "undefined") {
|
if (typeof value === "object" && typeof value.ctor === "string" && typeof value.data !== "undefined") {
|
||||||
|
Loading…
Reference in New Issue
Block a user