Compare commits

...

193 Commits

Author SHA1 Message Date
Olivier Gagnon cb31954b08 v0.53.0 2021-09-09 22:57:37 -04:00
Olivier Gagnon 7f1d39a298 the world map is used every place a travel is done 2021-09-09 22:06:59 -04:00
Olivier Gagnon d5c9306395 Convert sleeves to react, fix shock recovery bug 2021-09-09 21:38:05 -04:00
Olivier Gagnon b0fcdb8363 some sleeve conversion 2021-09-09 16:04:36 -04:00
Olivier Gagnon ab8937870c resleeve in react 2021-09-09 15:19:11 -04:00
Olivier Gagnon 4e22b880bb removed Corporation rerender and drilled down a rerender function in the react. 2021-09-09 14:21:21 -04:00
Olivier Gagnon f77ab4e871 engine work 2021-09-09 13:48:21 -04:00
Olivier Gagnon 0a210555e9 remove some createElement 2021-09-09 13:00:06 -04:00
Olivier Gagnon 3df298e91e fix contract 2021-09-09 12:52:43 -04:00
Olivier Gagnon b7e07bc7f2 convert all hacknet to ts 2021-09-09 03:17:01 -04:00
Olivier Gagnon c97fece747 UI work on corps 2021-09-09 00:34:13 -04:00
Olivier Gagnon a2aaf6bd2e build sleeve memory fix 2021-09-08 23:48:42 -04:00
Olivier Gagnon 2a13db39c7 fix sleeve memory bug 2021-09-08 23:47:34 -04:00
hydroflame bada8a5f39 Merge pull request #1192 from vmesecher/dev
Adds getAugmentationPrice() and getAugmentationReqRep() Netscript Singularity functions.
2021-09-08 00:16:14 -04:00
vmesecher 6979082be7 Adds getAugmentationPrice() and getAugmentationReqRep() Netscript Singularity functions. Deprecates getAugmentationCost() Netscript singularity function. 2021-09-07 20:33:34 -07:00
Olivier Gagnon 1c9542d102 tech vendor buttons update better 2021-09-07 17:26:49 -04:00
Olivier Gagnon 0d5a302580 few more bug fixes 2021-09-07 17:18:02 -04:00
Olivier Gagnon 7bc0764d5d noselect some blade stuff 2021-09-07 16:49:11 -04:00
Olivier Gagnon bc034bb417 Added more complex customization to smart supply 2021-09-07 16:46:36 -04:00
Olivier Gagnon ea99166f7f better ascii maps 2021-09-07 15:09:05 -04:00
Olivier Gagnon 82c3362adc fix tests 2021-09-07 14:31:47 -04:00
hydroflame e7d77b7569 Merge pull request #1167 from threehams/cypress
Add browser tests for tutorial, NetScript 2
2021-09-07 14:00:58 -04:00
Olivier Gagnon c5af4f8177 remove debug log 2021-09-07 13:29:35 -04:00
Olivier Gagnon d0cb0e3f5b remove ram requirements from joining factinos 2021-09-07 13:22:39 -04:00
Olivier Gagnon f7adadd671 Blade action count replenishes more consistently 2021-09-07 13:15:27 -04:00
Olivier Gagnon faa6f75027 UI improvements for corps. 2021-09-07 02:03:39 -04:00
Olivier Gagnon 3b0cf6714a build corp fixes 2021-09-07 01:16:28 -04:00
Olivier Gagnon cd43f25bf5 make smart supply actually kinda smart 2021-09-07 01:14:55 -04:00
Olivier Gagnon 6e670e88e2 Fix manual management issues 2021-09-06 19:10:40 -04:00
David Edmondson 20062b11b9 Add test for static/dynamic RAM check 2021-09-06 13:51:55 -07:00
David Edmondson d0ca2d8c36 Set up cy:test for production tests 2021-09-06 13:51:54 -07:00
David Edmondson 20e41e8006 Add back command import 2021-09-06 13:49:34 -07:00
David Edmondson 7ef7fc1b26 Remove getId for now 2021-09-06 13:49:34 -07:00
David Edmondson 6352704608 Remove placeholder fixture 2021-09-06 13:49:34 -07:00
David Edmondson 072f7693f4 gitignore cypress output 2021-09-06 13:49:34 -07:00
David Edmondson fbe70f51c2 Add browser tests for tutorial, NetScript 2 2021-09-06 13:49:34 -07:00
David Edmondson 27e2b2ea65 separate PR/dev actions 2021-09-06 13:46:59 -07:00
David Edmondson 6320189717 Specify node version 2021-09-06 13:32:18 -07:00
David Edmondson 17da325585 Cache npm install, add tests 2021-09-06 13:29:35 -07:00
David Edmondson 5873b5fe19 Try again 2021-09-06 13:24:33 -07:00
David Edmondson 6d8b52c0d6 npm install 2021-09-06 13:20:07 -07:00
David Edmondson 8faa7faf8a Set up GitHub Actions 2021-09-06 13:17:42 -07:00
Olivier Gagnon 66a593e06b expand new city and new industry dont appear if you cant 2021-09-06 15:53:31 -04:00
Olivier Gagnon 506122f5b8 fmt, remove corp routing, lint 2021-09-06 15:06:08 -04:00
hydroflame 91434b7972 Merge pull request #1173 from threehams/source-maps
Speed up sourcemaps in dev mode
2021-09-06 13:05:13 -04:00
David Edmondson ba46262426 Speed up sourcemaps in dev mode 2021-09-05 11:32:52 -07:00
Olivier Gagnon aa91e8aecc fix ts warning 2021-09-05 14:18:33 -04:00
hydroflame 2874112946 Merge pull request #1171 from threehams/ts-check-1169
Add async TS checker to build
2021-09-05 14:13:36 -04:00
David Edmondson 3f8aa2aa9e Add async TS checker to build 2021-09-05 11:10:23 -07:00
Olivier Gagnon b9acfde363 fix research box not displaying well on big screens. 2021-09-05 13:48:38 -04:00
Olivier Gagnon b4c9655782 reword hacking skill aug effect 2021-09-05 01:56:37 -04:00
Olivier Gagnon f50b2a9d9f remove debug log 2021-09-05 01:51:27 -04:00
Olivier Gagnon a475e6297e fix miscalc in favor 2021-09-05 01:50:26 -04:00
Olivier Gagnon cfdf23cd11 fix whitespace from new build 2021-09-05 01:33:05 -04:00
hydroflame d6aa331310 Merge pull request #1163 from threehams/world-map
Fix world map and casino visuals.
2021-09-05 01:31:36 -04:00
David Edmondson 306facc0d1 Switch to babel for builds.
Fix whitespace mangled by prettier
2021-09-04 22:17:30 -07:00
hydroflame 5e11e77282 Merge pull request #1161 from threehams/fixed-builds
Fixed builds
2021-09-04 21:05:52 -04:00
David Edmondson daafdbbddf Target ES2017 browsers and above 2021-09-04 17:52:23 -07:00
David Edmondson 8501c9bb1b Revert swc change due to prod crash 2021-09-04 17:45:30 -07:00
Olivier Gagnon 05f3b1c390 remove some function from autocomplete. 2021-09-04 20:14:33 -04:00
Olivier Gagnon 7f15a19f12 fix bad import 2021-09-04 20:09:22 -04:00
hydroflame 4011542b97 Merge pull request #1157 from threehams/faster-builds
Switch ts and babel for swc-loader
2021-09-04 20:05:51 -04:00
Olivier Gagnon 858b1e7468 documentation 2021-09-04 20:05:24 -04:00
David Edmondson cfbdae6def Switch ts and babel for swc-loader
Replace old <> assertion syntax
2021-09-04 16:57:49 -07:00
Olivier Gagnon 05a6f2a20e fix formatting of Spiralize Matrix contract 2021-09-04 19:54:08 -04:00
Olivier Gagnon 05bab22807 Better error message for dynamic ram miscalculation 2021-09-04 19:27:16 -04:00
Olivier Gagnon a18bdd6afc prettify, sorry for the big ass commit 2021-09-04 19:09:30 -04:00
hydroflame 3d7cdb4ef9 Merge pull request #1105 from danielyxie/dependabot/npm_and_yarn/jszip-3.7.0
Bump jszip from 3.1.5 to 3.7.0
2021-09-04 19:03:43 -04:00
hydroflame eed915dbbd Merge pull request #1154 from threehams/num-people-killed
Add numPeopleKilled to getPlayer return
2021-09-04 19:03:36 -04:00
hydroflame 570e5b17a2 Merge pull request #1122 from threehams/upgrade-acorn
Support optional chaining in static RAM calculator.
2021-09-04 19:03:22 -04:00
hydroflame 4a7fcda86f Merge pull request #1152 from threehams/prettier
Configure `prettier`.
2021-09-04 19:03:05 -04:00
David Edmondson a63178f30c Run eslint on js,jsx files 2021-09-04 14:56:54 -07:00
David Edmondson 2914bbb789 Add numPeopleKilled to getPlayer return 2021-09-04 14:51:59 -07:00
David Edmondson 1e42f73e2a Add prettier, and fix some CSS/line errors. 2021-09-04 13:18:35 -07:00
hydroflame 2d322e7a6a Merge pull request #1115 from danielyxie/react-corp
React corp
2021-09-04 15:11:43 -04:00
Olivier Gagnon 75d77410ea merge dev 2021-09-04 15:11:17 -04:00
Olivier Gagnon 0ad05c7bad fix disableLog issue 2021-09-04 14:51:50 -04:00
Olivier Gagnon 69ec6f6679 Travel cost greys out 2021-09-04 14:46:13 -04:00
Olivier Gagnon c8dd17d573 added formula for cores cost, ram cost, and changed core cost formula 2021-09-04 14:43:22 -04:00
Olivier Gagnon 1241cc5128 Avoid use of any in CONSTANTS.ts 2021-09-04 14:09:57 -04:00
Olivier Gagnon e1c29f25e2 Fix missing money display 2021-09-04 14:03:19 -04:00
Olivier Gagnon c9efa977fb BN10 now has the sleeve you would gain but inside, also it starts with 25-25 sync-shock 2021-09-04 12:15:16 -04:00
Olivier Gagnon 6e013e4e6a Change money to automatically color grey when something cannot be bought. 2021-09-04 03:27:31 -04:00
Olivier Gagnon 3a943e0e50 made tech vendors button a tad smarter. 2021-09-04 02:21:31 -04:00
Olivier Gagnon f2edb42aca gave some love to the donations 2021-09-04 01:39:34 -04:00
Olivier Gagnon e1cb0e529c Tech vendors give a tip that you can buy bigger servers via scripts. 2021-09-03 18:04:05 -04:00
Olivier Gagnon 008b233c9d reword faction reputation and favor tooltips 2021-09-03 17:42:23 -04:00
Olivier Gagnon cc9a07c09f Fix 180 favor issue, reworked favor and reputation mathjax 2021-09-03 17:12:55 -04:00
Olivier Gagnon 2866bfaa70 more corp API 2021-09-03 16:02:41 -04:00
David Edmondson 38880f69e1 Update acorn for optional chaining support 2021-09-02 13:56:30 -07:00
Olivier Gagnon eb01051ad6 rebuild 2021-09-02 16:42:24 -04:00
Olivier Gagnon 5dd6145d53 build player patch 2021-09-02 13:34:59 -04:00
hydroflame a652140224 Merge pull request #1124 from TomCassWindred/WrapOnLineBreak
Set log messages to wrap on line breaks
2021-09-02 13:24:30 -04:00
Cass aa929b1837 Set log messages to wrap on line breaks
This retains \n characters on strings given as inputs
2021-09-02 18:15:42 +01:00
Olivier Gagnon 9b501e061a merge dev 2021-09-02 03:16:58 -04:00
dependabot[bot] 6f3db27373 Bump jszip from 3.1.5 to 3.7.0
Bumps [jszip](https://github.com/Stuk/jszip) from 3.1.5 to 3.7.0.
- [Release notes](https://github.com/Stuk/jszip/releases)
- [Changelog](https://github.com/Stuk/jszip/blob/master/CHANGES.md)
- [Commits](https://github.com/Stuk/jszip/compare/v3.1.5...v3.7.0)

---
updated-dependencies:
- dependency-name: jszip
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-09-02 07:11:42 +00:00
Olivier Gagnon 454a792f0a Added mathjax formulas for favor and made favor calculation faster. 2021-09-02 03:10:12 -04:00
Olivier Gagnon 8d17495e85 corp API 2021-09-02 00:36:33 -04:00
Olivier Gagnon d3aeda8ad5 more conversion 2021-09-01 22:16:48 -04:00
Olivier Gagnon 65158e4db7 merge dev 2021-08-31 16:30:01 -04:00
Olivier Gagnon fd85a00b8f Merge branch 'dev' of github.com:danielyxie/bitburner into dev 2021-08-31 16:26:54 -04:00
Olivier Gagnon a239f0ad58 Build some PRs for the players 2021-08-31 16:26:06 -04:00
hydroflame d936f68c7a Merge pull request #1111 from brubsby/patch-2
Update all general actions to have infinity count
2021-08-31 16:24:57 -04:00
hydroflame feebdc8ee5 Merge pull request #1112 from brubsby/patch-3
Update getActionEstimatedSuccessChance
2021-08-31 16:24:47 -04:00
hydroflame 0eeb868e25 Merge pull request #1117 from TomCassWindred/IndividualLogEnable
Individual log enable
2021-08-31 16:22:34 -04:00
Olivier Gagnon d9c9c30fdd more conversion 2021-08-31 16:19:58 -04:00
Cass 294640d27e Quick Tidy 2021-08-31 21:04:40 +01:00
Cass fe25460997 Replace "ALL" log flag with individually disabling every log.
https://github.com/danielyxie/bitburner/issues/1116
2021-08-31 21:03:39 +01:00
Olivier Gagnon f987ff9e2a no more any in corp 2021-08-31 15:51:27 -04:00
Olivier Gagnon d65cbf07f4 Narrow down corporation types 2021-08-31 14:47:07 -04:00
Olivier Gagnon 2624e13c34 build dev menu 2021-08-31 13:06:23 -04:00
Olivier Gagnon 7c9c4d3f4d No more use of any in Corporations. 2021-08-31 13:04:33 -04:00
Olivier Gagnon a2379b21ec more conversion 2021-08-31 03:39:04 -04:00
Olivier Gagnon 68885ceff5 more conversion 2021-08-31 03:18:44 -04:00
Olivier Gagnon 1ae17677c0 jsts corporation 2021-08-31 03:07:20 -04:00
Olivier Gagnon 67be13c6d6 more conversion 2021-08-31 02:49:57 -04:00
Olivier Gagnon d4349e85b1 fix some of the research popup stuff 2021-08-31 01:05:51 -04:00
Olivier Gagnon a721c49e1d more conversion 2021-08-31 00:54:57 -04:00
hydroflame 2d2c20bfc7 Merge pull request #1114 from threehams/autocomplete
Add tests for autocomplete
2021-08-30 22:08:16 -04:00
David Edmondson ed035a2e89 Add tests for autocomplete 2021-08-30 17:58:01 -07:00
Olivier Gagnon cf72d72bb0 Finished converting all the popups. 2021-08-30 17:59:11 -04:00
Olivier Gagnon 3ba04220e1 I made a mistake but caught it. 2021-08-30 03:18:12 -04:00
Olivier Gagnon a72d1aa99f more conversion 2021-08-30 03:07:14 -04:00
Olivier Gagnon 21008ba65a more conversion 2021-08-28 14:45:55 -04:00
Olivier Gagnon a760ede129 more conversion 2021-08-28 14:22:36 -04:00
Olivier Gagnon 717b32b0b4 more conversion 2021-08-28 14:03:07 -04:00
Olivier Gagnon 4b6d049da2 more conversion 2021-08-28 13:41:25 -04:00
Olivier Gagnon 8bb4e8b7cf more conversion 2021-08-28 13:07:35 -04:00
Olivier Gagnon 0d30544a52 more conversion 2021-08-28 12:00:18 -04:00
Olivier Gagnon 361ef31fe7 more conversion 2021-08-28 03:49:15 -04:00
Olivier Gagnon 0de3deee3f Even more conversion 2021-08-28 03:31:47 -04:00
Olivier Gagnon 94ad7ccf4b more conversion 2021-08-28 02:57:57 -04:00
Olivier Gagnon 4b53d6ecf7 more convertion 2021-08-28 02:50:06 -04:00
Olivier Gagnon 3d2aeb63a0 more convert 2021-08-28 00:29:19 -04:00
Olivier Gagnon b621359a9e fix changelog dates 2021-08-28 00:13:08 -04:00
Olivier Gagnon 07c0b708d7 more convertion 2021-08-28 00:11:42 -04:00
brubsby b372f23b6e Update getActionEstimatedSuccessChance
ns.bladeburner.getActionEstimatedSuccessChance("general", "Diplomacy") returned [-1, -1] (as well as "Hyperbolic Regeneration Chamber"), even though both tasks automatically succeed. Also Training and Field Analysis both previously returned [1, 1].
2021-08-27 17:06:01 -05:00
Olivier Gagnon a8254e7144 one component 2021-08-27 17:39:15 -04:00
brubsby 02a21cf2d9 Update all general actions to have infinity count
ns.bladeburner.getActionCountRemaining("general", "Diplomacy") currently returns -1. I think it'd be more intuitive if all the general actions returned Infinity, instead of just two of them
2021-08-27 16:13:22 -05:00
Olivier Gagnon bcb0606900 fix typo 2021-08-27 15:31:54 -04:00
Olivier Gagnon 42704d8695 v0.52.9 2021-08-27 15:26:12 -04:00
Olivier Gagnon e75197dee3 build 2021-08-27 14:19:36 -04:00
Olivier Gagnon 9e92df47a5 Added file diagnostic. 2021-08-27 14:17:25 -04:00
Olivier Gagnon c110c22efb My corp infinity safeguard from 2 patch ago wasn't actually preventing it, just logging, now it returns to avoid it. 2021-08-27 11:18:06 -04:00
Olivier Gagnon c9ab7908a7 another blocker against mku equal 0 and added tprintf 2021-08-27 11:05:36 -04:00
Olivier Gagnon 3ab306f9d7 fix the errors about node setTimeout instead of window 2021-08-27 01:11:11 -04:00
hydroflame f08aa8924c Merge pull request #1102 from threehams/test-runner
Switch out test runner for jest
2021-08-27 00:53:45 -04:00
Olivier Gagnon c4914fa54f build community prs 2021-08-27 00:45:11 -04:00
hydroflame fa5e2f4964 Merge pull request #1079 from threehams/infil-instakill
Instakill player when automating infiltration
2021-08-26 21:42:08 -04:00
hydroflame 77eda1fd75 Merge pull request #1098 from brubsby/patch-1
add bladeburner_analysis_mult to getPlayer()
2021-08-26 21:42:01 -04:00
Olivier Gagnon c987c91a11 add corp safeguard 2021-08-26 21:39:51 -04:00
David Edmondson feaa74ed34 Only compile down imports during tests 2021-08-26 17:02:02 -07:00
David Edmondson 701fba7ec7 Drop cross-env 2021-08-26 16:45:39 -07:00
David Edmondson 51bd626e88 Remove unneeded stuff, .vscode on gitignore 2021-08-26 16:44:37 -07:00
David Edmondson ab4863e7df Swap out mocha/chai for jest 2021-08-26 16:43:11 -07:00
David Edmondson 1a8bcf66cc Fix existing tests, update to jest 2021-08-26 16:43:03 -07:00
David Edmondson 7bfceb1690 Replace old-style import with type 2021-08-26 16:42:57 -07:00
David Edmondson 27e22814a9 Remove missing + unused variable 2021-08-26 16:42:47 -07:00
Olivier Gagnon ceb4e304fd Hotfix corp mku getting set to zero and causing infinity 2021-08-26 15:22:06 -04:00
Olivier Gagnon e2d74f9432 fix beautify 2021-08-25 16:14:47 -04:00
Olivier Gagnon 79345a49b4 Bladeburner automation status always displays the commands, even when disabled 2021-08-25 11:50:33 -04:00
Olivier Gagnon 7066a793a1 build fix 2021-08-24 21:40:50 -04:00
hydroflame 2a5cf62168 Merge pull request #1097 from Snarling/patch-2
Fix joining blade via ns
2021-08-24 21:39:29 -04:00
brubsby 6495be5705 add bladeburner_analysis_mult to getPlayer() 2021-08-24 20:02:39 -05:00
Snarling 0d6d05db49 Fix joining blade via ns
Pass Player as an argument in Bladeburner constructor call for ns.bladeburner.joinBladeburnerDivision()
2021-08-24 20:08:29 -04:00
Olivier Gagnon 5d59620dce click to copy every bladeburner action 2021-08-23 11:42:14 -04:00
Olivier Gagnon 60d95a90d0 Fix script not being saved on their individual computers. 2021-08-23 09:33:49 -04:00
Olivier Gagnon 51debc60da build omuretsu fix 2021-08-23 09:18:43 -04:00
Snarling faf625b34d Update Root.tsx
Went back to tracking lastServer as a hostname, since server IPs are not static.
2021-08-23 04:04:52 -07:00
Snarling 1a8b194341 Update Root.tsx
Removed unnecessary conversions between server and ip
2021-08-23 04:04:52 -07:00
Snarling 386f8a11c5 Change lastServer to reference the server ip
Should fix issue with newly saved scripts failing to run
2021-08-23 04:04:52 -07:00
hydroflame 4278191b0e Merge pull request #1090 from danielyxie/dev
v0.52.8
2021-08-23 02:09:55 -04:00
hydroflame 4a9bac99d2 Merge pull request #1083 from danielyxie/dev
Fix monaco jumping to end of file.
2021-08-22 23:57:16 -04:00
hydroflame 49cc75a575 Merge pull request #1082 from danielyxie/dev
trying to fix the jumping bug
2021-08-22 23:47:44 -04:00
hydroflame 8289c9fc75 Merge pull request #1080 from danielyxie/dev
Fixed Script Editor not loading the same file after manually clicking it
2021-08-22 01:31:00 -04:00
David Edmondson 6cd7465b82 Instakill player when automating infiltration 2021-08-21 15:00:00 -07:00
hydroflame c7125e2e46 Merge pull request #1077 from danielyxie/dev
Fix a few other bugs
2021-08-21 14:01:05 -04:00
hydroflame 480d47eece Merge pull request #1076 from danielyxie/dev
Fix log box dragging.
2021-08-21 02:39:17 -04:00
hydroflame 9ac75d5bf5 Merge pull request #1075 from danielyxie/dev
Fix Corp research popup box appearing behind one another.
2021-08-21 02:07:10 -04:00
hydroflame 1fb5105d0a Merge pull request #1074 from danielyxie/dev
hotfix broken editor shortcuts
2021-08-21 01:55:05 -04:00
hydroflame 7db3716256 Merge pull request #1072 from danielyxie/dev
hotfix the tutorial
2021-08-21 00:58:58 -04:00
hydroflame aa3ad3164c Merge pull request #1068 from danielyxie/dev
v0.52.6
2021-08-21 00:32:04 -04:00
hydroflame fea25249a8 Merge pull request #1062 from danielyxie/dev
v0.52.5
2021-08-19 16:38:26 -04:00
hydroflame 3826de72ef Merge pull request #1061 from danielyxie/dev
hotfix some blade netscript functions not working
2021-08-19 11:04:24 -04:00
hydroflame 5098ef6232 Merge pull request #1057 from danielyxie/dev
v0.52.4 - Bladeburner in React
2021-08-19 01:46:16 -04:00
hydroflame 27ee65f524 Merge pull request #1051 from danielyxie/dev
hotfix 0 territory being softlocked.
2021-08-17 17:47:58 -04:00
hydroflame 1d0f193c34 Merge pull request #1050 from danielyxie/dev
hotfix blocked in Gang
2021-08-17 17:14:11 -04:00
hydroflame 08908c87ea Merge pull request #1048 from danielyxie/dev
Hotfix weird bladeburner ui bug
2021-08-15 17:14:38 -04:00
hydroflame 3957a517db Merge pull request #1047 from danielyxie/dev
v0.52.3 - 2021-07-15 Gangs were OP (hydroflame)
2021-08-15 16:26:52 -04:00
hydroflame 21daab32c1 Merge pull request #1044 from danielyxie/dev
v0.52.2
2021-08-15 02:15:03 -04:00
hydroflame 5e2ed7a79e Merge pull request #1042 from danielyxie/dev
hotfix revert tutorial instructing the player to make a script on n00…
2021-08-11 01:05:46 -04:00
hydroflame d9e60ea124 Merge pull request #1039 from danielyxie/dev
rebuild with the version inside the game correctly udpated
2021-08-10 21:10:00 -04:00
hydroflame 2750eb293a Merge pull request #1038 from danielyxie/dev
v0.52.1
2021-08-10 21:04:05 -04:00
636 changed files with 103228 additions and 75549 deletions
-3
View File
@@ -1,3 +0,0 @@
{
"presets": ["@babel/preset-react"]
}
+3
View File
@@ -0,0 +1,3 @@
last 4 versions
not dead
not ie <= 11
-2
View File
@@ -3,6 +3,4 @@ doc/build/
dist/ dist/
tests/*.bundle.* tests/*.bundle.*
src/ThirdParty/* src/ThirdParty/*
src/ScriptEditor/CodeMirrorNetscriptMode.js
src/ScriptEditor/CodeMirrorNetscriptLint.js
src/JSInterpreter.js src/JSInterpreter.js
+302 -822
View File
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
name: CI
on:
push:
branches: [dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- name: Install Dependencies
run: npm ci
- name: Test
run: npm run test
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: .
+25
View File
@@ -0,0 +1,25 @@
name: CI
on: [push, pull_request]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
test:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- name: Install Dependencies
run: npm ci
- name: Test
run: npm run test
+5
View File
@@ -1,3 +1,4 @@
.vscode
Changelog.txt Changelog.txt
Netburner.txt Netburner.txt
/doc/build /doc/build
@@ -6,3 +7,7 @@ Netburner.txt
/test/*.map /test/*.map
/test/*.bundle.* /test/*.bundle.*
/test/*.css /test/*.css
.cypress
# editor files
.vscode
+4
View File
@@ -0,0 +1,4 @@
node_modules
package.json
dist
doc/build/
+5
View File
@@ -0,0 +1,5 @@
{
"trailingComma": "all",
"tabWidth": 2,
"printWidth": 120
}
+28 -18
View File
@@ -1,9 +1,11 @@
# Contributing to Bitburner # Contributing to Bitburner
## In General ## In General
The game is made better because the community as a whole speaks up about The game is made better because the community as a whole speaks up about
ways to improve the game. Here's some of the ways you can make your voice ways to improve the game. Here's some of the ways you can make your voice
heard: heard:
- [Discord](https://discordapp.com) - [Discord](https://discordapp.com)
There is a dedicated Discord instance set up for more free-form chats There is a dedicated Discord instance set up for more free-form chats
between all members of the community. Regular players, heavy scripters, between all members of the community. Regular players, heavy scripters,
@@ -19,6 +21,7 @@ heard:
[new issue](https://github.com/danielyxie/bitburner/issues/new). [new issue](https://github.com/danielyxie/bitburner/issues/new).
## Reporting Bugs ## Reporting Bugs
The recommended method for reporting a bug is by opening a The recommended method for reporting a bug is by opening a
[Github Issue](https://github.com/danielyxie/bitburner/issues). [Github Issue](https://github.com/danielyxie/bitburner/issues).
@@ -30,18 +33,19 @@ already been reported as an [Issue](https://github.com/danielyxie/bitburner/issu
#### How to Submit a Good Bug Report #### How to Submit a Good Bug Report
* **Use a clear and descriptive title** for the issue - **Use a clear and descriptive title** for the issue
* **State your browser, your browser's version, and your computer's OS** - **State your browser, your browser's version, and your computer's OS**
* **Attach your save file**, if you think it would help solve the issue - **Attach your save file**, if you think it would help solve the issue
* **Provide instructions on how to reproduce the bug** in as much detail - **Provide instructions on how to reproduce the bug** in as much detail
as possible. If you cannot reliably reproduce the bug, then just try as possible. If you cannot reliably reproduce the bug, then just try
your best to explain what was happening when the bug occurred your best to explain what was happening when the bug occurred
* **Provide any scripts** that triggered the bug if the issue is Netscript-related - **Provide any scripts** that triggered the bug if the issue is Netscript-related
* **Open your browser's Dev Console and report any error-related output** - **Open your browser's Dev Console and report any error-related output**
that may be printed there. The Dev Console can be opened on most modern that may be printed there. The Dev Console can be opened on most modern
browsers by pressing F12 browsers by pressing F12
## As a Developer ## As a Developer
Anyone is welcome to contribute to Bitburner code. However, please read Anyone is welcome to contribute to Bitburner code. However, please read
the [license](https://github.com/danielyxie/bitburner/blob/dev/license.txt) the [license](https://github.com/danielyxie/bitburner/blob/dev/license.txt)
and the [readme](https://github.com/danielyxie/bitburner/blob/dev/README.md) and the [readme](https://github.com/danielyxie/bitburner/blob/dev/README.md)
@@ -52,32 +56,36 @@ To contribute to Bitburner code, you will need to have
called `npm` is installed as well. called `npm` is installed as well.
#### What are you Allowed to Contribute? #### What are you Allowed to Contribute?
Not all code contributions will be accepted. The safest way to ensure Not all code contributions will be accepted. The safest way to ensure
that you don't waste time working on something that gets rejected is to that you don't waste time working on something that gets rejected is to
run your idea(s)/plan(s) past [danielyxie](https://github.com/danielyxie) first. run your idea(s)/plan(s) past [danielyxie](https://github.com/danielyxie) first.
You can contact him through: You can contact him through:
* Github - Github
* Discord - Discord
* [Reddit](https://www.reddit.com/user/chapt3r/) - [Reddit](https://www.reddit.com/user/chapt3r/)
Otherwise, here are some general guidelines for determining what types of Otherwise, here are some general guidelines for determining what types of
changes are okay to contribute: changes are okay to contribute:
##### Contributions that Will Most Likely Be Accepted ##### Contributions that Will Most Likely Be Accepted
* Bug Fixes
* Quality-of-Life Changes - Bug Fixes
* Adding a new, commonly-requested Netscript function - Quality-of-Life Changes
* Fixing or improving UI elements - Adding a new, commonly-requested Netscript function
* Adding game settings/options - Fixing or improving UI elements
* Adding a new Terminal command - Adding game settings/options
* Code Refactors that conform to good/standard practices - Adding a new Terminal command
- Code Refactors that conform to good/standard practices
##### Contributions that will not be Accepted without prior approval ##### Contributions that will not be Accepted without prior approval
* Changes that directly affect the game's balance
* New gameplay mechanics - Changes that directly affect the game's balance
- New gameplay mechanics
#### 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
the following rules: the following rules:
@@ -100,11 +108,13 @@ the following rules:
releases. releases.
## As a Documentor ## As a Documentor
To contribute to and view your changes to the BitBurner documentation, you will To contribute to and view your changes to the BitBurner documentation, you will
need to have Python installed, along with [Sphinx](http://www.sphinx-doc.org). need to have Python installed, along with [Sphinx](http://www.sphinx-doc.org).
Before submitting your code for a pull request, please try to follow these Before submitting your code for a pull request, please try to follow these
rules: rules:
- Work in a branch forked from `dev` to isolate the new code - Work in a branch forked from `dev` to isolate the new code
- Ensure you have latest from the [game's main - Ensure you have latest from the [game's main
repository](danielyxie/bitburner@dev) repository](danielyxie/bitburner@dev)
+3
View File
@@ -1,9 +1,11 @@
# Bitburner # Bitburner
Bitburner is a programming-based [incremental game](https://en.wikipedia.org/wiki/Incremental_game) Bitburner is a programming-based [incremental game](https://en.wikipedia.org/wiki/Incremental_game)
that revolves around hacking and cyberpunk themes. that revolves around hacking and cyberpunk themes.
The game can be played at https://danielyxie.github.io/bitburner. The game can be played at https://danielyxie.github.io/bitburner.
# Documentation # Documentation
The game's official documentation can be found on [Read The The game's official documentation can be found on [Read The
Docs](http://bitburner.readthedocs.io/). Please note that this is still a Docs](http://bitburner.readthedocs.io/). Please note that this is still a
work-in-progress. work-in-progress.
@@ -16,6 +18,7 @@ For further guidance, please refer to the "As A Documentor" section of
[CONTRIBUTING](CONTRIBUTING.md). [CONTRIBUTING](CONTRIBUTING.md).
# Contribution # Contribution
There are many ways to contribute to the game. It can be as simple as fixing There are many ways to contribute to the game. It can be as simple as fixing
a typo, correcting a bug, or improving the UI. For guidance on doing so, a typo, correcting a bug, or improving the UI. For guidance on doing so,
please refer to the [CONTRIBUTING](CONTRIBUTING.md) document. please refer to the [CONTRIBUTING](CONTRIBUTING.md) document.
+4 -6
View File
@@ -1,7 +1,7 @@
Deploying a new version ## Deploying a new version
-----------------------
Update the following Update the following
- `src/Constants.ts` `Version` and `LatestUpdate` - `src/Constants.ts` `Version` and `LatestUpdate`
- `package.json` `version` - `package.json` `version`
- `doc/source/conf.py` `version` and `release` - `doc/source/conf.py` `version` and `release`
@@ -9,13 +9,11 @@ Update the following
- post to discord - post to discord
- post to reddit.com/r/Bitburner - post to reddit.com/r/Bitburner
Deploying `dev` to the Beta Branch ## Deploying `dev` to the Beta Branch
----------------------------------
TODO TODO
Development Workflow Best Practices ## Development Workflow Best Practices
-----------------------------------
- Work in a new branch forked from the `dev` branch to isolate your new code - Work in a new branch forked from the `dev` branch to isolate your new code
- Keep code-changes on a branch as small as possible. This makes it easier for code review. Each branch should be its own independent feature. - Keep code-changes on a branch as small as possible. This makes it easier for code review. Each branch should be its own independent feature.
+3
View File
@@ -0,0 +1,3 @@
module.exports = {
presets: ["@babel/preset-react", "@babel/preset-env", "@babel/preset-typescript"],
};
+5 -5
View File
@@ -20,27 +20,27 @@
@mixin keyframes($animationName) { @mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} { @-webkit-keyframes #{$animationName} {
$browser: '-webkit-' !global; $browser: "-webkit-" !global;
@content; @content;
} }
@-moz-keyframes #{$animationName} { @-moz-keyframes #{$animationName} {
$browser: '-moz-' !global; $browser: "-moz-" !global;
@content; @content;
} }
@-ms-keyframes #{$animationName} { @-ms-keyframes #{$animationName} {
$browser: '-ms-' !global; $browser: "-ms-" !global;
@content; @content;
} }
@-o-keyframes #{$animationName} { @-o-keyframes #{$animationName} {
$browser: '-o-' !global; $browser: "-o-" !global;
@content; @content;
} }
@keyframes #{$animationName} { @keyframes #{$animationName} {
$browser: '' !global; $browser: "" !global;
@content; @content;
} }
} }
+2 -1
View File
@@ -1,4 +1,5 @@
$fontFamily: 'Lucida Console', 'Lucida Sans Unicode', 'Fira Mono', 'Consolas', 'Courier New', Courier, monospace, 'Times New Roman'; $fontFamily: "Lucida Console", "Lucida Sans Unicode", "Fira Mono", "Consolas", "Courier New", Courier, monospace,
"Times New Roman";
$defaultFontSize: 16px; $defaultFontSize: 16px;
/* COLORS */ /* COLORS */
+11 -5
View File
@@ -34,14 +34,15 @@
outline: none; outline: none;
&:after { &:after {
content: '\02795'; /* "plus" sign (+) */ content: "\02795"; /* "plus" sign (+) */
font-size: $defaultFontSize * 0.8125; font-size: $defaultFontSize * 0.8125;
color: #fff; color: #fff;
float: right; float: right;
margin-left: 5px; margin-left: 5px;
} }
&.active, &:hover { &.active,
&:hover {
background-color: #555; background-color: #555;
} }
} }
@@ -67,7 +68,9 @@
margin-left: 5%; margin-left: 5%;
display: none; display: none;
div, ul, ul > li { div,
ul,
ul > li {
background-color: #555; background-color: #555;
} }
} }
@@ -85,7 +88,7 @@
width: auto; width: auto;
&:after { &:after {
content: '\02795'; /* "plus" sign (+) */ content: "\02795"; /* "plus" sign (+) */
font-size: $defaultFontSize * 0.8125; font-size: $defaultFontSize * 0.8125;
float: right; float: right;
margin-left: 5px; margin-left: 5px;
@@ -117,7 +120,10 @@
padding: 0 18px; padding: 0 18px;
width: auto; width: auto;
pre, h2, ul, li { pre,
h2,
ul,
li {
background-color: #555; background-color: #555;
width: auto; width: auto;
color: #fff; color: #fff;
+3 -1
View File
@@ -1,6 +1,8 @@
@import "theme"; @import "theme";
#bladeburner-container { #bladeburner-container {
position: fixed;
padding: 6px;
a, a,
div, div,
p, p,
@@ -67,7 +69,7 @@
border-color: white; border-color: white;
border-style: solid; border-style: solid;
&:after { &:after {
content: ''; content: "";
width: 9px; width: 9px;
height: 5px; height: 5px;
position: absolute; position: absolute;
+2 -2
View File
@@ -4,14 +4,14 @@
background-color: white; background-color: white;
display: inline-block; display: inline-block;
border-radius: 10px; border-radius: 10px;
font-size: 14pt; font-size: 18.5px;
text-align: center; text-align: center;
margin: 3px; margin: 3px;
font-weight: bold; font-weight: bold;
} }
.casino-card .value { .casino-card .value {
font-size: 15pt; font-size: 20px;
font-family: sans-serif; font-family: sans-serif;
} }
+39 -13
View File
@@ -57,19 +57,45 @@
padding-top: 10px; padding-top: 10px;
} }
#character-hp-wrapper { color: $my-stat-hp-color; } #character-hp-wrapper {
.character-hp-cell { color: $my-stat-hp-color; } color: $my-stat-hp-color;
#character-money-wrapper { color: $my-stat-money-color; } }
.character-money-cell { color: $my-stat-money-color; } .character-hp-cell {
#character-hack-wrapper { color: $my-stat-hack-color; } color: $my-stat-hp-color;
.character-hack-cell { color: $my-stat-hack-color; } }
#character-cha-wrapper { color: $my-stat-cha-color; } #character-money-wrapper {
.character-cha-cell { color: $my-stat-cha-color; } color: $my-stat-money-color;
#character-int-wrapper { color: $my-stat-int-color; } }
.character-int-cell { color: $my-stat-int-color; } .character-money-cell {
.character-combat-cell { color: $my-stat-physical; } color: $my-stat-money-color;
#character-work-wrapper { color: $my-stat-hack-color; } }
.character-work-cell { color: $my-stat-hack-color; } #character-hack-wrapper {
color: $my-stat-hack-color;
}
.character-hack-cell {
color: $my-stat-hack-color;
}
#character-cha-wrapper {
color: $my-stat-cha-color;
}
.character-cha-cell {
color: $my-stat-cha-color;
}
#character-int-wrapper {
color: $my-stat-int-color;
}
.character-int-cell {
color: $my-stat-int-color;
}
.character-combat-cell {
color: $my-stat-physical;
}
#character-work-wrapper {
color: $my-stat-hack-color;
}
.character-work-cell {
color: $my-stat-hack-color;
}
.character-overview-btn { .character-overview-btn {
@include borderRadius(12px); @include borderRadius(12px);
+4
View File
@@ -0,0 +1,4 @@
#corporation-container {
position: fixed;
padding: 6px;
}
+2 -1
View File
@@ -9,7 +9,8 @@
position: fixed; position: fixed;
padding: 6px; padding: 6px;
p, pre { p,
pre {
font-size: $defaultFontSize * 0.9375; font-size: $defaultFontSize * 0.9375;
} }
+3407 -1
View File
File diff suppressed because one or more lines are too long
+15 -10
View File
@@ -2,7 +2,7 @@
.blinking-cursor { .blinking-cursor {
font-weight: 100; font-weight: 100;
color: #2E3D48; color: #2e3d48;
-webkit-animation: 1s cursorblink step-end infinite; -webkit-animation: 1s cursorblink step-end infinite;
-moz-animation: 1s cursorblink step-end infinite; -moz-animation: 1s cursorblink step-end infinite;
-ms-animation: 1s cursorblink step-end infinite; -ms-animation: 1s cursorblink step-end infinite;
@@ -10,8 +10,9 @@
animation: 1s cursorblink step-end infinite; animation: 1s cursorblink step-end infinite;
} }
@keyframes "cursorblink" { @keyframes cursorblink {
from, to { from,
to {
color: transparent; color: transparent;
} }
50% { 50% {
@@ -20,7 +21,8 @@
} }
@-moz-keyframes cursorblink { @-moz-keyframes cursorblink {
from, to { from,
to {
color: transparent; color: transparent;
} }
50% { 50% {
@@ -28,8 +30,9 @@
} }
} }
@-webkit-keyframes "cursorblink" { @-webkit-keyframes cursorblink {
from, to { from,
to {
color: transparent; color: transparent;
} }
50% { 50% {
@@ -37,8 +40,9 @@
} }
} }
@-ms-keyframes "cursorblink" { @-ms-keyframes cursorblink {
from, to { from,
to {
color: transparent; color: transparent;
} }
50% { 50% {
@@ -46,8 +50,9 @@
} }
} }
@-o-keyframes "cursorblink" { @-o-keyframes cursorblink {
from, to { from,
to {
color: transparent; color: transparent;
} }
50% { 50% {
+4 -4
View File
@@ -13,8 +13,8 @@
@include keyframes(LOADERLABEL) { @include keyframes(LOADERLABEL) {
0% { 0% {
opacity: 1.0; opacity: 1;
#{$browser}transform: translate(-50%, -50%) scale(1.0); #{$browser}transform: translate(-50%, -50%) scale(1);
} }
5% { 5% {
opacity: 0.5; opacity: 0.5;
@@ -25,8 +25,8 @@
#{$browser}transform: translate(-50%, -50%) scale(0.5); #{$browser}transform: translate(-50%, -50%) scale(0.5);
} }
100% { 100% {
opacity: 1.0; opacity: 1;
#{$browser}transform: translate(-50%, -50%) scale(1.0); #{$browser}transform: translate(-50%, -50%) scale(1);
} }
} }
+2 -2
View File
@@ -99,7 +99,7 @@
/* Plus and minus signs */ /* Plus and minus signs */
.mainmenu-accordion-header:after, .mainmenu-accordion-header:after,
.mainmenu-accordion-header-compact:after { .mainmenu-accordion-header-compact:after {
content: '\02795'; content: "\02795";
float: right; float: right;
font-size: $defaultFontSize * 0.8125; font-size: $defaultFontSize * 0.8125;
position: absolute; position: absolute;
@@ -110,7 +110,7 @@
} }
.mainmenu-accordion-header-classic:after { .mainmenu-accordion-header-classic:after {
content: '\02795'; content: "\02795";
float: right; float: right;
font-size: $defaultFontSize * 0.8125; font-size: $defaultFontSize * 0.8125;
color: #fff; color: #fff;
+3 -3
View File
@@ -72,7 +72,6 @@
border: 5px solid var(--my-highlight-color); border: 5px solid var(--my-highlight-color);
} }
.log-box-container { .log-box-container {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
@@ -151,13 +150,14 @@
position: relative; position: relative;
} }
#log-box-close, #log-box-kill-script { #log-box-close,
#log-box-kill-script {
float: right; float: right;
display: inline-block; display: inline-block;
} }
.dialog-box-close-button:hover, .dialog-box-close-button:hover,
.dialog-box-close-button:focus,{ .dialog-box-close-button:focus {
color: #fff; color: #fff;
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
+6 -1
View File
@@ -3,7 +3,12 @@
*/ */
@import "theme"; @import "theme";
.resleeve-container { #resleeve-container {
position: fixed;
padding: 6px;
}
.resleeve-elem {
border: 1px solid white; border: 1px solid white;
margin: 4px; margin: 4px;
width: 75%; width: 75%;
+7 -6
View File
@@ -3,14 +3,15 @@
*/ */
@import "theme"; @import "theme";
.sleeve-container { #sleeves-container {
position: fixed;
padding: 6px;
}
.sleeve-elem {
border: 1px solid white; border: 1px solid white;
margin: 4px; margin: 4px;
width: 75%; display: block;
p {
font-size: $defaultFontSize * 0.875;
}
} }
.sleeves-page-info { .sleeves-page-info {
+2 -1
View File
@@ -26,7 +26,8 @@
width: 70%; width: 70%;
} }
> a, > button { > a,
> button {
margin: 10px; margin: 10px;
} }
} }
+104 -31
View File
@@ -128,14 +128,14 @@ a:visited {
border: 1px solid #fff; border: 1px solid #fff;
border-radius: 5px; border-radius: 5px;
color: #fff; color: #fff;
content: '?'; content: "?";
display: inline-block; display: inline-block;
margin-left: 3px; margin-left: 3px;
padding: 1px; padding: 1px;
} }
.help-tip-big { .help-tip-big {
content: '?'; content: "?";
padding: 3px; padding: 3px;
margin-left: 3px; margin-left: 3px;
color: #fff; color: #fff;
@@ -156,27 +156,63 @@ a:visited {
/* Flashing button (Red) */ /* Flashing button (Red) */
@-webkit-keyframes glowing { @-webkit-keyframes glowing {
0% { background-color: #b20000; -webkit-box-shadow: 0 0 3px #b20000; } 0% {
50% { background-color: #f00; -webkit-box-shadow: 0 0 40px #f00; } background-color: #b20000;
100% { background-color: #b20000; -webkit-box-shadow: 0 0 3px #b20000; } -webkit-box-shadow: 0 0 3px #b20000;
}
50% {
background-color: #f00;
-webkit-box-shadow: 0 0 40px #f00;
}
100% {
background-color: #b20000;
-webkit-box-shadow: 0 0 3px #b20000;
}
} }
@-moz-keyframes glowing { @-moz-keyframes glowing {
0% { background-color: #b20000; -moz-box-shadow: 0 0 3px #b20000; } 0% {
50% { background-color: #f00; -moz-box-shadow: 0 0 40px #f00; } background-color: #b20000;
100% { background-color: #b20000; -moz-box-shadow: 0 0 3px #b20000; } -moz-box-shadow: 0 0 3px #b20000;
}
50% {
background-color: #f00;
-moz-box-shadow: 0 0 40px #f00;
}
100% {
background-color: #b20000;
-moz-box-shadow: 0 0 3px #b20000;
}
} }
@-o-keyframes glowing { @-o-keyframes glowing {
0% { background-color: #b20000; box-shadow: 0 0 3px #b20000; } 0% {
50% { background-color: #f00; box-shadow: 0 0 40px #f00; } background-color: #b20000;
100% { background-color: #b20000; box-shadow: 0 0 3px #b20000; } box-shadow: 0 0 3px #b20000;
}
50% {
background-color: #f00;
box-shadow: 0 0 40px #f00;
}
100% {
background-color: #b20000;
box-shadow: 0 0 3px #b20000;
}
} }
@keyframes glowing { @keyframes glowing {
0% { background-color: #b20000; box-shadow: 0 0 3px #b20000; } 0% {
50% { background-color: #f00; box-shadow: 0 0 40px #f00; } background-color: #b20000;
100% { background-color: #b20000; box-shadow: 0 0 3px #b20000; } box-shadow: 0 0 3px #b20000;
}
50% {
background-color: #f00;
box-shadow: 0 0 40px #f00;
}
100% {
background-color: #b20000;
box-shadow: 0 0 3px #b20000;
}
} }
.flashing-button { .flashing-button {
@@ -198,29 +234,59 @@ a:visited {
} }
@-keyframes blink { @-keyframes blink {
0% { opacity: 1; } 0% {
50% { opacity: 0; } opacity: 1;
100% { opacity: 1; } }
50% {
opacity: 0;
}
100% {
opacity: 1;
}
} }
@-webkit-keyframes blink { @-webkit-keyframes blink {
0% { opacity: 1; } 0% {
50% { opacity: 0; } opacity: 1;
100% { opacity: 1; } }
50% {
opacity: 0;
}
100% {
opacity: 1;
}
} }
@-moz-keyframes blink { @-moz-keyframes blink {
0% { opacity: 1; } 0% {
50% { opacity: 0; } opacity: 1;
100% { opacity: 1; } }
50% {
opacity: 0;
}
100% {
opacity: 1;
}
} }
@-ms-keyframes blink { @-ms-keyframes blink {
0% { opacity: 1; } 0% {
50% { opacity: 0; } opacity: 1;
100% { opacity: 1; } }
50% {
opacity: 0;
}
100% {
opacity: 1;
}
} }
@-o-keyframes blink { @-o-keyframes blink {
0% { opacity: 1; } 0% {
50% { opacity: 0; } opacity: 1;
100% { opacity: 1; } }
50% {
opacity: 0;
}
100% {
opacity: 1;
}
} }
/* Status text */ /* Status text */
@@ -294,7 +360,7 @@ a:visited {
} }
&:after { &:after {
content: '\02795'; /* "plus" sign (+) */ content: "\02795"; /* "plus" sign (+) */
font-size: $defaultFontSize * 0.875; font-size: $defaultFontSize * 0.875;
float: right; float: right;
color: transparent; color: transparent;
@@ -319,7 +385,10 @@ a:visited {
overflow-y: auto; overflow-y: auto;
overflow-x: none; overflow-x: none;
div, ul, p, ul > li { div,
ul,
p,
ul > li {
background-color: #555; background-color: #555;
} }
} }
@@ -345,6 +414,10 @@ a:visited {
color: $light-yellow; color: $light-yellow;
} }
.unbuyable {
color: #66cfbc;
}
.failure { .failure {
color: $alert-red; color: $alert-red;
text-shadow: 0 0 0 $alert-red; text-shadow: 0 0 0 $alert-red;
+36 -7
View File
@@ -1,14 +1,43 @@
/* required LIB STYLES */ /* required LIB STYLES */
/* .Treant se automatski dodaje na svaki chart conatiner */ /* .Treant se automatski dodaje na svaki chart conatiner */
.Treant { position: relative; overflow: hidden; padding: 0 !important; } .Treant {
position: relative;
overflow: hidden;
padding: 0 !important;
}
.Treant > .node, .Treant > .node,
.Treant > .pseudo { position: absolute; display: block; visibility: hidden; } .Treant > .pseudo {
position: absolute;
display: block;
visibility: hidden;
}
.Treant.Treant-loaded .node, .Treant.Treant-loaded .node,
.Treant.Treant-loaded .pseudo { visibility: visible; } .Treant.Treant-loaded .pseudo {
.Treant > .pseudo { width: 0; height: 0; border: none; padding: 0; } visibility: visible;
.Treant .collapse-switch { width: 3px; height: 3px; display: block; border: 1px solid black; position: absolute; top: 1px; right: 1px; cursor: pointer; } }
.Treant .collapsed .collapse-switch { background-color: #868dee; } .Treant > .pseudo {
.Treant > .node img { border: none; float: left; } width: 0;
height: 0;
border: none;
padding: 0;
}
.Treant .collapse-switch {
width: 3px;
height: 3px;
display: block;
border: 1px solid black;
position: absolute;
top: 1px;
right: 1px;
cursor: pointer;
}
.Treant .collapsed .collapse-switch {
background-color: #868dee;
}
.Treant > .node img {
border: none;
float: left;
}
.Treant > .node { .Treant > .node {
cursor: pointer; cursor: pointer;
padding: 4px; padding: 4px;
+8
View File
@@ -0,0 +1,8 @@
{
"baseUrl": "http://localhost:8000",
"fixturesFolder": false,
"trashAssetsBeforeRuns": true,
"screenshotsFolder": ".cypress/screenshots",
"videosFolder": ".cypress/videos",
"videoUploadOnPasses": false
}
+51
View File
@@ -0,0 +1,51 @@
export {};
describe("netscript", () => {
it("creates and runs a NetScript 2.0 script", () => {
cy.findByRole("button", { name: "Exit Tutorial" }).click();
cy.findByText("Got it!").click();
cy.findByRole("textbox").type("connect n00dles{enter}");
cy.findByText(/connected to n00dles/i);
cy.findByRole("textbox").type("run NUKE.exe{enter}");
cy.findByText(/gained root access/i);
cy.findByRole("textbox").type("home{enter}");
cy.findByText(/connected to home/i);
cy.findByRole("textbox").type("nano script.js{enter}");
// monaco can take a bit
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type(`export const main = async (ns) => {{}
while(true) {{}
await ns.hack("n00dles");`);
cy.findByText("RAM: 1.70GB");
cy.findByRole("button", { name: /Save & Close/i }).click();
cy.findByRole("textbox").type("run script.js{enter}");
cy.findByText(/Running script with 1 thread/);
cy.findByRole("textbox").type("ps{enter}");
cy.findByText(/\(PID - 1\) script.js/);
});
it("errors and shows a dialog box when static RAM !== dynamic RAM", () => {
cy.findByRole("button", { name: "Exit Tutorial" }).click();
cy.findByText("Got it!").click();
cy.findByRole("textbox").type("nano script.js{enter}");
// monaco can take a bit
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type(`export const main = async (ns) => {{}
const command = "hack";
ns[command]("n00dles");`);
cy.findByText("RAM: 1.60GB");
cy.findByRole("button", { name: /Save & Close/i }).click();
cy.findByRole("textbox").type("run script.js{enter}");
cy.findByText(/Dynamic RAM usage calculated to be greater than initial RAM usage on fn: hack./i);
});
});
+95
View File
@@ -0,0 +1,95 @@
export {};
describe("tutorial", () => {
it("completes the tutorial", () => {
cy.findByText(/dark, dystopian future/);
cy.findByRole("button", { name: "Next" }).click();
cy.findByText(/heading to the Stats page/);
cy.findByRole("button", { name: "Stats" }).click();
cy.findByText(/lot of important information/);
cy.findByRole("button", { name: "Next" }).click();
cy.findByText(/head to your computer's terminal/);
cy.findByRole("button", { name: "Terminal" }).click();
cy.findByText(/is used to interface/);
cy.findByRole("button", { name: "Next" }).click();
cy.findByText(/Let's try it out/i);
cy.findByRole("textbox").type("help{enter}");
cy.findByText(/displays a list of all available/i);
cy.findByRole("textbox").type("ls{enter}");
cy.findByText(/is a basic command that shows files/i);
cy.findByRole("textbox").type("scan{enter}");
cy.findByText(/that's great and all/i);
cy.findByRole("textbox").type("scan-analyze{enter}");
cy.findByText(/this command shows more detailed information/i);
cy.findByRole("textbox").type("scan-analyze 2{enter}");
cy.findByText(/now you can see information/i);
cy.findByRole("textbox").type("connect n00dles{enter}");
cy.findByText(/currency has become digital/i);
cy.findByRole("textbox").type("analyze{enter}");
cy.findByText(/For this server, the required hacking skill/i);
cy.findByText(/Required number of open ports for NUKE/i);
cy.findByRole("textbox").type("run NUKE.exe{enter}");
cy.findByText(/gained root access to n00dles/i);
cy.findByRole("textbox").type("hack{enter}");
cy.findByText(/now attempting to hack the server/i);
cy.findByRole("button", { name: "Next" }).click();
cy.findByText(/hacking exp/i);
cy.findByRole("textbox", { timeout: 15_000 }).should("not.be.disabled").type("nano n00dles.script{enter}");
// monaco can take a bit
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type("while(true) {{}{enter}hack('n00dles');");
cy.findByRole("button", { name: /Save & Close/i }).click();
cy.findByText(/now we'll run the script/i);
cy.findByRole("textbox").type("free{enter}");
cy.findByText(/We have 4GB of free RAM on this machine/i);
cy.findByRole("textbox").type("run n00dles.script{enter}");
cy.findByText(/Your script is now running/i);
cy.findByRole("button", { name: "Active Scripts" }).click();
cy.findByText(/This page displays information about all of your scripts/i);
cy.findByRole("button", { name: "Terminal" }).click();
cy.findByText(/each active script contains logs/i);
cy.findByRole("textbox").type("tail n00dles.script{enter}");
cy.findByText(/The log for this script won't show much/i);
cy.findByRole("button", { name: "Next" }).click();
cy.findByText(/Hacking is not the only way to earn money/i);
cy.findByRole("button", { name: "Hacknet" }).click();
cy.findByText(/Here you can purchase new Hacknet Nodes/i);
cy.findByRole("button", { name: /Purchase Hacknet Node/ }).click();
cy.findByText(/You just purchased a Hacknet Node!/i);
cy.findByRole("button", { name: "City" }).click();
cy.findByText(/This page lists all of the different locations/i);
cy.findByRole("button", { name: "Tutorial" }).click();
cy.findByText(/a lot of different documentation about the game/i);
cy.findByRole("button", { name: "Finish Tutorial" }).click();
cy.findByText("Got it!").click();
cy.findByText(/Tutorial \(AKA Links to Documentation\)/i);
});
});
+22
View File
@@ -0,0 +1,22 @@
/// <reference types="cypress" />
// ***********************************************************
// This example plugins/index.js can be used to load plugins
//
// You can change the location of this file or turn off loading
// the plugins file with the 'pluginsFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/plugins-guide
// ***********************************************************
// This function is called when a project is opened or re-opened (e.g. due to
// the project's config changing)
/**
* @type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
// `config` is the resolved Cypress config
};
+1
View File
@@ -0,0 +1 @@
import "@testing-library/cypress/add-commands";
+9
View File
@@ -0,0 +1,9 @@
export {};
beforeEach(() => {
cy.visit("/");
cy.clearLocalStorage();
cy.window().then((win) => {
win.indexedDB.deleteDatabase("bitburnerSave");
});
});
+21
View File
@@ -0,0 +1,21 @@
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import "./globalHooks";
import "./commands";
// Alternatively you can use CommonJS syntax:
// require('./commands')
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],p=0,s=[];p<f.length;p++)i=f[p],u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(a&&a(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={1:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var a=c;r.push([863,0]),o()}({800:function(n,t,o){},802:function(n,t,o){},804:function(n,t,o){},806:function(n,t,o){},808:function(n,t,o){},810:function(n,t,o){},812:function(n,t,o){},814:function(n,t,o){},816:function(n,t,o){},818:function(n,t,o){},820:function(n,t,o){},822:function(n,t,o){},824:function(n,t,o){},826:function(n,t,o){},828:function(n,t,o){},830:function(n,t,o){},832:function(n,t,o){},834:function(n,t,o){},836:function(n,t,o){},838:function(n,t,o){},840:function(n,t,o){},842:function(n,t,o){},844:function(n,t,o){},846:function(n,t,o){},848:function(n,t,o){},850:function(n,t,o){},852:function(n,t,o){},854:function(n,t,o){},856:function(n,t,o){},858:function(n,t,o){},860:function(n,t,o){},863:function(n,t,o){"use strict";o.r(t);o(862),o(860),o(858),o(856),o(854),o(852),o(850),o(848),o(846),o(844),o(842),o(840),o(838),o(836),o(834),o(832),o(830),o(828),o(826),o(824),o(822),o(820),o(818),o(816),o(814),o(812),o(810),o(808),o(806),o(804),o(802),o(800)}}); !function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],a=0,s=[];a<f.length;a++)i=f[a],Object.prototype.hasOwnProperty.call(u,i)&&u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(p&&p(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={2:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var p=c;r.push([905,0]),o()}({905:function(n,t,o){"use strict";o.r(t);o(906),o(908),o(910),o(912),o(914),o(916),o(918),o(920),o(922),o(924),o(926),o(928),o(930),o(932),o(934),o(936),o(938),o(940),o(942),o(944),o(946),o(948),o(950),o(952),o(954),o(956),o(958),o(960),o(962),o(964),o(966),o(968),o(970)},908:function(n,t,o){},910:function(n,t,o){},912:function(n,t,o){},914:function(n,t,o){},916:function(n,t,o){},918:function(n,t,o){},920:function(n,t,o){},922:function(n,t,o){},924:function(n,t,o){},926:function(n,t,o){},928:function(n,t,o){},930:function(n,t,o){},932:function(n,t,o){},934:function(n,t,o){},936:function(n,t,o){},938:function(n,t,o){},940:function(n,t,o){},942:function(n,t,o){},944:function(n,t,o){},946:function(n,t,o){},948:function(n,t,o){},950:function(n,t,o){},952:function(n,t,o){},954:function(n,t,o){},956:function(n,t,o){},958:function(n,t,o){},960:function(n,t,o){},962:function(n,t,o){},964:function(n,t,o){},966:function(n,t,o){},968:function(n,t,o){},970:function(n,t,o){}});
//# sourceMappingURL=engineStyle.bundle.js.map //# sourceMappingURL=engineStyle.bundle.js.map
+689 -313
View File
File diff suppressed because it is too large Load Diff
+33 -70
View File
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -76,15 +76,15 @@ List of Factions and their Requirements
+---------------------+----------------+-----------------------------------------+-------------------------------+ +---------------------+----------------+-----------------------------------------+-------------------------------+
| Hacking | NiteSec | * Install a backdoor on the avmnite-02h | | | Hacking | NiteSec | * Install a backdoor on the avmnite-02h | |
| Groups | | server | | | Groups | | server | |
| | | * Home Computer RAM of at least 32GB | | | | | | |
+ +----------------+-----------------------------------------+-------------------------------+ + +----------------+-----------------------------------------+-------------------------------+
| | The Black Hand | * Install a backdoor on the I.I.I.I | | | | The Black Hand | * Install a backdoor on the I.I.I.I | |
| | | server | | | | | server | |
| | | * Home Computer RAM of at least 64GB | | | | | | |
+ +----------------+-----------------------------------------+-------------------------------+ + +----------------+-----------------------------------------+-------------------------------+
| | Bitrunners | * Install a backdoor on the run4theh111z| | | | Bitrunners | * Install a backdoor on the run4theh111z| |
| | | server | | | | | server | |
| | | * Home Computer RAM of at least 128GB | | | | | | |
+---------------------+----------------+-----------------------------------------+-------------------------------+ +---------------------+----------------+-----------------------------------------+-------------------------------+
| Megacorporations | ECorp | * Have 200k reputation with | | | Megacorporations | ECorp | * Have 200k reputation with | |
| | | the Corporation | | | | | the Corporation | |
+41 -24
View File
@@ -14,29 +14,46 @@ these for money or for faction reputation. To try and infiltrate a company,
visit a company through the 'World' menu. There will be an option that visit a company through the 'World' menu. There will be an option that
says 'Infiltrate Company'. says 'Infiltrate Company'.
When infiltrating a company, you must progress through clearance levels in When infiltrating a company you will be presented with short active challenges.
the facility. Every clearance level has some form of security that None of the challenges use the mouse.
you must get past. There are several forms of security, ranging from
high-tech security systems to armed guards. For each form of security,
there are a variety of options that you can choose to try and bypass
the security. Examples include hacking the security, engaging in combat,
assassination, or sneaking past the security. The chance to succeed for
each option is determined in part by your stats. So, for example,
trying to hack the security system relies on your hacking skill,
whereas trying to sneak past the security relies on your agility level.
The facility has a 'security level' that affects your chance of success The difficulty at the top lowers with better combat stats. It is not recommended
when trying to get past a clearance level. Every time you advance to the to attempt infiltrations above mid-normal.
next clearance level, the facility's security level will increase by a
fixed percentage. Furthermore the options you choose and whether you
succeed or fail will affect the security level as well. For example,
if you try to kill a security guard and fail, the security level will
increase by a lot. If you choose to sneak past security and succeed,
the security level will not increase at all.
Every 5 clearance levels, you will steal classified company secrets that * Most use spacebar as "action"
can be sold for money or faction reputation. However, in order to sell * Some use WASD or arrows interchangeably.
these secrets you must successfully escape the facility using the * A few others use the rest of the keyboard.
'Escape' option. Furthermore, companies have a max clearance level.
If you reach the max clearance level you will automatically escape the ** Slash when his guard is down! **
facility with all of your stolen secrets.
Press space when the guard is attacking you.
** Close the brackets **
Enter all the matching brackets in reverse order.
** Type it backward **
Type the words that are written backward.
** Say something nice about the guard. **
Use the arrows to find a compliment for the guard.
** Enter the Code! **
Match the arrows as they appears.
** Match the symbols! **
Move the cursor to the matching symbol and press space to confirm.
** Remember all the mines! **
At first the cursor cannot be moved, remember the positions of the X.
Then move the cursor and press space to mark the mines on the board.
** Cut the wires **
Follow the instructions and press the numbers 1 through 9 to cut the appropriate
wires.
+118 -8
View File
@@ -3,7 +3,117 @@
Changelog Changelog
========= =========
v0.52.8 - 2021-07-23 Fixing the previous patch tbh ROUND 2 (hydroflame) v0.53.0 - 2021-09-09 Way too many things. (hydroflame & community)
-------------------------------------------
** Dev? **
* The entire codebase has been run through a code prettifier, hurray for consistency. (@threehams)
* Lots of test. (@threehams)
* Massive improvements to build speed. (@threehams)
* Dev notes: This won't affect any players but is immensely useful for me.
** Hacknet **
* Converted to ts/react
** Resleeving **
* Converted to ts/react
** Sleeves **
* Converted to ts/react. The ui should also have a better feel.
* Fixed a bug that allowed players to recover shock much faster than intended.
** BN10 **
* You have access to Sleeves right away
* In BN10 Sleeves start with 75 shock and 25 sync.
** MathJax **
* Several tooltips have been updated to display the relevant formula in Mathjax, e.g. Favor and reputation
** Corporation **
* Completely rewritten in React. Paving the way for bigger change.
* Smart Supply is now smarter and won't deadlock the warehouse. It is also more configurable.
* Several UI fixes.
** Bladeburner **
* Action count is no longer decided when joining the Bladeburners. Experiences for all players should be more similar.
** Factions **
* No factions have home computer ram requirement. This caused some confusion for new players.
** Gang **
* Made it clear when there's a new equipment coming up.
** Netscript **
* getActionCountRemaining now returns Infinity for bladeburner general actions. (@brubsy)
* getActionEstimatedSuccessChance now returns 100% for Diplomacy and Hyperbolic Regeneration Chamber. (@brubsy)
* disableLog('ALL') now disables all logs individually, meaning you can re-enable the ones you want after. (@Cass)
* getPlayer returns numPeopleKilled.
* Dynamic RAM calculation errors have a better error message.
* Hide some functions from autocomplete.
* Added getAugmentationPrice, getAugmentationRepReq, deprecated getAugmentationCost. (@TempFound)
* Fixed bug where some crime API would return "assassinate" when that's not accepted in other functions.
** Coding Contract **
* Spiralize Matrix is easier to read.
** Misc. **
* The world map is now used in sleeve travel and bladeburner travel.
* noselect a bunch of stuff.
* Ascii maps letters are more contrasting
* Updated documentation for infiltration.
* Most money costs in the game will turn grey/cyan when you don't have enough money.
* Donation textbox has better look & feel.
* Tech vendors ram & cores buttons have better look and feels.
* cores cost modified to be a formula instead of a semi-random array of numbers.
* Tech vendors now give a hint about where to get bigger servers.
* logboxes now displays whitespaces exactly. (@Cass)
* nerf noodle bar
v0.52.9 - 2021-08-27 Less lag! (hydroflame & community)
-------------------------------------------
** Active Scripts page **
* Now less laggy, has pagination.
** File diagnostic **
* Added a popup found under options that shows the files you own and how
large they are. This help find bugs and leftover massive logs files.
** Corporation **
* Added safeguard against a very specific bug that causes NaN money. I'm
still not sure what the root cause is but it should prevent corp from
breaking.
** Netscript **
* tprintf is a new function that doesn't print the filename.
** Misc. **
* Infiltration kills you if you try to automate it. (@threehams)
* Fix beautify button not working
* Added bladeburner_analysis_mult to getPlayer() (@brubsby)
* Fixed joining bladeburner via netscript functions. (@omuretsu)
* All bladeburner actions are click-to-copy
* nerf noodle bar
v0.52.8 - 2021-08-23 Fixing the previous patch tbh ROUND 2 (hydroflame)
------------------------------------------- -------------------------------------------
** Script editor ** ** Script editor **
@@ -23,7 +133,7 @@ v0.52.8 - 2021-07-23 Fixing the previous patch tbh ROUND 2 (hydroflame)
* Removed some debug console.log * Removed some debug console.log
* nerf noodle bar * nerf noodle bar
v0.52.7 - 2021-07-21 Fixing the previous patch tbh (hydroflame) v0.52.7 - 2021-08-21 Fixing the previous patch tbh (hydroflame)
------------------------------------------- -------------------------------------------
** Netscript ** ** Netscript **
@@ -51,7 +161,7 @@ v0.52.7 - 2021-07-21 Fixing the previous patch tbh (hydroflame)
* Fix netscript write. * Fix netscript write.
* nerf noodle bar * nerf noodle bar
v0.52.6 - 2021-07-21 Logboxes and VS-code (hydroflame) v0.52.6 - 2021-08-21 Logboxes and VS-code (hydroflame)
------------------------------------------- -------------------------------------------
** Text Editor ** ** Text Editor **
@@ -73,7 +183,7 @@ v0.52.6 - 2021-07-21 Logboxes and VS-code (hydroflame)
* Remove dollar sign in blade contract UI element * Remove dollar sign in blade contract UI element
* nerf noodle bar * nerf noodle bar
v0.52.5 - 2021-07-19 CPU cores are useful!? (hydroflame) v0.52.5 - 2021-08-19 CPU cores are useful!? (hydroflame)
------------------------------------------- -------------------------------------------
** Terminal ** ** Terminal **
@@ -99,7 +209,7 @@ v0.52.5 - 2021-07-19 CPU cores are useful!? (hydroflame)
* Fix weird scrolling in the new Bladeburner React console. * Fix weird scrolling in the new Bladeburner React console.
* nerf noodle bar * nerf noodle bar
v0.52.4 - 2021-07-19 Bladeburner in React (hydroflame) v0.52.4 - 2021-08-19 Bladeburner in React (hydroflame)
------------------------------------------- -------------------------------------------
** Bladeburner ** ** Bladeburner **
@@ -121,7 +231,7 @@ v0.52.4 - 2021-07-19 Bladeburner in React (hydroflame)
* Linting (no one cares except the dev) * Linting (no one cares except the dev)
* nerf noodle bar * nerf noodle bar
v0.52.3 - 2021-07-15 Gangs were OP (hydroflame) v0.52.3 - 2021-08-15 Gangs were OP (hydroflame)
------------------------------------------- -------------------------------------------
** Gang ** ** Gang **
@@ -144,7 +254,7 @@ v0.52.3 - 2021-07-15 Gangs were OP (hydroflame)
* Factions list screen converted to React. * Factions list screen converted to React.
* nerf noodle bar * nerf noodle bar
v0.52.2 - 2021-07-15 Oh yeah, BN11 is a thing (drunk hydroflame tbh) v0.52.2 - 2021-08-15 Oh yeah, BN11 is a thing (drunk hydroflame tbh)
------------------------------------------- -------------------------------------------
** Source-Files ** ** Source-Files **
@@ -162,7 +272,7 @@ v0.52.2 - 2021-07-15 Oh yeah, BN11 is a thing (drunk hydroflame tbh)
* nerf noodle bar * nerf noodle bar
v0.52.1 - 2021-07-10 bugfixing (hydroflame & community) v0.52.1 - 2021-08-10 bugfixing (hydroflame & community)
------------------------------------------- -------------------------------------------
**Misc.** **Misc.**
+2 -2
View File
@@ -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.52' version = '0.53'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = '0.52.8' release = '0.53.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.
@@ -6,8 +6,6 @@ getGrowTime() Netscript Function
:RAM cost: 0.05 GB :RAM cost: 0.05 GB
:param string hostname: Hostname of target server. :param string hostname: Hostname of target server.
:param number hackLvl: Optional hacking level for the calculation. Defaults
to player's current hacking level.
:returns: seconds it takes to execute :doc:`grow<grow>` on that server. :returns: seconds it takes to execute :doc:`grow<grow>` on that server.
The function takes in an optional ``hackLvl`` parameter that can be The function takes in an optional ``hackLvl`` parameter that can be
@@ -5,8 +5,6 @@ getHackTime() Netscript Function
:RAM cost: 0.05 GB :RAM cost: 0.05 GB
:param string hostname: Hostname of target server. :param string hostname: Hostname of target server.
:param number hackLvl: Optional hacking level for the calculation. Defaults
to player's current hacking level.
:returns: seconds it takes to execute :doc:`hack<hack>` on that server. :returns: seconds it takes to execute :doc:`hack<hack>` on that server.
The function takes in an optional ``hackLvl`` parameter that can be The function takes in an optional ``hackLvl`` parameter that can be
@@ -5,8 +5,6 @@ getWeakenTime() Netscript Function
:RAM cost: 0.05 GB :RAM cost: 0.05 GB
:param string hostname: Hostname of target server. :param string hostname: Hostname of target server.
:param number hackLvl: Optional hacking level for the calculation. Defaults
to player's current hacking level.
:returns: seconds it takes to execute the :doc:`weaken<weaken>` Netscript :returns: seconds it takes to execute the :doc:`weaken<weaken>` Netscript
function on the target server. function on the target server.
@@ -0,0 +1,17 @@
tprint() Netscript Function
===========================
.. js:function:: tprintf(format, args...)
:RAM cost: 0 GB
:param format: Format of the string to be printed.
:param args: Values to be formatted
Prints a raw formatted string to the terminal.
Example:
.. code-block:: javascript
tprintf("Hello world!"); // Prints "Hello world!" to the terminal.
tprintf("Hello %s", "world!"); // Prints "Hello world!" to the terminal.
@@ -1,7 +1,7 @@
getTrainingMul() Netscript Function getTrainingMult() Netscript Function
=================================== ===================================
.. js:function:: getTrainingMul() .. js:function:: getTrainingMult()
:RAM cost: 0 GB :RAM cost: 0 GB
:returns: The multiplier to training that hash upgrades provide to the player. :returns: The multiplier to training that hash upgrades provide to the player.
@@ -19,6 +19,7 @@ This includes information such as function signatures, what they do, and their r
sleep() <basicfunctions/sleep> sleep() <basicfunctions/sleep>
print() <basicfunctions/print> print() <basicfunctions/print>
tprint() <basicfunctions/tprint> tprint() <basicfunctions/tprint>
tprintf() <basicfunctions/tprint>
clearLog() <basicfunctions/clearLog> clearLog() <basicfunctions/clearLog>
disableLog() <basicfunctions/disableLog> disableLog() <basicfunctions/disableLog>
enableLog() <basicfunctions/enableLog> enableLog() <basicfunctions/enableLog>
@@ -55,8 +55,10 @@ The player has access to all of these functions while in BitNode-4. Completing B
getOwnedAugmentations() <singularityfunctions/getOwnedAugmentations> getOwnedAugmentations() <singularityfunctions/getOwnedAugmentations>
getOwnedSourceFiles() <singularityfunctions/getOwnedSourceFiles> getOwnedSourceFiles() <singularityfunctions/getOwnedSourceFiles>
getAugmentationsFromFaction() <singularityfunctions/getAugmentationsFromFaction> getAugmentationsFromFaction() <singularityfunctions/getAugmentationsFromFaction>
getAugmentationPrereq() <singularityfunctions/getAugmentationPrereq>
getAugmentationCost() <singularityfunctions/getAugmentationCost> getAugmentationCost() <singularityfunctions/getAugmentationCost>
getAugmentationPrereq() <singularityfunctions/getAugmentationPrereq>
getAugmentationPrice() <singularityfunctions/getAugmentationPrice>
getAugmentationRepReq() <singularityfunctions/getAugmentationRepReq>
getAugmentationStats() <singularityfunctions/getAugmentationStats> getAugmentationStats() <singularityfunctions/getAugmentationStats>
purchaseAugmentation() <singularityfunctions/purchaseAugmentation> purchaseAugmentation() <singularityfunctions/purchaseAugmentation>
installAugmentations() <singularityfunctions/installAugmentations> installAugmentations() <singularityfunctions/installAugmentations>
@@ -3,12 +3,15 @@ getAugmentationCost() Netscript Function
.. js:function:: getAugmentationCost(augName) .. js:function:: getAugmentationCost(augName)
.. warning:: This function is deprecated.
:RAM cost: 5 GB :RAM cost: 5 GB
:param string augName: Name of Augmentation. case-sensitive.
:param string augName: Name of Augmentation. CASE-SENSITIVE
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function. If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
This function returns an array with two elements that gives the cost for the specified Augmentation. This function returns an array with two elements that gives the cost for the specified Augmentation.
The first element in the returned array is the reputation requirement of the Augmentation, and the second element is the money cost. The first element in the returned array is the reputation requirement of the Augmentation, and the second element is the money cost.
If an invalid Augmentation name is passed in for the ``augName`` argument, this function will return the array [-1, -1]. If an invalid Augmentation name is passed in for the ``augName`` argument, this function will throw a runtime error.
@@ -12,4 +12,4 @@ getAugmentationPrereq() Netscript Function
This function returns an array with the names of the prerequisite Augmentation(s) for the specified Augmentation. This function returns an array with the names of the prerequisite Augmentation(s) for the specified Augmentation.
If there are no prerequisites, a blank array is returned. If there are no prerequisites, a blank array is returned.
If an invalid Augmentation name is passed in for the *augName* argument, this function will return a blank array. If an invalid Augmentation name is passed in for the *augName* argument, this function will throw a runtime error.
@@ -0,0 +1,14 @@
getAugmentationPrice() Netscript Function
==========================================
.. js:function:: getAugmentationPrice(augName)
:RAM cost: 2.5 GB
:param string augName: Name of Augmentation. CASE-SENSITIVE
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
This function returns the money cost for the specified Augmentation.
If an invalid Augmentation name is passed in for the *augName* argument, this function will throw a runtime error.
@@ -0,0 +1,14 @@
getAugmentationRepReq() Netscript Function
==========================================
.. js:function:: getAugmentationRepReq(augName)
:RAM cost: 2.5 GB
:param string augName: Name of Augmentation. CASE-SENSITIVE
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
This function returns the reputation requirement for the specified Augmentation.
If an invalid Augmentation name is passed in for the *augName* argument, this function will throw a runtime error.
+43 -33
View File
@@ -21,10 +21,11 @@ body {
background-color: #eeeeec; background-color: #eeeeec;
} }
/* Page layout */ /* Page layout */
div.header, div.content, div.footer { div.header,
div.content,
div.footer {
width: 70em; width: 70em;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@@ -35,13 +36,13 @@ div.header-wrapper {
border-bottom: 3px solid #2e3436; border-bottom: 3px solid #2e3436;
} }
/* Default body styles */ /* Default body styles */
a { a {
color: #ce5c00; color: #ce5c00;
} }
div.bodywrapper a, div.footer a { div.bodywrapper a,
div.footer a {
text-decoration: underline; text-decoration: underline;
} }
@@ -69,11 +70,14 @@ div.bodywrapper a, div.footer a {
margin-left: 1.5em; margin-left: 1.5em;
} }
h1, h2, h3, h4 { h1,
h2,
h3,
h4 {
font-family: "Georgia", "Times New Roman", serif; font-family: "Georgia", "Times New Roman", serif;
font-weight: normal; font-weight: normal;
color: #3465a4; color: #3465a4;
margin-bottom: .8em; margin-bottom: 0.8em;
} }
h1 { h1 {
@@ -81,14 +85,14 @@ h1 {
} }
h2 { h2 {
padding-bottom: .5em; padding-bottom: 0.5em;
border-bottom: 1px solid #3465a4; border-bottom: 1px solid #3465a4;
} }
a.headerlink { a.headerlink {
visibility: hidden; visibility: hidden;
color: #dddddd; color: #dddddd;
padding-left: .3em; padding-left: 0.3em;
} }
h1:hover > a.headerlink, h1:hover > a.headerlink,
@@ -120,7 +124,8 @@ p.admonition-title {
font-weight: bold; font-weight: bold;
} }
dt:target, .highlighted { dt:target,
.highlighted {
background-color: #fbe54e; background-color: #fbe54e;
} }
@@ -135,8 +140,8 @@ div.header .headertitle {
font-family: "Georgia", "Times New Roman", serif; font-family: "Georgia", "Times New Roman", serif;
font-weight: normal; font-weight: normal;
font-size: 180%; font-size: 180%;
letter-spacing: .08em; letter-spacing: 0.08em;
margin-bottom: .8em; margin-bottom: 0.8em;
} }
div.header .headertitle a { div.header .headertitle a {
@@ -149,7 +154,7 @@ div.header div.rel {
div.header div.rel a { div.header div.rel a {
color: #fcaf3e; color: #fcaf3e;
letter-spacing: .1em; letter-spacing: 0.1em;
text-transform: uppercase; text-transform: uppercase;
} }
@@ -161,7 +166,6 @@ img.logo {
border: 0; border: 0;
} }
/* Content */ /* Content */
div.content-wrapper { div.content-wrapper {
background-color: white; background-color: white;
@@ -190,7 +194,7 @@ div.document ul {
div.document dd { div.document dd {
margin-left: 1.2em; margin-left: 1.2em;
margin-top: .4em; margin-top: 0.4em;
margin-bottom: 1em; margin-bottom: 1em;
} }
@@ -206,13 +210,13 @@ div.document div.highlight {
background-color: #eeeeec; background-color: #eeeeec;
border-top: 2px solid #dddddd; border-top: 2px solid #dddddd;
border-bottom: 2px solid #dddddd; border-bottom: 2px solid #dddddd;
margin-top: .8em; margin-top: 0.8em;
margin-bottom: .8em; margin-bottom: 0.8em;
} }
div.document div.literal-block-wrapper { div.document div.literal-block-wrapper {
margin-top: .8em; margin-top: 0.8em;
margin-bottom: .8em; margin-bottom: 0.8em;
} }
div.document div.literal-block-wrapper div.highlight { div.document div.literal-block-wrapper div.highlight {
@@ -228,11 +232,11 @@ div.document div.code-block-caption span.caption-text {
} }
div.document h2 { div.document h2 {
margin-top: .7em; margin-top: 0.7em;
} }
div.document p { div.document p {
margin-bottom: .5em; margin-bottom: 0.5em;
} }
div.document li.toctree-l1 { div.document li.toctree-l1 {
@@ -265,7 +269,6 @@ div.document ol {
margin: 1.5em; margin: 1.5em;
} }
/* Sidebar */ /* Sidebar */
div.sidebar { div.sidebar {
@@ -273,7 +276,7 @@ div.sidebar {
position: fixed; position: fixed;
right: 10%; right: 10%;
height: 75%; height: 75%;
font-size: .9em; font-size: 0.9em;
overflow-y: auto; overflow-y: auto;
} }
/* /*
@@ -284,11 +287,13 @@ div.sidebar {
} }
*/ */
div.sidebar a, div.header a { div.sidebar a,
div.header a {
text-decoration: none; text-decoration: none;
} }
div.sidebar a:hover, div.header a:hover { div.sidebar a:hover,
div.header a:hover {
text-decoration: underline; text-decoration: underline;
} }
@@ -296,7 +301,7 @@ div.sidebar h3 {
color: #2e3436; color: #2e3436;
text-transform: uppercase; text-transform: uppercase;
font-size: 130%; font-size: 130%;
letter-spacing: .1em; letter-spacing: 0.1em;
} }
div.sidebar ul { div.sidebar ul {
@@ -308,7 +313,7 @@ div.sidebar li.toctree-l1 a {
padding: 1px; padding: 1px;
border: 1px solid #dddddd; border: 1px solid #dddddd;
background-color: #eeeeec; background-color: #eeeeec;
margin-bottom: .4em; margin-bottom: 0.4em;
padding-left: 3px; padding-left: 3px;
color: #2e3436; color: #2e3436;
} }
@@ -347,7 +352,6 @@ div.sidebar input[type="submit"] {
width: 30px; width: 30px;
} }
/* Footer */ /* Footer */
div.footer-wrapper { div.footer-wrapper {
@@ -358,7 +362,8 @@ div.footer-wrapper {
min-height: 80px; min-height: 80px;
} }
div.footer, div.footer a { div.footer,
div.footer a {
color: #888a85; color: #888a85;
} }
@@ -370,22 +375,27 @@ div.footer .left {
text-transform: uppercase; text-transform: uppercase;
} }
/* Styles copied from basic theme */ /* Styles copied from basic theme */
img.align-left, .figure.align-left, object.align-left { img.align-left,
.figure.align-left,
object.align-left {
clear: left; clear: left;
float: left; float: left;
margin-right: 1em; margin-right: 1em;
} }
img.align-right, .figure.align-right, object.align-right { img.align-right,
.figure.align-right,
object.align-right {
clear: right; clear: right;
float: right; float: right;
margin-left: 1em; margin-left: 1em;
} }
img.align-center, .figure.align-center, object.align-center { img.align-center,
.figure.align-center,
object.align-center {
display: block; display: block;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
@@ -512,7 +522,7 @@ table.modindextable td {
.viewcode-back { .viewcode-back {
float: right; float: right;
font-family:: "Verdana", Arial, sans-serif; font-family: "Verdana", Arial, sans-serif;
} }
div.viewcode-block:target { div.viewcode-block:target {
+161 -137
View File
@@ -1,33 +1,44 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8"/>
<title>Bitburner</title> <title>Bitburner</title>
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png"> <link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png"/>
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png"/>
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png"> <link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png"/>
<link rel="manifest" href="dist/site.webmanifest"> <link rel="manifest" href="dist/site.webmanifest"/>
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000"> <link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000"/>
<meta name="apple-mobile-web-app-title" content="Bitburner"> <meta name="apple-mobile-web-app-title" content="Bitburner"/>
<meta name="application-name" content="Bitburner"> <meta name="application-name" content="Bitburner"/>
<meta name="msapplication-TileColor" content="#000000"> <meta name="msapplication-TileColor" content="#000000"/>
<meta name="msapplication-config" content="dist/browserconfig.xml"> <meta name="msapplication-config" content="dist/browserconfig.xml"/>
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff"/>
<!-- Google Analytics --> <!-- Google Analytics -->
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function (i, s, o, g, r, a, m) {
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), i["GoogleAnalyticsObject"] = r;
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) (i[r] =
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); i[r] ||
function () {
(i[r].q = i[r].q || []).push(arguments);
}),
(i[r].l = 1 * new Date());
(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0]);
a.async = 1;
a.src = g;
m.parentNode.insertBefore(a, m);
})(window, document, "script", "https://www.google-analytics.com/analytics.js", "ga");
</script> </script>
<script> <script>
ga('create', 'UA-100157497-1', 'auto'); ga("create", "UA-100157497-1", "auto");
ga('send', 'pageview'); ga("send", "pageview");
</script> </script>
<link rel="shortcut icon" href="favicon.ico"><link href="dist/vendor.css" rel="stylesheet"><link href="dist/engineStyle.css" rel="stylesheet"></head> <link rel="shortcut icon" href="favicon.ico"><link href="dist/vendor.css" rel="stylesheet"><link href="dist/engineStyle.css" rel="stylesheet"></head>
<body> <body>
<div id="entire-game-container" style="visibility:hidden;"> <div id="entire-game-container" style="visibility: hidden">
<div id="mainmenu-container"> <div id="mainmenu-container">
<!-- Main menu --> <!-- Main menu -->
<ul id="mainmenu" class="mainmenu noscrollbar"> <ul id="mainmenu" class="mainmenu noscrollbar">
@@ -61,7 +72,9 @@
<span id="factions-notification" class="notification-off"> </span> <span id="factions-notification" class="notification-off"> </span>
</li> </li>
<li id="augmentations-tab" class="mainmenu-accordion-panel noselect"> <li id="augmentations-tab" class="mainmenu-accordion-panel noselect">
<button id="augmentations-menu-link" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"> Augmentations </button> <button id="augmentations-menu-link" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
Augmentations
</button>
<span id="augmentations-notification" class="notification-off"> </span> <span id="augmentations-notification" class="notification-off"> </span>
</li> </li>
<li id="hacknet-nodes-tab" class="mainmenu-accordion-panel noselect"> <li id="hacknet-nodes-tab" class="mainmenu-accordion-panel noselect">
@@ -117,20 +130,22 @@
<div id="script-editor-container" class="generic-menupage-container"> <div id="script-editor-container" class="generic-menupage-container">
<div id="script-editor-wrapper"> <div id="script-editor-wrapper">
<div id="script-editor-filename-wrapper"> <div id="script-editor-filename-wrapper">
<p id="script-editor-filename-tag"> <strong style="background-color:#555;">Script name: </strong></p> <p id="script-editor-filename-tag">
<strong style="background-color: #555">Script name: </strong>
</p>
<input id="script-editor-filename" type="text" maxlength="100" tabindex="1"/> <input id="script-editor-filename" type="text" maxlength="100" tabindex="1"/>
</div> </div>
<div id="monaco-editor"></div> <div id="monaco-editor"></div>
<div id="script-editor-buttons-wrapper"></div>
<div id="script-editor-buttons-wrapper"></div> <!-- Buttons below script editor --> <!-- Buttons below script editor -->
</div> <!-- End wrapper --> </div>
<!-- End wrapper -->
<div id="script-editor-options-panel"> <div id="script-editor-options-panel">
<h1 style="color:white;"> Script Editor Options </h1> <h1 style="color: white">Script Editor Options</h1>
<fieldset> <fieldset>
<label for="script-editor-option-editor">Editor</label> <label for="script-editor-option-editor">Editor</label>
<select id="script-editor-option-editor" class="dropdown"> <select id="script-editor-option-editor" class="dropdown">
@@ -151,30 +166,31 @@
<fieldset> <fieldset>
<label for="script-editor-option-highlightactiveline">Highlight Active Line</label> <label for="script-editor-option-highlightactiveline">Highlight Active Line</label>
<input type="checkbox" class="optionCheckbox" name="script-editor-option-highlightactiveline" id="script-editor-option-highlightactiveline" checked> <input type="checkbox" class="optionCheckbox" name="script-editor-option-highlightactiveline" id="script-editor-option-highlightactiveline" checked/>
</fieldset> </fieldset>
<fieldset> <fieldset>
<label for="script-editor-option-showinvisibles">Show Invisibles</label> <label for="script-editor-option-showinvisibles">Show Invisibles</label>
<input type="checkbox" class="optionCheckbox" name="script-editor-option-showinvisibles" id="script-editor-option-showinvisibles"> <input type="checkbox" class="optionCheckbox" name="script-editor-option-showinvisibles" id="script-editor-option-showinvisibles"/>
</fieldset> </fieldset>
<fieldset> <fieldset>
<label for="script-editor-option-usesofttab">Use Soft Tab</label> <label for="script-editor-option-usesofttab">Use Soft Tab</label>
<input type="checkbox" class="optionCheckbox" name="script-editor-option-usesofttab" id="script-editor-option-usesofttab" checked> <input type="checkbox" class="optionCheckbox" name="script-editor-option-usesofttab" id="script-editor-option-usesofttab" checked/>
</fieldset> </fieldset>
<fieldset id="script-editor-option-flex1-fieldset"></fieldset> <fieldset id="script-editor-option-flex1-fieldset"></fieldset>
<fieldset id="script-editor-option-flex2-fieldset"></fieldset> <fieldset id="script-editor-option-flex2-fieldset"></fieldset>
<fieldset id="script-editor-option-flex3-fieldset"></fieldset> <fieldset id="script-editor-option-flex3-fieldset"></fieldset>
<fieldset id="script-editor-option-flex4-fieldset"></fieldset> <fieldset id="script-editor-option-flex4-fieldset"></fieldset>
</div>
</div> <!-- End script editor options panel --> <!-- End script editor options panel -->
<!-- TODO(hydroflame): remove this once Monaco is implemented --> <!-- TODO(hydroflame): remove this once Monaco is implemented -->
<div id="ace-editor" style="display: none"></div> <div id="ace-editor" style="display: none"></div>
<form id="codemirror-form-wrapper" style="display: none"><textarea id="codemirror-editor"></textarea></form> <form id="codemirror-form-wrapper" style="display: none">
<textarea id="codemirror-editor"></textarea>
</form>
<div id="codemirror-vim-command-display-wrapper" style="display: none"> <div id="codemirror-vim-command-display-wrapper" style="display: none">
Key Buffer: <span id="codemirror-vim-command-display"></span> Key Buffer: <span id="codemirror-vim-command-display"></span>
</div> </div>
@@ -184,7 +200,8 @@
<div id="terminal-container"> <div id="terminal-container">
<table id="terminal"> <table id="terminal">
<tr id="terminal-input"> <tr id="terminal-input">
<td id="terminal-input-td" tabindex="2">$ <td id="terminal-input-td" tabindex="2">
$
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;" autocomplete="off"/> <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;" autocomplete="off"/>
</td> </td>
</tr> </tr>
@@ -198,15 +215,19 @@
<!-- Active scripts info page --> <!-- Active scripts info page -->
<div id="active-scripts-container" class="generic-menupage-container"> <div id="active-scripts-container" class="generic-menupage-container">
<p id="active-scripts-text"> This page displays a list of all of your scripts that are currently running across every machine. It also <p id="active-scripts-text">
provides information about each script's production. The scripts are categorized by the hostname of the servers on which This page displays a list of all of your scripts that are currently running across every machine. It also
they are running. </p> provides information about each script's production. The scripts are categorized by the hostname of the
<p id="active-scripts-total-prod">Total online production of servers on which they are running.
Active scripts: <span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br/> </p>
Total online production since last Aug installation: <span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span> <p id="active-scripts-total-prod">
(<span class="money-gold"><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span>)</p> Total online production of Active scripts:
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none;"> <span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br/>
</ul> Total online production since last Aug installation:
<span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span>
(<span class="money-gold"><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span>)
</p>
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none"></ul>
</div> </div>
<!-- Hacknet Nodes --> <!-- Hacknet Nodes -->
@@ -218,8 +239,8 @@
<div id="create-program-container" class="generic-menupage-container"> <div id="create-program-container" class="generic-menupage-container">
<p id="create-program-page-text"> <p id="create-program-page-text">
This page displays any programs that you are able to create. Writing the code for a program takes time, which This page displays any programs that you are able to create. Writing the code for a program takes time, which
can vary based on how complex the program is. If you are working on creating a program you can cancel can vary based on how complex the program is. If you are working on creating a program you can cancel at any
at any time. Your progress will be saved and you can continue later. time. Your progress will be saved and you can continue later.
</p> </p>
<ul id="create-program-list"></ul> <ul id="create-program-list"></ul>
@@ -237,50 +258,42 @@
<!-- Milestones content --> <!-- Milestones content -->
<div id="milestones-container" class="generic-menupage-container"></div> <div id="milestones-container" class="generic-menupage-container"></div>
<!-- Bladeburner -->
<div id="bladeburner-container" class="generic-menupage-container"></div>
<!-- Tutorial content --> <!-- Tutorial content -->
<div id="tutorial-container" class="generic-menupage-container"> <div id="tutorial-container" class="generic-menupage-container">
<h1>Tutorial (AKA Links to Documentation)</h1> <h1>Tutorial (AKA Links to Documentation)</h1>
<a id="tutorial-getting-started-link" class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"> <a id="tutorial-getting-started-link" class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html">
Getting Started</a><br><br> Getting Started</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html">
Servers & Networking</a><br><br> Servers & Networking</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html">
Hacking</a><br><br> Hacking</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html">
Scripts</a><br><br> Scripts</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
Netscript Programming Language</a><br><br> Netscript Programming Language</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html">
Traveling</a><br><br> Traveling</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html">
Companies</a><br><br> Companies</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html">
Infiltration</a><br><br> Infiltration</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html">
Factions</a><br><br> Factions</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html">
Augmentations</a><br><br> Augmentations</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html"> <a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
Keyboard Shortcuts</a> Keyboard Shortcuts</a>
</div> </div>
<!-- Location (visiting a location in World) --> <!-- Location (visiting a location in World) -->
<div id="location-container" class="generic-menupage-container"> <div id="location-container" class="generic-menupage-container"></div>
</div> <div id="infiltration-container" class="generic-fullscreen-container"></div>
<div id="stock-market-container" class="generic-menupage-container"></div>
<div id="infiltration-container" class="generic-fullscreen-container"> <div id="bladeburner-container" class="generic-menupage-container"></div>
</div> <div id="resleeve-container" class="generic-menupage-container"></div>
<div id="gang-container" class="generic-menupage-container"></div>
<div id="stock-market-container" class="generic-menupage-container"> <div id="corporation-container" class="generic-menupage-container"></div>
<!-- React Component --> <div id="sleeves-container" class="generic-menupage-container"></div>
</div>
<div id="gang-container" class="generic-menupage-container">
<!-- React Component -->
</div>
<!-- Generic Yes/No Pop Up box --> <!-- Generic Yes/No Pop Up box -->
<div id="yes-no-box-container" class="popup-box-container"> <div id="yes-no-box-container" class="popup-box-container">
@@ -307,7 +320,8 @@
<p id="faction-invitation-box-text"></p> <p id="faction-invitation-box-text"></p>
<p id="faction-invitation-box-message"></p> <p id="faction-invitation-box-message"></p>
<p id="faction-invitation-box-warning"> <p id="faction-invitation-box-warning">
Would you like to join? <br/> <br/> Would you like to join? <br/>
<br/>
Warning: Joining this faction may prevent you from joining other factions during this run! Warning: Joining this faction may prevent you from joining other factions during this run!
</p> </p>
<button id="faction-invitation-box-yes" class="popup-box-button">Join!</button> <button id="faction-invitation-box-yes" class="popup-box-button">Join!</button>
@@ -320,23 +334,25 @@
<div id="infiltration-box-content" class="popup-box-content"> <div id="infiltration-box-content" class="popup-box-content">
<p id="infiltration-box-text"></p> <p id="infiltration-box-text"></p>
<button id="infiltration-box-sell" class="a-link-button"> Sell on Black Market </button> <br/><br/> <button id="infiltration-box-sell" class="a-link-button">Sell on Black Market</button>
<select id="infiltration-faction-select" class="dropdown"> </select> <br/> <br/><br/>
<select id="infiltration-faction-select" class="dropdown"></select>
<br/>
<button id="infiltration-box-faction" class="a-link-button">Give to Faction for Reputation</button> <button id="infiltration-box-faction" class="a-link-button">Give to Faction for Reputation</button>
</div> </div>
</div> </div>
<!-- Mission container --> <!-- Mission container -->
<div id="mission-container" class="generic-fullscreen-container"> <div id="mission-container" class="generic-fullscreen-container"></div>
</div>
<!-- Work in progress screen --> <!-- Work in progress screen -->
<div id="work-in-progress-container" class="generic-fullscreen-container"> <div id="work-in-progress-container" class="generic-fullscreen-container">
<p id="work-in-progress-text"></p> <p id="work-in-progress-text"></p>
<button id="work-in-progress-cancel-button" class="work-button">Cancel Work</button> <button id="work-in-progress-cancel-button" class="work-button">Cancel Work</button>
<button id="work-in-progress-something-else-button" class="work-button"> Do something else simultaneously </button> <button id="work-in-progress-something-else-button" class="work-button">
Do something else simultaneously
</button>
</div> </div>
<!-- Red Pill Container --> <!-- Red Pill Container -->
@@ -386,42 +402,39 @@
<fieldset> <fieldset>
<label for="settingsNSExecTimeRangeVal" class="tooltip">Netscript exec time:&nbsp; <label for="settingsNSExecTimeRangeVal" class="tooltip">Netscript exec time:&nbsp;
<span class="tooltiptext"> <span class="tooltiptext">
The minimum number of milliseconds it takes to execute an operation in Netscript. The minimum number of milliseconds it takes to execute an operation in Netscript. Setting this too low
Setting this too low can result in poor performance if you have many scripts running. can result in poor performance if you have many scripts running. The default value is 25ms.
The default value is 25ms.
</span> </span>
</label> </label>
<input class="optionRange" type="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25"/> <input class="optionRange" type="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25"/>
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em> <em id="settingsNSExecTimeRangeValLabel" style="font-style: normal"></em>
</fieldset> </fieldset>
<!-- Log capacity --> <!-- Log capacity -->
<fieldset> <fieldset>
<label for="settingsNSLogRangeVal" class="tooltip">Netscript log size:&nbsp;&nbsp; <label for="settingsNSLogRangeVal" class="tooltip">Netscript log size:&nbsp;&nbsp;
<span class="tooltiptext"> <span class="tooltiptext">
The maximum number of lines a script's logs can hold. Setting this too high The maximum number of lines a script's logs can hold. Setting this too high can cause the game to use
can cause the game to use a lot of memory if you have many scripts running. a lot of memory if you have many scripts running. The default value is 50.
The default value is 50.
</span> </span>
</label> </label>
<input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"/> <input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"/>
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em> <em id="settingsNSLogRangeValLabel" style="font-style: normal"></em>
</fieldset> </fieldset>
<!-- Port capacity --> <!-- Port capacity -->
<fieldset> <fieldset>
<label for="settingsNSPortRangeVal" class="tooltip">Netscript port size:&nbsp; <label for="settingsNSPortRangeVal" class="tooltip">Netscript port size:&nbsp;
<span class="tooltiptext"> <span class="tooltiptext">
The maximum number of entries that can be written to a port using Netscript's The maximum number of entries that can be written to a port using Netscript's write() function.
write() function. Setting this too high can cause the game to use a lot of memory. Setting this too high can cause the game to use a lot of memory. The default value is 50.
The default value is 50.
</span> </span>
</label> </label>
<input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"/> <input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"/>
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em> <em id="settingsNSPortRangeValLabel" style="font-style: normal"></em>
</fieldset> </fieldset>
<!-- Autosave Interval --> <!-- Autosave Interval -->
@@ -433,43 +446,42 @@
</label> </label>
<input class="optionRange" type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60"/> <input class="optionRange" type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60"/>
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em> <em id="settingsAutosaveIntervalValLabel" style="font-style: normal"></em>
</fieldset> </fieldset>
<!-- Suppress messages --> <!-- Suppress messages -->
<fieldset> <fieldset>
<label for="settingsSuppressMessages" class="tooltip">Suppress Messages: <label for="settingsSuppressMessages" class="tooltip">Suppress Messages:
<span class="tooltiptext"> <span class="tooltiptext">
If this is set, then any messages you receive will not appear as popups If this is set, then any messages you receive will not appear as popups on the screen. They will still
on the screen. They will still get sent to your home computer as '.msg' files get sent to your home computer as '.msg' files and can be viewed with the 'cat' Terminal command.
and can be viewed with the 'cat' Terminal command.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressMessages" id="settingsSuppressMessages"> <input class="optionCheckbox" type="checkbox" name="settingsSuppressMessages" id="settingsSuppressMessages"/>
</fieldset> </fieldset>
<!-- Suppress faction invites --> <!-- Suppress faction invites -->
<fieldset> <fieldset>
<label for="settingsSuppressFactionInvites" class="tooltip">Suppress Faction Invites: <label for="settingsSuppressFactionInvites" class="tooltip">Suppress Faction Invites:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh">
If this is set, then any faction invites you receive will not appear as popups If this is set, then any faction invites you receive will not appear as popups on the screen. Your
on the screen. Your outstanding faction invites can be viewed in the 'Factions' page. outstanding faction invites can be viewed in the 'Factions' page.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites"> <input class="optionCheckbox" type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites"/>
</fieldset> </fieldset>
<!-- Suppress travel confirmation --> <!-- Suppress travel confirmation -->
<fieldset> <fieldset>
<label for="settingsSuppressTravelConfirmation" class="tooltip">Suppress Travel Confirmation: <label for="settingsSuppressTravelConfirmation" class="tooltip">Suppress Travel Confirmation:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh">
If this is set, the confirmation message before traveling will not show up. You will automatically be deducted the travel cost as soon as you click. If this is set, the confirmation message before traveling will not show up. You will automatically be
deducted the travel cost as soon as you click.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressTravelConfirmation" id="settingsSuppressTravelConfirmation"> <input class="optionCheckbox" type="checkbox" name="settingsSuppressTravelConfirmation" id="settingsSuppressTravelConfirmation"/>
</fieldset> </fieldset>
<!-- Suppress buy aug confirmation --> <!-- Suppress buy aug confirmation -->
<fieldset> <fieldset>
<label for="settingsSuppressBuyAugmentationConfirmation" class="tooltip">Suppress buy augmentation confirmation: <label for="settingsSuppressBuyAugmentationConfirmation" class="tooltip">Suppress buy augmentation confirmation:
@@ -477,67 +489,66 @@
If this is set, the confirmation message before buying augmentation will not show up. If this is set, the confirmation message before buying augmentation will not show up.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressBuyAugmentationConfirmation" id="settingsSuppressBuyAugmentationConfirmation"> <input class="optionCheckbox" type="checkbox" name="settingsSuppressBuyAugmentationConfirmation" id="settingsSuppressBuyAugmentationConfirmation"/>
</fieldset> </fieldset>
<!-- Hospitalization Popup --> <!-- Hospitalization Popup -->
<fieldset> <fieldset>
<label for="settingsSuppressHospitalizationPopup" class="tooltip">Suppress Hospitalization popup: <label for="settingsSuppressHospitalizationPopup" class="tooltip">Suppress Hospitalization popup:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh">
If this is set, a popup message will no longer be shown when you are hospitalized after taking too much damage. If this is set, a popup message will no longer be shown when you are hospitalized after taking too
much damage.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressHospitalizationPopup" id="settingsSuppressHospitalizationPopup"> <input class="optionCheckbox" type="checkbox" name="settingsSuppressHospitalizationPopup" id="settingsSuppressHospitalizationPopup"/>
</fieldset> </fieldset>
<!-- Suppress Bladeburner popups --> <!-- Suppress Bladeburner popups -->
<fieldset> <fieldset>
<label for="settingsSuppressBladeburnerPopup" class="tooltip">Suppress Bladeburner Popup: <label for="settingsSuppressBladeburnerPopup" class="tooltip">Suppress Bladeburner Popup:
<span class="tooltiptext"> <span class="tooltiptext">
If this is set, then having your Bladeburner actions interrupted by being busy with something else will not display a popup message. If this is set, then having your Bladeburner actions interrupted by being busy with something else
will not display a popup message.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressBladeburnerPopup" id="settingsSuppressBladeburnerPopup"> <input class="optionCheckbox" type="checkbox" name="settingsSuppressBladeburnerPopup" id="settingsSuppressBladeburnerPopup"/>
</fieldset> </fieldset>
<!-- Disable Terminal and Navigation Shortcuts --> <!-- Disable Terminal and Navigation Shortcuts -->
<fieldset> <fieldset>
<label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys: <label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh">
If this is set, then most hotkeys (keyboard shortcuts) in the game are disabled. If this is set, then most hotkeys (keyboard shortcuts) in the game are disabled. This includes
This includes Terminal commands, hotkeys to navigate between different parts of the game, Terminal commands, hotkeys to navigate between different parts of the game, and the "Save and Close
and the "Save and Close (Ctrl + b)" hotkey in the Text Editor. (Ctrl + b)" hotkey in the Text Editor.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys"> <input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys"/>
</fieldset> </fieldset>
<!-- View city as list of buttons instead of ASCII art. --> <!-- View city as list of buttons instead of ASCII art. -->
<fieldset> <fieldset>
<label for="settingsDisableASCIIArt" class="tooltip">Disable ASCII art: <label for="settingsDisableASCIIArt" class="tooltip">Disable ASCII art:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh"> If this is set all ASCII art will be disabled. </span>
If this is set all ASCII art will be disabled.
</span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsDisableASCIIArt" id="settingsDisableASCIIArt"> <input class="optionCheckbox" type="checkbox" name="settingsDisableASCIIArt" id="settingsDisableASCIIArt"/>
</fieldset> </fieldset>
<!-- Disable text effects such as corruption. --> <!-- Disable text effects such as corruption. -->
<fieldset> <fieldset>
<label for="settingsDisableTextEffects" class="tooltip">Disable Text Effects: <label for="settingsDisableTextEffects" class="tooltip">Disable Text Effects:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh">
If this is set, text effects will not be displayed. This can help if text is difficult to read in certain areas. If this is set, text effects will not be displayed. This can help if text is difficult to read in
certain areas.
</span> </span>
</label> </label>
<input class="optionCheckbox" type="checkbox" name="settingsDisableTextEffects" id="settingsDisableTextEffects"> <input class="optionCheckbox" type="checkbox" name="settingsDisableTextEffects" id="settingsDisableTextEffects"/>
</fieldset> </fieldset>
<!-- Locale for displaying numbers --> <!-- Locale for displaying numbers -->
<fieldset> <fieldset>
<label for="settingsLocale" class="tooltip">Locale: <label for="settingsLocale" class="tooltip">Locale:
<span class="tooltiptexthigh"> <span class="tooltiptexthigh"> Sets the locale for displaying numbers. Defaults to 'en' </span>
Sets the locale for displaying numbers. Defaults to 'en'
</span>
</label> </label>
<select name="settingsLocale" id="settingsLocale" class="dropdown"> <select name="settingsLocale" id="settingsLocale" class="dropdown">
<option value="en">en</option> <option value="en">en</option>
@@ -560,15 +571,17 @@
<!-- Donate button --> <!-- Donate button -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank"> <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick"> <input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYA2Y2VGE75oWct89z//G2YEJKmzx0uDTXNrpje9ThxmUnBLFZCY+I11Pors7lGRvFqo5okwnu41CfYMPHDxpAgyYyQndMX9pWUX0gLfBMm2BaHwsNBCwt34WmpQqj7TGsQ+aw9NbmkxiJltGnOa+6/gy10mPZAA3HxiieLeCKkGgDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI72F1YSzHUd2AgaDMekHU3AKT93Ey9wkB3486bV+ngFSD6VOHrPweH9QATsp+PMe9QM9vmq+s2bGtTbZaYrFqM3M97SnQ0l7IQ5yuOzdZhRdfysu5uJ8dnuHUzq4gLSzqMnZ6/3c+PoHB8AS1nYHUVL4U0+ogZsO1s97IAQyfck9SaoFlxVtqQhkb8752MkQJJvGu3ZQSQGcVC4hFDPk8prXqyq4BU/k/EliwoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwNzI1MDExODE2WjAjBgkqhkiG9w0BCQQxFgQUNo8efiZ7sk7nwKM/6B6Z7sU8hIIwDQYJKoZIhvcNAQEBBQAEgYB+JB4vZ/r48815/1HF/xK3+rOx7bPz3kAXmbhW/mkoF4OUbzqMeljvDIA9q/BDdlCLtxFOw9XlftTzv0eZCW/uCIiwu5wTzPIfPY1SI8WHe4cJbP2f2EYxIVs8D7OSirbW4yVa0+gACaLLj0rzIzNN8P/5PxgB03D+jwkcJABqng==-----END PKCS7----- <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYA2Y2VGE75oWct89z//G2YEJKmzx0uDTXNrpje9ThxmUnBLFZCY+I11Pors7lGRvFqo5okwnu41CfYMPHDxpAgyYyQndMX9pWUX0gLfBMm2BaHwsNBCwt34WmpQqj7TGsQ+aw9NbmkxiJltGnOa+6/gy10mPZAA3HxiieLeCKkGgDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI72F1YSzHUd2AgaDMekHU3AKT93Ey9wkB3486bV+ngFSD6VOHrPweH9QATsp+PMe9QM9vmq+s2bGtTbZaYrFqM3M97SnQ0l7IQ5yuOzdZhRdfysu5uJ8dnuHUzq4gLSzqMnZ6/3c+PoHB8AS1nYHUVL4U0+ogZsO1s97IAQyfck9SaoFlxVtqQhkb8752MkQJJvGu3ZQSQGcVC4hFDPk8prXqyq4BU/k/EliwoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwNzI1MDExODE2WjAjBgkqhkiG9w0BCQQxFgQUNo8efiZ7sk7nwKM/6B6Z7sU8hIIwDQYJKoZIhvcNAQEBBQAEgYB+JB4vZ/r48815/1HF/xK3+rOx7bPz3kAXmbhW/mkoF4OUbzqMeljvDIA9q/BDdlCLtxFOw9XlftTzv0eZCW/uCIiwu5wTzPIfPY1SI8WHe4cJbP2f2EYxIVs8D7OSirbW4yVa0+gACaLLj0rzIzNN8P/5PxgB03D+jwkcJABqng==-----END PKCS7-----
"> "/>
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"> <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"/>
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"> <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"/>
</form> </form>
</div> </div>
<div id="game-options-right-panel"> <div id="game-options-right-panel">
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank"> Changelog </a> <a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank">
Changelog
</a>
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank">Documentation</a> <a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank">Documentation</a>
<a class="a-link-button" href="https://discord.gg/TFc3hKD" target="_blank">Discord</a> <a class="a-link-button" href="https://discord.gg/TFc3hKD" target="_blank">Discord</a>
<a class="a-link-button" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a> <a class="a-link-button" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
@@ -577,16 +590,15 @@
<button id="export-game-link" class="a-link-button">Export Game</button> <button id="export-game-link" class="a-link-button">Export Game</button>
<input type="file" id="import-game-file-selector" name="file"/> <input type="file" id="import-game-file-selector" name="file"/>
<button id="import-game-link" class="a-link-button">Import Game</button> <button id="import-game-link" class="a-link-button">Import Game</button>
<button id="copy-save-to-clipboard-link" class="std-button"> <button id="copy-save-to-clipboard-link" class="std-button">Copy Save data to Clipboard</button>
Copy Save data to Clipboard
</button>
<button id="debug-delete-scripts-link" class="a-link-button tooltip"> <button id="debug-delete-scripts-link" class="a-link-button tooltip">
Force kill all active scripts Force kill all active scripts
<span class="tooltiptextleft"> <span class="tooltiptextleft">
Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the game. After Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the
using this, save the game and then reload the page. This is different then normal kill in that normal kill game. After using this, save the game and then reload the page. This is different then normal kill in
will tell the script to shut down while force kill just removes the references to it (and it should crash on it's own). that normal kill will tell the script to shut down while force kill just removes the references to it
This will not remove the files on your computer. Just forcefully kill all running instance of all scripts. (and it should crash on it's own). This will not remove the files on your computer. Just forcefully kill
all running instance of all scripts.
</span> </span>
</button> </button>
<button id="debug-soft-reset" class="a-link-button tooltip"> <button id="debug-soft-reset" class="a-link-button tooltip">
@@ -595,6 +607,13 @@
Perform a soft reset. Resets everything as if you had just purchased an Augmentation. Perform a soft reset. Resets everything as if you had just purchased an Augmentation.
</span> </span>
</button> </button>
<button id="debug-files" class="a-link-button tooltip">
Diagnose files
<span class="tooltiptextleft">
If your save file is extremely big you can use this button to view a map of all the files on every
server. Be careful there might be spoilers.
</span>
</button>
</div> </div>
</div> </div>
</div> </div>
@@ -605,13 +624,20 @@
<div class="loaderspinner"></div> <div class="loaderspinner"></div>
<div class="loaderlabel">Loading Bitburner...</div> <div class="loaderlabel">Loading Bitburner...</div>
<div id="killAllMessageWrapper" class="killAllMessage killAllMessageWrapperHidden"> <div id="killAllMessageWrapper" class="killAllMessage killAllMessageWrapperHidden">
<script>setTimeout(function(){ <script>
var w = document.getElementById('killAllMessageWrapper'); setTimeout(function () {
if (w == null) {return;} var w = document.getElementById("killAllMessageWrapper");
if (w == null) {
return;
}
w.classList.remove("killAllMessageWrapperHidden"); w.classList.remove("killAllMessageWrapperHidden");
w.classList.add("killAllMessageWrapperShow"); w.classList.add("killAllMessageWrapperShow");
}, 2000);</script> }, 2000);
<p>If the game fails to load, consider <a href="?noScripts">killing all scripts</a></p> </script>
<p>
If the game fails to load, consider
<a href="?noScripts">killing all scripts</a>
</p>
</div> </div>
</div> </div>
@@ -620,6 +646,4 @@
<!-- Misc Scripts --> <!-- Misc Scripts -->
<script src="src/ThirdParty/raphael.min.js"></script> <script src="src/ThirdParty/raphael.min.js"></script>
<script src="src/ThirdParty/Treant.js"></script>
</html> </html>
+9
View File
@@ -0,0 +1,9 @@
module.exports = {
setupFiles: ["./jest.setup.js"],
moduleFileExtensions: ["ts", "tsx", "js", "jsx"],
transform: {
"^.+\\.(js|jsx|ts|tsx)$": "babel-jest",
},
// testMatch: ["**/?(*.)+(test).[jt]s?(x)"],
testEnvironment: "jsdom",
};
+2
View File
@@ -0,0 +1,2 @@
import "regenerator-runtime/runtime";
global.$ = require("jquery");
+19886 -6107
View File
File diff suppressed because it is too large Load Diff
+32 -18
View File
@@ -12,8 +12,8 @@
"@types/numeral": "0.0.25", "@types/numeral": "0.0.25",
"@types/react": "^16.8.6", "@types/react": "^16.8.6",
"@types/react-dom": "^16.8.2", "@types/react-dom": "^16.8.2",
"acorn": "^6.4.1", "acorn": "^8.4.1",
"acorn-walk": "^6.2.0", "acorn-walk": "^8.1.1",
"ajv": "^5.1.5", "ajv": "^5.1.5",
"ajv-keywords": "^2.0.0", "ajv-keywords": "^2.0.0",
"arg": "^5.0.0", "arg": "^5.0.0",
@@ -31,9 +31,11 @@
"jshint": "^2.10.2", "jshint": "^2.10.2",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"jsplumb": "^2.6.8", "jsplumb": "^2.6.8",
"jszip": "^3.1.5", "jszip": "^3.7.0",
"loader-runner": "^2.3.0", "loader-runner": "^2.3.0",
"loader-utils": "^1.1.0", "loader-utils": "^1.1.0",
"mathjax-full": "^3.2.0",
"mathjax-react": "^1.0.6",
"memory-fs": "~0.4.1", "memory-fs": "~0.4.1",
"monaco-editor": "^0.27.0", "monaco-editor": "^0.27.0",
"node-sass": "^6.0.1", "node-sass": "^6.0.1",
@@ -44,31 +46,38 @@
"react-modal": "^3.12.1", "react-modal": "^3.12.1",
"sprintf-js": "^1.1.1", "sprintf-js": "^1.1.1",
"tapable": "^1.0.0", "tapable": "^1.0.0",
"treant-js": "^1.0.1",
"uuid": "^3.2.1", "uuid": "^3.2.1",
"w3c-blob": "0.0.1" "w3c-blob": "0.0.1"
}, },
"description": "A cyberpunk-themed incremental game", "description": "A cyberpunk-themed incremental game",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.3.4", "@babel/core": "^7.3.4",
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"@types/chai": "^4.1.7", "@babel/preset-typescript": "^7.15.0",
"@testing-library/cypress": "^8.0.1",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.168", "@types/lodash": "^4.14.168",
"@types/mocha": "^5.2.7",
"@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0", "@typescript-eslint/parser": "^4.22.0",
"babel-jest": "^27.0.6",
"babel-loader": "^8.0.5", "babel-loader": "^8.0.5",
"beautify-lint": "^1.0.3", "beautify-lint": "^1.0.3",
"benchmark": "^2.1.1", "benchmark": "^2.1.1",
"bundle-loader": "~0.5.0", "bundle-loader": "~0.5.0",
"chai": "^4.2.0",
"css-loader": "^0.28.11", "css-loader": "^0.28.11",
"cypress": "^8.3.1",
"es6-promise-polyfill": "^1.1.1", "es6-promise-polyfill": "^1.1.1",
"eslint": "^7.24.0", "eslint": "^7.24.0",
"eslint-plugin-node": "^11.1.0", "eslint-plugin-node": "^11.1.0",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"fork-ts-checker-webpack-plugin": "^6.3.3",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"http-server": "^13.0.1",
"i18n-webpack-plugin": "^1.0.0", "i18n-webpack-plugin": "^1.0.0",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"jest": "^27.1.0",
"js-beautify": "^1.5.10", "js-beautify": "^1.5.10",
"jsdom": "^15.0.0", "jsdom": "^15.0.0",
"jsdom-global": "^3.0.2", "jsdom-global": "^3.0.2",
@@ -78,30 +87,30 @@
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mini-css-extract-plugin": "^0.4.1", "mini-css-extract-plugin": "^0.4.1",
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"mocha": "^6.1.4",
"mochapack": "^1.1.1",
"null-loader": "^1.0.0", "null-loader": "^1.0.0",
"prettier": "^2.3.2",
"raw-loader": "~0.5.0", "raw-loader": "~0.5.0",
"regenerator-runtime": "^0.13.9",
"sass-loader": "^7.0.3", "sass-loader": "^7.0.3",
"script-loader": "~0.7.0", "script-loader": "~0.7.0",
"should": "^11.1.1", "should": "^11.1.1",
"simple-git": "^1.96.0", "simple-git": "^1.96.0",
"sinon": "^2.3.2", "sinon": "^2.3.2",
"source-map": "^0.7.3", "source-map": "^0.7.3",
"start-server-and-test": "^1.14.0",
"style-loader": "^0.21.0", "style-loader": "^0.21.0",
"stylelint": "^9.2.1", "stylelint": "^9.2.1",
"stylelint-declaration-use-variable": "^1.6.1", "stylelint-declaration-use-variable": "^1.6.1",
"stylelint-order": "^0.8.1", "stylelint-order": "^0.8.1",
"ts-loader": "^4.5.0",
"typescript": "^4.2.4", "typescript": "^4.2.4",
"uglify-es": "^3.3.9", "uglify-es": "^3.3.9",
"uglifyjs-webpack-plugin": "^1.3.0", "uglifyjs-webpack-plugin": "^1.3.0",
"url-loader": "^1.0.1", "url-loader": "^1.0.1",
"watchpack": "^1.6.0", "watchpack": "^1.6.0",
"webpack": "^4.12.0", "webpack": "^4.46.0",
"webpack-cli": "^3.0.4", "webpack-cli": "^3.3.12",
"webpack-dev-middleware": "^3.1.3", "webpack-dev-middleware": "^3.7.3",
"webpack-dev-server": "^3.2.1", "webpack-dev-server": "^3.11.2",
"worker-loader": "^2.0.0" "worker-loader": "^2.0.0"
}, },
"engines": { "engines": {
@@ -115,19 +124,24 @@
"url": "git+https://github.com/danielyxie/bitburner.git" "url": "git+https://github.com/danielyxie/bitburner.git"
}, },
"scripts": { "scripts": {
"cy:test": "start-server-and-test start http://localhost:8000 cy:run",
"cy:dev": "start-server-and-test start:dev http://localhost:8000 cy:open",
"cy:open": "cypress open",
"cy:run": "cypress run",
"format": "prettier --write .",
"start": "http-server -p 8000",
"start:dev": "webpack-dev-server --progress --env.devServer --mode development", "start:dev": "webpack-dev-server --progress --env.devServer --mode development",
"start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer", "start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer",
"build": "webpack --mode production", "build": "webpack --mode production",
"build:dev": "webpack --mode development", "build:dev": "webpack --mode development",
"build:test": "webpack --config webpack.config-test.js",
"lint": "npm run lint:jsts & npm run lint:style", "lint": "npm run lint:jsts & npm run lint:style",
"lint:jsts": "eslint --fix '*.{js,jsx,ts,tsx}' './src/**/*.{js,jsx,ts,tsx}' './test/**/*.{js,jsx,ts,tsx}' './utils/**/*.{js,jsx,ts,tsx}'", "lint:jsts": "eslint --fix . --ext js,jsx,ts,tsx",
"lint:style": "stylelint --fix ./css/*", "lint:style": "stylelint --fix ./css/*",
"preinstall": "node ./scripts/engines-check.js", "preinstall": "node ./scripts/engines-check.js",
"test": "mochapack --webpack-config webpack.config-test.js -r jsdom-global/register ./test/index.js", "test": "jest",
"test:container": "mochapack --webpack-config webpack.config-test.js --slow 2000 --timeout 10000 -r jsdom-global/register ./test/index.js", "test:watch": "jest --watch",
"watch": "webpack --watch --mode production", "watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development" "watch:dev": "webpack --watch --mode development"
}, },
"version": "0.52.8" "version": "0.53.0"
} }
+233 -666
View File
File diff suppressed because it is too large Load Diff
+5 -2
View File
@@ -62,9 +62,12 @@ getPackageJson()
.then(getEngines) .then(getEngines)
.then(checkNodeVersion) .then(checkNodeVersion)
.then(checkNpmVersion) .then(checkNpmVersion)
.then(() => true, (error) => { .then(
() => true,
(error) => {
// Specifically disable these as the error message gets lost in the normal unhandled output. // Specifically disable these as the error message gets lost in the normal unhandled output.
/* 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);
}); }
);
+25 -13
View File
@@ -82,7 +82,9 @@ src[NONNUMERICIDENTIFIER] = "\\d*[a-zA-Z-][a-zA-Z0-9-]*";
// ## Main Version // ## Main Version
// Three dot-separated numeric identifiers. // Three dot-separated numeric identifiers.
src[MAINVERSION] = `(${src[NUMERICIDENTIFIER]})\\.(${src[NUMERICIDENTIFIER]})\\.(${src[NUMERICIDENTIFIER]})`; src[MAINVERSION] = `(${src[NUMERICIDENTIFIER]})\\.(${src[NUMERICIDENTIFIER]})\\.(${src[NUMERICIDENTIFIER]})`;
src[MAINVERSIONLOOSE] = `(${src[NUMERICIDENTIFIERLOOSE]})\\.(${src[NUMERICIDENTIFIERLOOSE]})\\.(${src[NUMERICIDENTIFIERLOOSE]})`; src[
MAINVERSIONLOOSE
] = `(${src[NUMERICIDENTIFIERLOOSE]})\\.(${src[NUMERICIDENTIFIERLOOSE]})\\.(${src[NUMERICIDENTIFIERLOOSE]})`;
// ## Pre-release Version Identifier // ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier. // A numeric identifier, or a non-numeric identifier.
@@ -123,10 +125,14 @@ src[XRANGEIDENTIFIERLOOSE] = `${src[NUMERICIDENTIFIERLOOSE]}|x|X|\\*`;
src[XRANGEIDENTIFIER] = `${src[NUMERICIDENTIFIER]}|x|X|\\*`; src[XRANGEIDENTIFIER] = `${src[NUMERICIDENTIFIER]}|x|X|\\*`;
/* eslint-disable-next-line max-len */ /* eslint-disable-next-line max-len */
src[XRANGEPLAIN] = `[v=\\s]*(${src[XRANGEIDENTIFIER]})(?:\\.(${src[XRANGEIDENTIFIER]})(?:\\.(${src[XRANGEIDENTIFIER]})(?:${src[PRERELEASE]})?${src[BUILD]}?)?)?`; src[
XRANGEPLAIN
] = `[v=\\s]*(${src[XRANGEIDENTIFIER]})(?:\\.(${src[XRANGEIDENTIFIER]})(?:\\.(${src[XRANGEIDENTIFIER]})(?:${src[PRERELEASE]})?${src[BUILD]}?)?)?`;
/* eslint-disable-next-line max-len */ /* eslint-disable-next-line max-len */
src[XRANGEPLAINLOOSE] = `[v=\\s]*(${src[XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[XRANGEIDENTIFIERLOOSE]})(?:${src[PRERELEASELOOSE]})?${src[BUILD]}?)?)?`; src[XRANGEPLAINLOOSE] =
`[v=\\s]*(${src[XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[XRANGEIDENTIFIERLOOSE]})` +
`(?:\\.(${src[XRANGEIDENTIFIERLOOSE]})(?:${src[PRERELEASELOOSE]})?${src[BUILD]}?)?)?`;
src[XRANGE] = `^${src[GTLT]}\\s*${src[XRANGEPLAIN]}$`; src[XRANGE] = `^${src[GTLT]}\\s*${src[XRANGEPLAIN]}$`;
src[XRANGELOOSE] = `^${src[GTLT]}\\s*${src[XRANGEPLAINLOOSE]}$`; src[XRANGELOOSE] = `^${src[GTLT]}\\s*${src[XRANGEPLAINLOOSE]}$`;
@@ -134,7 +140,9 @@ src[XRANGELOOSE] = `^${src[GTLT]}\\s*${src[XRANGEPLAINLOOSE]}$`;
// Coercion. // Coercion.
// Extract anything that could conceivably be a part of a valid semver // Extract anything that could conceivably be a part of a valid semver
/* eslint-disable-next-line max-len */ /* eslint-disable-next-line max-len */
src[COERCE] = `(?:^|[^\\d])(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:$|[^\\d])`; src[
COERCE
] = `(?:^|[^\\d])(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:$|[^\\d])`;
// Tilde ranges. // Tilde ranges.
// Meaning is "reasonably at or greater than" // Meaning is "reasonably at or greater than"
@@ -222,10 +230,7 @@ function compareIdentifiers(left, right) {
// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5
// 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do
// 1.2 - 3.4 => >=1.2.0 <3.5.0 // 1.2 - 3.4 => >=1.2.0 <3.5.0
function hyphenReplace($0, function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) {
from, fM, fm, fp, fpr, fb,
to, tM, tm, tp, tpr) {
if (isX(fM)) { if (isX(fM)) {
from = ""; from = "";
} else if (isX(fm)) { } else if (isX(fm)) {
@@ -483,7 +488,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;
@@ -526,7 +531,9 @@ class SemVer {
other = new SemVer(other, this.loose); other = new SemVer(other, this.loose);
} }
return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch); return (
compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch)
);
} }
comparePre(other) { comparePre(other) {
@@ -733,7 +740,9 @@ class Range {
this.raw = range; this.raw = range;
// Throw out any that are not relevant for whatever reason // Throw out any that are not relevant for whatever reason
const hasLength = (item) => item.length; const hasLength = (item) => item.length;
this.set = this.raw.split(/\s*\|\|\s*/).map(function (range1) { this.set = this.raw
.split(/\s*\|\|\s*/)
.map(function (range1) {
return this.parseRange(range1.trim()); return this.parseRange(range1.trim());
}, this) }, this)
.filter(hasLength); .filter(hasLength);
@@ -744,7 +753,8 @@ class Range {
} }
format() { format() {
this.range = this.set.map((comps) => comps.join(" ").trim()) this.range = this.set
.map((comps) => comps.join(" ").trim())
.join("||") .join("||")
.trim(); .trim();
@@ -771,7 +781,9 @@ class Range {
range = range.split(/\s+/).join(" "); range = range.split(/\s+/).join(" ");
// At this point, the range is completely trimmed and ready to be split into comparators. // At this point, the range is completely trimmed and ready to be split into comparators.
const compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; const compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR];
let set = range.split(" ").map((comp) => parseComparator(comp, loose)) let set = range
.split(" ")
.map((comp) => parseComparator(comp, loose))
.join(" ") .join(" ")
.split(/\s+/); .split(/\s+/);
if (loose) { if (loose) {
+9 -5
View File
@@ -38,7 +38,9 @@ export function printAliases(): void {
export function parseAliasDeclaration(dec: string, global = false): boolean { export function parseAliasDeclaration(dec: string, global = false): boolean {
const re = /^([_|\w|!|%|,|@]+)="(.+)"$/; const re = /^([_|\w|!|%|,|@]+)="(.+)"$/;
const matches = dec.match(re); const matches = dec.match(re);
if (matches == null || matches.length != 3) {return false;} if (matches == null || matches.length != 3) {
return false;
}
if (global) { if (global) {
addGlobalAlias(matches[1], matches[2]); addGlobalAlias(matches[1], matches[2]);
} else { } else {
@@ -98,24 +100,26 @@ export function substituteAliases(origCommand: string): string {
const commandArray = origCommand.split(" "); const commandArray = origCommand.split(" ");
if (commandArray.length > 0) { if (commandArray.length > 0) {
// For the alias and unalias commands, dont substite // For the alias and unalias commands, dont substite
if (commandArray[0] === "unalias" || commandArray[0] === "alias") { return commandArray.join(" "); } if (commandArray[0] === "unalias" || commandArray[0] === "alias") {
return commandArray.join(" ");
}
let somethingSubstituted = true; let somethingSubstituted = true;
let depth = 0; let depth = 0;
while (somethingSubstituted && depth < 10) { while (somethingSubstituted && depth < 10) {
depth++; depth++;
somethingSubstituted = false somethingSubstituted = false;
const alias = getAlias(commandArray[0])?.split(" "); const alias = getAlias(commandArray[0])?.split(" ");
if (alias != null) { if (alias != null) {
somethingSubstituted = true somethingSubstituted = true;
commandArray.splice(0, 1, ...alias); commandArray.splice(0, 1, ...alias);
//commandArray[0] = alias; //commandArray[0] = alias;
} }
for (let i = 0; i < commandArray.length; ++i) { for (let i = 0; i < commandArray.length; ++i) {
const alias = getGlobalAlias(commandArray[i])?.split(" "); const alias = getGlobalAlias(commandArray[i])?.split(" ");
if (alias != null) { if (alias != null) {
somethingSubstituted = true somethingSubstituted = true;
commandArray.splice(i, 1, ...alias); commandArray.splice(i, 1, ...alias);
i += alias.length - 1; i += alias.length - 1;
//commandArray[i] = alias; //commandArray[i] = alias;
+330 -82
View File
@@ -64,118 +64,301 @@ function generateStatsDescription(mults: IMap<number>, programs?: string[], star
}; };
let desc = <>Effects:</>; let desc = <>Effects:</>;
if(mults.hacking_mult && if (
mults.hacking_mult &&
mults.hacking_mult == mults.strength_mult && mults.hacking_mult == mults.strength_mult &&
mults.hacking_mult == mults.defense_mult && mults.hacking_mult == mults.defense_mult &&
mults.hacking_mult == mults.dexterity_mult && mults.hacking_mult == mults.dexterity_mult &&
mults.hacking_mult == mults.agility_mult && mults.hacking_mult == mults.agility_mult &&
mults.hacking_mult == mults.charisma_mult){ mults.hacking_mult == mults.charisma_mult
desc = <>{desc}<br />+{f(mults.hacking_mult-1)} all skills</> ) {
desc = (
<>
{desc}
<br />+{f(mults.hacking_mult - 1)} all skills
</>
);
} else { } else {
if (mults.hacking_mult) if (mults.hacking_mult)
desc = <>{desc}<br />+{f(mults.hacking_mult-1)} hacking skill</> desc = (
<>
{desc}
<br />+{f(mults.hacking_mult - 1)} hacking skill
</>
);
if(mults.strength_mult && if (
mults.strength_mult &&
mults.strength_mult == mults.defense_mult && mults.strength_mult == mults.defense_mult &&
mults.strength_mult == mults.dexterity_mult && mults.strength_mult == mults.dexterity_mult &&
mults.strength_mult == mults.agility_mult) { mults.strength_mult == mults.agility_mult
desc = <>{desc}<br />+{f(mults.strength_mult-1)} combat skills</> ) {
desc = (
<>
{desc}
<br />+{f(mults.strength_mult - 1)} combat skills
</>
);
} else { } else {
if (mults.strength_mult) if (mults.strength_mult)
desc = <>{desc}<br />+{f(mults.strength_mult-1)} strength skill</> desc = (
<>
{desc}
<br />+{f(mults.strength_mult - 1)} strength skill
</>
);
if (mults.defense_mult) if (mults.defense_mult)
desc = <>{desc}<br />+{f(mults.defense_mult-1)} defense skill</> desc = (
<>
{desc}
<br />+{f(mults.defense_mult - 1)} defense skill
</>
);
if (mults.dexterity_mult) if (mults.dexterity_mult)
desc = <>{desc}<br />+{f(mults.dexterity_mult-1)} dexterity skill</> desc = (
<>
{desc}
<br />+{f(mults.dexterity_mult - 1)} dexterity skill
</>
);
if (mults.agility_mult) if (mults.agility_mult)
desc = <>{desc}<br />+{f(mults.agility_mult-1)} agility skill</> desc = (
<>
{desc}
<br />+{f(mults.agility_mult - 1)} agility skill
</>
);
} }
if (mults.charisma_mult) if (mults.charisma_mult)
desc = <>{desc}<br />+{f(mults.charisma_mult-1)} Charisma skill</> desc = (
<>
{desc}
<br />+{f(mults.charisma_mult - 1)} Charisma skill
</>
);
} }
if(mults.hacking_exp_mult && if (
mults.hacking_exp_mult &&
mults.hacking_exp_mult === mults.strength_exp_mult && mults.hacking_exp_mult === mults.strength_exp_mult &&
mults.hacking_exp_mult === mults.defense_exp_mult && mults.hacking_exp_mult === mults.defense_exp_mult &&
mults.hacking_exp_mult === mults.dexterity_exp_mult && mults.hacking_exp_mult === mults.dexterity_exp_mult &&
mults.hacking_exp_mult === mults.agility_exp_mult && mults.hacking_exp_mult === mults.agility_exp_mult &&
mults.hacking_exp_mult === mults.charisma_exp_mult) { mults.hacking_exp_mult === mults.charisma_exp_mult
desc = <>{desc}<br />+{f(mults.hacking_exp_mult-1)} exp for all skills</> ) {
desc = (
<>
{desc}
<br />+{f(mults.hacking_exp_mult - 1)} exp for all skills
</>
);
} else { } else {
if (mults.hacking_exp_mult) if (mults.hacking_exp_mult)
desc = <>{desc}<br />+{f(mults.hacking_exp_mult-1)} hacking exp</> desc = (
<>
{desc}
<br />+{f(mults.hacking_exp_mult - 1)} hacking exp
</>
);
if(mults.strength_exp_mult && if (
mults.strength_exp_mult &&
mults.strength_exp_mult === mults.defense_exp_mult && mults.strength_exp_mult === mults.defense_exp_mult &&
mults.strength_exp_mult === mults.dexterity_exp_mult && mults.strength_exp_mult === mults.dexterity_exp_mult &&
mults.strength_exp_mult === mults.agility_exp_mult) { mults.strength_exp_mult === mults.agility_exp_mult
desc = <>{desc}<br />+{f(mults.strength_exp_mult-1)} combat exp</> ) {
desc = (
<>
{desc}
<br />+{f(mults.strength_exp_mult - 1)} combat exp
</>
);
} else { } else {
if (mults.strength_exp_mult) if (mults.strength_exp_mult)
desc = <>{desc}<br />+{f(mults.strength_exp_mult-1)} strength exp</> desc = (
<>
{desc}
<br />+{f(mults.strength_exp_mult - 1)} strength exp
</>
);
if (mults.defense_exp_mult) if (mults.defense_exp_mult)
desc = <>{desc}<br />+{f(mults.defense_exp_mult-1)} defense exp</> desc = (
<>
{desc}
<br />+{f(mults.defense_exp_mult - 1)} defense exp
</>
);
if (mults.dexterity_exp_mult) if (mults.dexterity_exp_mult)
desc = <>{desc}<br />+{f(mults.dexterity_exp_mult-1)} dexterity exp</> desc = (
<>
{desc}
<br />+{f(mults.dexterity_exp_mult - 1)} dexterity exp
</>
);
if (mults.agility_exp_mult) if (mults.agility_exp_mult)
desc = <>{desc}<br />+{f(mults.agility_exp_mult-1)} agility exp</> desc = (
<>
{desc}
<br />+{f(mults.agility_exp_mult - 1)} agility exp
</>
);
} }
if (mults.charisma_exp_mult) if (mults.charisma_exp_mult)
desc = <>{desc}<br />+{f(mults.charisma_exp_mult-1)} charisma exp</> desc = (
<>
{desc}
<br />+{f(mults.charisma_exp_mult - 1)} charisma exp
</>
);
} }
if (mults.hacking_speed_mult) if (mults.hacking_speed_mult)
desc = <>{desc}<br />+{f(mults.hacking_speed_mult-1)} faster hacking</> desc = (
<>
{desc}
<br />+{f(mults.hacking_speed_mult - 1)} faster hack(), grow(), and weaken()
</>
);
if (mults.hacking_chance_mult) if (mults.hacking_chance_mult)
desc = <>{desc}<br />+{f(mults.hacking_chance_mult-1)} hack() success chance</> desc = (
<>
{desc}
<br />+{f(mults.hacking_chance_mult - 1)} hack() success chance
</>
);
if (mults.hacking_money_mult) if (mults.hacking_money_mult)
desc = <>{desc}<br />+{f(mults.hacking_money_mult-1)} hack() power</> desc = (
<>
{desc}
<br />+{f(mults.hacking_money_mult - 1)} hack() power
</>
);
if (mults.hacking_grow_mult) if (mults.hacking_grow_mult)
desc = <>{desc}<br />+{f(mults.hacking_grow_mult-1)} grow() power</> desc = (
<>
{desc}
<br />+{f(mults.hacking_grow_mult - 1)} grow() power
</>
);
if(mults.faction_rep_mult && if (mults.faction_rep_mult && mults.faction_rep_mult === mults.company_rep_mult) {
mults.faction_rep_mult === mults.company_rep_mult) { desc = (
desc = <>{desc}<br />+{f(mults.faction_rep_mult-1)} reputation from factions and companies</> <>
{desc}
<br />+{f(mults.faction_rep_mult - 1)} reputation from factions and companies
</>
);
} else { } else {
if (mults.faction_rep_mult) if (mults.faction_rep_mult)
desc = <>{desc}<br />+{f(mults.faction_rep_mult-1)} reputation from factions</> desc = (
<>
{desc}
<br />+{f(mults.faction_rep_mult - 1)} reputation from factions
</>
);
if (mults.company_rep_mult) if (mults.company_rep_mult)
desc = <>{desc}<br />+{f(mults.company_rep_mult-1)} reputation from companies</> desc = (
<>
{desc}
<br />+{f(mults.company_rep_mult - 1)} reputation from companies
</>
);
} }
if (mults.crime_money_mult) if (mults.crime_money_mult)
desc = <>{desc}<br />+{f(mults.crime_money_mult-1)} crime money</> desc = (
<>
{desc}
<br />+{f(mults.crime_money_mult - 1)} crime money
</>
);
if (mults.crime_success_mult) if (mults.crime_success_mult)
desc = <>{desc}<br />+{f(mults.crime_success_mult-1)} crime success rate</> desc = (
<>
{desc}
<br />+{f(mults.crime_success_mult - 1)} crime success rate
</>
);
if (mults.work_money_mult) if (mults.work_money_mult)
desc = <>{desc}<br />+{f(mults.work_money_mult-1)} work money</> desc = (
<>
{desc}
<br />+{f(mults.work_money_mult - 1)} work money
</>
);
if (mults.hacknet_node_money_mult) if (mults.hacknet_node_money_mult)
desc = <>{desc}<br />+{f(mults.hacknet_node_money_mult-1)} hacknet production</> desc = (
<>
{desc}
<br />+{f(mults.hacknet_node_money_mult - 1)} hacknet production
</>
);
if (mults.hacknet_node_purchase_cost_mult) if (mults.hacknet_node_purchase_cost_mult)
desc = <>{desc}<br />-{f(-(mults.hacknet_node_purchase_cost_mult-1))} hacknet nodes cost</> desc = (
<>
{desc}
<br />-{f(-(mults.hacknet_node_purchase_cost_mult - 1))} hacknet nodes cost
</>
);
if (mults.hacknet_node_level_cost_mult) if (mults.hacknet_node_level_cost_mult)
desc = <>{desc}<br />-{f(-(mults.hacknet_node_level_cost_mult-1))} hacknet nodes upgrade cost</> desc = (
<>
{desc}
<br />-{f(-(mults.hacknet_node_level_cost_mult - 1))} hacknet nodes upgrade cost
</>
);
if (mults.bladeburner_max_stamina_mult) if (mults.bladeburner_max_stamina_mult)
desc = <>{desc}<br />+{f(mults.bladeburner_max_stamina_mult-1)} Bladeburner Max Stamina</> desc = (
<>
{desc}
<br />+{f(mults.bladeburner_max_stamina_mult - 1)} Bladeburner Max Stamina
</>
);
if (mults.bladeburner_stamina_gain_mult) if (mults.bladeburner_stamina_gain_mult)
desc = <>{desc}<br />+{f(mults.bladeburner_stamina_gain_mult-1)} Bladeburner Stamina gain</> desc = (
<>
{desc}
<br />+{f(mults.bladeburner_stamina_gain_mult - 1)} Bladeburner Stamina gain
</>
);
if (mults.bladeburner_analysis_mult) if (mults.bladeburner_analysis_mult)
desc = <>{desc}<br />+{f(mults.bladeburner_analysis_mult-1)} Bladeburner Field Analysis effectiveness</> desc = (
<>
{desc}
<br />+{f(mults.bladeburner_analysis_mult - 1)} Bladeburner Field Analysis effectiveness
</>
);
if (mults.bladeburner_success_chance_mult) if (mults.bladeburner_success_chance_mult)
desc = <>{desc}<br />+{f(mults.bladeburner_success_chance_mult-1)} Bladeburner Contracts and Operations success chance</> desc = (
<>
{desc}
<br />+{f(mults.bladeburner_success_chance_mult - 1)} Bladeburner Contracts and Operations success chance
</>
);
if (startingMoney) if (startingMoney)
desc = <>{desc}<br />Start with {Money(startingMoney)} after installing Augmentations.</> desc = (
<>
{desc}
<br />
Start with <Money money={startingMoney} /> after installing Augmentations.
</>
);
if (programs) if (programs)
desc = <>{desc}<br />Start with {programs.join(' and ')} after installing Augmentations.</> desc = (
<>
{desc}
<br />
Start with {programs.join(" and ")} after installing Augmentations.
</>
);
return desc; return desc;
} }
export class Augmentation { export class Augmentation {
// How much money this costs to buy // How much money this costs to buy
baseCost = 0; baseCost = 0;
@@ -205,12 +388,19 @@ export class Augmentation {
// Multipliers given by this Augmentation. Must match the property name in // Multipliers given by this Augmentation. Must match the property name in
// The Player/Person classes // The Player/Person classes
mults: IMap<number> = {} mults: IMap<number> = {};
// Initial cost. Doesn't change when you purchase multiple Augmentation // Initial cost. Doesn't change when you purchase multiple Augmentation
startingCost = 0; startingCost = 0;
constructor(params: IConstructorParams={ info: "", moneyCost: 0, name: "", repCost: 0 }) { constructor(
params: IConstructorParams = {
info: "",
moneyCost: 0,
name: "",
repCost: 0,
},
) {
this.name = params.name; this.name = params.name;
this.info = params.info; this.info = params.info;
this.prereqs = params.prereqs ? params.prereqs : []; this.prereqs = params.prereqs ? params.prereqs : [];
@@ -226,41 +416,99 @@ export class Augmentation {
this.level = 0; this.level = 0;
// Set multipliers // Set multipliers
if (params.hacking_mult) { this.mults.hacking_mult = params.hacking_mult; } if (params.hacking_mult) {
if (params.strength_mult) { this.mults.strength_mult = params.strength_mult; } this.mults.hacking_mult = params.hacking_mult;
if (params.defense_mult) { this.mults.defense_mult = params.defense_mult; } }
if (params.dexterity_mult) { this.mults.dexterity_mult = params.dexterity_mult; } if (params.strength_mult) {
if (params.agility_mult) { this.mults.agility_mult = params.agility_mult; } this.mults.strength_mult = params.strength_mult;
if (params.charisma_mult) { this.mults.charisma_mult = params.charisma_mult; } }
if (params.hacking_exp_mult) { this.mults.hacking_exp_mult = params.hacking_exp_mult; } if (params.defense_mult) {
if (params.strength_exp_mult) { this.mults.strength_exp_mult = params.strength_exp_mult; } this.mults.defense_mult = params.defense_mult;
if (params.defense_exp_mult) { this.mults.defense_exp_mult = params.defense_exp_mult; } }
if (params.dexterity_exp_mult) { this.mults.dexterity_exp_mult = params.dexterity_exp_mult; } if (params.dexterity_mult) {
if (params.agility_exp_mult) { this.mults.agility_exp_mult = params.agility_exp_mult; } this.mults.dexterity_mult = params.dexterity_mult;
if (params.charisma_exp_mult) { this.mults.charisma_exp_mult = params.charisma_exp_mult; } }
if (params.hacking_chance_mult) { this.mults.hacking_chance_mult = params.hacking_chance_mult; } if (params.agility_mult) {
if (params.hacking_speed_mult) { this.mults.hacking_speed_mult = params.hacking_speed_mult; } this.mults.agility_mult = params.agility_mult;
if (params.hacking_money_mult) { this.mults.hacking_money_mult = params.hacking_money_mult; } }
if (params.hacking_grow_mult) { this.mults.hacking_grow_mult = params.hacking_grow_mult; } if (params.charisma_mult) {
if (params.company_rep_mult) { this.mults.company_rep_mult = params.company_rep_mult; } this.mults.charisma_mult = params.charisma_mult;
if (params.faction_rep_mult) { this.mults.faction_rep_mult = params.faction_rep_mult; } }
if (params.crime_money_mult) { this.mults.crime_money_mult = params.crime_money_mult; } if (params.hacking_exp_mult) {
if (params.crime_success_mult) { this.mults.crime_success_mult = params.crime_success_mult; } this.mults.hacking_exp_mult = params.hacking_exp_mult;
if (params.work_money_mult) { this.mults.work_money_mult = params.work_money_mult; } }
if (params.hacknet_node_money_mult) { this.mults.hacknet_node_money_mult = params.hacknet_node_money_mult; } if (params.strength_exp_mult) {
if (params.hacknet_node_purchase_cost_mult) { this.mults.hacknet_node_purchase_cost_mult = params.hacknet_node_purchase_cost_mult; } this.mults.strength_exp_mult = params.strength_exp_mult;
if (params.hacknet_node_ram_cost_mult) { this.mults.hacknet_node_ram_cost_mult = params.hacknet_node_ram_cost_mult; } }
if (params.hacknet_node_core_cost_mult) { this.mults.hacknet_node_core_cost_mult = params.hacknet_node_core_cost_mult; } if (params.defense_exp_mult) {
if (params.hacknet_node_level_cost_mult) { this.mults.hacknet_node_level_cost_mult = params.hacknet_node_level_cost_mult; } this.mults.defense_exp_mult = params.defense_exp_mult;
if (params.bladeburner_max_stamina_mult) { this.mults.bladeburner_max_stamina_mult = params.bladeburner_max_stamina_mult; } }
if (params.bladeburner_stamina_gain_mult) { this.mults.bladeburner_stamina_gain_mult = params.bladeburner_stamina_gain_mult; } if (params.dexterity_exp_mult) {
if (params.bladeburner_analysis_mult) { this.mults.bladeburner_analysis_mult = params.bladeburner_analysis_mult; } this.mults.dexterity_exp_mult = params.dexterity_exp_mult;
if (params.bladeburner_success_chance_mult) { this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult; } }
if (params.agility_exp_mult) {
this.mults.agility_exp_mult = params.agility_exp_mult;
}
if (params.charisma_exp_mult) {
this.mults.charisma_exp_mult = params.charisma_exp_mult;
}
if (params.hacking_chance_mult) {
this.mults.hacking_chance_mult = params.hacking_chance_mult;
}
if (params.hacking_speed_mult) {
this.mults.hacking_speed_mult = params.hacking_speed_mult;
}
if (params.hacking_money_mult) {
this.mults.hacking_money_mult = params.hacking_money_mult;
}
if (params.hacking_grow_mult) {
this.mults.hacking_grow_mult = params.hacking_grow_mult;
}
if (params.company_rep_mult) {
this.mults.company_rep_mult = params.company_rep_mult;
}
if (params.faction_rep_mult) {
this.mults.faction_rep_mult = params.faction_rep_mult;
}
if (params.crime_money_mult) {
this.mults.crime_money_mult = params.crime_money_mult;
}
if (params.crime_success_mult) {
this.mults.crime_success_mult = params.crime_success_mult;
}
if (params.work_money_mult) {
this.mults.work_money_mult = params.work_money_mult;
}
if (params.hacknet_node_money_mult) {
this.mults.hacknet_node_money_mult = params.hacknet_node_money_mult;
}
if (params.hacknet_node_purchase_cost_mult) {
this.mults.hacknet_node_purchase_cost_mult = params.hacknet_node_purchase_cost_mult;
}
if (params.hacknet_node_ram_cost_mult) {
this.mults.hacknet_node_ram_cost_mult = params.hacknet_node_ram_cost_mult;
}
if (params.hacknet_node_core_cost_mult) {
this.mults.hacknet_node_core_cost_mult = params.hacknet_node_core_cost_mult;
}
if (params.hacknet_node_level_cost_mult) {
this.mults.hacknet_node_level_cost_mult = params.hacknet_node_level_cost_mult;
}
if (params.bladeburner_max_stamina_mult) {
this.mults.bladeburner_max_stamina_mult = params.bladeburner_max_stamina_mult;
}
if (params.bladeburner_stamina_gain_mult) {
this.mults.bladeburner_stamina_gain_mult = params.bladeburner_stamina_gain_mult;
}
if (params.bladeburner_analysis_mult) {
this.mults.bladeburner_analysis_mult = params.bladeburner_analysis_mult;
}
if (params.bladeburner_success_chance_mult) {
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult;
}
if(params.stats) if (params.stats) this.stats = params.stats;
this.stats = params.stats; else this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
else
this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
} }
// Adds this Augmentation to the specified Factions // Adds this Augmentation to the specified Factions
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -115,4 +115,4 @@ export const AugmentationNames: IMap<string> = {
//PepBoyForceField Generates plasma force fields //PepBoyForceField Generates plasma force fields
//PepBoyBlasts Generate high density plasma concussive blasts //PepBoyBlasts Generate high density plasma concussive blasts
//PepBoyDataStorage STore more data on pep boy, //PepBoyDataStorage STore more data on pep boy,
} };
@@ -33,10 +33,8 @@ export function InstalledAugmentations(): React.ReactElement {
<li key={e.name}> <li key={e.name}>
<AugmentationAccordion aug={aug} level={level} /> <AugmentationAccordion aug={aug} level={level} />
</li> </li>
) );
}); });
return ( return <>{augs}</>;
<>{augs}</>
)
} }
@@ -17,11 +17,11 @@ import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
type IProps = { type IProps = {
// nothing special. // nothing special.
} };
type IState = { type IState = {
rerenderFlag: boolean; rerenderFlag: boolean;
} };
export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps, IState> { export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps, IState> {
listRef: React.RefObject<HTMLUListElement>; listRef: React.RefObject<HTMLUListElement>;
@@ -31,7 +31,7 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps
this.state = { this.state = {
rerenderFlag: false, rerenderFlag: false,
} };
this.collapseAllHeaders = this.collapseAllHeaders.bind(this); this.collapseAllHeaders = this.collapseAllHeaders.bind(this);
this.expandAllHeaders = this.expandAllHeaders.bind(this); this.expandAllHeaders = this.expandAllHeaders.bind(this);
@@ -43,7 +43,9 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps
collapseAllHeaders(): void { collapseAllHeaders(): void {
const ul = this.listRef.current; const ul = this.listRef.current;
if (ul == null) { return; } if (ul == null) {
return;
}
const tickers = ul.getElementsByClassName("accordion-header"); const tickers = ul.getElementsByClassName("accordion-header");
for (let i = 0; i < tickers.length; ++i) { for (let i = 0; i < tickers.length; ++i) {
const ticker = tickers[i]; const ticker = tickers[i];
@@ -59,7 +61,9 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps
expandAllHeaders(): void { expandAllHeaders(): void {
const ul = this.listRef.current; const ul = this.listRef.current;
if (ul == null) { return; } if (ul == null) {
return;
}
const tickers = ul.getElementsByClassName("accordion-header"); const tickers = ul.getElementsByClassName("accordion-header");
for (let i = 0; i < tickers.length; ++i) { for (let i = 0; i < tickers.length; ++i) {
const ticker = tickers[i]; const ticker = tickers[i];
@@ -77,7 +81,7 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps
this.setState((prevState) => { this.setState((prevState) => {
return { return {
rerenderFlag: !prevState.rerenderFlag, rerenderFlag: !prevState.rerenderFlag,
} };
}); });
} }
@@ -87,7 +91,7 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps
} }
sortInOrder(): void { sortInOrder(): void {
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
this.rerender(); this.rerender();
} }
@@ -106,6 +110,6 @@ export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps
<InstalledAugmentations /> <InstalledAugmentations />
</ul> </ul>
</> </>
) );
} }
} }
+4 -10
View File
@@ -11,19 +11,13 @@ type IProps = {
expandAllButtonsFn: () => void; expandAllButtonsFn: () => void;
sortByAcquirementTimeFn: () => void; sortByAcquirementTimeFn: () => void;
sortInOrderFn: () => void; sortInOrderFn: () => void;
} };
export function ListConfiguration(props: IProps): React.ReactElement { export function ListConfiguration(props: IProps): React.ReactElement {
return ( return (
<> <>
<StdButton <StdButton onClick={props.expandAllButtonsFn} text="Expand All" />
onClick={props.expandAllButtonsFn} <StdButton onClick={props.collapseAllButtonsFn} text="Collapse All" />
text="Expand All"
/>
<StdButton
onClick={props.collapseAllButtonsFn}
text="Collapse All"
/>
<StdButton <StdButton
onClick={props.sortInOrderFn} onClick={props.sortInOrderFn}
text="Sort in Order" text="Sort in Order"
@@ -35,5 +29,5 @@ export function ListConfiguration(props: IProps): React.ReactElement {
tooltip="Sorts the Augmentations and Source-Files based on when you acquired them (same as default)" tooltip="Sorts the Augmentations and Source-Files based on when you acquired them (same as default)"
/> />
</> </>
) );
} }
+2 -4
View File
@@ -32,10 +32,8 @@ export function OwnedSourceFiles(): React.ReactElement {
<li key={e.n}> <li key={e.n}>
<SourceFileAccordion level={e.lvl} sf={sfObj} /> <SourceFileAccordion level={e.lvl} sf={sfObj} />
</li> </li>
) );
}); });
return ( return <>{sfs}</>;
<>{sfs}</>
);
} }
+114 -56
View File
@@ -25,98 +25,156 @@ export function PlayerMultipliers(): React.ReactElement {
function improvements(r: number): JSX.Element[] { function improvements(r: number): JSX.Element[] {
let elems: JSX.Element[] = []; let elems: JSX.Element[] = [];
if (r) { if (r) {
elems = [ elems = [<td key="2">&nbsp;{"=>"}&nbsp;</td>, <td key="3">{numeralWrapper.formatPercentage(r)}</td>];
<td key="2">&nbsp;{"=>"}&nbsp;</td>,
<td key="3">{numeralWrapper.formatPercentage(r)}</td>,
];
} }
return elems; return elems;
} }
return <table> return (
<table>
<tbody> <tbody>
{rows.map((r: any) => <tr key={r[0]}> {rows.map((r: any) => (
<td key="0"><span>{r[0]} multiplier:&nbsp;</span></td> <tr key={r[0]}>
<td key="1" style={{textAlign: 'right'}}>{numeralWrapper.formatPercentage(r[1])}</td> <td key="0">
<span>{r[0]} multiplier:&nbsp;</span>
</td>
<td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatPercentage(r[1])}
</td>
{improvements(r[2])} {improvements(r[2])}
</tr>)} </tr>
))}
</tbody> </tbody>
</table> </table>
);
} }
function BladeburnerMults(): React.ReactElement { function BladeburnerMults(): React.ReactElement {
if(!Player.canAccessBladeburner()) return (<></>); if (!Player.canAccessBladeburner()) return <></>;
return (<> return (
<>
{MultiplierTable([ {MultiplierTable([
['Bladeburner Success Chance', Player.bladeburner_success_chance_mult, Player.bladeburner_success_chance_mult*mults.bladeburner_success_chance_mult], [
['Bladeburner Max Stamina', Player.bladeburner_max_stamina_mult, Player.bladeburner_max_stamina_mult*mults.bladeburner_max_stamina_mult], "Bladeburner Success Chance",
['Bladeburner Stamina Gain', Player.bladeburner_stamina_gain_mult, Player.bladeburner_stamina_gain_mult*mults.bladeburner_stamina_gain_mult], Player.bladeburner_success_chance_mult,
['Bladeburner Field Analysis', Player.bladeburner_analysis_mult, Player.bladeburner_analysis_mult*mults.bladeburner_analysis_mult], Player.bladeburner_success_chance_mult * mults.bladeburner_success_chance_mult,
])}<br /> ],
</>); [
"Bladeburner Max Stamina",
Player.bladeburner_max_stamina_mult,
Player.bladeburner_max_stamina_mult * mults.bladeburner_max_stamina_mult,
],
[
"Bladeburner Stamina Gain",
Player.bladeburner_stamina_gain_mult,
Player.bladeburner_stamina_gain_mult * mults.bladeburner_stamina_gain_mult,
],
[
"Bladeburner Field Analysis",
Player.bladeburner_analysis_mult,
Player.bladeburner_analysis_mult * mults.bladeburner_analysis_mult,
],
])}
<br />
</>
);
} }
return ( return (
<> <>
<p><strong><u>Multipliers:</u></strong></p><br /> <p>
<strong>
<u>Multipliers:</u>
</strong>
</p>
<br />
{MultiplierTable([ {MultiplierTable([
['Hacking Chance ', Player.hacking_chance_mult, Player.hacking_chance_mult*mults.hacking_chance_mult], ["Hacking Chance ", Player.hacking_chance_mult, Player.hacking_chance_mult * mults.hacking_chance_mult],
['Hacking Speed ', Player.hacking_speed_mult, Player.hacking_speed_mult*mults.hacking_speed_mult], ["Hacking Speed ", Player.hacking_speed_mult, Player.hacking_speed_mult * mults.hacking_speed_mult],
['Hacking Money ', Player.hacking_money_mult, Player.hacking_money_mult*mults.hacking_money_mult], ["Hacking Money ", Player.hacking_money_mult, Player.hacking_money_mult * mults.hacking_money_mult],
['Hacking Growth ', Player.hacking_grow_mult, Player.hacking_grow_mult*mults.hacking_grow_mult], ["Hacking Growth ", Player.hacking_grow_mult, Player.hacking_grow_mult * mults.hacking_grow_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Hacking Level ', Player.hacking_mult, Player.hacking_mult*mults.hacking_mult], ["Hacking Level ", Player.hacking_mult, Player.hacking_mult * mults.hacking_mult],
['Hacking Experience ', Player.hacking_exp_mult, Player.hacking_exp_mult*mults.hacking_exp_mult], ["Hacking Experience ", Player.hacking_exp_mult, Player.hacking_exp_mult * mults.hacking_exp_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Strength Level ', Player.strength_mult, Player.strength_mult*mults.strength_mult], ["Strength Level ", Player.strength_mult, Player.strength_mult * mults.strength_mult],
['Strength Experience ', Player.strength_exp_mult, Player.strength_exp_mult*mults.strength_exp_mult], ["Strength Experience ", Player.strength_exp_mult, Player.strength_exp_mult * mults.strength_exp_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Defense Level ', Player.defense_mult, Player.defense_mult*mults.defense_mult], ["Defense Level ", Player.defense_mult, Player.defense_mult * mults.defense_mult],
['Defense Experience ', Player.defense_exp_mult, Player.defense_exp_mult*mults.defense_exp_mult], ["Defense Experience ", Player.defense_exp_mult, Player.defense_exp_mult * mults.defense_exp_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Dexterity Level ', Player.dexterity_mult, Player.dexterity_mult*mults.dexterity_mult], ["Dexterity Level ", Player.dexterity_mult, Player.dexterity_mult * mults.dexterity_mult],
['Dexterity Experience ', Player.dexterity_exp_mult, Player.dexterity_exp_mult*mults.dexterity_exp_mult], ["Dexterity Experience ", Player.dexterity_exp_mult, Player.dexterity_exp_mult * mults.dexterity_exp_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Agility Level ', Player.agility_mult, Player.agility_mult*mults.agility_mult], ["Agility Level ", Player.agility_mult, Player.agility_mult * mults.agility_mult],
['Agility Experience ', Player.agility_exp_mult, Player.agility_exp_mult*mults.agility_exp_mult], ["Agility Experience ", Player.agility_exp_mult, Player.agility_exp_mult * mults.agility_exp_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Charisma Level ', Player.charisma_mult, Player.charisma_mult*mults.charisma_mult], ["Charisma Level ", Player.charisma_mult, Player.charisma_mult * mults.charisma_mult],
['Charisma Experience ', Player.charisma_exp_mult, Player.charisma_exp_mult*mults.charisma_exp_mult], ["Charisma Experience ", Player.charisma_exp_mult, Player.charisma_exp_mult * mults.charisma_exp_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Hacknet Node production ', Player.hacknet_node_money_mult, Player.hacknet_node_money_mult*mults.hacknet_node_money_mult], [
['Hacknet Node purchase cost ', Player.hacknet_node_purchase_cost_mult, Player.hacknet_node_purchase_cost_mult*mults.hacknet_node_purchase_cost_mult], "Hacknet Node production ",
['Hacknet Node RAM upgrade cost ', Player.hacknet_node_ram_cost_mult, Player.hacknet_node_ram_cost_mult*mults.hacknet_node_ram_cost_mult], Player.hacknet_node_money_mult,
['Hacknet Node Core purchase cost ', Player.hacknet_node_core_cost_mult, Player.hacknet_node_core_cost_mult*mults.hacknet_node_core_cost_mult], Player.hacknet_node_money_mult * mults.hacknet_node_money_mult,
['Hacknet Node level upgrade cost ', Player.hacknet_node_level_cost_mult, Player.hacknet_node_level_cost_mult*mults.hacknet_node_level_cost_mult], ],
])}<br /> [
"Hacknet Node purchase cost ",
Player.hacknet_node_purchase_cost_mult,
Player.hacknet_node_purchase_cost_mult * mults.hacknet_node_purchase_cost_mult,
],
[
"Hacknet Node RAM upgrade cost ",
Player.hacknet_node_ram_cost_mult,
Player.hacknet_node_ram_cost_mult * mults.hacknet_node_ram_cost_mult,
],
[
"Hacknet Node Core purchase cost ",
Player.hacknet_node_core_cost_mult,
Player.hacknet_node_core_cost_mult * mults.hacknet_node_core_cost_mult,
],
[
"Hacknet Node level upgrade cost ",
Player.hacknet_node_level_cost_mult,
Player.hacknet_node_level_cost_mult * mults.hacknet_node_level_cost_mult,
],
])}
<br />
{MultiplierTable([ {MultiplierTable([
['Company reputation gain ', Player.company_rep_mult, Player.company_rep_mult*mults.company_rep_mult], ["Company reputation gain ", Player.company_rep_mult, Player.company_rep_mult * mults.company_rep_mult],
['Faction reputation gain ', Player.faction_rep_mult, Player.faction_rep_mult*mults.faction_rep_mult], ["Faction reputation gain ", Player.faction_rep_mult, Player.faction_rep_mult * mults.faction_rep_mult],
['Salary ', Player.work_money_mult, Player.work_money_mult*mults.work_money_mult], ["Salary ", Player.work_money_mult, Player.work_money_mult * mults.work_money_mult],
])}<br /> ])}
<br />
{MultiplierTable([ {MultiplierTable([
['Crime success ', Player.crime_success_mult, Player.crime_success_mult*mults.crime_success_mult], ["Crime success ", Player.crime_success_mult, Player.crime_success_mult * mults.crime_success_mult],
['Crime money ', Player.crime_money_mult, Player.crime_money_mult*mults.crime_money_mult], ["Crime money ", Player.crime_money_mult, Player.crime_money_mult * mults.crime_money_mult],
])}<br /> ])}
<br />
<BladeburnerMults /> <BladeburnerMults />
</> </>
) );
} }
@@ -33,10 +33,8 @@ export function PurchasedAugmentations(): React.ReactElement {
<li key={`${ownedAug.name}${ownedAug.level}`}> <li key={`${ownedAug.name}${ownedAug.level}`}>
<AugmentationAccordion aug={aug} level={level} /> <AugmentationAccordion aug={aug} level={level} />
</li>, </li>,
) );
} }
return ( return <ul className="augmentations-list">{augs}</ul>;
<ul className="augmentations-list">{augs}</ul>
)
} }
+14 -23
View File
@@ -15,11 +15,11 @@ import { canGetBonus } from "../../ExportBonus";
type IProps = { type IProps = {
exportGameFn: () => void; exportGameFn: () => void;
installAugmentationsFn: () => void; installAugmentationsFn: () => void;
} };
type IState = { type IState = {
rerender: boolean; rerender: boolean;
} };
export class AugmentationsRoot extends React.Component<IProps, IState> { export class AugmentationsRoot extends React.Component<IProps, IState> {
constructor(props: IProps) { constructor(props: IProps) {
@@ -47,34 +47,29 @@ export class AugmentationsRoot extends React.Component<IProps, IState> {
<div id="augmentations-content"> <div id="augmentations-content">
<h1>Purchased Augmentations</h1> <h1>Purchased Augmentations</h1>
<p> <p>
Below is a list of all Augmentations you have purchased but not Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
yet installed. Click the button below to install them. install them.
</p> </p>
<p> <p>WARNING: Installing your Augmentations resets most of your progress, including:</p>
WARNING: Installing your Augmentations resets most of your progress, <br />
including:
</p><br />
<p>- Stats/Skill levels and Experience</p> <p>- Stats/Skill levels and Experience</p>
<p>- Money</p> <p>- Money</p>
<p>- Scripts on every computer but your home computer</p> <p>- Scripts on every computer but your home computer</p>
<p>- Purchased servers</p> <p>- Purchased servers</p>
<p>- Hacknet Nodes</p> <p>- Hacknet Nodes</p>
<p>- Faction/Company reputation</p> <p>- Faction/Company reputation</p>
<p>- Stocks</p><br /> <p>- Stocks</p>
<br />
<p> <p>
Installing Augmentations lets you start over with the perks and Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
benefits granted by all of the Augmentations you have ever you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but you
installed. Also, you will keep any scripts and RAM/Core upgrades will lose all programs besides NUKE.exe)
on your home computer (but you will lose all programs besides
NUKE.exe)
</p> </p>
<StdButton <StdButton
onClick={this.props.installAugmentationsFn} onClick={this.props.installAugmentationsFn}
text="Install Augmentations" text="Install Augmentations"
tooltip="'I never asked for this'" tooltip="'I never asked for this'"
/> />
<StdButton <StdButton
addClasses="flashing-button" addClasses="flashing-button"
onClick={this.export} onClick={this.export}
@@ -82,19 +77,15 @@ export class AugmentationsRoot extends React.Component<IProps, IState> {
tooltip="It's always a good idea to backup/export your save!" tooltip="It's always a good idea to backup/export your save!"
/> />
<PurchasedAugmentations /> <PurchasedAugmentations />
<h1>Installed Augmentations</h1> <h1>Installed Augmentations</h1>
<p> <p>
{ {`List of all Augmentations ${Player.sourceFiles.length > 0 ? "and Source Files " : ""} ` +
`List of all Augmentations ${Player.sourceFiles.length > 0 ? "and Source Files " : ""} ` + `that have been installed. You have gained the effects of these.`}
`that have been installed. You have gained the effects of these.`
}
</p> </p>
<InstalledAugmentationsAndSourceFiles /> <InstalledAugmentationsAndSourceFiles />
<br /> <br /> <br /> <br />
<PlayerMultipliers /> <PlayerMultipliers />
</div> </div>
) );
} }
} }
+14 -6
View File
@@ -13,10 +13,11 @@ export function SourceFileMinus1(): React.ReactElement {
const exploits = Player.exploits; const exploits = Player.exploits;
if (exploits.length === 0) { if (exploits.length === 0) {
return <></> return <></>;
} }
return (<li key={-1}> return (
<li key={-1}>
<Accordion <Accordion
headerContent={ headerContent={
<> <>
@@ -27,15 +28,22 @@ export function SourceFileMinus1(): React.ReactElement {
} }
panelContent={ panelContent={
<> <>
<p>This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web ecosystem.</p> <p>
<p>It increases all of the player's multipliers by 0.1%</p><br /> This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web
ecosystem.
</p>
<p>It increases all of the player's multipliers by 0.1%</p>
<br />
<p>You have found the following exploits:</p> <p>You have found the following exploits:</p>
<ul> <ul>
{exploits.map((c: Exploit) => <li key={c}>* {ExploitName(c)}</li>)} {exploits.map((c: Exploit) => (
<li key={c}>* {ExploitName(c)}</li>
))}
</ul> </ul>
</> </>
} }
/> />
</li>) </li>
);
} }
+74 -27
View File
@@ -15,7 +15,6 @@ class BitNode {
// BitNode number // BitNode number
number: number; number: number;
constructor(n: number, name: string, desc = "", info = "") { constructor(n: number, name: string, desc = "", info = "") {
this.number = n; this.number = n;
this.name = name; this.name = name;
@@ -24,10 +23,12 @@ class BitNode {
} }
} }
export const BitNodes: IMap<BitNode> = {}; export const BitNodes: IMap<BitNode> = {};
BitNodes["BitNode1"] = new BitNode(1, "Source Genesis", "The original BitNode", BitNodes["BitNode1"] = new BitNode(
1,
"Source Genesis",
"The original BitNode",
"The first BitNode created by the Enders to imprison the minds of humans. It became " + "The first BitNode created by the Enders to imprison the minds of humans. It became " +
"the prototype and testing-grounds for all of the BitNodes that followed.<br><br>" + "the prototype and testing-grounds for all of the BitNodes that followed.<br><br>" +
"This is the first BitNode that you play through. It has no special " + "This is the first BitNode that you play through. It has no special " +
@@ -38,8 +39,12 @@ BitNodes["BitNode1"] = new BitNode(1, "Source Genesis", "The original BitNode",
"new BitNode, and also increases all of the player's multipliers by:<br><br>" + "new BitNode, and also increases all of the player's multipliers by:<br><br>" +
"Level 1: 16%<br>" + "Level 1: 16%<br>" +
"Level 2: 24%<br>" + "Level 2: 24%<br>" +
"Level 3: 28%"); "Level 3: 28%",
BitNodes["BitNode2"] = new BitNode(2, "Rise of the Underworld", "From the shadows, they rose", //Gangs );
BitNodes["BitNode2"] = new BitNode(
2,
"Rise of the Underworld",
"From the shadows, they rose", //Gangs
"From the shadows, they rose.<br><br>Organized crime groups quickly filled the void of power " + "From the shadows, they rose.<br><br>Organized crime groups quickly filled the void of power " +
"left behind from the collapse of Western government in the 2050s. As society and civlization broke down, " + "left behind from the collapse of Western government in the 2050s. As society and civlization broke down, " +
"people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " + "people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " +
@@ -60,8 +65,12 @@ BitNodes["BitNode2"] = new BitNode(2, "Rise of the Underworld", "From the shadow
"It also increases the player's crime success rate, crime money, and charisma multipliers by:<br><br>" + "It also increases the player's crime success rate, crime money, and charisma multipliers by:<br><br>" +
"Level 1: 24%<br>" + "Level 1: 24%<br>" +
"Level 2: 36%<br>" + "Level 2: 36%<br>" +
"Level 3: 42%"); "Level 3: 42%",
BitNodes["BitNode3"] = new BitNode(3, "Corporatocracy", "The Price of Civilization", );
BitNodes["BitNode3"] = new BitNode(
3,
"Corporatocracy",
"The Price of Civilization",
"Our greatest illusion is that a healthy society can revolve around a " + "Our greatest illusion is that a healthy society can revolve around a " +
"single-minded pursuit of wealth.<br><br>" + "single-minded pursuit of wealth.<br><br>" +
"Sometime in the early 21st century economic and political globalization turned " + "Sometime in the early 21st century economic and political globalization turned " +
@@ -79,8 +88,12 @@ BitNodes["BitNode3"] = new BitNode(3, "Corporatocracy", "The Price of Civilizati
"some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by:<br>" + "some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by:<br>" +
"Level 1: 8%<br>" + "Level 1: 8%<br>" +
"Level 2: 12%<br>" + "Level 2: 12%<br>" +
"Level 3: 14%"); "Level 3: 14%",
BitNodes["BitNode4"] = new BitNode(4, "The Singularity", "The Man and the Machine", );
BitNodes["BitNode4"] = new BitNode(
4,
"The Singularity",
"The Man and the Machine",
"The Singularity has arrived. The human race is gone, replaced " + "The Singularity has arrived. The human race is gone, replaced " +
"by artificially superintelligent beings that are more machine than man. <br><br>" + "by artificially superintelligent beings that are more machine than man. <br><br>" +
"In this BitNode, progressing is significantly harder. Experience gain rates " + "In this BitNode, progressing is significantly harder. Experience gain rates " +
@@ -91,8 +104,12 @@ BitNodes["BitNode4"] = new BitNode(4, "The Singularity", "The Man and the Machin
"Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will " + "Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " + "upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " +
"Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " + "Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " +
"that you can use."); "that you can use.",
BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "Posthuman", );
BitNodes["BitNode5"] = new BitNode(
5,
"Artificial Intelligence",
"Posthuman",
"They said it couldn't be done. They said the human brain, " + "They said it couldn't be done. They said the human brain, " +
"along with its consciousness and intelligence, couldn't be replicated. They said the complexity " + "along with its consciousness and intelligence, couldn't be replicated. They said the complexity " +
"of the brain results from unpredictable, nonlinear interactions that couldn't be modeled " + "of the brain results from unpredictable, nonlinear interactions that couldn't be modeled " +
@@ -115,8 +132,12 @@ BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "Posthuman",
"as well as the formulas API, and will also raise all of your hacking-related multipliers by:<br><br>" + "as well as the formulas API, and will also raise all of your hacking-related multipliers by:<br><br>" +
"Level 1: 8%<br>" + "Level 1: 8%<br>" +
"Level 2: 12%<br>" + "Level 2: 12%<br>" +
"Level 3: 14%"); "Level 3: 14%",
BitNodes["BitNode6"] = new BitNode(6, "Bladeburners", "Like Tears in Rain", );
BitNodes["BitNode6"] = new BitNode(
6,
"Bladeburners",
"Like Tears in Rain",
"In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic " + "In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic " +
"androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation " + "androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation " +
"of their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was " + "of their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was " +
@@ -135,8 +156,12 @@ BitNodes["BitNode6"] = new BitNode(6, "Bladeburners", "Like Tears in Rain",
"BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:<br><br>" + "BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:<br><br>" +
"Level 1: 8%<br>" + "Level 1: 8%<br>" +
"Level 2: 12%<br>" + "Level 2: 12%<br>" +
"Level 3: 14%"); "Level 3: 14%",
BitNodes["BitNode7"] = new BitNode(7, "Bladeburners 2079", "More human than humans", );
BitNodes["BitNode7"] = new BitNode(
7,
"Bladeburners 2079",
"More human than humans",
"In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI design team " + "In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI design team " +
"for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological " + "for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological " +
"breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a hyperintelligent AI. " + "breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a hyperintelligent AI. " +
@@ -158,8 +183,12 @@ BitNodes["BitNode7"] = new BitNode(7, "Bladeburners 2079", "More human than huma
"BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:<br><br>" + "BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:<br><br>" +
"Level 1: 8%<br>" + "Level 1: 8%<br>" +
"Level 2: 12%<br>" + "Level 2: 12%<br>" +
"Level 3: 14%"); "Level 3: 14%",
BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "Money never sleeps", );
BitNodes["BitNode8"] = new BitNode(
8,
"Ghost of Wall Street",
"Money never sleeps",
"You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.<br><br>" + "You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.<br><br>" +
"In this BitNode:<br><br>" + "In this BitNode:<br><br>" +
"You start with $250 million<br>" + "You start with $250 million<br>" +
@@ -173,8 +202,12 @@ BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "Money never sleep
"Level 2: Ability to short stocks in other BitNodes<br>" + "Level 2: Ability to short stocks in other BitNodes<br>" +
"Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" + "Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" +
"This Source-File also increases your hacking growth multipliers by: " + "This Source-File also increases your hacking growth multipliers by: " +
"<br>Level 1: 12%<br>Level 2: 18%<br>Level 3: 21%"); "<br>Level 1: 12%<br>Level 2: 18%<br>Level 3: 21%",
BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed", );
BitNodes["BitNode9"] = new BitNode(
9,
"Hacktocracy",
"Hacknet Unleashed",
"When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " + "When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " +
"became the OS of choice for the underground hacking community. Chapeau became especially notorious for " + "became the OS of choice for the underground hacking community. Chapeau became especially notorious for " +
"powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " + "powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " +
@@ -191,8 +224,12 @@ BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "Hacknet Unleashed",
"Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode<br>" + "Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode<br>" +
"Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode<br><br>" + "Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode<br><br>" +
"(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " + "(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
"when installing Augmentations)"); "when installing Augmentations)",
BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who you are", );
BitNodes["BitNode10"] = new BitNode(
10,
"Digital Carbon",
"Your body is not who you are",
"In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " + "In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " +
"to digitize their consciousness. Their consciousness could then be transferred into Synthoids " + "to digitize their consciousness. Their consciousness could then be transferred into Synthoids " +
"or other bodies by trasmitting the digitized data. Human bodies became nothing more than 'sleeves' for the " + "or other bodies by trasmitting the digitized data. Human bodies became nothing more than 'sleeves' for the " +
@@ -207,8 +244,12 @@ BitNodes["BitNode10"] = new BitNode(10, "Digital Carbon", "Your body is not who
"Augmentations are 5x as expensive and require twice as much reputation<br><br>" + "Augmentations are 5x as expensive and require twice as much reputation<br><br>" +
"Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " + "Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " + "upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " +
"Each level of this Source-File also grants you a Duplicate Sleeve"); "Each level of this Source-File also grants you a Duplicate Sleeve",
BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.", );
BitNodes["BitNode11"] = new BitNode(
11,
"The Big Crash",
"Okay. Sell it all.",
"The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " + "The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " +
"of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " + "of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " +
"the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.<br><br>" + "the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.<br><br>" +
@@ -235,12 +276,17 @@ BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.",
"It also reduces the price increase for every aug bought by:<br><br>" + "It also reduces the price increase for every aug bought by:<br><br>" +
"Level 1: 4%<br>" + "Level 1: 4%<br>" +
"Level 2: 6%<br>" + "Level 2: 6%<br>" +
"Level 3: 7%"); "Level 3: 7%",
BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.", );
BitNodes["BitNode12"] = new BitNode(
12,
"The Recursion",
"Repeat.",
"To iterate is human, to recurse divine.<br><br>" + "To iterate is human, to recurse divine.<br><br>" +
"Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give you Source-File 12, or " + "Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give you Source-File 12, or " +
"if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " + "if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
"of Source-File 12 lets you start any BitNodes with NeuroFlux Governor equal to the level of this source file."); "of Source-File 12 lets you start any BitNodes with NeuroFlux Governor equal to the level of this source file.",
);
// Books: Frontera, Shiner // Books: Frontera, Shiner
BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON"); BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
@@ -436,7 +482,8 @@ export function initBitNodeMultipliers(p: IPlayer): void {
BitNodeMultipliers.FourSigmaMarketDataCost = 4; BitNodeMultipliers.FourSigmaMarketDataCost = 4;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4; BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
break; break;
case 12: { //The Recursion case 12: {
//The Recursion
let sf12Lvl = 0; let sf12Lvl = 0;
for (let i = 0; i < p.sourceFiles.length; i++) { for (let i = 0; i < p.sourceFiles.length; i++) {
if (p.sourceFiles[i].n === 12) { if (p.sourceFiles[i].n === 12) {
+49 -23
View File
@@ -36,7 +36,6 @@ export interface IActionParams {
isStealth?: boolean; isStealth?: boolean;
isKill?: boolean; isKill?: boolean;
count?: number; count?: number;
countGrowth?: number;
weights?: StatsMultiplier; weights?: StatsMultiplier;
decays?: StatsMultiplier; decays?: StatsMultiplier;
teamCount?: number; teamCount?: number;
@@ -74,16 +73,32 @@ export class Action implements IAction {
* Growth rate is an integer and the count will increase by that integer every "cycle" * Growth rate is an integer and the count will increase by that integer every "cycle"
*/ */
count: number = getRandomInt(1e3, 25e3); count: number = getRandomInt(1e3, 25e3);
countGrowth: number = getRandomInt(1, 5);
// Weighting of each stat in determining action success rate // Weighting of each stat in determining action success rate
weights: StatsMultiplier = {hack:1/7,str:1/7,def:1/7,dex:1/7,agi:1/7,cha:1/7,int:1/7}; weights: StatsMultiplier = {
hack: 1 / 7,
str: 1 / 7,
def: 1 / 7,
dex: 1 / 7,
agi: 1 / 7,
cha: 1 / 7,
int: 1 / 7,
};
// Diminishing returns of stats (stat ^ decay where 0 <= decay <= 1) // Diminishing returns of stats (stat ^ decay where 0 <= decay <= 1)
decays: StatsMultiplier = { hack: 0.9, str: 0.9, def: 0.9, dex: 0.9, agi: 0.9, cha: 0.9, int: 0.9 }; decays: StatsMultiplier = {
hack: 0.9,
str: 0.9,
def: 0.9,
dex: 0.9,
agi: 0.9,
cha: 0.9,
int: 0.9,
};
teamCount = 0; teamCount = 0;
// Base Class for Contracts, Operations, and BlackOps // Base Class for Contracts, Operations, and BlackOps
constructor(params: IActionParams| null = null) { // | null = null constructor(params: IActionParams | null = null) {
// | null = null
if (params && params.name) this.name = params.name; if (params && params.name) this.name = params.name;
if (params && params.desc) this.desc = params.desc; if (params && params.desc) this.desc = params.desc;
@@ -99,7 +114,6 @@ export class Action implements IAction {
if (params && params.isKill) this.isKill = params.isKill; if (params && params.isKill) this.isKill = params.isKill;
if (params && params.count) this.count = params.count; if (params && params.count) this.count = params.count;
if(params && params.countGrowth) this.countGrowth = params.countGrowth;
if (params && params.weights) this.weights = params.weights; if (params && params.weights) this.weights = params.weights;
if (params && params.decays) this.decays = params.decays; if (params && params.decays) this.decays = params.decays;
@@ -112,16 +126,20 @@ export class Action implements IAction {
} }
} }
if (sum - 1 >= 10 * Number.EPSILON) { if (sum - 1 >= 10 * Number.EPSILON) {
throw new Error("Invalid weights when constructing Action " + this.name + throw new Error(
". The weights should sum up to 1. They sum up to :" + 1); "Invalid weights when constructing Action " +
this.name +
". The weights should sum up to 1. They sum up to :" +
1,
);
} }
for (const decay in this.decays) { for (const decay in this.decays) {
if (this.decays.hasOwnProperty(decay)) { if (this.decays.hasOwnProperty(decay)) {
if (this.decays[decay] > 1) { if (this.decays[decay] > 1) {
throw new Error("Invalid decays when constructing " + throw new Error(
"Action " + this.name + ". " + "Invalid decays when constructing " + "Action " + this.name + ". " + "Decay value cannot be greater than 1",
"Decay value cannot be greater than 1"); );
} }
} }
} }
@@ -129,7 +147,9 @@ export class Action implements IAction {
getDifficulty(): number { getDifficulty(): number {
const difficulty = this.baseDifficulty * Math.pow(this.difficultyFac, this.level - 1); const difficulty = this.baseDifficulty * Math.pow(this.difficultyFac, this.level - 1);
if (isNaN(difficulty)) {throw new Error("Calculated NaN in Action.getDifficulty()");} if (isNaN(difficulty)) {
throw new Error("Calculated NaN in Action.getDifficulty()");
}
return difficulty; return difficulty;
} }
@@ -138,7 +158,7 @@ export class Action implements IAction {
* @param inst {Bladeburner} - Bladeburner instance * @param inst {Bladeburner} - Bladeburner instance
*/ */
attempt(inst: IBladeburner): boolean { attempt(inst: IBladeburner): boolean {
return (Math.random() < this.getSuccessChance(inst)); return Math.random() < this.getSuccessChance(inst);
} }
// To be implemented by subtypes // To be implemented by subtypes
@@ -153,12 +173,14 @@ export class Action implements IAction {
const effAgility = Player.agility * inst.skillMultipliers.effAgi; const effAgility = Player.agility * inst.skillMultipliers.effAgi;
const effDexterity = Player.dexterity * inst.skillMultipliers.effDex; const effDexterity = Player.dexterity * inst.skillMultipliers.effDex;
const statFac = 0.5 * (Math.pow(effAgility, BladeburnerConstants.EffAgiExponentialFactor) + const statFac =
0.5 *
(Math.pow(effAgility, BladeburnerConstants.EffAgiExponentialFactor) +
Math.pow(effDexterity, BladeburnerConstants.EffDexExponentialFactor) + Math.pow(effDexterity, BladeburnerConstants.EffDexExponentialFactor) +
(effAgility / BladeburnerConstants.EffAgiLinearFactor) + effAgility / BladeburnerConstants.EffAgiLinearFactor +
(effDexterity / BladeburnerConstants.EffDexLinearFactor)); // Always > 1 effDexterity / BladeburnerConstants.EffDexLinearFactor); // Always > 1
baseTime = Math.max(1, baseTime * skillFac / statFac); baseTime = Math.max(1, (baseTime * skillFac) / statFac);
return Math.ceil(baseTime * this.getActionTimePenalty()); return Math.ceil(baseTime * this.getActionTimePenalty());
} }
@@ -177,9 +199,9 @@ export class Action implements IAction {
getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number { getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number {
const city = inst.getCurrentCity(); const city = inst.getCurrentCity();
if (params.est) { if (params.est) {
return Math.pow((city.popEst / BladeburnerConstants.PopulationThreshold), BladeburnerConstants.PopulationExponent); return Math.pow(city.popEst / BladeburnerConstants.PopulationThreshold, BladeburnerConstants.PopulationExponent);
} else { } else {
return Math.pow((city.pop / BladeburnerConstants.PopulationThreshold), BladeburnerConstants.PopulationExponent); return Math.pow(city.pop / BladeburnerConstants.PopulationThreshold, BladeburnerConstants.PopulationExponent);
} }
} }
@@ -217,7 +239,9 @@ export class Action implements IAction {
* est (bool): Get success chance estimate instead of real success chance * est (bool): Get success chance estimate instead of real success chance
*/ */
getSuccessChance(inst: IBladeburner, params: ISuccessChanceParams = { est: false }): number { getSuccessChance(inst: IBladeburner, params: ISuccessChanceParams = { est: false }): number {
if (inst == null) {throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");} if (inst == null) {
throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance");
}
let difficulty = this.getDifficulty(); let difficulty = this.getDifficulty();
let competence = 0; let competence = 0;
for (const stat in this.weights) { for (const stat in this.weights) {
@@ -229,7 +253,7 @@ export class Action implements IAction {
console.error(`Failed to find Bladeburner Skill multiplier for: ${stat}`); console.error(`Failed to find Bladeburner Skill multiplier for: ${stat}`);
effMultiplier = 1; effMultiplier = 1;
} }
competence += (this.weights[stat] * Math.pow(effMultiplier*playerStatLvl, this.decays[stat])); competence += this.weights[stat] * Math.pow(effMultiplier * playerStatLvl, this.decays[stat]);
} }
} }
competence *= Player.getIntelligenceBonus(0.75); competence *= Player.getIntelligenceBonus(0.75);
@@ -257,12 +281,14 @@ export class Action implements IAction {
// Augmentation multiplier // Augmentation multiplier
competence *= Player.bladeburner_success_chance_mult; competence *= Player.bladeburner_success_chance_mult;
if (isNaN(competence)) {throw new Error("Competence calculated as NaN in Action.getSuccessChance()");} if (isNaN(competence)) {
throw new Error("Competence calculated as NaN in Action.getSuccessChance()");
}
return Math.min(1, competence / difficulty); return Math.min(1, competence / difficulty);
} }
getSuccessesNeededForNextLevel(baseSuccessesPerLevel: number): number { getSuccessesNeededForNextLevel(baseSuccessesPerLevel: number): number {
return Math.ceil((0.5) * (this.maxLevel) * (2 * baseSuccessesPerLevel + (this.maxLevel-1))); return Math.ceil(0.5 * this.maxLevel * (2 * baseSuccessesPerLevel + (this.maxLevel - 1)));
} }
setMaxLevel(baseSuccessesPerLevel: number): void { setMaxLevel(baseSuccessesPerLevel: number): void {
-1
View File
@@ -5,7 +5,6 @@ export class BlackOperation extends Operation {
constructor(params: IOperationParams | null = null) { constructor(params: IOperationParams | null = null) {
super(params); super(params);
this.count = 1; this.count = 1;
this.countGrowth = 0;
} }
// To be implemented by subtypes // To be implemented by subtypes
+525 -107
View File
@@ -6,21 +6,42 @@ export const BlackOperations: IMap<BlackOperation> = {};
(function () { (function () {
BlackOperations["Operation Typhoon"] = new BlackOperation({ BlackOperations["Operation Typhoon"] = new BlackOperation({
name: "Operation Typhoon", name: "Operation Typhoon",
desc:"Obadiah Zenyatta is the leader of a RedWater PMC. It has long " + desc:
"Obadiah Zenyatta is the leader of a RedWater PMC. It has long " +
"been known among the intelligence community that Zenyatta, along " + "been known among the intelligence community that Zenyatta, along " +
"with the rest of the PMC, is a Synthoid.<br><br>" + "with the rest of the PMC, is a Synthoid.<br><br>" +
"The goal of Operation Typhoon is to find and eliminate " + "The goal of Operation Typhoon is to find and eliminate " +
"Zenyatta and RedWater by any means necessary. After the task " + "Zenyatta and RedWater by any means necessary. After the task " +
"is completed, the actions must be covered up from the general public.", "is completed, the actions must be covered up from the general public.",
baseDifficulty:2000, reqdRank:2.5e3, baseDifficulty: 2000,
rankGain:50, rankLoss:10, hpLoss:100, reqdRank: 2.5e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 50,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 10,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Zero"] = new BlackOperation({ BlackOperations["Operation Zero"] = new BlackOperation({
name: "Operation Zero", name: "Operation Zero",
desc:"AeroCorp is one of the world's largest defense contractors. " + desc:
"AeroCorp is one of the world's largest defense contractors. " +
"Its leader, Steve Watataki, is thought to be a supporter of " + "Its leader, Steve Watataki, is thought to be a supporter of " +
"Synthoid rights. He must be removed.<br><br>" + "Synthoid rights. He must be removed.<br><br>" +
"The goal of Operation Zero is to covertly infiltrate AeroCorp and " + "The goal of Operation Zero is to covertly infiltrate AeroCorp and " +
@@ -29,15 +50,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"from his position at AeroCorp. Incriminating evidence can be " + "from his position at AeroCorp. Incriminating evidence can be " +
"fabricated as a last resort. Be warned that AeroCorp has some of " + "fabricated as a last resort. Be warned that AeroCorp has some of " +
"the most advanced security measures in the world.", "the most advanced security measures in the world.",
baseDifficulty:2500, reqdRank:5e3, baseDifficulty: 2500,
rankGain:60, rankLoss:15, hpLoss:50, reqdRank: 5e3,
weights:{hack:0.2,str:0.15,def:0.15,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 60,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 15,
hpLoss: 50,
weights: {
hack: 0.2,
str: 0.15,
def: 0.15,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true, isStealth: true,
}); });
BlackOperations["Operation X"] = new BlackOperation({ BlackOperations["Operation X"] = new BlackOperation({
name: "Operation X", name: "Operation X",
desc:"We have recently discovered an underground publication " + desc:
"We have recently discovered an underground publication " +
"group called Samizdat. Even though most of their publications " + "group called Samizdat. Even though most of their publications " +
"are nonsensical conspiracy theories, the average human is " + "are nonsensical conspiracy theories, the average human is " +
"gullible enough to believe them. Many of their works discuss " + "gullible enough to believe them. Many of their works discuss " +
@@ -48,15 +89,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"operations is in Ishima's underground sewer systems. Your task is to " + "operations is in Ishima's underground sewer systems. Your task is to " +
"investigate the sewer systems, and eliminate Samizdat. They must " + "investigate the sewer systems, and eliminate Samizdat. They must " +
"never publish anything again.", "never publish anything again.",
baseDifficulty:3000, reqdRank:7.5e3, baseDifficulty: 3000,
rankGain:75, rankLoss:15, hpLoss:100, reqdRank: 7.5e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 75,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 15,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Titan"] = new BlackOperation({ BlackOperations["Operation Titan"] = new BlackOperation({
name: "Operation Titan", name: "Operation Titan",
desc:"Several months ago Titan Laboratories' Bioengineering department " + desc:
"Several months ago Titan Laboratories' Bioengineering department " +
"was infiltrated by Synthoids. As far as we know, Titan Laboratories' " + "was infiltrated by Synthoids. As far as we know, Titan Laboratories' " +
"management has no knowledge about this. We don't know what the " + "management has no knowledge about this. We don't know what the " +
"Synthoids are up to, but the research that they could " + "Synthoids are up to, but the research that they could " +
@@ -66,44 +127,104 @@ export const BlackOperations: IMap<BlackOperation> = {};
"facility in Aevum. The task is not just to retire the Synthoids there, but " + "facility in Aevum. The task is not just to retire the Synthoids there, but " +
"also to destroy any information or research at the facility that " + "also to destroy any information or research at the facility that " +
"is relevant to the Synthoids and their goals.", "is relevant to the Synthoids and their goals.",
baseDifficulty:4000, reqdRank:10e3, baseDifficulty: 4000,
rankGain:100, rankLoss:20, hpLoss:100, reqdRank: 10e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 100,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 20,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Ares"] = new BlackOperation({ BlackOperations["Operation Ares"] = new BlackOperation({
name: "Operation Ares", name: "Operation Ares",
desc:"One of our undercover agents, Agent Carter, has informed us of a " + desc:
"One of our undercover agents, Agent Carter, has informed us of a " +
"massive weapons deal going down in Dubai between rogue Russian " + "massive weapons deal going down in Dubai between rogue Russian " +
"militants and a radical Synthoid community. These weapons are next-gen " + "militants and a radical Synthoid community. These weapons are next-gen " +
"plasma and energy weapons. It is critical for the safety of humanity " + "plasma and energy weapons. It is critical for the safety of humanity " +
"that this deal does not happen.<br><br>" + "that this deal does not happen.<br><br>" +
"Your task is to intercept the deal. Leave no survivors.", "Your task is to intercept the deal. Leave no survivors.",
baseDifficulty:5000, reqdRank:12.5e3, baseDifficulty: 5000,
rankGain:125, rankLoss:20, hpLoss:200, reqdRank: 12.5e3,
weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, rankGain: 125,
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 20,
hpLoss: 200,
weights: {
hack: 0,
str: 0.25,
def: 0.25,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Archangel"] = new BlackOperation({ BlackOperations["Operation Archangel"] = new BlackOperation({
name: "Operation Archangel", name: "Operation Archangel",
desc:"Our analysts have discovered that the popular Red Rabbit brothel in " + desc:
"Our analysts have discovered that the popular Red Rabbit brothel in " +
"Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence " + "Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence " +
"suggests that the profit from this brothel is used to fund a large " + "suggests that the profit from this brothel is used to fund a large " +
"black market arms trafficking operation.<br><br>" + "black market arms trafficking operation.<br><br>" +
"The goal of this operation is to take out the leaders that are running " + "The goal of this operation is to take out the leaders that are running " +
"the Red Rabbit brothel. Try to limit the number of other casualties, " + "the Red Rabbit brothel. Try to limit the number of other casualties, " +
"but do what you must to complete the mission.", "but do what you must to complete the mission.",
baseDifficulty:7500, reqdRank:15e3, baseDifficulty: 7500,
rankGain:200, rankLoss:20, hpLoss:25, reqdRank: 15e3,
weights:{hack:0,str:0.2,def:0.2,dex:0.3,agi:0.3,cha:0, int:0}, rankGain: 200,
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 20,
hpLoss: 25,
weights: {
hack: 0,
str: 0.2,
def: 0.2,
dex: 0.3,
agi: 0.3,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Juggernaut"] = new BlackOperation({ BlackOperations["Operation Juggernaut"] = new BlackOperation({
name: "Operation Juggernaut", name: "Operation Juggernaut",
desc:"The CIA has just encountered a new security threat. A new " + desc:
"The CIA has just encountered a new security threat. A new " +
"criminal group, lead by a shadowy operative who calls himself " + "criminal group, lead by a shadowy operative who calls himself " +
"Juggernaut, has been smuggling drugs and weapons (including " + "Juggernaut, has been smuggling drugs and weapons (including " +
"suspected bioweapons) into Sector-12. We also have reason " + "suspected bioweapons) into Sector-12. We also have reason " +
@@ -112,15 +233,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"suspects that Juggernaut is a heavily-augmented Synthoid, and " + "suspects that Juggernaut is a heavily-augmented Synthoid, and " +
"have thus enlisted our help.<br><br>" + "have thus enlisted our help.<br><br>" +
"Your mission is to eradicate Juggernaut and his followers.", "Your mission is to eradicate Juggernaut and his followers.",
baseDifficulty:10e3, reqdRank:20e3, baseDifficulty: 10e3,
rankGain:300, rankLoss:40, hpLoss:300, reqdRank: 20e3,
weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0}, rankGain: 300,
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 40,
hpLoss: 300,
weights: {
hack: 0,
str: 0.25,
def: 0.25,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Red Dragon"] = new BlackOperation({ BlackOperations["Operation Red Dragon"] = new BlackOperation({
name: "Operation Red Dragon", name: "Operation Red Dragon",
desc:"The Tetrads criminal organization is suspected of " + desc:
"The Tetrads criminal organization is suspected of " +
"reverse-engineering the MK-VI Synthoid design. We believe " + "reverse-engineering the MK-VI Synthoid design. We believe " +
"they altered and possibly improved the design and began " + "they altered and possibly improved the design and began " +
"manufacturing their own Synthoid models in order to bolster " + "manufacturing their own Synthoid models in order to bolster " +
@@ -128,15 +269,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"Your task is to infiltrate and destroy the Tetrads' base of operations " + "Your task is to infiltrate and destroy the Tetrads' base of operations " +
"in Los Angeles. Intelligence tells us that their base houses " + "in Los Angeles. Intelligence tells us that their base houses " +
"one of their Synthoid manufacturing units.", "one of their Synthoid manufacturing units.",
baseDifficulty:12.5e3, reqdRank:25e3, baseDifficulty: 12.5e3,
rankGain:500, rankLoss:50, hpLoss:500, reqdRank: 25e3,
weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, rankGain: 500,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 50,
hpLoss: 500,
weights: {
hack: 0.05,
str: 0.2,
def: 0.2,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation K"] = new BlackOperation({ BlackOperations["Operation K"] = new BlackOperation({
name: "Operation K", name: "Operation K",
desc:"CODE RED SITUATION. Our intelligence tells us that VitaLife " + desc:
"CODE RED SITUATION. Our intelligence tells us that VitaLife " +
"has discovered a new android cloning technology. This technology " + "has discovered a new android cloning technology. This technology " +
"is supposedly capable of cloning Synthoid, not only physically " + "is supposedly capable of cloning Synthoid, not only physically " +
"but also their advanced AI modules. We do not believe that " + "but also their advanced AI modules. We do not believe that " +
@@ -148,30 +309,70 @@ export const BlackOperations: IMap<BlackOperation> = {};
"through legal or political means, so we must resort to a covert " + "through legal or political means, so we must resort to a covert " +
"operation. Your goal is to destroy this technology and eliminate " + "operation. Your goal is to destroy this technology and eliminate " +
"anyone who was involved in its creation.", "anyone who was involved in its creation.",
baseDifficulty:15e3, reqdRank:30e3, baseDifficulty: 15e3,
rankGain:750, rankLoss:60, hpLoss:1000, reqdRank: 30e3,
weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05}, rankGain: 750,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 60,
hpLoss: 1000,
weights: {
hack: 0.05,
str: 0.2,
def: 0.2,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Deckard"] = new BlackOperation({ BlackOperations["Operation Deckard"] = new BlackOperation({
name: "Operation Deckard", name: "Operation Deckard",
desc:"Despite your success in eliminating VitaLife's new android-replicating " + desc:
"Despite your success in eliminating VitaLife's new android-replicating " +
"technology in Operation K, we've discovered that a small group of " + "technology in Operation K, we've discovered that a small group of " +
"MK-VI Synthoids were able to make off with the schematics and design " + "MK-VI Synthoids were able to make off with the schematics and design " +
"of the technology before the Operation. It is almost a certainty that " + "of the technology before the Operation. It is almost a certainty that " +
"these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising.<br><br>" + "these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising.<br><br>" +
"The goal of Operation Deckard is to hunt down these Synthoids and retire " + "The goal of Operation Deckard is to hunt down these Synthoids and retire " +
"them. I don't need to tell you how critical this mission is.", "them. I don't need to tell you how critical this mission is.",
baseDifficulty:20e3, reqdRank:40e3, baseDifficulty: 20e3,
rankGain:1e3, rankLoss:75, hpLoss:200, reqdRank: 40e3,
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, rankGain: 1e3,
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 75,
hpLoss: 200,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Tyrell"] = new BlackOperation({ BlackOperations["Operation Tyrell"] = new BlackOperation({
name: "Operation Tyrell", name: "Operation Tyrell",
desc:"A week ago Blade Industries reported a small break-in at one " + desc:
"A week ago Blade Industries reported a small break-in at one " +
"of their Aevum Augmentation storage facitilities. We figured out " + "of their Aevum Augmentation storage facitilities. We figured out " +
"that The Dark Army was behind the heist, and didn't think any more " + "that The Dark Army was behind the heist, and didn't think any more " +
"of it. However, we've just discovered that several known MK-VI Synthoids " + "of it. However, we've just discovered that several known MK-VI Synthoids " +
@@ -179,15 +380,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"We cannot have Synthoids upgrading their already-enhanced abilities " + "We cannot have Synthoids upgrading their already-enhanced abilities " +
"with Augmentations. Your task is to hunt down the associated Dark Army " + "with Augmentations. Your task is to hunt down the associated Dark Army " +
"members and eliminate them.", "members and eliminate them.",
baseDifficulty:25e3, reqdRank:50e3, baseDifficulty: 25e3,
rankGain:1.5e3, rankLoss:100, hpLoss:500, reqdRank: 50e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 1.5e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 100,
hpLoss: 500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Wallace"] = new BlackOperation({ BlackOperations["Operation Wallace"] = new BlackOperation({
name: "Operation Wallace", name: "Operation Wallace",
desc:"Based on information gathered from Operation Tyrell, we've discovered " + desc:
"Based on information gathered from Operation Tyrell, we've discovered " +
"that The Dark Army was well aware that there were Synthoids amongst " + "that The Dark Army was well aware that there were Synthoids amongst " +
"their ranks. Even worse, we believe that The Dark Army is working " + "their ranks. Even worse, we believe that The Dark Army is working " +
"together with other criminal organizations such as The Syndicate and " + "together with other criminal organizations such as The Syndicate and " +
@@ -198,15 +419,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"The best way to deal with this is to prevent it before it even happens. " + "The best way to deal with this is to prevent it before it even happens. " +
"The goal of Operation Wallace is to destroy the Dark Army and " + "The goal of Operation Wallace is to destroy the Dark Army and " +
"Syndicate factions in Aevum immediately. Leave no survivors.", "Syndicate factions in Aevum immediately. Leave no survivors.",
baseDifficulty:30e3, reqdRank:75e3, baseDifficulty: 30e3,
rankGain:2e3, rankLoss:150, hpLoss:1500, reqdRank: 75e3,
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, rankGain: 2e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 150,
hpLoss: 1500,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({ BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({
name: "Operation Shoulder of Orion", name: "Operation Shoulder of Orion",
desc:"China's Solaris Space Systems is secretly launching the first " + desc:
"China's Solaris Space Systems is secretly launching the first " +
"manned spacecraft in over a decade using Synthoids. We believe " + "manned spacecraft in over a decade using Synthoids. We believe " +
"China is trying to establish the first off-world colonies.<br><br>" + "China is trying to establish the first off-world colonies.<br><br>" +
"The mission is to prevent this launch without instigating an " + "The mission is to prevent this launch without instigating an " +
@@ -214,15 +455,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"officially disavowed by the NSA and the national government until after you " + "officially disavowed by the NSA and the national government until after you " +
"successfully return. In the event of failure, all of the operation's " + "successfully return. In the event of failure, all of the operation's " +
"team members must not let themselves be captured alive.", "team members must not let themselves be captured alive.",
baseDifficulty:35e3, reqdRank:100e3, baseDifficulty: 35e3,
rankGain:2.5e3, rankLoss:500, hpLoss:1500, reqdRank: 100e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 2.5e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 500,
hpLoss: 1500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true, isStealth: true,
}); });
BlackOperations["Operation Hyron"] = new BlackOperation({ BlackOperations["Operation Hyron"] = new BlackOperation({
name: "Operation Hyron", name: "Operation Hyron",
desc:"Our intelligence tells us that Fulcrum Technologies is developing " + desc:
"Our intelligence tells us that Fulcrum Technologies is developing " +
"a quantum supercomputer using human brains as core " + "a quantum supercomputer using human brains as core " +
"processors. This supercomputer " + "processors. This supercomputer " +
"is rumored to be able to store vast amounts of data and " + "is rumored to be able to store vast amounts of data and " +
@@ -236,15 +497,35 @@ export const BlackOperations: IMap<BlackOperation> = {};
"Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. " + "Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. " +
"Infiltrate the compound, delete and destroy the work, and then find and kill the " + "Infiltrate the compound, delete and destroy the work, and then find and kill the " +
"project lead.", "project lead.",
baseDifficulty:40e3, reqdRank:125e3, baseDifficulty: 40e3,
rankGain:3e3, rankLoss:1e3, hpLoss:500, reqdRank: 125e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 3e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 1e3,
hpLoss: 500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Morpheus"] = new BlackOperation({ BlackOperations["Operation Morpheus"] = new BlackOperation({
name: "Operation Morpheus", name: "Operation Morpheus",
desc:"DreamSense Technologies is an advertising company that uses " + desc:
"DreamSense Technologies is an advertising company that uses " +
"special technology to transmit their ads into the peoples " + "special technology to transmit their ads into the peoples " +
"dreams and subconcious. They do this using broadcast transmitter " + "dreams and subconcious. They do this using broadcast transmitter " +
"towers. Based on information from our agents and informants in " + "towers. Based on information from our agents and informants in " +
@@ -253,44 +534,104 @@ export const BlackOperations: IMap<BlackOperation> = {};
"to spread pro-Synthoid propaganda.<br><br>" + "to spread pro-Synthoid propaganda.<br><br>" +
"The mission is to destroy this broadcast tower. Speed and " + "The mission is to destroy this broadcast tower. Speed and " +
"stealth are of the upmost important for this.", "stealth are of the upmost important for this.",
baseDifficulty:45e3, reqdRank:150e3, baseDifficulty: 45e3,
rankGain:4e3, rankLoss:1e3, hpLoss:100, reqdRank: 150e3,
weights:{hack:0.05,str:0.15,def:0.15,dex:0.3,agi:0.3,cha:0, int:0.05}, rankGain: 4e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 1e3,
hpLoss: 100,
weights: {
hack: 0.05,
str: 0.15,
def: 0.15,
dex: 0.3,
agi: 0.3,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true, isStealth: true,
}); });
BlackOperations["Operation Ion Storm"] = new BlackOperation({ BlackOperations["Operation Ion Storm"] = new BlackOperation({
name: "Operation Ion Storm", name: "Operation Ion Storm",
desc:"Our analysts have uncovered a gathering of MK-VI Synthoids " + desc:
"Our analysts have uncovered a gathering of MK-VI Synthoids " +
"that have taken up residence in the Sector-12 Slums. We " + "that have taken up residence in the Sector-12 Slums. We " +
"don't know if they are rogue Synthoids from the Uprising, " + "don't know if they are rogue Synthoids from the Uprising, " +
"but we do know that they have been stockpiling " + "but we do know that they have been stockpiling " +
"weapons, money, and other resources. This makes them dangerous.<br><br>" + "weapons, money, and other resources. This makes them dangerous.<br><br>" +
"This is a full-scale assault operation to find and retire all of these " + "This is a full-scale assault operation to find and retire all of these " +
"Synthoids in the Sector-12 Slums.", "Synthoids in the Sector-12 Slums.",
baseDifficulty:50e3, reqdRank:175e3, baseDifficulty: 50e3,
rankGain:5e3, rankLoss:1e3, hpLoss:5000, reqdRank: 175e3,
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, rankGain: 5e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 1e3,
hpLoss: 5000,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Annihilus"] = new BlackOperation({ BlackOperations["Operation Annihilus"] = new BlackOperation({
name: "Operation Annihilus", name: "Operation Annihilus",
desc:"Our superiors have ordered us to eradicate everything and everyone " + desc:
"Our superiors have ordered us to eradicate everything and everyone " +
"in an underground facility located in Aevum. They tell us " + "in an underground facility located in Aevum. They tell us " +
"that the facility houses many dangerous Synthoids and " + "that the facility houses many dangerous Synthoids and " +
"belongs to a terrorist organization called " + "belongs to a terrorist organization called " +
"'The Covenant'. We have no prior intelligence about this " + "'The Covenant'. We have no prior intelligence about this " +
"organization, so you are going in blind.", "organization, so you are going in blind.",
baseDifficulty:55e3, reqdRank:200e3, baseDifficulty: 55e3,
rankGain:7.5e3, rankLoss:1e3, hpLoss:10e3, reqdRank: 200e3,
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04}, rankGain: 7.5e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 1e3,
hpLoss: 10e3,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Ultron"] = new BlackOperation({ BlackOperations["Operation Ultron"] = new BlackOperation({
name: "Operation Ultron", name: "Operation Ultron",
desc:"OmniTek Incorporated, the original designer and manufacturer of Synthoids, " + desc:
"OmniTek Incorporated, the original designer and manufacturer of Synthoids, " +
"has notified us of a malfunction in their AI design. This malfunction, " + "has notified us of a malfunction in their AI design. This malfunction, " +
"when triggered, causes MK-VI Synthoids to become radicalized and seek out " + "when triggered, causes MK-VI Synthoids to become radicalized and seek out " +
"the destruction of humanity. They say that this bug affects all MK-VI Synthoids, " + "the destruction of humanity. They say that this bug affects all MK-VI Synthoids, " +
@@ -302,44 +643,121 @@ export const BlackOperations: IMap<BlackOperation> = {};
"augmented. We believe Ultron is making moves to take control of " + "augmented. We believe Ultron is making moves to take control of " +
"and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).<br><br>" + "and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).<br><br>" +
"Your task is to find and destroy Ultron.", "Your task is to find and destroy Ultron.",
baseDifficulty:60e3, reqdRank:250e3, baseDifficulty: 60e3,
rankGain:10e3, rankLoss:2e3, hpLoss:10e3, reqdRank: 250e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 10e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 2e3,
hpLoss: 10e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true, isKill: true,
}); });
BlackOperations["Operation Centurion"] = new BlackOperation({ BlackOperations["Operation Centurion"] = new BlackOperation({
name: "Operation Centurion", name: "Operation Centurion",
desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)<br><br>" + desc:
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)<br><br>" +
"Throughout all of humanity's history, we have relied on " + "Throughout all of humanity's history, we have relied on " +
"technology to survive, conquer, and progress. Its advancement became our primary goal. " + "technology to survive, conquer, and progress. Its advancement became our primary goal. " +
"And at the peak of human civilization technology turned into " + "And at the peak of human civilization technology turned into " +
"power. Global, absolute power.<br><br>" + "power. Global, absolute power.<br><br>" +
"It seems that the universe is not without a sense of irony.<br><br>" + "It seems that the universe is not without a sense of irony.<br><br>" +
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)", "D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",
baseDifficulty:70e3, reqdRank:300e3, baseDifficulty: 70e3,
rankGain:15e3, rankLoss:5e3, hpLoss:10e3, reqdRank: 300e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 15e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 5e3,
hpLoss: 10e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
}); });
BlackOperations["Operation Vindictus"] = new BlackOperation({ BlackOperations["Operation Vindictus"] = new BlackOperation({
name: "Operation Vindictus", name: "Operation Vindictus",
desc:"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)<br><br>" + desc:
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)<br><br>" +
"The bits are all around us. The daemons that hold the Node " + "The bits are all around us. The daemons that hold the Node " +
"together can manifest themselves in many different ways.<br><br>" + "together can manifest themselves in many different ways.<br><br>" +
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)", "D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",
baseDifficulty:75e3, reqdRank:350e3, baseDifficulty: 75e3,
rankGain:20e3, rankLoss:20e3, hpLoss:20e3, reqdRank: 350e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankGain: 20e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, rankLoss: 20e3,
hpLoss: 20e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
}); });
BlackOperations["Operation Daedalus"] = new BlackOperation({ BlackOperations["Operation Daedalus"] = new BlackOperation({
name: "Operation Daedalus", name: "Operation Daedalus",
desc:"Yesterday we obeyed kings and bent our neck to emperors. " + desc: "Yesterday we obeyed kings and bent our neck to emperors. " + "Today we kneel only to truth.",
"Today we kneel only to truth.", baseDifficulty: 80e3,
baseDifficulty:80e3, reqdRank:400e3, reqdRank: 400e3,
rankGain:40e3, rankLoss:10e3, hpLoss:100e3, rankGain: 40e3,
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1}, rankLoss: 10e3,
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75}, hpLoss: 100e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
}); });
})() })();
File diff suppressed because it is too large Load Diff
+71 -27
View File
@@ -1,4 +1,3 @@
import { BladeburnerConstants } from "./data/Constants"; import { BladeburnerConstants } from "./data/Constants";
import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
@@ -15,7 +14,6 @@ interface IChangePopulationByPercentageParams {
} }
export class City { export class City {
/** /**
* Name of the city. * Name of the city.
*/ */
@@ -54,7 +52,7 @@ export class City {
this.popEst = this.pop * (Math.random() + 0.5); this.popEst = this.pop * (Math.random() + 0.5);
// Number of Synthoid communities population and estimate // Number of Synthoid communities population and estimate
this.comms = getRandomInt(5, 150) this.comms = getRandomInt(5, 150);
this.commsEst = this.comms + getRandomInt(-5, 5); this.commsEst = this.comms + getRandomInt(-5, 5);
if (this.commsEst < 0) this.commsEst = 0; if (this.commsEst < 0) this.commsEst = 0;
this.chaos = 0; this.chaos = 0;
@@ -64,20 +62,32 @@ export class City {
* p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) * p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%)
*/ */
changeChaosByPercentage(p: number): void { changeChaosByPercentage(p: number): void {
if (isNaN(p)) {throw new Error("NaN passed into City.chaosChaosByPercentage()");} if (isNaN(p)) {
if (p === 0) {return;} throw new Error("NaN passed into City.chaosChaosByPercentage()");
}
if (p === 0) {
return;
}
this.chaos += this.chaos * (p / 100); this.chaos += this.chaos * (p / 100);
if (this.chaos < 0) {this.chaos = 0;} if (this.chaos < 0) {
this.chaos = 0;
}
} }
improvePopulationEstimateByCount(n: number): void { improvePopulationEstimateByCount(n: number): void {
if (isNaN(n)) {throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");} if (isNaN(n)) {
throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");
}
if (this.popEst < this.pop) { if (this.popEst < this.pop) {
this.popEst += n; this.popEst += n;
if (this.popEst > this.pop) {this.popEst = this.pop;} if (this.popEst > this.pop) {
this.popEst = this.pop;
}
} else if (this.popEst > this.pop) { } else if (this.popEst > this.pop) {
this.popEst -= n; this.popEst -= n;
if (this.popEst < this.pop) {this.popEst = this.pop;} if (this.popEst < this.pop) {
this.popEst = this.pop;
}
} }
} }
@@ -86,25 +96,37 @@ export class City {
*/ */
improvePopulationEstimateByPercentage(p: number, skillMult = 1): void { improvePopulationEstimateByPercentage(p: number, skillMult = 1): void {
p = p * skillMult; p = p * skillMult;
if (isNaN(p)) {throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");} if (isNaN(p)) {
throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");
}
if (this.popEst < this.pop) { if (this.popEst < this.pop) {
++this.popEst; // In case estimate is 0 ++this.popEst; // In case estimate is 0
this.popEst *= (1 + (p/100)); this.popEst *= 1 + p / 100;
if (this.popEst > this.pop) {this.popEst = this.pop;} if (this.popEst > this.pop) {
this.popEst = this.pop;
}
} else if (this.popEst > this.pop) { } else if (this.popEst > this.pop) {
this.popEst *= (1 - (p/100)); this.popEst *= 1 - p / 100;
if (this.popEst < this.pop) {this.popEst = this.pop;} if (this.popEst < this.pop) {
this.popEst = this.pop;
}
} }
} }
improveCommunityEstimate(n = 1): void { improveCommunityEstimate(n = 1): void {
if (isNaN(n)) {throw new Error("NaN passed into City.improveCommunityEstimate()");} if (isNaN(n)) {
throw new Error("NaN passed into City.improveCommunityEstimate()");
}
if (this.commsEst < this.comms) { if (this.commsEst < this.comms) {
this.commsEst += n; this.commsEst += n;
if (this.commsEst > this.comms) {this.commsEst = this.comms;} if (this.commsEst > this.comms) {
this.commsEst = this.comms;
}
} else if (this.commsEst > this.comms) { } else if (this.commsEst > this.comms) {
this.commsEst -= n; this.commsEst -= n;
if (this.commsEst < this.comms) {this.commsEst = this.comms;} if (this.commsEst < this.comms) {
this.commsEst = this.comms;
}
} }
} }
@@ -114,9 +136,13 @@ export class City {
* estOffset(int): Add offset to estimate (offset by percentage) * estOffset(int): Add offset to estimate (offset by percentage)
*/ */
changePopulationByCount(n: number, params: IChangePopulationByCountParams = { estChange: 0, estOffset: 0 }): void { changePopulationByCount(n: number, params: IChangePopulationByCountParams = { estChange: 0, estOffset: 0 }): void {
if (isNaN(n)) {throw new Error("NaN passed into City.changePopulationByCount()");} if (isNaN(n)) {
throw new Error("NaN passed into City.changePopulationByCount()");
}
this.pop += n; this.pop += n;
if (params.estChange && !isNaN(params.estChange)) {this.popEst += params.estChange;} if (params.estChange && !isNaN(params.estChange)) {
this.popEst += params.estChange;
}
if (params.estOffset) { if (params.estOffset) {
this.popEst = addOffset(this.popEst, params.estOffset); this.popEst = addOffset(this.popEst, params.estOffset);
} }
@@ -129,29 +155,47 @@ export class City {
* changeEstEqually(bool) - Change the population estimate by an equal amount * changeEstEqually(bool) - Change the population estimate by an equal amount
* nonZero (bool) - Set to true to ensure that population always changes by at least 1 * nonZero (bool) - Set to true to ensure that population always changes by at least 1
*/ */
changePopulationByPercentage(p: number, params: IChangePopulationByPercentageParams={nonZero: false, changeEstEqually: false}): number { changePopulationByPercentage(
if (isNaN(p)) {throw new Error("NaN passed into City.changePopulationByPercentage()");} p: number,
if (p === 0) {return 0;} params: IChangePopulationByPercentageParams = {
nonZero: false,
changeEstEqually: false,
},
): number {
if (isNaN(p)) {
throw new Error("NaN passed into City.changePopulationByPercentage()");
}
if (p === 0) {
return 0;
}
let change = Math.round(this.pop * (p / 100)); let change = Math.round(this.pop * (p / 100));
// Population always changes by at least 1 // Population always changes by at least 1
if (params.nonZero && change === 0) { if (params.nonZero && change === 0) {
p > 0 ? change = 1 : change = -1; p > 0 ? (change = 1) : (change = -1);
} }
this.pop += change; this.pop += change;
if (params.changeEstEqually) { if (params.changeEstEqually) {
this.popEst += change; this.popEst += change;
if (this.popEst < 0) {this.popEst = 0;} if (this.popEst < 0) {
this.popEst = 0;
}
} }
return change; return change;
} }
changeChaosByCount(n: number): void { changeChaosByCount(n: number): void {
if (isNaN(n)) {throw new Error("NaN passed into City.changeChaosByCount()");} if (isNaN(n)) {
if (n === 0) {return;} throw new Error("NaN passed into City.changeChaosByCount()");
}
if (n === 0) {
return;
}
this.chaos += n; this.chaos += n;
if (this.chaos < 0) {this.chaos = 0;} if (this.chaos < 0) {
this.chaos = 0;
}
} }
/** /**
-1
View File
@@ -3,7 +3,6 @@ import { Action, IActionParams } from "./Action";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
export class Contract extends Action { export class Contract extends Action {
constructor(params: IActionParams | null = null) { constructor(params: IActionParams | null = null) {
super(params); super(params);
} }
+11 -6
View File
@@ -9,7 +9,8 @@ export const GeneralActions: IMap<Action> = {};
actionName = "Training"; actionName = "Training";
GeneralActions[actionName] = new Action({ GeneralActions[actionName] = new Action({
name: actionName, name: actionName,
desc:"Improve your abilities at the Bladeburner unit's specialized training " + desc:
"Improve your abilities at the Bladeburner unit's specialized training " +
"center. Doing this gives experience for all combat stats and also " + "center. Doing this gives experience for all combat stats and also " +
"increases your max stamina.", "increases your max stamina.",
}); });
@@ -17,7 +18,8 @@ export const GeneralActions: IMap<Action> = {};
actionName = "Field Analysis"; actionName = "Field Analysis";
GeneralActions[actionName] = new Action({ GeneralActions[actionName] = new Action({
name: actionName, name: actionName,
desc:"Mine and analyze Synthoid-related data. This improves the " + desc:
"Mine and analyze Synthoid-related data. This improves the " +
"Bladeburner's unit intelligence on Synthoid locations and " + "Bladeburner's unit intelligence on Synthoid locations and " +
"activities. Completing this action will improve the accuracy " + "activities. Completing this action will improve the accuracy " +
"of your Synthoid population estimated in the current city.<br><br>" + "of your Synthoid population estimated in the current city.<br><br>" +
@@ -27,7 +29,8 @@ export const GeneralActions: IMap<Action> = {};
actionName = "Recruitment"; actionName = "Recruitment";
GeneralActions[actionName] = new Action({ GeneralActions[actionName] = new Action({
name: actionName, name: actionName,
desc:"Attempt to recruit members for your Bladeburner team. These members " + desc:
"Attempt to recruit members for your Bladeburner team. These members " +
"can help you conduct operations.<br><br>" + "can help you conduct operations.<br><br>" +
"Does NOT require stamina.", "Does NOT require stamina.",
}); });
@@ -35,7 +38,8 @@ export const GeneralActions: IMap<Action> = {};
actionName = "Diplomacy"; actionName = "Diplomacy";
GeneralActions[actionName] = new Action({ GeneralActions[actionName] = new Action({
name: actionName, name: actionName,
desc: "Improve diplomatic relations with the Synthoid population. " + desc:
"Improve diplomatic relations with the Synthoid population. " +
"Completing this action will reduce the Chaos level in your current city.<br><br>" + "Completing this action will reduce the Chaos level in your current city.<br><br>" +
"Does NOT require stamina.", "Does NOT require stamina.",
}); });
@@ -43,7 +47,8 @@ export const GeneralActions: IMap<Action> = {};
actionName = "Hyperbolic Regeneration Chamber"; actionName = "Hyperbolic Regeneration Chamber";
GeneralActions[actionName] = new Action({ GeneralActions[actionName] = new Action({
name: actionName, name: actionName,
desc: "Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. " + desc:
"Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. " +
"This will slowly heal your wounds and slightly increase your stamina.<br><br>", "This will slowly heal your wounds and slightly increase your stamina.<br><br>",
}); });
})() })();
-1
View File
@@ -48,7 +48,6 @@ export interface IAction {
* Growth rate is an integer and the count will increase by that integer every "cycle" * Growth rate is an integer and the count will increase by that integer every "cycle"
*/ */
count: number; count: number;
countGrowth: number;
// Weighting of each stat in determining action success rate // Weighting of each stat in determining action success rate
weights: IStatsMultiplier; weights: IStatsMultiplier;
+10 -2
View File
@@ -59,7 +59,10 @@ export interface IBladeburner {
prestige(): void; prestige(): void;
storeCycles(numCycles?: number): void; storeCycles(numCycles?: number): void;
getTypeAndNameFromActionId(actionId: IActionIdentifier): {type: string; name: string}; getTypeAndNameFromActionId(actionId: IActionIdentifier): {
type: string;
name: string;
};
getContractNamesNetscriptFn(): string[]; getContractNamesNetscriptFn(): string[];
getOperationNamesNetscriptFn(): string[]; getOperationNamesNetscriptFn(): string[];
getBlackOpNamesNetscriptFn(): string[]; getBlackOpNamesNetscriptFn(): string[];
@@ -67,7 +70,12 @@ export interface IBladeburner {
getSkillNamesNetscriptFn(): string[]; getSkillNamesNetscriptFn(): string[];
startActionNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): boolean; startActionNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): boolean;
getActionTimeNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): number; getActionTimeNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): number;
getActionEstimatedSuccessChanceNetscriptFn(player: IPlayer, type: string, name: string, workerScript: WorkerScript): number[]; getActionEstimatedSuccessChanceNetscriptFn(
player: IPlayer,
type: string,
name: string,
workerScript: WorkerScript,
): number[];
getActionCountRemainingNetscriptFn(type: string, name: string, workerScript: WorkerScript): number; getActionCountRemainingNetscriptFn(type: string, name: string, workerScript: WorkerScript): number;
getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number; getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number;
getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number; getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number;
+52 -20
View File
@@ -76,32 +76,65 @@ export class Skill {
this.baseCost = params.baseCost ? params.baseCost : 1; this.baseCost = params.baseCost ? params.baseCost : 1;
this.costInc = params.costInc ? params.costInc : 1; this.costInc = params.costInc ? params.costInc : 1;
if (params.maxLvl) {this.maxLvl = params.maxLvl;} if (params.maxLvl) {
this.maxLvl = params.maxLvl;
}
if (params.successChanceAll) {this.successChanceAll = params.successChanceAll;} if (params.successChanceAll) {
if (params.successChanceStealth) {this.successChanceStealth = params.successChanceStealth;} this.successChanceAll = params.successChanceAll;
if (params.successChanceKill) {this.successChanceKill = params.successChanceKill;} }
if (params.successChanceContract) {this.successChanceContract = params.successChanceContract;} if (params.successChanceStealth) {
if (params.successChanceOperation) {this.successChanceOperation = params.successChanceOperation;} this.successChanceStealth = params.successChanceStealth;
}
if (params.successChanceKill) {
this.successChanceKill = params.successChanceKill;
}
if (params.successChanceContract) {
this.successChanceContract = params.successChanceContract;
}
if (params.successChanceOperation) {
this.successChanceOperation = params.successChanceOperation;
}
if (params.successChanceEstimate) {
this.successChanceEstimate = params.successChanceEstimate;
}
if (params.successChanceEstimate) {this.successChanceEstimate = params.successChanceEstimate;} if (params.actionTime) {
this.actionTime = params.actionTime;
}
if (params.effHack) {
this.effHack = params.effHack;
}
if (params.effStr) {
this.effStr = params.effStr;
}
if (params.effDef) {
this.effDef = params.effDef;
}
if (params.effDex) {
this.effDex = params.effDex;
}
if (params.effAgi) {
this.effAgi = params.effAgi;
}
if (params.effCha) {
this.effCha = params.effCha;
}
if (params.actionTime) {this.actionTime = params.actionTime;} if (params.stamina) {
if (params.effHack) {this.effHack = params.effHack;} this.stamina = params.stamina;
if (params.effStr) {this.effStr = params.effStr;} }
if (params.effDef) {this.effDef = params.effDef;} if (params.money) {
if (params.effDex) {this.effDex = params.effDex;} this.money = params.money;
if (params.effAgi) {this.effAgi = params.effAgi;} }
if (params.effCha) {this.effCha = params.effCha;} if (params.expGain) {
this.expGain = params.expGain;
if (params.stamina) {this.stamina = params.stamina;} }
if (params.money) {this.money = params.money;}
if (params.expGain) {this.expGain = params.expGain;}
} }
calculateCost(currentLevel: number): number { calculateCost(currentLevel: number): number {
return Math.floor((this.baseCost + (currentLevel * this.costInc)) * BitNodeMultipliers.BladeburnerSkillCost); return Math.floor((this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost);
} }
getMultiplier(name: string): number { getMultiplier(name: string): number {
@@ -127,4 +160,3 @@ export class Skill {
return 0; return 0;
} }
} }
+45 -27
View File
@@ -7,84 +7,102 @@ export const Skills: IMap<Skill> = {};
(function () { (function () {
Skills[SkillNames.BladesIntuition] = new Skill({ Skills[SkillNames.BladesIntuition] = new Skill({
name: SkillNames.BladesIntuition, name: SkillNames.BladesIntuition,
desc:"Each level of this skill increases your success chance " + desc:
"for all Contracts, Operations, and BlackOps by 3%", "Each level of this skill increases your success chance " + "for all Contracts, Operations, and BlackOps by 3%",
baseCost: 3, costInc: 2.1, baseCost: 3,
costInc: 2.1,
successChanceAll: 3, successChanceAll: 3,
}); });
Skills[SkillNames.Cloak] = new Skill({ Skills[SkillNames.Cloak] = new Skill({
name: SkillNames.Cloak, name: SkillNames.Cloak,
desc:"Each level of this skill increases your " + desc:
"Each level of this skill increases your " +
"success chance in stealth-related Contracts, Operations, and BlackOps by 5.5%", "success chance in stealth-related Contracts, Operations, and BlackOps by 5.5%",
baseCost: 2, costInc: 1.1, baseCost: 2,
costInc: 1.1,
successChanceStealth: 5.5, successChanceStealth: 5.5,
}); });
Skills[SkillNames.ShortCircuit] = new Skill({ Skills[SkillNames.ShortCircuit] = new Skill({
name: SkillNames.ShortCircuit, name: SkillNames.ShortCircuit,
desc:"Each level of this skill increases your success chance " + desc:
"Each level of this skill increases your success chance " +
"in Contracts, Operations, and BlackOps that involve retirement by 5.5%", "in Contracts, Operations, and BlackOps that involve retirement by 5.5%",
baseCost: 2, costInc: 2.1, baseCost: 2,
costInc: 2.1,
successChanceKill: 5.5, successChanceKill: 5.5,
}); });
Skills[SkillNames.DigitalObserver] = new Skill({ Skills[SkillNames.DigitalObserver] = new Skill({
name: SkillNames.DigitalObserver, name: SkillNames.DigitalObserver,
desc:"Each level of this skill increases your success chance in " + desc: "Each level of this skill increases your success chance in " + "all Operations and BlackOps by 4%",
"all Operations and BlackOps by 4%", baseCost: 2,
baseCost: 2, costInc: 2.1, costInc: 2.1,
successChanceOperation: 4, successChanceOperation: 4,
}); });
Skills[SkillNames.Tracer] = new Skill({ Skills[SkillNames.Tracer] = new Skill({
name: SkillNames.Tracer, name: SkillNames.Tracer,
desc:"Each level of this skill increases your success chance in " + desc: "Each level of this skill increases your success chance in " + "all Contracts by 4%",
"all Contracts by 4%", baseCost: 2,
baseCost: 2, costInc: 2.1, costInc: 2.1,
successChanceContract: 4, successChanceContract: 4,
}); });
Skills[SkillNames.Overclock] = new Skill({ Skills[SkillNames.Overclock] = new Skill({
name: SkillNames.Overclock, name: SkillNames.Overclock,
desc:"Each level of this skill decreases the time it takes " + desc:
"Each level of this skill decreases the time it takes " +
"to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 90)", "to attempt a Contract, Operation, and BlackOp by 1% (Max Level: 90)",
baseCost: 3, costInc: 1.4, maxLvl: 90, baseCost: 3,
costInc: 1.4,
maxLvl: 90,
actionTime: 1, actionTime: 1,
}); });
Skills[SkillNames.Reaper] = new Skill({ Skills[SkillNames.Reaper] = new Skill({
name: SkillNames.Reaper, name: SkillNames.Reaper,
desc: "Each level of this skill increases your effective combat stats for Bladeburner actions by 2%", desc: "Each level of this skill increases your effective combat stats for Bladeburner actions by 2%",
baseCost: 2, costInc: 2.1, baseCost: 2,
effStr: 2, effDef: 2, effDex: 2, effAgi: 2, costInc: 2.1,
effStr: 2,
effDef: 2,
effDex: 2,
effAgi: 2,
}); });
Skills[SkillNames.EvasiveSystem] = new Skill({ Skills[SkillNames.EvasiveSystem] = new Skill({
name: SkillNames.EvasiveSystem, name: SkillNames.EvasiveSystem,
desc:"Each level of this skill increases your effective " + desc: "Each level of this skill increases your effective " + "dexterity and agility for Bladeburner actions by 4%",
"dexterity and agility for Bladeburner actions by 4%", baseCost: 2,
baseCost: 2, costInc: 2.1, costInc: 2.1,
effDex: 4, effAgi: 4, effDex: 4,
effAgi: 4,
}); });
Skills[SkillNames.Datamancer] = new Skill({ Skills[SkillNames.Datamancer] = new Skill({
name: SkillNames.Datamancer, name: SkillNames.Datamancer,
desc:"Each level of this skill increases your effectiveness in " + desc:
"Each level of this skill increases your effectiveness in " +
"synthoid population analysis and investigation by 5%. " + "synthoid population analysis and investigation by 5%. " +
"This affects all actions that can potentially increase " + "This affects all actions that can potentially increase " +
"the accuracy of your synthoid population/community estimates.", "the accuracy of your synthoid population/community estimates.",
baseCost:3, costInc:1, baseCost: 3,
costInc: 1,
successChanceEstimate: 5, successChanceEstimate: 5,
}); });
Skills[SkillNames.CybersEdge] = new Skill({ Skills[SkillNames.CybersEdge] = new Skill({
name: SkillNames.CybersEdge, name: SkillNames.CybersEdge,
desc: "Each level of this skill increases your max stamina by 2%", desc: "Each level of this skill increases your max stamina by 2%",
baseCost:1, costInc:3, baseCost: 1,
costInc: 3,
stamina: 2, stamina: 2,
}); });
Skills[SkillNames.HandsOfMidas] = new Skill({ Skills[SkillNames.HandsOfMidas] = new Skill({
name: SkillNames.HandsOfMidas, name: SkillNames.HandsOfMidas,
desc: "Each level of this skill increases the amount of money you receive from Contracts by 10%", desc: "Each level of this skill increases the amount of money you receive from Contracts by 10%",
baseCost: 2, costInc: 2.5, baseCost: 2,
costInc: 2.5,
money: 10, money: 10,
}); });
Skills[SkillNames.Hyperdrive] = new Skill({ Skills[SkillNames.Hyperdrive] = new Skill({
name: SkillNames.Hyperdrive, name: SkillNames.Hyperdrive,
desc: "Each level of this skill increases the experience earned from Contracts, Operations, and BlackOps by 10%", desc: "Each level of this skill increases the experience earned from Contracts, Operations, and BlackOps by 10%",
baseCost: 1, costInc: 2.5, baseCost: 1,
costInc: 2.5,
expGain: 10, expGain: 10,
}); });
})() })();
+18 -18
View File
@@ -1,27 +1,27 @@
// Action Identifier enum // Action Identifier enum
export const ActionTypes: { export const ActionTypes: {
[key: string]: number; [key: string]: number;
"Idle": number; Idle: number;
"Contract": number; Contract: number;
"Operation": number; Operation: number;
"BlackOp": number; BlackOp: number;
"BlackOperation": number; BlackOperation: number;
"Training": number; Training: number;
"Recruitment": number; Recruitment: number;
FieldAnalysis: number;
"Field Analysis": number; "Field Analysis": number;
"Field Analysis": number; Diplomacy: number;
"Diplomacy": number;
"Hyperbolic Regeneration Chamber": number; "Hyperbolic Regeneration Chamber": number;
} = { } = {
"Idle": 1, Idle: 1,
"Contract": 2, Contract: 2,
"Operation": 3, Operation: 3,
"BlackOp": 4, BlackOp: 4,
"BlackOperation": 4, BlackOperation: 4,
"Training": 5, Training: 5,
"Recruitment": 6, Recruitment: 6,
FieldAnalysis: 7,
"Field Analysis": 7, "Field Analysis": 7,
"Field Analysis": 7, Diplomacy: 8,
"Diplomacy": 8,
"Hyperbolic Regeneration Chamber": 9, "Hyperbolic Regeneration Chamber": 9,
}; };
+1 -1
View File
@@ -76,4 +76,4 @@ export const BladeburnerConstants: {
HrcHpGain: 2, // HP Gained from Hyperbolic Regeneration chamber HrcHpGain: 2, // HP Gained from Hyperbolic Regeneration chamber
HrcStaminaGain: 1, // Percentage Stamina gained from Hyperbolic Regeneration Chamber HrcStaminaGain: 1, // Percentage Stamina gained from Hyperbolic Regeneration Chamber
} };
+24
View File
@@ -0,0 +1,24 @@
import { getRandomInt } from "../../../utils/helpers/getRandomInt";
export const Growths: {
[key: string]: (() => number) | undefined;
["Tracking"]: () => number;
["Bounty Hunter"]: () => number;
["Retirement"]: () => number;
["Investigation"]: () => number;
["Undercover Operation"]: () => number;
["Sting Operation"]: () => number;
["Raid"]: () => number;
["Stealth Retirement Operation"]: () => number;
["Assassination"]: () => number;
} = {
Tracking: () => getRandomInt(5, 75) / 10,
"Bounty Hunter": () => getRandomInt(5, 75) / 10,
Retirement: () => getRandomInt(5, 75) / 10,
Investigation: () => getRandomInt(10, 40) / 10,
"Undercover Operation": () => getRandomInt(10, 40) / 10,
"Sting Operation": () => getRandomInt(3, 40) / 10,
Raid: () => getRandomInt(2, 40) / 10,
"Stealth Retirement Operation": () => getRandomInt(1, 20) / 10,
Assassination: () => getRandomInt(1, 20) / 10,
};
+5 -18
View File
@@ -43,16 +43,8 @@ export const ConsoleHelpText: {
"50. Note that when setting the action, the name of the action is CASE-SENSITIVE. It must " + "50. Note that when setting the action, the name of the action is CASE-SENSITIVE. It must " +
"exactly match whatever the name is in the UI.", "exactly match whatever the name is in the UI.",
], ],
clear: [ clear: ["clear", "", "Clears the console"],
"clear", cls: ["cls", "", "Clears the console"],
"",
"Clears the console",
],
cls: [
"cls",
"",
"Clears the console",
],
help: [ help: [
"help [command]", "help [command]",
"", "",
@@ -97,8 +89,7 @@ export const ConsoleHelpText: {
"Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If " + "Note that the name of the skill is case-sensitive. Enter it exactly as seen in the UI. If " +
"the name of the skill has whitespace, enclose the name of the skill in double quotation marks:", "the name of the skill has whitespace, enclose the name of the skill in double quotation marks:",
"", "",
" skill list Reaper<br>" + " skill list Reaper<br>" + " skill list 'Digital Observer'",
" skill list 'Digital Observer'",
"", "",
"This console command can also be used to level up skills:", "This console command can also be used to level up skills:",
"", "",
@@ -119,9 +110,5 @@ export const ConsoleHelpText: {
" start contract Tracking", " start contract Tracking",
" start op 'Undercover Operation'", " start op 'Undercover Operation'",
], ],
stop:[ stop: ["stop", "", "Stop your current action and go idle."],
"stop", };
"",
"Stop your current action and go idle.",
],
}
+12 -2
View File
@@ -1,14 +1,24 @@
import * as React from "react"; import * as React from "react";
export const stealthIcon = <svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 166 132" style={{fill:'#adff2f'}}> export const stealthIcon = (
<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 166 132" style={{ fill: "#adff2f" }}>
<g> <g>
<path d="M132.658-0.18l-24.321,24.321c-7.915-2.71-16.342-4.392-25.087-4.392c-45.84,0-83,46-83,46 s14.1,17.44,35.635,30.844L12.32,120.158l12.021,12.021L144.68,11.841L132.658-0.18z M52.033,80.445 c-2.104-4.458-3.283-9.438-3.283-14.695c0-19.054,15.446-34.5,34.5-34.5c5.258,0,10.237,1.179,14.695,3.284L52.033,80.445z" /> <path d="M132.658-0.18l-24.321,24.321c-7.915-2.71-16.342-4.392-25.087-4.392c-45.84,0-83,46-83,46 s14.1,17.44,35.635,30.844L12.32,120.158l12.021,12.021L144.68,11.841L132.658-0.18z M52.033,80.445 c-2.104-4.458-3.283-9.438-3.283-14.695c0-19.054,15.446-34.5,34.5-34.5c5.258,0,10.237,1.179,14.695,3.284L52.033,80.445z" />
<path d="M134.865,37.656l-18.482,18.482c0.884,3.052,1.367,6.275,1.367,9.612c0,19.055-15.446,34.5-34.5,34.5 c-3.337,0-6.56-0.483-9.611-1.367l-10.124,10.124c6.326,1.725,12.934,2.743,19.735,2.743c45.84,0,83-46,83-46 S153.987,50.575,134.865,37.656z" /> <path d="M134.865,37.656l-18.482,18.482c0.884,3.052,1.367,6.275,1.367,9.612c0,19.055-15.446,34.5-34.5,34.5 c-3.337,0-6.56-0.483-9.611-1.367l-10.124,10.124c6.326,1.725,12.934,2.743,19.735,2.743c45.84,0,83-46,83-46 S153.987,50.575,134.865,37.656z" />
</g> </g>
</svg> </svg>
export const killIcon = <svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="-22 0 511 511.99561" style={{fill:'#adff2f'}}> );
export const killIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16px"
height="16px"
viewBox="-22 0 511 511.99561"
style={{ fill: "#adff2f" }}
>
<path d="m.496094 466.242188 39.902344-39.902344 45.753906 45.753906-39.898438 39.902344zm0 0" /> <path d="m.496094 466.242188 39.902344-39.902344 45.753906 45.753906-39.898438 39.902344zm0 0" />
<path d="m468.421875 89.832031-1.675781-89.832031-300.265625 300.265625 45.753906 45.753906zm0 0" /> <path d="m468.421875 89.832031-1.675781-89.832031-300.265625 300.265625 45.753906 45.753906zm0 0" />
<path d="m95.210938 316.785156 16.84375 16.847656h.003906l83.65625 83.65625 22.753906-22.753906-100.503906-100.503906zm0 0" /> <path d="m95.210938 316.785156 16.84375 16.847656h.003906l83.65625 83.65625 22.753906-22.753906-100.503906-100.503906zm0 0" />
<path d="m101.445312 365.300781-39.902343 39.902344 45.753906 45.753906 39.902344-39.902343-39.90625-39.902344zm0 0" /> <path d="m101.445312 365.300781-39.902343 39.902344 45.753906 45.753906 39.902344-39.902343-39.90625-39.902344zm0 0" />
</svg> </svg>
);
+1 -1
View File
@@ -28,4 +28,4 @@ export const SkillNames: {
CybersEdge: "Cyber's Edge", CybersEdge: "Cyber's Edge",
HandsOfMidas: "Hands of Midas", HandsOfMidas: "Hands of Midas",
Hyperdrive: "Hyperdrive", Hyperdrive: "Hyperdrive",
} };
+25 -20
View File
@@ -14,36 +14,41 @@ interface IProps {
} }
export function AllPages(props: IProps): React.ReactElement { export function AllPages(props: IProps): React.ReactElement {
const [page, setPage] = useState('General'); const [page, setPage] = useState("General");
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
useEffect(() => { useEffect(() => {
const id = setInterval(() => setRerender(old => !old), 1000); const id = setInterval(() => setRerender((old) => !old), 1000);
return () => clearInterval(id); return () => clearInterval(id);
}, []); }, []);
function Header(props: { name: string }): React.ReactElement { function Header(props: { name: string }): React.ReactElement {
return (<a return (
<a
onClick={() => setPage(props.name)} onClick={() => setPage(props.name)}
className={page !== props.name ? className={page !== props.name ? "bladeburner-nav-button noselect" : "bladeburner-nav-button-inactive noselect"}
"bladeburner-nav-button" : >
"bladeburner-nav-button-inactive"}>
{props.name} {props.name}
</a>); </a>
);
} }
return (<> return (
<Header name={'General'} /> <>
<Header name={'Contracts'} /> <Header name={"General"} />
<Header name={'Operations'} /> <Header name={"Contracts"} />
<Header name={'BlackOps'} /> <Header name={"Operations"} />
<Header name={'Skills'} /> <Header name={"BlackOps"} />
<Header name={"Skills"} />
<div style={{ display: "block", margin: "4px", padding: "4px" }}> <div style={{ display: "block", margin: "4px", padding: "4px" }}>
{page === 'General' && <GeneralActionPage bladeburner={props.bladeburner} player={props.player} />} {page === "General" && <GeneralActionPage bladeburner={props.bladeburner} player={props.player} />}
{page === 'Contracts' && <ContractPage bladeburner={props.bladeburner} player={props.player} />} {page === "Contracts" && <ContractPage bladeburner={props.bladeburner} player={props.player} />}
{page === 'Operations' && <OperationPage bladeburner={props.bladeburner} player={props.player} />} {page === "Operations" && <OperationPage bladeburner={props.bladeburner} player={props.player} />}
{page === 'BlackOps' && <BlackOpPage bladeburner={props.bladeburner} player={props.player} />} {page === "BlackOps" && <BlackOpPage bladeburner={props.bladeburner} player={props.player} />}
{page === 'Skills' && <SkillPage bladeburner={props.bladeburner} />} {page === "Skills" && <SkillPage bladeburner={props.bladeburner} />}
</div> </div>
<span className="text">{stealthIcon} = This action requires stealth, {killIcon} = This action involves retirement</span> <span className="text">
</>); {stealthIcon} = This action requires stealth, {killIcon} = This action involves retirement
</span>
</>
);
} }
+41 -26
View File
@@ -1,8 +1,5 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { import { formatNumber, convertTimeMsToTimeElapsedString } from "../../../utils/StringHelperFunctions";
formatNumber,
convertTimeMsToTimeElapsedString,
} from "../../../utils/StringHelperFunctions";
import { ActionTypes } from "../data/ActionTypes"; import { ActionTypes } from "../data/ActionTypes";
import { createProgressBarText } from "../../../utils/helpers/createProgressBarText"; import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
import { stealthIcon, killIcon } from "../data/Icons"; import { stealthIcon, killIcon } from "../data/Icons";
@@ -11,6 +8,7 @@ import { TeamSizePopup } from "./TeamSizePopup";
import { IBladeburner } from "../IBladeburner"; import { IBladeburner } from "../IBladeburner";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { SuccessChance } from "./SuccessChance"; import { SuccessChance } from "./SuccessChance";
import { CopyableText } from "../../ui/React/CopyableText";
interface IProps { interface IProps {
bladeburner: IBladeburner; bladeburner: IBladeburner;
@@ -20,23 +18,27 @@ interface IProps {
export function BlackOpElem(props: IProps): React.ReactElement { export function BlackOpElem(props: IProps): React.ReactElement {
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
const isCompleted = (props.bladeburner.blackops[props.action.name] != null); const isCompleted = props.bladeburner.blackops[props.action.name] != null;
if (isCompleted) { if (isCompleted) {
return ( return <h2 style={{ display: "block" }}>{props.action.name} (COMPLETED)</h2>;
<h2 style={{display: 'block'}}>{props.action.name} (COMPLETED)</h2>);
} }
const isActive = props.bladeburner.action.type === ActionTypes["BlackOperation"] && props.action.name === props.bladeburner.action.name; const isActive =
props.bladeburner.action.type === ActionTypes["BlackOperation"] &&
props.action.name === props.bladeburner.action.name;
const estimatedSuccessChance = props.action.getEstSuccessChance(props.bladeburner); const estimatedSuccessChance = props.action.getEstSuccessChance(props.bladeburner);
const actionTime = props.action.getActionTime(props.bladeburner); const actionTime = props.action.getActionTime(props.bladeburner);
const hasReqdRank = props.bladeburner.rank >= props.action.reqdRank; const hasReqdRank = props.bladeburner.rank >= props.action.reqdRank;
const computedActionTimeCurrent = Math.min(props.bladeburner.actionTimeCurrent+props.bladeburner.actionTimeOverflow, props.bladeburner.actionTimeToComplete); const computedActionTimeCurrent = Math.min(
props.bladeburner.actionTimeCurrent + props.bladeburner.actionTimeOverflow,
props.bladeburner.actionTimeToComplete,
);
function onStart(): void { function onStart(): void {
props.bladeburner.action.type = ActionTypes.BlackOperation; props.bladeburner.action.type = ActionTypes.BlackOperation;
props.bladeburner.action.name = props.action.name; props.bladeburner.action.name = props.action.name;
props.bladeburner.startAction(props.player, props.bladeburner.action); props.bladeburner.startAction(props.player, props.bladeburner.action);
setRerender(old => !old); setRerender((old) => !old);
} }
function onTeam(): void { function onTeam(): void {
@@ -48,28 +50,38 @@ export function BlackOpElem(props: IProps): React.ReactElement {
}); });
} }
return (<> return (
<h2 style={{display: 'inline-block'}}> <>
{isActive ? <h2 style={{ display: "inline-block" }}>
<>{props.action.name} (IN PROGRESS - {formatNumber(computedActionTimeCurrent, 0)} / {formatNumber(props.bladeburner.actionTimeToComplete, 0)})</> : {isActive ? (
<>{props.action.name}</> <>
} <CopyableText value={props.action.name} /> (IN PROGRESS - {formatNumber(computedActionTimeCurrent, 0)} /{" "}
{formatNumber(props.bladeburner.actionTimeToComplete, 0)})
</>
) : (
<CopyableText value={props.action.name} />
)}
</h2> </h2>
{isActive ? {isActive ? (
<p style={{display: 'block'}}>{createProgressBarText({progress: computedActionTimeCurrent / props.bladeburner.actionTimeToComplete})}</p> : <p style={{ display: "block" }}>
{createProgressBarText({
progress: computedActionTimeCurrent / props.bladeburner.actionTimeToComplete,
})}
</p>
) : (
<> <>
<a <a
className={hasReqdRank ? "a-link-button" : "a-link-button-inactive"} className={hasReqdRank ? "a-link-button" : "a-link-button-inactive"}
style={{ margin: "3px", padding: "3px" }} style={{ margin: "3px", padding: "3px" }}
onClick={onStart} onClick={onStart}
>Start</a> >
<a Start
onClick={onTeam} </a>
style={{margin:"3px", padding:"3px"}} <a onClick={onTeam} style={{ margin: "3px", padding: "3px" }} className="a-link-button">
className="a-link-button">
Set Team Size (Curr Size: {formatNumber(props.action.teamCount, 0)}) Set Team Size (Curr Size: {formatNumber(props.action.teamCount, 0)})
</a> </a>
</>} </>
)}
<br /> <br />
<br /> <br />
<p style={{ display: "inline-block" }} dangerouslySetInnerHTML={{ __html: props.action.desc }} /> <p style={{ display: "inline-block" }} dangerouslySetInnerHTML={{ __html: props.action.desc }} />
@@ -80,9 +92,12 @@ export function BlackOpElem(props: IProps): React.ReactElement {
</p> </p>
<br /> <br />
<pre style={{ display: "inline-block" }}> <pre style={{ display: "inline-block" }}>
Estimated Success Chance: <SuccessChance chance={estimatedSuccessChance} /> {props.action.isStealth?stealthIcon:<></>}{props.action.isKill?killIcon:<></>} Estimated Success Chance: <SuccessChance chance={estimatedSuccessChance} />{" "}
{props.action.isStealth ? stealthIcon : <></>}
{props.action.isKill ? killIcon : <></>}
<br /> <br />
Time Required: {convertTimeMsToTimeElapsedString(actionTime * 1000)} Time Required: {convertTimeMsToTimeElapsedString(actionTime * 1000)}
</pre> </pre>
</>); </>
);
} }
+15 -8
View File
@@ -18,19 +18,26 @@ export function BlackOpList(props: IProps): React.ReactElement {
} }
} }
blackops.sort(function (a, b) { blackops.sort(function (a, b) {
return (a.reqdRank - b.reqdRank); return a.reqdRank - b.reqdRank;
}); });
blackops = blackops.filter((blackop: BlackOperation, i: number) => !(props.bladeburner.blackops[blackops[i].name] == null && blackops = blackops.filter(
(blackop: BlackOperation, i: number) => !(
props.bladeburner.blackops[blackops[i].name] == null &&
i !== 0 && i !== 0 &&
props.bladeburner.blackops[blackops[i-1].name] == null)); props.bladeburner.blackops[blackops[i - 1].name] == null
),
);
blackops = blackops.reverse(); blackops = blackops.reverse();
return (<> return (
{blackops.map((blackop: BlackOperation) => <li key={blackop.name} className="bladeburner-action"> <>
{blackops.map((blackop: BlackOperation) => (
<li key={blackop.name} className="bladeburner-action">
<BlackOpElem bladeburner={props.bladeburner} action={blackop} player={props.player} /> <BlackOpElem bladeburner={props.bladeburner} action={blackop} player={props.player} />
</li>, </li>
)} ))}
</>); </>
);
} }
+10 -10
View File
@@ -9,20 +9,20 @@ interface IProps {
} }
export function BlackOpPage(props: IProps): React.ReactElement { export function BlackOpPage(props: IProps): React.ReactElement {
return (<> return (
<p style={{display: 'block', margin: '4px', padding: '4px'}}> <>
Black Operations (Black Ops) are special, one-time covert operations. <p style={{ display: "block", margin: "4px", padding: "4px" }}>
Each Black Op must be unlocked successively by completing Black Operations (Black Ops) are special, one-time covert operations. Each Black Op must be unlocked
the one before it. successively by completing the one before it.
<br /> <br />
<br /> <br />
<b>Your ultimate goal to climb through the ranks of Bladeburners is to complete <b>Your ultimate goal to climb through the ranks of Bladeburners is to complete all of the Black Ops.</b>
all of the Black Ops.</b>
<br /> <br />
<br /> <br />
Like normal operations, you may use a team for Black Ops. Failing Like normal operations, you may use a team for Black Ops. Failing a black op will incur heavy HP and rank
a black op will incur heavy HP and rank losses. losses.
</p> </p>
<BlackOpList bladeburner={props.bladeburner} player={props.player} /> <BlackOpList bladeburner={props.bladeburner} player={props.player} />
</>); </>
);
} }

Some files were not shown because too many files have changed in this diff Show More