Compare commits

..

235 Commits

Author SHA1 Message Date
Olivier Gagnon
87c63cde59 merge v0.56.0 2021-10-12 01:35:30 -04:00
Olivier Gagnon
83137a2364 v0.56.0 2021-10-12 00:29:16 -04:00
Olivier Gagnon
78d9c25671 fix error message with wrong reviver, refactor part of player 2021-10-11 23:14:15 -04:00
Olivier Gagnon
56c8a23631 corp MAXMPPROD is now case insensitive 2021-10-11 22:54:28 -04:00
Olivier Gagnon
1d4cf45a92 fix issue with corp export popup 2021-10-11 22:48:34 -04:00
Olivier Gagnon
b1e37acaa1 added autocomplete for scp 2021-10-11 22:35:00 -04:00
Olivier Gagnon
65ee49fb92 Added cp command 2021-10-11 22:34:04 -04:00
Olivier Gagnon
6a795a7c50 neuroflux doesnt appear in gangs 2021-10-11 19:00:14 -04:00
Olivier Gagnon
ae33a23db4 remove Neuroflux from specila factions 2021-10-11 18:56:51 -04:00
Olivier Gagnon
faad0ae8a7 Try to make an error message more helpful 2021-10-11 18:47:05 -04:00
Olivier Gagnon
1ff7f4bcd4 table pagination text no longer black 2021-10-11 18:30:46 -04:00
Olivier Gagnon
1335ca8e01 Impossible to buy real estate with negative money 2021-10-11 18:22:57 -04:00
Olivier Gagnon
8e07cc999d change GB to TBPBEB 2021-10-11 18:14:10 -04:00
Olivier Gagnon
06775b20fa saving file now saves game 2021-10-11 17:57:17 -04:00
Olivier Gagnon
30554560da softcap hacknet max moneyt upgrade 2021-10-11 17:43:48 -04:00
Olivier Gagnon
ac3a6b9a6f setToCommitCrime sleeve works with rough crime name 2021-10-11 17:12:08 -04:00
Olivier Gagnon
b126bd01ee ram check is debounced 2021-10-11 16:59:37 -04:00
Olivier Gagnon
8f13363466 prettier 2021-10-11 16:38:50 -04:00
Olivier Gagnon
828c9c2de6 improve contributing.md 2021-10-11 16:28:01 -04:00
Olivier Gagnon
dd61fd6efb document learn js and make getServer not require sf5 2021-10-11 16:18:05 -04:00
hydroflame
383b02fdbb Merge pull request #1457 from Snarling/patch-3
Change effect replacer text to x% instead of +x%
2021-10-11 14:27:01 -04:00
Olivier Gagnon
010f43e5d4 few bugfix 2021-10-11 14:26:44 -04:00
Olivier Gagnon
3d36982a56 fix disableLog not disabling blade functions 2021-10-11 13:31:12 -04:00
Olivier Gagnon
3fd26bea9b fix int not calculating 2021-10-11 13:18:37 -04:00
Snarling
41de3102c7 Change effect replacer text to x% instead of +x%
This will make replacement work for hacknet cost (which is -x% so currently is not seen for replacement) and will keep the + or - for effectiveness (e.g. +12.3% hacking skill instead of just 12.3% hacking skill)
2021-10-10 23:00:11 -04:00
Olivier Gagnon
e9ba4ae9a2 added vscode module def in netscript 2021-10-10 13:52:56 -04:00
Olivier Gagnon
12b192ab43 prerawloader 2021-10-10 13:23:36 -04:00
Olivier Gagnon
cdbbc657e2 nano new ns2 file starts with param 2021-10-09 23:21:22 -04:00
Olivier Gagnon
995a0b11d9 build fix for duplicate autocomplete 2021-10-09 23:07:18 -04:00
Olivier Gagnon
06df10d2f9 build fix for duplicate autocomplete 2021-10-09 22:59:06 -04:00
Olivier Gagnon
01d15176ac Added kindof monokai to monaco 2021-10-09 19:00:27 -04:00
Olivier Gagnon
f9afff57b2 fix ram miscalc 2021-10-09 15:07:42 -04:00
Olivier Gagnon
2bf47c60df fix sleeve consuming too much time at once. 2021-10-09 14:31:06 -04:00
Olivier Gagnon
783750051e build w dev 2021-10-09 12:51:44 -04:00
Olivier Gagnon
752534bc4d fix joinBladeburner 2021-10-09 12:49:53 -04:00
Olivier Gagnon
3346f3539c increase the price of Wilson to stop feedback loop 2021-10-09 02:24:31 -04:00
Olivier Gagnon
0aa26df9d7 build sg 2021-10-09 01:09:27 -04:00
Olivier Gagnon
bbf3a1d19a fix server ram recalc 2021-10-08 23:45:54 -04:00
Olivier Gagnon
a2599f19d7 patch time compression 2021-10-08 15:31:32 -04:00
Olivier Gagnon
8e4722c5e7 write can be awaited in order to wait for the ram calculation to go through 2021-10-08 14:05:47 -04:00
Olivier Gagnon
e91c183d37 blade getCurrentAction says type general 2021-10-08 13:17:27 -04:00
Olivier Gagnon
2ed29e10b3 build cores 2021-10-08 12:10:28 -04:00
Olivier Gagnon
effa9f15af growthanalyze has core argument 2021-10-08 12:09:44 -04:00
Olivier Gagnon
4355420349 made staneks gift work with prestiges 2021-10-08 03:16:51 -04:00
Olivier Gagnon
35ebb06761 change highlight color 2021-10-08 02:05:53 -04:00
Olivier Gagnon
5d21bd7840 more theme 2021-10-08 02:04:12 -04:00
Olivier Gagnon
815b04037c more theme 2021-10-08 01:49:12 -04:00
Olivier Gagnon
3cd0ae51e7 Change rdt theme to match game sorta 2021-10-08 01:39:40 -04:00
Olivier Gagnon
ed57a8c4f4 trying dark theme 2 2021-10-08 00:59:36 -04:00
Olivier Gagnon
0f7ad063ca thing to know if rrdt has reloaded 2021-10-08 00:55:55 -04:00
Olivier Gagnon
809f9117b8 thing to know if rrdt has reloaded 2021-10-08 00:55:40 -04:00
Olivier Gagnon
38e165100f Tried to change the theme 2021-10-08 00:55:06 -04:00
Olivier Gagnon
f4ecbd9b48 merge dev 2021-10-08 00:26:35 -04:00
Olivier Gagnon
7db1164a1a build script editor filename issue 2021-10-08 00:22:32 -04:00
Olivier Gagnon
3ca7c49ce8 Fixed Script Editor last filename not keeping proper track 2021-10-08 00:21:30 -04:00
Olivier Gagnon
528a8f30db more elements around 2021-10-08 00:13:18 -04:00
Olivier Gagnon
500063e87e Merge branch 'dev' into sg 2021-10-07 23:53:49 -04:00
Olivier Gagnon
ec3037f8c6 readded font 2021-10-07 23:53:44 -04:00
Olivier Gagnon
8d7f0488f8 merge dev 2021-10-07 17:58:32 -04:00
Olivier Gagnon
7d0536a4d2 finish convert to hostname 2021-10-07 17:55:49 -04:00
Olivier Gagnon
2958034ad4 more ip conversion 2021-10-07 17:04:32 -04:00
Olivier Gagnon
a7dfb1a537 more convertion from ip to hostname 2021-10-07 16:56:01 -04:00
Olivier Gagnon
be29481689 unexport AllServers 2021-10-07 16:04:04 -04:00
Olivier Gagnon
1d488565c6 build logbox 2021-10-07 15:11:58 -04:00
Olivier Gagnon
42890843fb Merge branch 'dev' of github.com:danielyxie/bitburner into dev 2021-10-07 15:08:27 -04:00
Olivier Gagnon
c06aff3437 Improve logbox behavior 2021-10-07 15:02:54 -04:00
Olivier Gagnon
62bdfb1875 notes 2021-10-07 14:49:40 -04:00
hydroflame
123f071c12 Merge pull request #1427 from Tyasuh/dev
Corpo Typo Fixes
2021-10-07 13:55:15 -04:00
tyasuh.taeragan@gmail.com
0edd4ffdf1 Corpo Typo Fixes 2021-10-07 13:46:33 -04:00
Olivier Gagnon
8e5c10cc2f enable dev for beta 2021-10-07 01:47:13 -04:00
Olivier Gagnon
15a03dd532 enable dev for beta 2021-10-07 01:42:06 -04:00
Olivier Gagnon
8e58482db0 sg 2021-10-07 01:36:59 -04:00
Olivier Gagnon
b1d1de9118 revert growthAnalyze stuff because it causes errors 2021-10-06 19:41:36 -04:00
Olivier Gagnon
83a84c6d38 corp bonus time consumes faster 2021-10-06 01:59:41 -04:00
Olivier Gagnon
75a2742911 fix netscript port read not correctly converting ns1 objects 2021-10-05 16:37:54 -04:00
Olivier Gagnon
a420a87eba fix bug with hacknet servers and grow 2021-10-05 15:23:30 -04:00
Olivier Gagnon
f579ee398b made log box resize a tad better 2021-10-05 01:44:46 -04:00
Olivier Gagnon
4901c84d34 remove some unused css 2021-10-05 01:30:37 -04:00
Olivier Gagnon
227fbd7060 made log box resizable 2021-10-05 01:23:20 -04:00
Olivier Gagnon
70796e7674 use react-draggable 2021-10-05 00:59:40 -04:00
Olivier Gagnon
da746a63c3 add incremental game plaza stuff 2021-10-04 23:56:24 -04:00
Olivier Gagnon
2f677c7ec8 more work 2021-10-04 23:51:39 -04:00
Olivier Gagnon
c5e29dafc4 fix mc 2021-10-04 22:31:07 -04:00
Olivier Gagnon
bb0bdb776b extracted some of the Netscript functions into their own file. 2021-10-04 22:25:21 -04:00
Olivier Gagnon
48b839d68c Added font size to text editor 2021-10-04 21:06:55 -04:00
Olivier Gagnon
c47a5bc8cc added grow, weaken, and time compression 2021-10-04 19:58:34 -04:00
Olivier Gagnon
33ea31be87 convert autocomplete to tooltip 2021-10-04 17:52:20 -04:00
Olivier Gagnon
27fc90c87a fix corp ui text fields now clearing on city change 2021-10-04 13:49:27 -04:00
Olivier Gagnon
d58e2df9c7 cat now accepts newline 2021-10-04 13:15:04 -04:00
Olivier Gagnon
c989e6713f fix logbox newlines and corp researching multiple times 2021-10-04 12:37:19 -04:00
Olivier Gagnon
880654c222 ui work 2021-10-04 12:28:57 -04:00
Olivier Gagnon
4fc6d393e4 fix mc 2021-10-03 21:44:15 -04:00
Olivier Gagnon
d21382e96e remove debug log 2021-10-03 21:37:05 -04:00
Olivier Gagnon
81fd2c1236 remove log 2021-10-03 21:34:56 -04:00
hydroflame
bdb10217db Merge pull request #1409 from BartKoppelmans/patch-3
Removed console warning for Sleeves
2021-10-03 21:34:21 -04:00
Olivier Gagnon
ab2ffb112f fix some bugs 2021-10-03 21:33:48 -04:00
Olivier Gagnon
7304e5379f sg 2021-10-03 20:34:36 -04:00
Bart Koppelmans
ee0532eba7 Removed console warning for Sleeves 2021-10-03 20:29:20 +02:00
Olivier Gagnon
1a749505e7 build research tree 2021-10-02 00:25:50 -04:00
Olivier Gagnon
fae6e6d22f fix research tree, kinda 2021-10-02 00:24:50 -04:00
Olivier Gagnon
826357e8b8 change SF9 to seem more appealing 2021-10-01 23:20:44 -04:00
Olivier Gagnon
94550dbaee forgot about grwothAnalyze 2021-10-01 23:03:37 -04:00
Olivier Gagnon
83c159e901 fix miscalculation in growth formulas 2021-10-01 23:02:09 -04:00
Olivier Gagnon
3f5b412547 fixed prompt 2021-10-01 22:53:23 -04:00
Olivier Gagnon
1fdb5c33c7 fix sleeves not being able to work at volhaven 2021-10-01 22:42:31 -04:00
Olivier Gagnon
665d25650a fixed log boxes 2021-10-01 22:31:58 -04:00
Olivier Gagnon
447731c5f3 fix infil 2021-10-01 22:27:32 -04:00
Olivier Gagnon
cc02701e97 fix autolink wrong font 2021-10-01 16:42:07 -04:00
Olivier Gagnon
50cf362b3b v0.55.0 2021-10-01 16:22:33 -04:00
Olivier Gagnon
5ba7b2796d build gang in mui 2021-10-01 15:39:56 -04:00
Olivier Gagnon
9cbb525da3 remove hacking missions 2021-10-01 15:26:12 -04:00
Olivier Gagnon
0ae8b72188 100% mui I think 2021-10-01 15:19:37 -04:00
Olivier Gagnon
1e641468f7 build the little mui conversions 2021-10-01 13:40:16 -04:00
Olivier Gagnon
3187bb990d Everything except Gang is Muified 2021-10-01 13:36:59 -04:00
Olivier Gagnon
4e8bb96f3f removing some of the classes 2021-10-01 13:08:37 -04:00
Olivier Gagnon
97c04a1037 logbox manager, alert manager and fix bitverse colors 2021-10-01 10:39:09 -04:00
Olivier Gagnon
62cd8ffcc6 pre-dialogbox-convert 2021-10-01 01:00:50 -04:00
Olivier Gagnon
0d9caac455 mui-fy some modals 2021-09-30 20:06:40 -04:00
Olivier Gagnon
f701cbffa7 lint 2021-09-30 18:57:44 -04:00
Olivier Gagnon
73d0dd98f2 stock market in Mui 2021-09-30 18:56:09 -04:00
Olivier Gagnon
c05be66c60 corp in mui 2021-09-30 17:24:08 -04:00
Olivier Gagnon
b0e4a2a775 finalize corp in mui 2021-09-30 17:02:07 -04:00
Olivier Gagnon
86ddc940aa convert some corp to mui 2021-09-30 15:12:06 -04:00
Olivier Gagnon
510fcedf90 convert some corp to mui 2021-09-30 13:51:55 -04:00
Olivier Gagnon
5cce1c255c convert some corp to mui 2021-09-29 19:05:25 -04:00
Olivier Gagnon
854239ceb1 convert some corp to mui 2021-09-29 17:41:19 -04:00
Olivier Gagnon
73834d03cd faction dont rerender 2021-09-29 10:33:21 -04:00
Olivier Gagnon
cefd499ff6 use tabs for corp 2021-09-29 01:54:17 -04:00
Olivier Gagnon
c5713fa6d8 learned and implemented default props 2021-09-29 01:49:22 -04:00
Olivier Gagnon
b0739f8942 fix bad scritp not dying properly 2021-09-28 20:48:44 -04:00
Olivier Gagnon
a6d7f93111 work on corp mui 2021-09-28 19:38:51 -04:00
Olivier Gagnon
86678b6290 convert blade to mui 2021-09-27 17:09:48 -04:00
Olivier Gagnon
498a204c88 rm unused log 2021-09-26 21:38:21 -04:00
Olivier Gagnon
d6584386ff set disabled color 2021-09-26 21:37:22 -04:00
Olivier Gagnon
b5abbbc240 hacknet nodes in mui 2021-09-26 21:26:25 -04:00
Olivier Gagnon
514b467e27 Merge branch 'dev' of github.com:danielyxie/bitburner into dev 2021-09-26 21:22:13 -04:00
Olivier Gagnon
1fc2e6fd2a added unfocus aug 2021-09-26 21:11:49 -04:00
hydroflame
b758807ba1 Merge pull request #1384 from vmesecher/dev
Fixes Corporation bribe uninentionally affect Bladeburners under cert…
2021-09-26 20:59:12 -04:00
Olivier Gagnon
14e6dd0158 sleeves to mui 2021-09-26 20:55:38 -04:00
vmesecher
ce578206eb Fixes Corporation bribe uninentionally affect Bladeburners under certain circumstances. Also contains small lint fixes found by running npm run lint. 2021-09-25 15:43:30 -07:00
Olivier Gagnon
3289f76cd0 safeguards 2021-09-25 17:29:51 -04:00
Olivier Gagnon
793d9b34ce update BN13 for new UI 2021-09-25 17:21:50 -04:00
Olivier Gagnon
3aacab504b convert casino to mui 2021-09-25 15:42:37 -04:00
Olivier Gagnon
6d179be018 buttons should have typograaphy as child 2021-09-25 15:41:00 -04:00
Olivier Gagnon
86da356478 convert most of the city to mui 2021-09-25 15:34:12 -04:00
Olivier Gagnon
c0e1706128 rm the top level utils folder 2021-09-25 14:45:12 -04:00
Olivier Gagnon
06f716c0fa moved a bunch of files 2021-09-25 14:42:57 -04:00
Olivier Gagnon
07bc697477 remove uneeded part of the tutorial 2021-09-25 14:21:34 -04:00
Olivier Gagnon
60a91cd9f7 index.html is empty now 2021-09-25 14:14:50 -04:00
Olivier Gagnon
97624395c1 convert game saved to snackbar, index.html is nearly empty now 2021-09-25 14:10:32 -04:00
Olivier Gagnon
d49fea4cbc convert unclickable inside the react tree 2021-09-25 14:00:38 -04:00
Olivier Gagnon
125e9484f7 Work on hacknet to mui 2021-09-25 13:52:26 -04:00
Olivier Gagnon
ef17f0d617 ui 2021-09-25 13:31:42 -04:00
Olivier Gagnon
f7aa393a8f fix getNodeStats error 2021-09-25 13:03:09 -04:00
Olivier Gagnon
7fb2b8b590 fix tooltips 2021-09-25 11:23:56 -04:00
Olivier Gagnon
cba40c71b2 mui stuff 2021-09-25 03:09:27 -04:00
Olivier Gagnon
4254cc2807 small improvements to augmentation page. 2021-09-25 02:42:21 -04:00
Olivier Gagnon
8b15adda8a lint 2021-09-25 02:36:49 -04:00
Olivier Gagnon
b0f20c8c8f lint 2021-09-25 01:26:03 -04:00
Olivier Gagnon
5c6c472b64 Augmentations in mui 2021-09-25 01:06:17 -04:00
Olivier Gagnon
5170c0e004 create script in mui 2021-09-24 23:36:28 -04:00
Olivier Gagnon
fe18c55173 removed some unused files. 2021-09-24 23:09:18 -04:00
Olivier Gagnon
69c9b20e68 sleeve ui says bonus time and sleeves cant consume all bonus time at once. 2021-09-24 23:02:27 -04:00
Olivier Gagnon
2d45784102 theme editor now allows import/export 2021-09-24 22:54:25 -04:00
Olivier Gagnon
65cb519801 fix infiltration keybinding 2021-09-24 22:15:19 -04:00
Olivier Gagnon
76e6cb4ecc forgot one ts in utils 2021-09-24 22:04:30 -04:00
hydroflame
7b6f9293c7 Merge pull request #1379 from danielyxie/netscript-functions-ts
all typescript
2021-09-24 21:50:09 -04:00
Olivier Gagnon
dc2bf871cf all typescript 2021-09-24 21:49:49 -04:00
Olivier Gagnon
1d349c25f7 imrpove terminal performance 2021-09-24 19:12:53 -04:00
Olivier Gagnon
5484c64a95 build script not dying 2021-09-24 19:10:20 -04:00
Olivier Gagnon
ec33fb411c fix scripts not dying 2021-09-24 19:09:19 -04:00
Olivier Gagnon
2a966d0726 build the typescript conversion 2021-09-24 18:43:30 -04:00
Olivier Gagnon
29143999a6 move JSInterpreter 2021-09-24 18:42:13 -04:00
Olivier Gagnon
a32b8eabe3 SaveObject in ts 2021-09-24 18:40:17 -04:00
Olivier Gagnon
43723a3fbb engine in ts 2021-09-24 18:29:25 -04:00
Olivier Gagnon
ad75fa5ebc convert to ts 2021-09-24 18:13:20 -04:00
Olivier Gagnon
4abc1df840 convert to ts 2021-09-24 17:56:30 -04:00
Olivier Gagnon
da488e586b convert to ts 2021-09-24 17:16:14 -04:00
Olivier Gagnon
413333c919 convert to ts 2021-09-24 17:07:53 -04:00
Olivier Gagnon
4f219a3214 convert to ts 2021-09-24 16:37:42 -04:00
Olivier Gagnon
2e05f14c0d convert to ts 2021-09-24 16:34:21 -04:00
Olivier Gagnon
47f54a11c3 ts convertion 2021-09-24 16:02:38 -04:00
Olivier Gagnon
b8faa9dc0b convert player to ts 2021-09-23 18:47:43 -04:00
Olivier Gagnon
8fd6b2e7da convert some files to ts 2021-09-23 13:30:13 -04:00
Olivier Gagnon
cdd9c174e7 electron always dev tools 2021-09-23 13:15:27 -04:00
Olivier Gagnon
e6291a09a0 refresh theme on load 2021-09-22 13:43:23 -04:00
hydroflame
9ccfca3c72 Merge pull request #1368 from MartinFournier/theme-load-at-startup
Load theme from settings during game load (#1364)
2021-09-22 13:40:27 -04:00
Martin Fournier
346024af45 Load theme from settings during game load (#1364) 2021-09-22 13:33:41 -04:00
Olivier Gagnon
66a2adaeb4 update prettier 2021-09-22 12:56:55 -04:00
Olivier Gagnon
c1945ab12e fix donation 2021-09-22 12:49:29 -04:00
Olivier Gagnon
3a7c64872a fix messge problem 2021-09-22 12:38:13 -04:00
Olivier Gagnon
06edf5b70c theme editor with color picker 2021-09-22 12:06:03 -04:00
hydroflame
d2008e86b4 Merge pull request #1361 from MartinFournier/theme-color-picker
Add material-ui-color picker in theme editor
2021-09-22 12:03:44 -04:00
Martin Fournier
32d1affb50 Add material-ui-color picker in theme editor 2021-09-22 12:00:00 -04:00
Olivier Gagnon
558b671206 few bugfix 2021-09-22 11:32:04 -04:00
Olivier Gagnon
a954259e25 can buy trp 2021-09-22 10:59:58 -04:00
Olivier Gagnon
64c7831c81 convert milestones to mui 2021-09-22 03:33:15 -04:00
Olivier Gagnon
61dd393bb5 convert tutorial screen to mui 2021-09-22 03:30:06 -04:00
Olivier Gagnon
28aca06208 convert work in progress to mui 2021-09-22 03:25:12 -04:00
Olivier Gagnon
c79fa240e1 Factions have a property explaining if they should keep on install 2021-09-22 03:09:37 -04:00
Olivier Gagnon
e1741778f9 add new sort option 2021-09-22 02:56:15 -04:00
Olivier Gagnon
80560ce9f6 build theme editor 2021-09-22 02:20:29 -04:00
Olivier Gagnon
f9a4eadb71 removed some of fconf 2021-09-22 01:36:17 -04:00
Olivier Gagnon
96f0879230 fix bug with nano 2021-09-22 01:10:29 -04:00
Olivier Gagnon
9c40cf6f28 fix infiltration timer 2021-09-22 01:03:25 -04:00
Olivier Gagnon
55901f0574 Let player copy terminal 2021-09-22 00:57:37 -04:00
Olivier Gagnon
43f0746be7 fix ls not working on dir 2021-09-22 00:48:13 -04:00
Olivier Gagnon
8eeed583c2 corp research show research points 2021-09-22 00:42:45 -04:00
Olivier Gagnon
dc518e7032 asdf 2021-09-21 20:39:25 -04:00
Olivier Gagnon
0c932dd4d1 build bunch of fixes 2021-09-21 20:30:00 -04:00
Olivier Gagnon
c94ec2f170 remove message from covenant when you're maxed sleeves 2021-09-21 18:04:47 -04:00
Olivier Gagnon
6111c50eb1 updatedco 2021-09-21 17:47:27 -04:00
Olivier Gagnon
8977f299e5 respect disable ascii art 2021-09-21 17:46:01 -04:00
Olivier Gagnon
2a8b1c2116 Fix corp not moving 2021-09-21 17:38:51 -04:00
Olivier Gagnon
9a6b185141 few fixes 2021-09-21 17:36:42 -04:00
Olivier Gagnon
501ce70702 re-add back button from faction to factions 2021-09-21 17:13:35 -04:00
Olivier Gagnon
9b94692942 fix faction screen size 2021-09-21 17:12:16 -04:00
Olivier Gagnon
06880c68e1 fix casino infinite loop 2021-09-21 16:58:20 -04:00
Olivier Gagnon
637f88efcd add bug report button 2021-09-21 16:50:33 -04:00
Olivier Gagnon
57a5c8b0b4 add difficulty to bitnode screen 2021-09-21 16:49:38 -04:00
Olivier Gagnon
c3ac16f330 electron open pages in external browser 2021-09-21 13:32:06 -04:00
Olivier Gagnon
c564de40b3 add f5f8 to electron 2021-09-21 13:29:16 -04:00
Olivier Gagnon
1b26d25a53 aug screen popup 2021-09-21 13:21:25 -04:00
Olivier Gagnon
7aa2d00460 fix aug page 2021-09-21 13:08:05 -04:00
Olivier Gagnon
ffa9600302 active scritp production typo and add new page size 2021-09-21 11:50:48 -04:00
hydroflame
db35fde42e Merge pull request #1307 from Nolshine/improve_gang_ascend_modal
improve gang ascend modal
2021-09-21 11:04:23 -04:00
hydroflame
d73040fdc5 Merge pull request #1319 from Nolshine/fix_missing_onclick_for_bulk_purchase
fix 'confirm bulk purchase' button missing onclick
2021-09-21 11:03:39 -04:00
hydroflame
a38df2e613 Merge pull request #1318 from Nolshine/visibility_icons
implement visibility icon toggling
2021-09-21 11:03:25 -04:00
hydroflame
b931ab5566 Merge pull request #1323 from Nolshine/documentation_1273
amend deprecation warning warning on getAugmentationCost's doc
2021-09-21 11:03:11 -04:00
Nolshine
4e44e784c6 amend warning on getAugmentationCost doc
now directs players to use the desired functions
2021-09-21 14:11:51 +01:00
Nolshine
aa4451b12d fix 'confirm bulk purchase' button missing onclick 2021-09-21 12:22:04 +01:00
Nolshine
2a52f6fa2b implement visibility icon toggling 2021-09-21 07:07:47 +01:00
Olivier Gagnon
8b7723338b change electron so it works. 2021-09-20 22:30:11 -04:00
Olivier Gagnon
9e62438b43 Rework faction augs menu 2021-09-20 20:42:13 -04:00
Nolshine
a9c57e23a5 improve gang ascend modal 2021-09-20 06:47:13 +01:00
614 changed files with 30538 additions and 34951 deletions

View File

@@ -3,4 +3,5 @@ doc/build/
dist/
tests/*.bundle.*
src/ThirdParty/*
src/JSInterpreter.js
src/JSInterpreter.js
main.bundle.js

View File

@@ -99,7 +99,6 @@ module.exports = {
"no-catch-shadow": ["error"],
"no-class-assign": ["error"],
"no-compare-neg-zero": ["error"],
"no-cond-assign": ["off", "except-parens"],
"no-confusing-arrow": ["error"],
"no-console": ["off"],
"no-const-assign": ["error"],

View File

@@ -84,6 +84,28 @@ changes are okay to contribute:
- Changes that directly affect the game's balance
- New gameplay mechanics
### How to setup fork properly
Fork and clone the repo
```
# This will add the game original code as a repo in your local copy
$ git remote add danielyxie git@github.com:danielyxie/bitburner.git
# You can verify you did this right by doing the following command
$ git remote show
danielyxie
origin
# Then download all the branches from the game. (there might be more branches)
$ git fetch danielyxie
From github.com:danielyxie/bitburner
* [new branch] dev -> danielyxie/dev
* [new branch] master -> danielyxie/master
# Makes sure you always start from `danielyxie/dev` to avoid merge conflicts.
```
#### Submitting a Pull Request
When submitting a pull request with your code contributions, please abide by

View File

@@ -1,61 +0,0 @@
@mixin animation($property) {
-webkit-animation: $property;
-moz-animation: $property;
-ms-animation: $property;
-o-animation: $property;
animation: $property;
}
@mixin borderRadius($property) {
-webkit-border-radius: $property;
-moz-border-radius: $property;
border-radius: $property;
}
@mixin boxShadow($value) {
-webkit-box-shadow: $value;
-moz-box-shadow: $value;
box-shadow: $value;
}
@mixin keyframes($animationName) {
@-webkit-keyframes #{$animationName} {
$browser: "-webkit-" !global;
@content;
}
@-moz-keyframes #{$animationName} {
$browser: "-moz-" !global;
@content;
}
@-ms-keyframes #{$animationName} {
$browser: "-ms-" !global;
@content;
}
@-o-keyframes #{$animationName} {
$browser: "-o-" !global;
@content;
}
@keyframes #{$animationName} {
$browser: "" !global;
@content;
}
}
@mixin transform($property) {
-webkit-transform: $property;
-moz-transform: $property;
-ms-transform: $property;
-o-transform: $property;
transform: $property;
}
@mixin userSelect($value) {
-webkit-user-select: $value;
-moz-user-select: $value;
-ms-user-select: $value;
user-select: $value;
}

View File

@@ -1,15 +0,0 @@
@import "theme";
* {
font-size: $defaultFontSize;
font-family: $fontFamily;
}
*,
*:before,
*:after {
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: middle;
}

View File

@@ -1,18 +0,0 @@
$fontFamily: "Lucida Console", "Lucida Sans Unicode", "Fira Mono", "Consolas", "Courier New", Courier, monospace,
"Times New Roman";
$defaultFontSize: 16px;
/* COLORS */
$hacker-green: #adff2f;
$success-green: #3adb76;
$alert-red: #ff2929;
$money-gold: #ffd700;
$light-yellow: #faffdf;
/* Attributes */
$my-stat-hp-color: #dd3434;
$my-stat-money-color: $money-gold;
$my-stat-hack-color: $hacker-green;
$my-stat-physical: $light-yellow;
$my-stat-cha-color: #a671d1;
$my-stat-int-color: #6495ed;

View File

@@ -1,24 +0,0 @@
/**
* Styling for the Augmentations UI. This is the page that displays all of the
* player's owned and purchased Augmentations and Source-Files. It also allows
* the player to install Augmentations
*/
@import "theme";
.augmentations-content {
> p {
font-size: $defaultFontSize * 0.875;
}
}
.augmentations-list {
button,
div {
color: var(--my-font-color);
text-decoration: none;
}
button {
padding: 4px;
}
}

View File

@@ -1,135 +0,0 @@
@import "theme";
.bladeburner-container {
a,
div,
p,
pre,
td {
font-size: $defaultFontSize * 0.8125;
}
}
.bladeburner-action {
border: 1px solid #fff;
margin: 7px;
padding: 7px;
white-space: pre-wrap;
pre {
white-space: pre-wrap;
}
}
/* Whatever action is currently active */
.bladeburner-active-action {
border: 4px solid #fff;
}
/* Action & Skills panel navigation button */
%bladeburner-nav-button {
border: 1px solid #fff;
margin: 2px;
padding: 2px;
color: #fff;
}
.bladeburner-nav-button {
@extend %bladeburner-nav-button;
&:hover {
background-color: #3d4044;
}
}
.bladeburner-nav-button-inactive {
@extend %bladeburner-nav-button;
text-decoration: none;
background-color: #555;
cursor: default;
pointer-events: none;
}
/* Checkbox for (de)selecting autoleveling */
.bbcheckbox {
position: relative;
display: inline;
label {
width: 20px;
height: 20px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
background: black;
border-width: 1px;
border-color: white;
border-style: solid;
&:after {
content: "";
width: 9px;
height: 5px;
position: absolute;
top: 5px;
left: 5px;
border: 3px solid white;
border-top: none;
border-right: none;
opacity: 0;
transform: rotate(-45deg);
}
}
input[type="checkbox"] {
margin: 3px;
visibility: hidden;
&:checked + label:after {
opacity: 1;
}
}
}
/* Bladeburner Console */
.bladeburner-console-div {
display: inline-block;
width: 40%;
border: 1px solid #fff;
overflow: auto;
height: 100%;
position: absolute;
}
.bladeburner-console-table {
height: auto;
overflow: auto;
table-layout: fixed;
width: 100%;
}
.bladeburner-console-input-row {
transition: height 1s;
width: 100%;
}
.bladeburner-console-input-cell {
display: flex;
}
.bladeburner-console-input {
display: inline-block;
padding: 0 !important;
margin: 0 !important;
border: 0;
background-color: var(--my-background-color);
font-size: $defaultFontSize * 0.8125;
outline: none;
color: var(--my-font-color);
flex: 1 1 auto;
}
.bladeburner-console-line {
word-wrap: break-word;
hyphens: auto;
-webkit-hyphens: auto;
-moz-hyphens: auto;
}

View File

@@ -1,112 +0,0 @@
@import "mixins";
@import "theme";
@import "styles";
/**
* Styling for all buttons
*
* Includes <button> elements as well as classes that are used
* for formatting buttons
*/
/* Remove default <button> styling */
button {
border: none;
background-color: transparent;
}
.a-link-button,
.std-button {
@extend .noselect;
text-decoration: none;
background-color: #555;
color: #fff;
padding: 3px 5px;
margin: 5px;
border: 1px solid #333;
&:hover {
background-color: #666;
}
&:active {
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
}
}
.a-link-button-inactive,
.std-button-disabled,
.std-button:disabled {
text-decoration: none;
background-color: #333;
color: #fff;
padding: 3px 5px;
margin: 5px;
border: 1px solid #333;
cursor: default;
-moz-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
&:hover {
.tooltiptext,
.tooltiptexthigh,
.tooltiptextleft {
visibility: visible;
}
}
&:active {
pointer-events: none;
}
}
.a-link-button-bought,
.std-button-bought {
@extend .noselect;
text-decoration: none;
background-color: #0a0;
color: #fff;
padding: 3px 5px;
margin: 5px;
border: 1px solid #0a0;
cursor: default;
&:hover {
.tooltiptext,
.tooltiptexthigh,
.tooltiptextleft {
visibility: visible;
}
}
&:active {
pointer-events: none;
}
}
/**
* This is a button that is meant to be used on accordions (accordion-header and accordion-panel classes)
* It has a black background so it does not clash with the default accordion coloring
*/
.accordion-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
font-size: $defaultFontSize;
font-weight: bold;
margin: 4px;
padding: 4px;
background-color: #000;
&:hover,
&:active {
color: #fff;
text-decoration: none;
cursor: pointer;
}
/* TODO focus selector? */
}

View File

@@ -1,24 +0,0 @@
.casino-card {
padding: 10px;
border: solid 1px #808080;
background-color: white;
display: inline-block;
border-radius: 10px;
font-size: 18.5px;
text-align: center;
margin: 3px;
font-weight: bold;
}
.casino-card .value {
font-size: 20px;
font-family: sans-serif;
}
.casino-card.red {
color: red;
}
.casino-card.black {
color: black;
}

View File

@@ -1,12 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the Character Overview Panel (top-right panel)
*/
#character-overview {
position: fixed;
top: 0;
right: 0;
}

View File

@@ -1,168 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for Corporations
* The names/labels refer to "Company Management", which was the old name
* for the mechanic before it got changed to avoid confusion with normal
* companies
*/
.cmpy-mgmt-container p,
.cmpy-mgmt-container a,
.cmpy-mgmt-container div,
.cmpy-mgmt-container br {
font-size: $defaultFontSize * 0.8125;
}
/* Header tabs */
.cmpy-mgmt-header-tab {
display: inline-block;
color: #fff;
background-color: #555;
border: 1px solid #fff;
padding: 4px;
}
.cmpy-mgmt-header-tab:hover {
background-color: #666;
}
.cmpy-mgmt-header-tab.current {
background-color: #777;
}
/* Switch between Cities */
.cmpy-mgmt-city-tab {
display: inline-block;
color: #fff;
background-color: #555;
border: 1px solid #fff;
padding: 4px;
}
.cmpy-mgmt-city-tab:hover {
background-color: #666;
}
.cmpy-mgmt-city-tab.current {
background-color: #777;
}
/* Panels */
#cmpy-mgmt-panel {
height: 90%;
}
.cmpy-mgmt-industry-left-panel,
.cmpy-mgmt-industry-right-panel {
display: inline-block;
height: 100%;
overflow-y: auto;
overflow-x: auto;
overflow: visible;
top: 10px;
width: 45%;
vertical-align: top;
margin-top: 10px;
}
.cmpy-mgmt-industry-overview-panel {
border: 1px solid #fff;
color: var(--my-font-color);
display: inline-block;
padding: 3px;
width: 100%;
}
.cmpy-mgmt-employee-panel {
border: 1px solid #fff;
display: block;
padding: 3px;
width: 100%;
}
.cmpy-mgmt-warehouse-panel {
border: 1px solid #fff;
display: inline-block;
padding: 3px;
width: 100%;
}
/* Hiring new employees */
.cmpy-mgmt-find-employee-option {
border: 1px solid #fff;
margin: 6px;
}
.cmpy-mgmt-find-employee-option:hover {
background-color: #3d4044;
}
/* Warehouse */
.cmpy-mgmt-warehouse-material-div {
padding: 2px;
border: 1px solid #fff;
}
.cmpy-mgmt-warehouse-product-div {
padding: 2px;
border: 1px solid #fff;
}
/* Exporting materials/products */
.cmpy-mgmt-existing-export {
border: 1px solid #fff;
border-radius: 25px;
margin: 4px;
padding: 4px;
}
.cmpy-mgmt-existing-export:hover {
background-color: #333;
}
/* Corporation Upgrades */
.cmpy-mgmt-upgrade-container {
border: 1px solid #fff;
width: 60%;
margin: 4px;
}
.cmpy-mgmt-upgrade-header {
margin: 6px;
padding: 6px;
}
.cmpy-mgmt-upgrade-div {
text-align: left;
display: inline-block;
border: 1px solid #fff;
margin: 2px;
padding: 6px;
border-radius: 25px;
font-size: $defaultFontSize * 0.75;
color: var(--my-font-color);
}
.cmpy-mgmt-upgrade-div:hover {
background-color: #333;
}
/* Industry Upgrades */
.industry-purchases-and-upgrades-header {
font-size: 14px;
margin: 2px;
padding: 2px;
}
/* Advertising */
.cmpy-mgmt-advertising-info {
font-size: $defaultFontSize * 0.75;
}
/* Research */
#corporation-research-popup-box-content {
overflow-x: auto !important;
overflow-y: auto !important;
}

View File

@@ -1,32 +0,0 @@
.add-exp-button {
margin-right: 0;
}
.remove-exp-button {
margin-left: 0;
}
.exp-input {
margin: 5px 0 5px 0;
padding: 2px 5px;
}
.text-center {
margin: auto;
text-align: center;
vertical-align: middle;
}
.touch-right {
margin-right: 0;
}
.touch-left {
margin-left: 0;
}
.touch-sides {
margin-left: 0;
margin-right: 0;
}

View File

@@ -1,19 +0,0 @@
/* Styling for the game options/settings
*
* Styling for the actual Game Options popup box can be found in popupboxes.scss
* This stylesheet is for everything inside the Game Options pop-up box
*/
@import "theme";
#game-options-right-panel {
a {
display: block;
width: 46%;
}
button {
display: inline-block;
width: 46%;
}
}

View File

@@ -1,46 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the Gang mechanic UI (BitNode-2)
*/
.gang-container {
p,
pre {
font-size: $defaultFontSize * 0.9375;
}
select {
background-color: black;
color: white;
}
}
#gang-management-subpage > p {
padding: 4px;
}
.gang-member-info-div {
background-color: #555;
display: inline;
float: left;
width: 30%;
}
/**
* Showing owned upgrades in the Equipment Box
*/
.gang-owned-upgrades-div {
display: inline-block;
margin-left: 6px;
width: 75%;
}
.gang-owned-upgrade {
border: 1px solid white;
font-size: 12px;
margin: 1px;
padding: 1px;
}

3413
css/grid.min.css vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,69 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the Hacknet Nodes UI Page
*/
.hacknet-general-info {
margin: 10px;
}
#hacknet-nodes-container li {
float: left;
overflow: hidden;
white-space: nowrap;
&.hacknet-node {
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
@include boxShadow($boxShadowArgs);
margin: 6px;
padding: 7px;
width: 35vw;
border: 2px solid var(--my-highlight-color);
}
}
#hacknet-nodes-list {
list-style: none;
width: 82vw;
}
#hacknet-nodes-money {
margin: 10px;
float: left;
}
#hacknet-nodes-money-multipliers-div {
display: inline-block;
width: 70vw;
}
#hacknet-nodes-multipliers {
float: right;
}
#hacknet-nodes-purchase-button {
display: inline-block;
}
.hacknet-node-container {
display: inline-table;
.row {
display: table-row;
height: 30px;
p {
display: table-cell;
}
}
.upgradable-info {
display: inline-block;
margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */
padding: 0 4px;
width: $defaultFontSize * 4;
}
}

View File

@@ -1,61 +0,0 @@
@import "theme";
.blinking-cursor {
font-weight: 100;
color: #2e3d48;
-webkit-animation: 1s cursorblink step-end infinite;
-moz-animation: 1s cursorblink step-end infinite;
-ms-animation: 1s cursorblink step-end infinite;
-o-animation: 1s cursorblink step-end infinite;
animation: 1s cursorblink step-end infinite;
}
@keyframes cursorblink {
from,
to {
color: transparent;
}
50% {
color: $hacker-green;
}
}
@-moz-keyframes cursorblink {
from,
to {
color: transparent;
}
50% {
color: $hacker-green;
}
}
@-webkit-keyframes cursorblink {
from,
to {
color: transparent;
}
50% {
color: $hacker-green;
}
}
@-ms-keyframes cursorblink {
from,
to {
color: transparent;
}
50% {
color: $hacker-green;
}
}
@-o-keyframes cursorblink {
from,
to {
color: transparent;
}
50% {
color: $hacker-green;
}
}

View File

@@ -1,90 +0,0 @@
@import "mixins";
@import "theme";
/* interactivetutorial.css */
#interactive-tutorial-wrapper {
position: relative;
}
#interactive-tutorial-container {
display: none;
position: fixed; /* Stay in place */
right: 0;
top: 0;
height: 450px;
padding: 10px;
border: 5px solid #fff;
width: 23%;
overflow: hidden;
background-color: #444; /* Fallback color */
color: #fff;
> strong {
background-color: #444;
}
}
#interactive-tutorial-text {
padding: 4px;
margin: 4px;
color: #fff;
background-color: #444;
font-size: $defaultFontSize * 0.875;
max-height: 350px;
overflow-y: auto;
}
#interactive-tutorial-exit,
#interactive-tutorial-next,
#interactive-tutorial-back {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
font-size: $defaultFontSize * 1.125;
font-weight: bold;
background-color: #000;
&:hover,
&:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
}
#interactive-tutorial-exit {
position: absolute;
bottom: 0;
left: 0;
padding: 4px;
}
#interactive-tutorial-back {
float: left;
padding: 4px;
}
#interactive-tutorial-next {
float: right;
padding: 4px;
}
.interactive-tutorial-command {
background-color: #000;
color: $hacker-green;
white-space: nowrap;
}
.interactive-tutorial-code {
background-color: #272822;
color: white;
padding: 3px;
}
.interactive-tutorial-tab {
background-color: #555;
color: #e6e6e6;
padding: 3px;
box-shadow: 0 0 3px #000;
}

View File

@@ -1,111 +0,0 @@
@import "mixins";
@import "reset";
@import "theme";
@include keyframes(LOADERSPINNER) {
0% {
#{$browser}transform: translate(-50%, -50%) rotate(0deg);
}
100% {
#{$browser}transform: translate(-50%, -50%) rotate(360deg);
}
}
@include keyframes(LOADERLABEL) {
0% {
opacity: 1;
#{$browser}transform: translate(-50%, -50%) scale(1);
}
5% {
opacity: 0.5;
#{$browser}transform: translate(-50%, -50%) scale(0.5);
}
95% {
opacity: 0.5;
#{$browser}transform: translate(-50%, -50%) scale(0.5);
}
100% {
opacity: 1;
#{$browser}transform: translate(-50%, -50%) scale(1);
}
}
.loaderoverlay {
$spinnerBoxSize: 200px;
$themeColor: #0c0;
position: absolute;
width: 100%;
height: 100%;
background: #000;
color: $themeColor;
%spinnerBox {
border: 20px solid rgba(0, 0, 0, 0);
border-top-color: $themeColor;
border-bottom-color: $themeColor;
border-radius: 1000px;
position: absolute;
top: 50%;
left: 50%;
}
.loaderspinner:before,
.loaderspinner:after {
content: "";
}
.loaderspinner {
@extend %spinnerBox;
@include animation(LOADERSPINNER 5s linear infinite);
width: $spinnerBoxSize;
height: $spinnerBoxSize;
}
.loaderspinner:before {
@extend %spinnerBox;
@include animation(LOADERSPINNER 10s linear infinite);
width: $spinnerBoxSize * 0.8;
height: $spinnerBoxSize * 0.8;
}
.loaderspinner:after {
@extend %spinnerBox;
@include animation(LOADERSPINNER 5s linear infinite);
width: $spinnerBoxSize * 0.6;
height: $spinnerBoxSize * 0.6;
}
.loaderlabel {
@include animation(LOADERLABEL 5s linear infinite);
text-transform: uppercase;
font-family: sans-serif;
font-size: $defaultFontSize * 1.375;
font-weight: 700;
letter-spacing: 2px;
position: absolute;
top: 50%;
left: 50%;
}
}
.killAllMessage {
position: absolute;
top: 95%;
left: 50%;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
}
.killAllMessageWrapperHidden {
display: none;
}
.killAllMessageWrapperShow {
display: block;
}

View File

@@ -1,137 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the main navigation menu on the left-hand-side
*/
.mainmenu {
list-style-type: none;
margin: 0;
padding: 0;
width: 10%;
position: fixed;
height: 100%;
overflow: auto;
border: 0;
border-bottom: 1px solid #000;
border-radius: 0;
background-color: #333;
}
/* Default buttons */
.mainmenu > li a,
.mainmenu > li button {
display: block;
color: #e6e6e6;
background-color: #555;
padding: 12px 8px;
text-decoration: none;
cursor: pointer;
width: 100%;
text-align: left;
}
.mainmenu.classic > li a,
.mainmenu.classic > li button {
padding: 16px;
}
.mainmenu.compact > li a,
.mainmenu.compact > li button {
display: block;
color: #e6e6e6;
background-color: #555;
text-decoration: none;
cursor: pointer;
width: 100%;
text-align: left;
padding: 4px;
}
/* Hovering makes them lighter */
.mainmenu > li a:hover,
.mainmenu > li a:hover:not(.active),
.mainmenu > li a:focus {
background-color: #777;
color: #fff;
}
.mainmenu > li button:hover,
.mainmenu > li button:hover:not(.active) {
background-color: #777;
color: #fff;
}
/* Panel headers can become active, and they are "lighter" than the rest */
.mainmenu > li a.active,
.mainmenu > li button.active {
background-color: #777;
color: #fff;
}
.mainmenu > li a.active:hover,
.mainmenu > li button.active:hover {
background-color: #aaa;
}
.menu-header {
position: relative;
}
#hacking-menu-header-li,
#character-menu-header-li,
#world-menu-header-li,
#help-menu-header-li {
position: relative;
}
/* Accordion Outline */
.mainmenu-accordion-header,
.mainmenu-accordion-header-compact {
outline: 2px solid #fff !important;
}
.mainmenu-accordion-header-classic {
border: 2px solid #fff;
padding: 16px !important;
}
/* Plus and minus signs */
.mainmenu-accordion-header:after,
.mainmenu-accordion-header-compact:after {
content: "\02795";
float: right;
font-size: $defaultFontSize * 0.8125;
position: absolute;
bottom: 25%;
right: 3px;
color: transparent;
text-shadow: 0 0 0 #fff;
}
.mainmenu-accordion-header-classic:after {
content: "\02795";
float: right;
font-size: $defaultFontSize * 0.8125;
color: #fff;
margin-left: 5px;
}
.mainmenu-accordion-header.opened,
.mainmenu-accordion-header-classic.opened,
.mainmenu-accordion-header-compact.opened {
background-color: #222 !important;
&:after {
content: "\2796";
}
}
/* Slide down transition */
.mainmenu-accordion-panel {
transition: max-height 0.2s ease-out;
}

View File

@@ -1,128 +0,0 @@
@import "mixins";
@import "theme";
/* CSS for different main menu pages, such as character info, script editor, etc (but excluding
terminal which has its own page) */
#generic-react-container {
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
flex-grow: 1;
}
#generic-react-container::-webkit-scrollbar {
display: none; /* for Chrome, Safari, and Opera */
}
#world-city-name,
#world-city-desc {
padding: 4px;
margin: 4px;
}
#create-program-page-text,
#create-program-list {
width: 70%;
}
.faction-work-div {
width: 70%;
height: 100%;
}
.faction-work-div-wrapper {
overflow: hidden;
border: 2px solid #333;
padding: 6px;
margin: 6px;
width: 70%;
}
.faction-container p,
.faction-container pre {
padding: 4px 6px;
margin: 4px 6px;
}
.faction-container pre {
width: 70%;
white-space: pre-wrap; /* Since CSS 2.1 */
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
white-space: -pre-wrap; /* Opera 4-6 */
white-space: -o-pre-wrap; /* Opera 7 */
word-wrap: break-word; /* Internet Explorer 5.5+ */
}
/* World */
#world-container li {
margin: 0 0 15px 0;
list-style-type: none;
}
/* Tutorial */
#tutorial-container {
position: fixed;
padding-top: 10px;
}
#tutorial-text {
width: 70%;
margin: 10px;
}
#tutorial-container a {
width: 50%;
}
/* Dev menu */
#dev-menu-container {
position: fixed;
padding-top: 10px;
}
#dev-menu-text {
width: 70%;
margin: 10px;
}
#dev-menu-container a {
width: 50%;
}
/* Location */
#location-container {
position: fixed;
padding: 6px;
overflow-x: hidden;
}
#location-container a {
display: inline-block;
width: 30%;
}
#location-slums-description {
width: 70%;
margin: 10px;
}
#location-return-to-world-button {
margin: 10px;
padding: 6px;
}
#location-container > * {
margin: 10px 5px 10px 5px;
}
#location-job-reputation,
#location-company-favor {
display: inline;
}
/* Infiltration */
#infiltration-container {
position: fixed;
margin: 5px;
width: 70%;
}

View File

@@ -1,3 +0,0 @@
.milestones-container {
width: 60%;
}

View File

@@ -1,119 +0,0 @@
@import "mixins";
@import "theme";
/* css for Missions */
/* Hacking missions */
#mission-container {
overflow: hidden;
}
.hack-mission-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
grid-gap: 2.5%;
height: 90%;
position: absolute;
width: 100%;
overflow-y: auto;
padding-right: 10px;
&::-webkit-scrollbar {
display: none;
}
}
.hack-mission-node {
z-index: 5;
background-color: #808080;
align-self: center;
justify-self: center;
display: inline-block;
p {
@include userSelect(none);
margin-top: 8px;
color: #fff;
font-size: $defaultFontSize * 0.75;
text-align: center;
}
}
.hack-mission-player-node {
color: #fff;
background-color: #00f;
}
.hack-mission-player-node-active {
border: 2px solid #fff;
background-color: #66f;
}
.hack-mission-enemy-node {
color: #fff;
background-color: #f00;
}
.hack-mission-cpu-node {
@include borderRadius(50%);
width: 100%;
height: 100%;
}
.hack-mission-firewall-node {
width: 90%;
height: 100%;
}
.hack-mission-database-node {
@include transform(skew(20deg));
width: 100%;
height: 90%;
p {
@include transform(skew(-20deg));
@include userSelect(none);
color: #fff;
font-size: $defaultFontSize * 0.75;
margin-top: 8px;
text-align: center;
}
}
.hack-mission-transfer-node {
@include transform(skew(-20deg));
width: 100%;
height: 90%;
p {
@include transform(skew(20deg));
@include userSelect(none);
color: #fff;
font-size: $defaultFontSize * 0.75;
margin-top: 8px;
text-align: center;
}
}
.hack-mission-spam-node,
.hack-mission-shield-node {
height: 100%;
width: 100%;
}
/* Non-map related DOM elements */
/* Element at the top of the Hacking Mission page (intro page, start button, guide buttons, etc.) */
.hack-mission-header-element {
margin: 6px;
}
.hack-mission-action-buttons-container {
border: 2px solid #fff;
}

View File

@@ -1,244 +0,0 @@
@import "mixins";
@import "theme";
@import "styles";
/* Pop-up boxes */
.popup-box-container {
display: none; /* Initially hidden */
position: fixed; /* Stay in place */
z-index: 1300; /* Sit on top */
left: 0;
top: 0;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background-color: rbga(var(--my-background-color), 0.4);
}
.popup-box-content {
background-color: var(--my-background-color);
padding: 12px;
border: 5px solid var(--my-highlight-color);
width: 70%;
max-height: 80%;
overflow-y: auto;
z-index: 11; /* Sit on top of the container */
color: var(--my-font-color);
}
.popup-box-input-div {
margin: 2px;
}
.popup-box-button,
.popup-box-button-inactive {
color: #aaa;
float: right;
font-size: $defaultFontSize;
font-weight: bold;
padding: 2px;
margin: 6px;
border: 1px solid #fff;
background-color: #000;
}
.popup-box-button:hover,
.popup-box-button:focus {
color: var(--my-font-color);
text-decoration: none;
cursor: pointer;
}
.popupbox-button-inactive {
pointer-events: none;
cursor: default;
}
#yes-no-text-input-box-input {
color: var(--my-font-color);
border: 1px solid #fff;
background-color: #000;
}
.dialog-box-container {
display: block;
position: absolute;
z-index: 10;
width: 50%;
height: auto;
max-height: 50%;
top: 40%;
left: 50%;
margin: -10% 0 0 -25%;
overflow: auto;
background-color: var(--my-background-color);
border: 5px solid var(--my-highlight-color);
}
.log-box-container {
display: flex;
flex-flow: column;
background-color: gray;
width: 50%;
position: fixed;
left: 50%;
top: 40%;
margin: -10% 0 0 -25%;
height: auto;
max-height: 50%;
z-index: 10;
background-color: var(--my-background-color);
border: 2px solid var(--my-highlight-color);
}
.log-box-header {
z-index: 1300;
background-color: #333;
border: 1px solid var(--my-highlight-color);
display: flex;
flex: row nowrap;
align-items: center;
justify-content: space-between;
}
.log-box-log-container {
overflow-y: auto;
}
.log-box-button {
color: #aaa;
font-size: $defaultFontSize;
font-weight: bold;
padding: 2px;
margin: 6px;
border: 1px solid #fff;
background-color: #000;
}
.log-box-button:hover,
.log-box-button:focus {
color: var(--my-font-color);
text-decoration: none;
cursor: pointer;
}
.dialog-box-content {
z-index: 2;
background-color: var(--my-background-color);
padding: 10px;
p span {
padding: 0;
margin: 0;
}
}
.dialog-box-close-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
@extend .noselect;
float: right;
color: #aaa;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
}
#log-box-close {
position: fixed;
right: 27%;
}
#log-box-kill-script {
right: 11%;
position: relative;
}
#log-box-close,
#log-box-kill-script {
float: right;
display: inline-block;
}
.dialog-box-close-button:hover,
.dialog-box-close-button:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
/* Faction invitation box */
#faction-invitation-box-container {
transition: opacity 400ms ease-in;
}
#faction-invitation-box-warning {
margin: 4px;
padding: 4px;
}
/* Infiltration-box */
#infiltration-box-sell,
#infiltration-box-faction {
display: block;
padding: 8px;
margin: 8px;
}
#infiltration-box-content span {
padding: 0;
margin: 0;
}
#infiltration-faction-select {
background-color: #000;
}
/* Game Options */
#game-options-container {
transition: opacity 400ms ease-in;
}
#game-options-content {
background-color: var(--my-background-color);
padding: 10px;
border: 5px solid var(--my-highlight-color);
color: var(--my-font-color);
width: 80%;
max-height: 80%;
overflow-y: auto;
}
#game-options-left-panel,
#game-options-right-panel {
display: inline-block;
width: 49%;
}
#game-options-close-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
float: right;
margin: 4px;
padding: 4px;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
}
#game-options-close-button:hover,
#game-options-close-button:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
#game-options-left-panel fieldset {
padding: 2px;
margin: 2px;
}
#import-game-file-selector {
display: none;
}

View File

@@ -1,34 +0,0 @@
@import "theme";
/**
* Styling for the Red Pill screen (the BitNode selection UI)
*/
#red-pill-container {
position: fixed;
}
.bitnode {
&.level-0 {
color: red;
}
&.level-1 {
color: yellow;
}
&.level-2 {
color: #48d1cc;
}
&.level-3 {
color: blue;
}
&.unimplemented {
color: gray;
}
&:hover {
color: #fff;
}
}

View File

@@ -1,28 +0,0 @@
/**
* Styling for the Re-Sleeving Page
*/
@import "theme";
.resleeve-elem {
border: 1px solid white;
margin: 4px;
width: 75%;
p {
font-size: $defaultFontSize * 0.8125;
}
}
.resleeve-panel {
display: inline-block;
margin: 0;
padding: 2px;
}
.resleeve-aug-selector {
font-size: $defaultFontSize * 0.8125;
option {
font-size: $defaultFontSize * 0.8125;
}
}

View File

@@ -1,92 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for Script Editor (both Ace and CodeMirror)
*/
#script-editor-buttons-wrapper {
width: 100%;
padding-right: 0;
margin-right: 0;
}
.script-editor-wrapper {
height: 110vh;
width: 70%;
background: transparent;
}
#script-editor-filename-wrapper {
background-color: #555;
margin-right: 0;
padding-left: 6px;
width: 100%;
border: 2px solid var(--my-highlight-color);
}
#script-editor-filename-tag {
display: inline-block;
padding-top: 10px;
padding-bottom: 0;
float: center;
background-color: #555;
color: #fff;
}
#script-editor-filename {
$boxShadowArgs: inset 0 0 8px rgba(0, 0, 0, 0.1), 0 0 16px rgba(0, 0, 0, 0.1);
@include boxShadow($boxShadowArgs);
background-color: #555;
border: 2px solid var(--my-highlight-color);
color: #fff;
display: inline-block;
float: center;
margin: 4px;
padding: 2px;
resize: none;
width: 60%;
}
#script-editor-status {
float: left;
color: #fff;
}
#script-editor-options-panel {
position: absolute;
right: 9%;
bottom: 15%;
border: 2px solid #fff;
width: 19%;
background-color: #444;
padding: 2px;
overflow: auto;
z-index: 1;
color: #fff;
max-height: 50%;
}
#script-editor-options-panel fieldset {
margin-top: 8px;
margin-bottom: 8px;
padding: 2px;
font-size: $defaultFontSize * 0.75;
input {
margin: 2px;
}
}
.editor-options-container {
display: flex;
flex-flow: column;
}
.editor-options-line {
display: flex;
flex: row nowrap;
align-items: center;
justify-content: start;
}

View File

@@ -1,25 +0,0 @@
/**
* Styling for the Sleeves Management page
*/
@import "theme";
.sleeve-elem {
border: 1px solid white;
margin: 4px;
display: block;
}
.sleeves-page-info {
display: "block";
width: 75%;
}
.sleeve-panel {
display: inline-block;
margin: 0;
padding: 2px;
select {
display: block;
}
}

23
css/staneksgift.scss Normal file
View File

@@ -0,0 +1,23 @@
.staneksgift_row {
padding: 0;
margin: 0;
}
.staneksgift_cell {
width: 25px;
height: 25px;
background-color: #808080;
font-color: white;
padding: 0px;
margin: 0px;
border: 1px solid black;
float: left;
}
.staneksgift_cell:first-child {
clear: left;
}
.staneksgift_container {
position: fixed;
}

View File

@@ -1,96 +0,0 @@
@import "theme";
.stock-market-container {
p {
font-size: $defaultFontSize * 0.8125;
}
a {
font-size: $defaultFontSize * 0.875;
}
}
.stock-market-info-and-purchases {
> h2 {
display: block;
margin-top: 10px;
margin-left: 10px;
}
> p {
display: block;
margin-left: 10px;
width: 70%;
}
> a,
> button {
margin: 10px;
}
}
#stock-market-list {
list-style: none;
li {
button {
font-size: $defaultFontSize;
}
}
}
#stock-market-watchlist-filter {
display: block;
margin: 5px 5px 5px 10px;
padding: 4px;
width: 50%;
}
.stock-market-input {
display: inline-block;
padding: 4px;
margin: 2px;
background-color: #000;
border: 1px solid #fff;
color: var(--my-font-color);
}
.stock-market-price-movement-warning {
border: 1px solid white;
color: red;
margin: 2px;
padding: 2px;
}
.stock-market-position-text {
color: #fff;
display: block;
p {
color: #fff;
display: inline-block;
margin: 4px;
}
h3 {
margin: 4px;
}
}
.stock-market-order-list {
overflow-y: auto;
max-height: 100px;
li {
color: #fff;
padding: 4px;
}
}
.stock-market-order-cancel-btn {
background-color: #000;
border: 1px solid #fff;
color: var(--my-font-color);
margin: 2px;
padding: 0;
}

View File

@@ -1,528 +0,0 @@
@import "mixins";
@import "theme";
@import "reset";
:root {
--my-font-color: #0c0;
--my-background-color: #000;
--my-highlight-color: #fff;
--my-prompt-color: #f92672;
}
body {
background-color: var(--my-background-color);
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
}
body::-webkit-scrollbar {
display: none; /* for Chrome, Safari, and Opera */
}
p,
pre,
h2,
h3,
h4,
.text,
td {
color: var(--my-font-color);
}
h1 {
font-size: $defaultFontSize * 1.375;
color: var(--my-font-color);
}
ul {
padding: 2px;
list-style-type: none;
}
li {
list-style-type: none;
}
br {
@extend .noselect;
}
#entire-game-container {
background-color: transparent;
}
/* Disable border highlight on elements */
input:focus,
textarea:focus,
button:focus,
td:focus,
tr:focus {
outline: none;
}
/* Make html links ("a" elements) nice looking buttons with this class */
a:link,
a:visited {
color: #fff;
}
.dropdown {
color: #fff;
background-color: #000;
}
.text-input {
color: #fff;
background-color: #000;
border-style: solid;
border-width: 1px;
border-color: white;
}
/* Notification icon (for create program right now only) */
#create-program-tab {
position: relative;
}
#create-program-notification {
font-size: $defaultFontSize * 0.625;
position: absolute; /* Position the badge within the relatively positioned button */
top: 0;
right: 0;
}
#factions-tab {
position: relative;
}
#factions-notification {
font-size: $defaultFontSize * 0.625;
position: absolute; /* Position the badge within the relatively positioned button */
top: 0;
right: 0;
}
#augmentations-tab {
position: relative;
}
#augmentations-notification {
font-size: $defaultFontSize * 0.625;
position: absolute; /* Position the badge within the relatively positioned button */
top: 0;
right: 0;
}
.notification-on {
background-color: #fa3e3e;
color: #fff;
border-radius: 2px;
padding: 1px 3px;
font-size: $defaultFontSize * 0.625;
top: 0;
right: 0;
position: absolute;
}
.notification-off {
background-color: #333;
color: #333;
border-radius: 0;
padding: 0;
display: "none";
}
.notification {
position: relative;
display: inline-block;
}
.notification .badge {
position: absolute;
top: 0;
right: 0;
padding: 2px;
background: red;
color: white;
}
/* help tip. Question mark that opens popup with info/details */
.help-tip {
background-color: black;
border: 1px solid #fff;
border-radius: 5px;
color: #fff;
content: "?";
display: inline-block;
margin-left: 3px;
padding: 1px;
}
.help-tip-big {
content: "?";
padding: 3px;
margin-left: 3px;
color: #fff;
border: 1px solid #fff;
border-radius: 8px;
display: inline-block;
}
.help-tip:hover,
.help-tip-big:hover {
background-color: #888;
}
.help-tip:active,
.help-tip-big:active {
@include boxShadow(inset 0 1px 4px rgba(0, 0, 0, 0.6));
}
/* Flashing button (Red) */
@-webkit-keyframes glowing {
0% {
background-color: #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 {
0% {
background-color: #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 {
0% {
background-color: #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 {
0% {
background-color: #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 {
-webkit-animation: glowing 1500ms infinite;
-moz-animation: glowing 1500ms infinite;
-o-animation: glowing 1500ms infinite;
animation: glowing 1500ms infinite;
}
/* Blinking Cursor */
/* ----- blinking cursor animation ----- */
.typed-cursor {
opacity: 1;
-webkit-animation: blink 0.95s infinite;
-moz-animation: blink 0.95s infinite;
-ms-animation: blink 0.95s infinite;
-o-animation: blink 0.95s infinite;
animation: blink 0.95s infinite;
}
@-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-moz-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-ms-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-o-keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
/* Status text */
@-webkit-keyframes status-text {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.status-text {
z-index: 2;
-webkit-animation: status-text 3s 1;
}
#status-text-container {
background-color: transparent;
position: fixed;
top: 0;
left: 50%;
}
#status-text {
background-color: transparent;
bottom: 0;
color: #fff;
display: none;
font-size: $defaultFontSize * 1.25;
margin-right: 14px;
opacity: 0;
padding: 4px;
right: 0;
top: 0;
width: auto;
}
/* Scan analyze links from AutoLink */
.scan-analyze-link {
cursor: pointer;
color: #fff;
text-decoration: underline;
&:hover {
text-decoration: none;
}
}
/* Accordion menus (Header with collapsible panel) */
.accordion-header {
background-color: #444;
color: #fff;
font-size: $defaultFontSize * 1.25;
margin: 6px 6px 0 6px;
padding: 4px 6px;
cursor: pointer;
width: 80%;
text-align: left;
border: none;
outline: none;
position: relative;
&.active,
&:hover {
background-color: #555;
}
&.active:hover {
background-color: #666;
}
&:after {
content: "\02795"; /* "plus" sign (+) */
font-size: $defaultFontSize * 0.875;
float: right;
color: transparent;
text-shadow: 0 0 0 #fff;
position: absolute;
bottom: 5px;
right: 6px;
}
&.active:after {
content: "\2796"; /* "minus" sign (-) */
}
}
.accordion-panel {
margin: 0 6px 6px 6px;
padding: 0 6px 6px 6px;
width: 75%;
margin-left: 5%;
display: none;
background-color: #555;
overflow-y: auto;
overflow-x: none;
div,
ul,
p,
ul > li {
background-color: #555;
}
}
/* override the global <span> styling */
#active-scripts-total-production-active,
#active-scripts-total-prod-aug-total,
#active-scripts-total-prod-aug-avg {
margin: 0;
padding: 0;
}
/* Helper Classes */
.hacker-green {
color: $hacker-green;
}
.money-gold {
color: $money-gold;
}
.light-yellow {
color: $light-yellow;
}
.unbuyable {
color: #66cfbc;
}
.failure {
color: $alert-red;
text-shadow: 0 0 0 $alert-red;
}
.success {
color: $success-green;
text-shadow: 0 0 0 $success-green;
}
.physical-yellow {
color: $my-stat-physical;
}
.charisma-purple {
color: $my-stat-cha-color;
}
.reputation {
color: $light-yellow;
}
.smallfont {
font-size: $defaultFontSize * 0.8125;
}
.samefont {
font-size: inherit;
}
.noscrollbar {
-ms-overflow-style: none; /* IE and Edge */
/* stylelint-disable-next-line property-no-unknown */
scrollbar-width: none; /* Firefox https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-width */
}
.noscrollbar::-webkit-scrollbar {
display: none;
}
input[type="checkbox"] {
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10);
}
.optionCheckbox {
margin: 5px;
float: right;
}
.optionRange {
-webkit-appearance: none;
background: #777;
outline: none;
opacity: 0.7;
height: 10px;
-webkit-transition: 0.2s;
transition: opacity 0.2s;
margin: 3px;
}
.optionRange::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 10px;
height: 10px;
background: var(--my-font-color);
cursor: pointer;
}
.optionRange::-moz-range-thumb {
width: 10px;
height: 10px;
background: var(--my-font-color);
cursor: pointer;
}
.noselect {
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}

View File

@@ -1,129 +0,0 @@
@import "theme";
/* Styling for tooltip-style elements */
/* Tool tips (when hovering over an element */
.tooltip {
display: inline-block;
position: relative;
.tooltiptext {
visibility: hidden;
width: 300px;
background-color: var(--my-background-color);
border: 2px solid var(--my-highlight-color);
color: #fff;
text-align: center;
padding: 4px;
left: 101%;
pointer-events: none;
position: absolute;
z-index: 99;
}
/* Positioned to left of element rather than right */
.tooltiptextleft {
visibility: hidden;
width: 300px;
background-color: var(--my-background-color);
border: 2px solid var(--my-highlight-color);
color: #fff;
text-align: center;
padding: 4px;
top: 50%;
left: 50%;
transform: translate(-100%, -100%);
/* Backwards compatibility */
-webkit-transform: translate(-100%, -100%);
-moz-transform: translate(-100%, -100%);
-o-transform: translate(-100%, -100%);
-ms-transform: translate(-100%, -100%);
position: absolute;
z-index: 99;
}
/* Tooltip goes below cursor instead of above */
.tooltiptextlow {
visibility: hidden;
width: 300px;
background-color: var(--my-background-color);
border: 2px solid var(--my-highlight-color);
color: #fff;
text-align: center;
padding: 4px;
left: 101%;
pointer-events: none;
position: absolute;
z-index: 99;
bottom: 25%;
}
}
/* Same thing as a normal tooltip except its a bit higher */
.tooltip .tooltiptexthigh {
visibility: hidden;
width: 300px;
background-color: var(--my-background-color);
border: 2px solid var(--my-highlight-color);
color: #fff;
text-align: center;
padding: 4px;
left: 101%;
bottom: -25%;
position: absolute;
z-index: 99;
}
.tooltip:hover .tooltiptext,
.tooltip:hover .tooltiptexthigh,
.tooltip:hover .tooltiptextleft,
.tooltip:hover .tooltiptextlow {
visibility: visible;
}
.copy_tooltip {
position: relative;
display: inline-block;
}
.copy_tooltip_copied {
color: #fff;
transition: color 0.3s;
}
.copy_tooltip .copy_tooltip_text {
visibility: hidden;
font-size: 15px;
padding: 5px;
background-color: var(--my-background-color);
color: #fff;
text-align: center;
position: absolute;
z-index: 1;
top: 120%;
left: 5%;
opacity: 0;
border: 2px solid var(--my-highlight-color);
}
.copy_tooltip .copy_tooltip_text::after {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -6px;
border-width: 8px;
border-style: solid;
border-color: transparent transparent white transparent;
}
.copy_tooltip .copy_tooltip_text_visible {
visibility: visible;
opacity: 1;
transition: opacity 0.3s;
}

View File

@@ -1,68 +0,0 @@
/* required LIB STYLES */
/* .Treant se automatski dodaje na svaki chart conatiner */
.Treant {
position: relative;
overflow: hidden;
padding: 0 !important;
}
.Treant > .node,
.Treant > .pseudo {
position: absolute;
display: block;
visibility: hidden;
}
.Treant.Treant-loaded .node,
.Treant.Treant-loaded .pseudo {
visibility: visible;
}
.Treant > .pseudo {
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 {
cursor: pointer;
padding: 4px;
min-width: 60px;
text-align: center;
border: 2px solid #e8e8e3;
border-radius: 2px;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
font-size: 12px;
}
.Treant > .researched {
background-color: #666;
font-size: 16px;
}
.Treant > .locked > div {
color: red;
pointer-events: none;
}
.Treant > .node > div {
font-size: 12px;
}
.Treant > .unlocked:hover {
background-color: #666;
}

View File

@@ -1,51 +0,0 @@
@import "mixins";
@import "theme";
/* Both Work in progress and BitNode stuff */
.generic-fullscreen-container {
color: var(--my-font-color);
width: 99%;
height: 100%;
overflow-y: hidden;
}
.generic-fullscreen-container-scroll {
height: 100%;
width: 100%;
overflow: auto;
padding-right: 20px;
}
#work-in-progress-container {
position: fixed;
}
#work-in-progress-text {
color: var(--my-font-color);
width: 70%;
margin: 10px;
}
.work-button {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #aaa;
float: left;
font-size: $defaultFontSize * 1.25;
font-weight: bold;
margin: 10px;
padding: 5px;
border: 3px solid #fff;
}
.work-button:hover,
.work-button:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}
#cinematic-text-container {
position: fixed;
}

193
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
.. _gameplay_sourcefiles:
.. warning:: This page contains spoilers regarding the game's story/plot-line.
.. warning:: This page contains spoilers for the game
Source-Files
============

View File

@@ -3,6 +3,131 @@
Changelog
=========
v0.56.0 - 2021-10-11 Trimming the backlog (hydroflame & community)
-------------------------------------------
** BREAKING **
* The 'write' function is now async. This helps when making scripts that write scripts.
** Terminal **
* 'grow' and 'weaken' have been added as terminal command. This should help player transition
from commands to scripts. The tutorial also talks about it.
* 'cp' command added
* Improved performance by rate limiting refresh.
** IP vs Hostname **
* The game now uses hostname as primary key for it's servers (yeah believe it or not IPs were
used until then). This has caused some issues with purchased servers (they couldn't be sold).
You might need to soft reset for the game to fully convert itself.
** Sleeve **
* Fixed bug where they couldn't train at Volhaven.
* No longer consume all bonus time at once, making it look buggy.
** SF9 **
* Now boosts hacknet production by 8/12/14%
** Hacknet Servers **
* production nerfed by 10%
* Max money increase gets weaker above 10t max money
** Corporation **
* Warehouse tooltip now also displays the amount of space taken by products.
* Changed research box completely to avoid dependency on Treant (Treant is a pita)
* All textbox should accept MAX/MP case insensitive.
* Fixed export popup not refreshing dropdowns correctly.
* Fixed product mku becoming zero
* Increased scaling of Wilson to avoid feedback loop.
* Can no longer get in debt by buying real estate
* Bonus time is consumed faster.
** Netscript **
* isBusy takes bitverse and infiltration into account
* hospitalize can't be called when in infiltration.
* setToCommitCrime now accepts crime rough name instead of perfect name.
* disableLog All now works for bladeburner functions.
* Fixed netscript port for ns1.
** Augmentation **
* Added augmentation to Ti Di Hui that removes penalty for being unfocused.
* Neuroflux no longer appears in special factions.
** Script Editor **
* Ram check is debounced instead of refreshed every second.
* Added the vscode extension documentation to the game (it doesn't work well, thought)
* Fixed issue where autocomplete list would grow forever
* Added semi-monokai as theme.
* Fixed issue where modifying filename would mess it up.
* Font size can be changed now.
** Infiltration **
* Fixed issue where game controls would become unfocused.
** Misc. **
* Fixed loader incorrectly assuming some null values are incorrect.
* installBackdoor trigger Bitverse sequence
* Some improvements to the theme editor
* Improved documentation about where to learn javascript.
* Added some instructions for contributors.
* Fixed typo in corporation sell shares modal (@Saynt_Garmo)
* Fixed pagination being black on black in Active Scripts
* Create Script tab renamed to Script Editor
* Fixed an issue where corp some textbox wouldn't update when changing city.
* Fixed an issue where hacknet online time was always 0.
* Netscript function prompt fixed.
* Fixed miscalculation in growth.
* Script with syntax errors will try to be a tad more helpful.
* Corporations can no longer bribe bladeburners.
* Augmentation Graphene Branchiblade renamed to Brachi, like the rest of them.
* All ram is displayed in GB/TB/PB now.
* Game now saves when saving a file, this can be turned off.
* Several improvement to log window.
* Bladeburner current action returns General type instead of the name of the action.
* Bladeburner travel and Sleeve travel respect disable ASCII.
* Tutorial fits on small screens.
* Import is much slower but more consistent now.
* Fix intelligence not updating properly.
* Added SF -1: Time Compression
* ReadTheDoc theme now matches the game.
* Logbox should wrap text better
* Logbox behavior should feel better.
* Fix font for AutoLink.exe
* nerf noodle bar
v0.55.0 - 2021-09-20 Material UI (hydroflame & community)
-------------------------------------------
** Global **
* The game is now 100% in typescript, react, and Material-UI
** Misc. **
* Corporations can no longer bribe special factions
* Infiltration can no longer lose focus of the keyboard.
* Fix terminal line limit
* Added theme editor
* Theme applies on game load (@Nolshine)
* Sleeves no longer consume all bonus time for some actions
* Fix a bug where the autocomlete list would get duplicates
* Fix tutorial not scaling properly on small screens
* Import should be more consistent
* Typo with 'help' command
* Fix infinite loop in casino
* nerf noodle bar
v0.54.0 - 2021-09-20 One big react node (hydroflame & community)
-------------------------------------------

View File

@@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
# built documents.
#
# The short X.Y version.
version = '0.54'
version = '0.56'
# The full version, including alpha/beta/rc tags.
release = '0.54.0'
release = '0.56.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -189,3 +189,4 @@ intersphinx_mapping = {'https://docs.python.org/': None}
def setup(app):
print("Initializing (setup())");
app.add_stylesheet('maxwidthoverride.css')
app.add_stylesheet('dark_theme.css')

View File

@@ -30,5 +30,6 @@ to reach out to the developer!
Gang API <netscript/netscriptgangapi>
Coding Contract API <netscript/netscriptcodingcontractapi>
Sleeve API <netscript/netscriptsleeveapi>
Stanek API <netscript/netscriptstanekapi>
Formulas API <netscript/netscriptformulasapi>
Miscellaneous <netscript/netscriptmisc>

View File

@@ -6,8 +6,6 @@ getServer() Netscript Function
:RAM cost: 2 GB
:param string hostname: Hostname of the server, defaults to host server.
If you are not in BitNode-5, then you must have Source-File 5-1 in order to run this function.
This function is meant to be used in conjunction with the :doc:`formulas API<../netscriptformulasapi>`.
Returns an object with the Server's stats. The object has the following properties::

View File

@@ -28,6 +28,8 @@ grow() Netscript Function
server, but there is no required hacking level to run the command. It also
raises the security level of the target server by 0.004 per thread.
Action time is calculated at the start, effect is calculated at the end.
Example:
.. code-block:: javascript

View File

@@ -1,12 +1,13 @@
growthAnalyze() Netscript Function
==================================
.. js:function:: growthAnalyze(hostname, growthAmount)
.. js:function:: growthAnalyze(hostname, growthAmount[, cores])
:RAM cost: 1 GB
:param string hostname: Hostname of server to analyze.
:param number growthAmount: Multiplicative factor by which the server is
grown. Decimal form. Must be >= 1.
:param number cores: Amount of cores on the server that would run the growth, defaults to 1
:returns: The amount of :doc:`grow<grow>` threads needed to grow the specified
server by the specified amount.

View File

@@ -27,6 +27,8 @@ hack() Netscript Function
A successful :doc:`hack<hack>` on a server will raise that server's security
level by 0.002.
Action time is calculated at the start, effect is calculated at the end.
Example:
.. code-block:: javascript

View File

@@ -15,6 +15,7 @@ help you learn some basic programming concepts.
Here are some good tutorials for learning programming/JavaScript as a beginner:
* `Learn-JS <http://www.learn-js.org/en/Welcome>`_
* `programiz <https://www.programiz.com/javascript/get-started>`_
* `Speaking JavaScript <http://speakingjs.com/es5/index.html>`_
This is a bit on the longer side. You can skip all of the historical
background stuff. Recommended chapters: 1, 7-18

View File

@@ -0,0 +1,20 @@
.. _netscriptstanek:
Netscript Stanek Functions
============================
.. warning:: This page contains spoilers for the game.
The Stanek API allow you to control Stanek's Gift.
All these function require Source-File 13-1 or to be in BitNode 13.
.. toctree::
charge() <stanekapi/charge>
fragmentDefinitions() <stanekapi/fragmentDefinitions>
placedFragments() <stanekapi/placedFragments>
clear() <stanekapi/clear>
canPlace() <stanekapi/canPlace>
place() <stanekapi/place>
fragmentAt() <stanekapi/fragmentAt>
deleteAt() <stanekapi/deleteAt>

View File

@@ -3,7 +3,9 @@ getAugmentationCost() Netscript Function
.. js:function:: getAugmentationCost(augName)
.. warning:: This function is deprecated.
.. warning:: This function is deprecated. It still functions, but new
scripts should prefer :doc:`getAugmentationPrice<getAugmentationPrice>`
and :doc:`getAugmentationRepReq<getAugmentationRepReq>` instead.
:RAM cost: 5 GB

View File

@@ -0,0 +1,15 @@
canPlace() Netscript Function
=======================================
.. js:function:: canPlace(worldX, worldY, fragmentId)
:RAM cost: 0.5 GB
:param int worldX: World X against which to align the top left of the fragment.
:param int worldY: World Y against which to align the top left of the fragment.
:param int fragmentId: ID of the fragment to place.
:returns: `true` if the fragment can be placed at that position. `false` otherwise.
Example:
.. code-block:: javascript
canPlace(0, 4, 17); // returns true

View File

@@ -0,0 +1,21 @@
charge() Netscript Function
=======================================
.. js:function:: charge(worldX, worldY)
:RAM cost: 0.4 GB
:param int worldX: World X of the fragment to charge.
:param int worldY: World Y of the fragment to charge.
Charge a fragment, increasing it's power but also it's heat. The
effectiveness of the charge depends on the amount of ram the running script
consumes as well as the fragments current heat. This operation takes time to
complete.
Example:
.. code-block:: javascript
charge(0, 4); // Finishes 5 seconds later.
.. warning::
Netscript JS users: This function is `async`

View File

@@ -0,0 +1,13 @@
clear() Netscript Function
=======================================
.. js:function:: clear()
:RAM cost: 0 GB
Completely clear Stanek's Gift.
Example:
.. code-block:: javascript
clear(); // No more fragments.

View File

@@ -0,0 +1,16 @@
deleteAt() Netscript Function
=======================================
.. js:function:: deleteAt(worldX, worldY)
:RAM cost: 0.15 GB
:param int worldX: World X coordinate of the fragment to delete.
:param int worldY: World Y coordinate of the fragment to delete.
:returns: `true` if the fragment was deleted. `false` otherwise.
Delete the fragment located at `[worldX, worldY]`.
Example:
.. code-block:: javascript
deleteAt(0, 4); // returns true

View File

@@ -0,0 +1,28 @@
fragmentAt() Netscript Function
=======================================
.. js:function:: fragmentAt(worldX, worldY)
:RAM cost: 2 GB
:param int worldX: World X coordinate of the fragment.
:param int worldY: World Y coordinate of the fragment.
:returns: The fragment located at `[worldX, worldY]` in Stanek's Gift, or null.
.. code-block:: typescript
{
// In world coordinates
x: number;
y: number;
heat: number;
charge: number;
id: number;
shape: boolean[][];
type: string;
magnitude: number;
limit: number;
}
Example:
.. code-block:: javascript
var fragment = fragmentAt(0, 4);
print(fragment); // {'heat': 50, 'charge': 98}

View File

@@ -0,0 +1,23 @@
fragmentDefinitions() Netscript Function
=======================================
.. js:function:: fragmentDefinitions()
:RAM cost: 0 GB
:returns: The list of all fragment that can be embedded in Stanek's Gift.
.. code-block:: typescript
[
{
id: number;
shape: boolean[][];
type: string;
magnitude: number;
limit: number;
}
]
Example:
.. code-block:: javascript
var fragments = fragmentDefinitions();
print(fragment); // prints all possible fragments

View File

@@ -0,0 +1,15 @@
place() Netscript Function
=======================================
.. js:function:: place(worldX, worldY, fragmentId)
:RAM cost: 5 GB
:param int worldX: World X against which to align the top left of the fragment.
:param int worldY: World Y against which to align the top left of the fragment.
:param int fragmentId: ID of the fragment to place.
:returns: `true` if the fragment has been placed at that position. `false` otherwise.
Example:
.. code-block:: javascript
place(0, 4, 17); // returns true

View File

@@ -0,0 +1,27 @@
placedFragments() Netscript Function
=======================================
.. js:function:: placedFragments()
:RAM cost: 5 GB
:returns: The list of all fragment that are embedded in Stanek's Gift.
.. code-block:: typescript
[
{
// In world coordinates
x: number;
y: number;
heat: number;
charge: number;
id: number;
shape: boolean[][];
type: string;
magnitude: number;
limit: number;
}
]
Example:
.. code-block:: javascript
var myFragments = placedFragments();

View File

@@ -0,0 +1,453 @@
:root {
--dark-text-color: #0c0;
--dark-link-color: #090;
}
body {
color: #000;
}
.wy-nav-content-wrap {
background-color: #000;
}
.wy-nav-content {
background-color: #000;
}
.section {
color: var(--dark-text-color);
}
.rst-content .highlighted {
background: #333;
box-shadow: none;
}
.highlight {
background-color: #17181c;
}
.highlight .nn {
color: var(--dark-text-color);
}
.highlight .nb {
color: #8bb8df;
}
.highlight .kn,
.highlight .kc,
.highlight .k {
color: #41c2ea;
}
.highlight .s1,
.highlight .s2 {
color: #b3e87f;
}
.highlight .nt {
color: #ccb350;
}
.highlight .c1 {
color: #686868;
}
.rst-content div[class^="highlight"] {
border-color: #1a1a1a;
}
.icon,
.icon-home {
color: var(--dark-link-color);
}
.wy-nav-content a,
.wy-nav-content a:visited {
color: var(--dark-link-color) !important;
text-decoration: underline;
}
.btn-neutral {
background-color: #17181c !important;
}
.btn-neutral:hover {
background-color: #101114 !important;
}
.btn-neutral:visited {
color: #c1c1c1 !important;
}
.btn {
box-shadow: none;
}
footer {
color: #bdbdbd;
}
.wy-nav-side {
background-color: #000;
border: 1px solid #333;
}
.wy-menu-vertical > a {
color: var(--dark-text-color);
}
.wy-menu-vertical li.current {
background-color: #000;
}
.wy-menu-vertical li.current > a,
.wy-menu-vertical li.on a {
background-color: #000;
color: var(--dark-text-color);
}
.wy-menu-vertical li.toctree-l1.current > a,
.wy-menu-vertical li.current a {
border-color: #000;
}
.wy-menu-vertical header,
.wy-menu-vertical p.caption {
color: var(--dark-text-color);
}
html.writer-html4 .rst-content dl:not(.docutils) > dt,
html.writer-html5
.rst-content
dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)
> dt {
background-color: #333;
}
.wy-menu-vertical li.current a {
color: #090;
}
.wy-menu-vertical a {
color: var(--dark-text-color);
}
.wy-menu-vertical li.current a:hover {
background-color: #222;
}
.wy-menu-vertical a:hover,
.wy-menu-vertical li.current > a:hover,
.wy-menu-vertical li.on a:hover {
background-color: #000;
color: var(--dark-text-color);
}
.wy-menu-vertical li.toctree-l2.current > a,
.wy-menu-vertical li.toctree-l2.current li.toctree-l3 > a {
background-color: #000;
}
.wy-side-nav-search {
background-color: #000;
color: var(--dark-text-color);
}
.wy-side-nav-search .wy-dropdown > a,
.wy-side-nav-search > a {
color: var(--dark-text-color);
}
.wy-side-nav-search input[type="text"] {
border-left: 0px;
border-right: 0px;
border-top: 0px;
border-radius: 0px;
box-shadow: none;
border-bottom-color: #0c0;
background-color: #333;
color: var(--dark-text-color);
}
.theme-switcher {
background-color: #0b0c0d;
color: var(--dark-text-color);
}
writer-html4 .rst-content dl:not(.docutils) > dt,
writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) > dt {
background-color: #0b0b0b;
color: #007dce;
border-color: #282828;
}
.rst-content code,
.rst-content tt {
color: var(--dark-text-color);
}
writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list) > dt,
writer-html5
.rst-content
dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)
dl:not(.field-list)
> dt {
background-color: #0f0f0f;
color: #959595;
border-color: #2b2b2b;
}
.rst-content code,
.rst-content tt,
code {
background-color: #2d2d2d;
border-color: #1c1c1c;
}
.rst-content code.xref,
.rst-content tt.xref,
a .rst-content code,
a .rst-content tt {
color: #cecece;
}
.rst-content .hint,
.rst-content .important,
.rst-content .tip,
.rst-content .wy-alert-success.admonition,
.rst-content .wy-alert-success.admonition-todo,
.rst-content .wy-alert-success.attention,
.rst-content .wy-alert-success.caution,
.rst-content .wy-alert-success.danger,
.rst-content .wy-alert-success.error,
.rst-content .wy-alert-success.note,
.rst-content .wy-alert-success.seealso,
.rst-content .wy-alert-success.warning,
.wy-alert.wy-alert-success {
background-color: #00392e;
}
.rst-content .hint .admonition-title,
.rst-content .hint .wy-alert-title,
.rst-content .important .admonition-title,
.rst-content .important .wy-alert-title,
.rst-content .tip .admonition-title,
.rst-content .tip .wy-alert-title,
.rst-content .wy-alert-success.admonition-todo .admonition-title,
.rst-content .wy-alert-success.admonition-todo .wy-alert-title,
.rst-content .wy-alert-success.admonition .admonition-title,
.rst-content .wy-alert-success.admonition .wy-alert-title,
.rst-content .wy-alert-success.attention .admonition-title,
.rst-content .wy-alert-success.attention .wy-alert-title,
.rst-content .wy-alert-success.caution .admonition-title,
.rst-content .wy-alert-success.caution .wy-alert-title,
.rst-content .wy-alert-success.danger .admonition-title,
.rst-content .wy-alert-success.danger .wy-alert-title,
.rst-content .wy-alert-success.error .admonition-title,
.rst-content .wy-alert-success.error .wy-alert-title,
.rst-content .wy-alert-success.note .admonition-title,
.rst-content .wy-alert-success.note .wy-alert-title,
.rst-content .wy-alert-success.seealso .admonition-title,
.rst-content .wy-alert-success.seealso .wy-alert-title,
.rst-content .wy-alert-success.warning .admonition-title,
.rst-content .wy-alert-success.warning .wy-alert-title,
.rst-content .wy-alert.wy-alert-success .admonition-title,
.wy-alert.wy-alert-success .rst-content .admonition-title,
.wy-alert.wy-alert-success .wy-alert-title {
background-color: #006a56;
}
.rst-content .note,
.rst-content .seealso,
.rst-content .wy-alert-info.admonition,
.rst-content .wy-alert-info.admonition-todo,
.rst-content .wy-alert-info.attention,
.rst-content .wy-alert-info.caution,
.rst-content .wy-alert-info.danger,
.rst-content .wy-alert-info.error,
.rst-content .wy-alert-info.hint,
.rst-content .wy-alert-info.important,
.rst-content .wy-alert-info.tip,
.rst-content .wy-alert-info.warning,
.wy-alert.wy-alert-info {
background-color: #002c4d;
}
.rst-content .note .admonition-title,
.rst-content .note .wy-alert-title,
.rst-content .seealso .admonition-title,
.rst-content .seealso .wy-alert-title,
.rst-content .wy-alert-info.admonition-todo .admonition-title,
.rst-content .wy-alert-info.admonition-todo .wy-alert-title,
.rst-content .wy-alert-info.admonition .admonition-title,
.rst-content .wy-alert-info.admonition .wy-alert-title,
.rst-content .wy-alert-info.attention .admonition-title,
.rst-content .wy-alert-info.attention .wy-alert-title,
.rst-content .wy-alert-info.caution .admonition-title,
.rst-content .wy-alert-info.caution .wy-alert-title,
.rst-content .wy-alert-info.danger .admonition-title,
.rst-content .wy-alert-info.danger .wy-alert-title,
.rst-content .wy-alert-info.error .admonition-title,
.rst-content .wy-alert-info.error .wy-alert-title,
.rst-content .wy-alert-info.hint .admonition-title,
.rst-content .wy-alert-info.hint .wy-alert-title,
.rst-content .wy-alert-info.important .admonition-title,
.rst-content .wy-alert-info.important .wy-alert-title,
.rst-content .wy-alert-info.tip .admonition-title,
.rst-content .wy-alert-info.tip .wy-alert-title,
.rst-content .wy-alert-info.warning .admonition-title,
.rst-content .wy-alert-info.warning .wy-alert-title,
.rst-content .wy-alert.wy-alert-info .admonition-title,
.wy-alert.wy-alert-info .rst-content .admonition-title,
.wy-alert.wy-alert-info .wy-alert-title {
background-color: #004a7b;
}
.rst-content dl:not(.docutils) dt {
background-color: #333;
}
.rst-content {
color: var(--dark-text-color);
}
.rst-content .admonition-todo,
.rst-content .attention,
.rst-content .caution,
.rst-content .warning,
.rst-content .wy-alert-warning.admonition,
.rst-content .wy-alert-warning.danger,
.rst-content .wy-alert-warning.error,
.rst-content .wy-alert-warning.hint,
.rst-content .wy-alert-warning.important,
.rst-content .wy-alert-warning.note,
.rst-content .wy-alert-warning.seealso,
.rst-content .wy-alert-warning.tip,
.wy-alert.wy-alert-warning {
background-color: #533500;
}
.rst-content .admonition-todo .admonition-title,
.rst-content .admonition-todo .wy-alert-title,
.rst-content .attention .admonition-title,
.rst-content .attention .wy-alert-title,
.rst-content .caution .admonition-title,
.rst-content .caution .wy-alert-title,
.rst-content .warning .admonition-title,
.rst-content .warning .wy-alert-title,
.rst-content .wy-alert-warning.admonition .admonition-title,
.rst-content .wy-alert-warning.admonition .wy-alert-title,
.rst-content .wy-alert-warning.danger .admonition-title,
.rst-content .wy-alert-warning.danger .wy-alert-title,
.rst-content .wy-alert-warning.error .admonition-title,
.rst-content .wy-alert-warning.error .wy-alert-title,
.rst-content .wy-alert-warning.hint .admonition-title,
.rst-content .wy-alert-warning.hint .wy-alert-title,
.rst-content .wy-alert-warning.important .admonition-title,
.rst-content .wy-alert-warning.important .wy-alert-title,
.rst-content .wy-alert-warning.note .admonition-title,
.rst-content .wy-alert-warning.note .wy-alert-title,
.rst-content .wy-alert-warning.seealso .admonition-title,
.rst-content .wy-alert-warning.seealso .wy-alert-title,
.rst-content .wy-alert-warning.tip .admonition-title,
.rst-content .wy-alert-warning.tip .wy-alert-title,
.rst-content .wy-alert.wy-alert-warning .admonition-title,
.wy-alert.wy-alert-warning .rst-content .admonition-title,
.wy-alert.wy-alert-warning .wy-alert-title {
background-color: #803b00;
}
.rst-content .danger,
.rst-content .error,
.rst-content .wy-alert-danger.admonition,
.rst-content .wy-alert-danger.admonition-todo,
.rst-content .wy-alert-danger.attention,
.rst-content .wy-alert-danger.caution,
.rst-content .wy-alert-danger.hint,
.rst-content .wy-alert-danger.important,
.rst-content .wy-alert-danger.note,
.rst-content .wy-alert-danger.seealso,
.rst-content .wy-alert-danger.tip,
.rst-content .wy-alert-danger.warning,
.wy-alert.wy-alert-danger {
background-color: #82231a;
}
.rst-content .danger .admonition-title,
.rst-content .danger .wy-alert-title,
.rst-content .error .admonition-title,
.rst-content .error .wy-alert-title,
.rst-content .wy-alert-danger.admonition-todo .admonition-title,
.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,
.rst-content .wy-alert-danger.admonition .admonition-title,
.rst-content .wy-alert-danger.admonition .wy-alert-title,
.rst-content .wy-alert-danger.attention .admonition-title,
.rst-content .wy-alert-danger.attention .wy-alert-title,
.rst-content .wy-alert-danger.caution .admonition-title,
.rst-content .wy-alert-danger.caution .wy-alert-title,
.rst-content .wy-alert-danger.hint .admonition-title,
.rst-content .wy-alert-danger.hint .wy-alert-title,
.rst-content .wy-alert-danger.important .admonition-title,
.rst-content .wy-alert-danger.important .wy-alert-title,
.rst-content .wy-alert-danger.note .admonition-title,
.rst-content .wy-alert-danger.note .wy-alert-title,
.rst-content .wy-alert-danger.seealso .admonition-title,
.rst-content .wy-alert-danger.seealso .wy-alert-title,
.rst-content .wy-alert-danger.tip .admonition-title,
.rst-content .wy-alert-danger.tip .wy-alert-title,
.rst-content .wy-alert-danger.warning .admonition-title,
.rst-content .wy-alert-danger.warning .wy-alert-title,
.rst-content .wy-alert.wy-alert-danger .admonition-title,
.wy-alert.wy-alert-danger .rst-content .admonition-title,
.wy-alert.wy-alert-danger .wy-alert-title {
background-color: #b9372b;
}
.wy-nav-top {
background-color: #0b152d;
}
.rst-content table.docutils thead,
.rst-content table.field-list thead,
.wy-table thead {
color: var(--dark-text-color);
}
.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,
.wy-table-backed,
.wy-table-odd td,
.wy-table-striped tr:nth-child(2n-1) td {
background-color: #333;
}
.rst-content table.docutils:not(.field-list) tr:nth-child(2n) td,
.wy-table-backed,
.wy-table-odd td,
.wy-table-striped tr:nth-child(2n) td {
background-color: #444;
}
.rst-content table.docutils td,
.wy-table-bordered-all td,
writer-html5 .rst-content table.docutils th,
.rst-content table.docutils,
.wy-table-bordered-all {
border-color: #262626;
}
.rst-content table.docutils caption,
.rst-content table.field-list caption,
.wy-table caption {
color: var(--dark-text-color);
}
.wy-menu-vertical li.toctree-l3.current > a,
.wy-menu-vertical li.toctree-l3.current li.toctree-l4 > a {
background-color: #000;
}
.wy-side-nav-search > div.version {
color: var(--dark-text-color);
}

View File

@@ -1,10 +1,11 @@
const { app, BrowserWindow, Menu } = require("electron");
const { app, BrowserWindow, Menu, globalShortcut, shell } = require("electron");
Menu.setApplicationMenu(false);
function createWindow() {
const win = new BrowserWindow({
show: false,
webPreferences: {
devTools: false,
devTools: true,
},
});
@@ -12,6 +13,24 @@ function createWindow() {
win.maximize();
win.loadFile("index.html");
win.show();
win.webContents.openDevTools();
globalShortcut.register("f5", function () {
win.loadFile("index.html");
});
globalShortcut.register("f8", function () {
win.loadFile("index.html", { query: { noScripts: "true" } });
});
win.webContents.on("new-window", function (e, url) {
// make sure local urls stay in electron perimeter
if (url.substr(0, "file://".length) === "file://") {
return;
}
// and open every other protocols on the browser
e.preventDefault();
shell.openExternal(url);
});
}
app.whenReady().then(() => {

View File

@@ -36,19 +36,22 @@
ga("send", "pageview");
</script>
<link rel="shortcut icon" href="favicon.ico"><link href="dist/vendor.css" rel="stylesheet"><link href="main.css" rel="stylesheet"></head>
<style>
body {
background-color: black;
}
* {
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
}
*::-webkit-scrollbar {
display: none; /* for Chrome, Safari, and Opera */
}
</style>
<link rel="shortcut icon" href="favicon.ico"></head>
<body>
<div id="entire-game-container">
<div id="mainmenu-container" style="display: flex; flex-direction: row"></div>
<!-- Status text -->
<div id="status-text-container">
<p id="status-text"></p>
</div>
</div>
<div id="unclickable" style="display: none">Click on this to upgrade your Source-File -1!</div>
<div id="root"/>
<script type="text/javascript" src="dist/vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>
<script src="src/ThirdParty/raphael.min.js"></script>
<!-- http://plaza.dsolver.ca/m/hydroflame4418 -->
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

4743
main.css

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

1749
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "bitburner",
"license": "SEE LICENSE IN license.txt",
"version": "0.53.0",
"version": "0.56.0",
"main": "electron-main.js",
"author": {
"name": "Daniel Xie"
@@ -17,10 +17,12 @@
"@mui/lab": "^5.0.0-alpha.46",
"@mui/material": "^5.0.0-rc.1",
"@mui/styles": "^5.0.0-rc.1",
"@types/escodegen": "^0.0.7",
"@types/js-beautify": "^1.13.2",
"@types/numeral": "0.0.25",
"@types/react": "^17.0.21",
"@types/react-dom": "^17.0.9",
"@types/react-resizable": "^1.7.3",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"ajv": "^5.1.5",
@@ -43,6 +45,7 @@
"jszip": "^3.7.0",
"loader-runner": "^2.3.0",
"loader-utils": "^1.1.0",
"material-ui-color": "^1.2.0",
"mathjax-full": "^3.2.0",
"mathjax-react": "^1.0.6",
"memory-fs": "~0.4.1",
@@ -52,13 +55,16 @@
"numeral": "2.0.6",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-draggable": "^4.4.4",
"react-modal": "^3.12.1",
"react-resizable": "^3.0.4",
"sprintf-js": "^1.1.1",
"tapable": "^1.0.0",
"treant-js": "^1.0.1",
"unused-webpack-plugin": "^2.4.0",
"uuid": "^3.2.1",
"w3c-blob": "0.0.1"
"w3c-blob": "0.0.1",
"webpack-deadcode-plugin": "^0.1.15"
},
"description": "A cyberpunk-themed incremental game",
"devDependencies": {
@@ -145,6 +151,7 @@
"format": "prettier --write .",
"start": "http-server -p 8000",
"start:dev": "webpack-dev-server --progress --env.devServer --mode development",
"start:dev-fast": "webpack-dev-server --progress --env.devServer --mode development --fast true",
"start:container": "webpack-dev-server --progress --env.devServer --mode development --env.runInContainer",
"build": "webpack --mode production",
"build:dev": "webpack --mode development",

View File

@@ -1,14 +1,19 @@
# npm install electron --save-dev
# npm install electron-packager --save-dev
mkdir -p .package/dist || true
mkdir -p .package/dist/src/ThirdParty || true
mkdir -p .package/src/ThirdParty || true
cp index.html .package
cp electron/* .package
cp dist/engine.bundle.js .package/dist
cp dist/engineStyle.css .package/dist
# The css files
cp dist/vendor.css .package/dist
cp dist/engineStyle.bundle.js .package/dist
cp dist/vendor.bundle.js .package/dist
cp main.css .package/main.css
# The js files.
cp dist/vendor.bundle.js .package/dist/vendor.bundle.js
cp main.bundle.js .package/main.bundle.js
cp src/ThirdParty/raphael.min.js .package/src/ThirdParty/raphael.min.js
npm run package-electron

View File

@@ -2,433 +2,366 @@ const numSpaces = 4;
const maxLineLength = 160;
module.exports = {
"env": {
"es6": true,
"node": true
env: {
es6: true,
node: true,
},
extends: "eslint:recommended",
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true
},
"ecmaVersion": 8,
"sourceType": "module"
},
"rules": {
"accessor-pairs": [
"error",
{
"getWithoutSet": false,
"setWithoutGet": true
}
],
"array-bracket-newline": ["error"],
"array-bracket-spacing": ["error"],
"array-callback-return": ["error"],
"array-element-newline": ["error"],
"arrow-body-style": ["error"],
"arrow-parens": ["error"],
"arrow-spacing": ["error"],
"block-scoped-var": ["error"],
"block-spacing": ["error"],
"brace-style": ["error"],
"callback-return": ["error"],
"camelcase": ["error"],
"capitalized-comments": ["error"],
"class-methods-use-this": ["error"],
"comma-dangle": ["error"],
"comma-spacing": ["error"],
"comma-style": [
"error",
"last"
],
"complexity": ["error"],
"computed-property-spacing": [
"error",
"never"
],
"consistent-return": ["error"],
"consistent-this": ["error"],
"constructor-super": ["error"],
"curly": ["error"],
"default-case": ["error"],
"dot-location": [
"error",
"property"
],
"dot-notation": ["error"],
"eol-last": ["error"],
"eqeqeq": ["error"],
"for-direction": ["error"],
"func-call-spacing": ["error"],
"func-name-matching": ["error"],
"func-names": [
"error",
"never"
],
"func-style": ["error"],
"function-paren-newline": ["error"],
"generator-star-spacing": [
"error",
"before"
],
"getter-return": [
"error",
{
"allowImplicit": false
}
],
"global-require": ["error"],
"guard-for-in": ["error"],
"handle-callback-err": ["error"],
"id-blacklist": ["error"],
"id-length": ["error"],
"id-match": ["error"],
"implicit-arrow-linebreak": [
"error",
"beside"
],
"indent": [
"error",
numSpaces,
{
"SwitchCase": 1
}
],
"init-declarations": ["error"],
"jsx-quotes": ["error"],
"key-spacing": ["error"],
"keyword-spacing": ["error"],
"line-comment-position": ["error"],
"linebreak-style": [
"error",
"windows"
],
"lines-around-comment": ["error"],
"lines-between-class-members": ["error"],
"max-depth": ["error"],
"max-len": [
"error",
maxLineLength
],
"max-lines": [
"error",
{
"skipBlankLines": true,
"skipComments": true
}
],
"max-nested-callbacks": ["error"],
"max-params": ["error"],
"max-statements": ["error"],
"max-statements-per-line": ["error"],
"multiline-comment-style": [
"off",
"starred-block"
],
"multiline-ternary": [
"error",
"never"
],
"new-cap": ["error"],
"new-parens": ["error"],
// TODO: configure this...
"newline-before-return": ["error"],
"newline-per-chained-call": ["error"],
"no-alert": ["error"],
"no-array-constructor": ["error"],
"no-await-in-loop": ["error"],
"no-bitwise": ["error"],
"no-buffer-constructor": ["error"],
"no-caller": ["error"],
"no-case-declarations": ["error"],
"no-catch-shadow": ["error"],
"no-class-assign": ["error"],
"no-compare-neg-zero": ["error"],
"no-cond-assign": [
"error",
"except-parens"
],
"no-confusing-arrow": ["error"],
"no-console": ["error"],
"no-const-assign": ["error"],
"no-constant-condition": [
"error",
{
"checkLoops": false
}
],
"no-continue": ["off"],
"no-control-regex": ["error"],
"no-debugger": ["error"],
"no-delete-var": ["error"],
"no-div-regex": ["error"],
"no-dupe-args": ["error"],
"no-dupe-class-members": ["error"],
"no-dupe-keys": ["error"],
"no-duplicate-case": ["error"],
"no-duplicate-imports": [
"error",
{
"includeExports": true
}
],
"no-else-return": ["error"],
"no-empty": [
"error",
{
"allowEmptyCatch": false
}
],
"no-empty-character-class": ["error"],
"no-empty-function": ["error"],
"no-empty-pattern": ["error"],
"no-eq-null": ["error"],
"no-eval": ["error"],
"no-ex-assign": ["error"],
"no-extend-native": ["error"],
"no-extra-bind": ["error"],
"no-extra-boolean-cast": ["error"],
"no-extra-label": ["error"],
"no-extra-parens": [
"error",
"all",
{
"conditionalAssign": false
}
],
"no-extra-semi": ["error"],
"no-fallthrough": ["error"],
"no-floating-decimal": ["error"],
"no-func-assign": ["error"],
"no-global-assign": ["error"],
"no-implicit-coercion": ["error"],
"no-implicit-globals": ["error"],
"no-implied-eval": ["error"],
"no-inline-comments": ["error"],
"no-inner-declarations": [
"error",
"both"
],
"no-invalid-regexp": ["error"],
"no-invalid-this": ["error"],
"no-irregular-whitespace": [
"error",
{
"skipComments": false,
"skipRegExps": false,
"skipStrings": false,
"skipTemplates": false
}
],
"no-iterator": ["error"],
"no-label-var": ["error"],
"no-labels": ["error"],
"no-lone-blocks": ["error"],
"no-lonely-if": ["error"],
"no-loop-func": ["error"],
"no-magic-numbers": [
"error",
{
"ignore": [
-1,
0,
1
],
"ignoreArrayIndexes": true
}
],
"no-mixed-operators": ["error"],
"no-mixed-requires": ["error"],
"no-mixed-spaces-and-tabs": ["error"],
"no-multi-assign": ["error"],
"no-multi-spaces": ["error"],
"no-multi-str": ["error"],
"no-multiple-empty-lines": [
"error",
{
"max": 1
}
],
"no-native-reassign": ["error"],
"no-negated-condition": ["error"],
"no-negated-in-lhs": ["error"],
"no-nested-ternary": ["error"],
"no-new": ["error"],
"no-new-func": ["error"],
"no-new-object": ["error"],
"no-new-require": ["error"],
"no-new-symbol": ["error"],
"no-new-wrappers": ["error"],
"no-obj-calls": ["error"],
"no-octal": ["error"],
"no-octal-escape": ["error"],
"no-param-reassign": ["error"],
"no-path-concat": ["error"],
"no-plusplus": [
"error",
{
"allowForLoopAfterthoughts": true
}
],
"no-process-env": ["error"],
"no-process-exit": ["error"],
"no-proto": ["error"],
"no-prototype-builtins": ["error"],
"no-redeclare": ["error"],
"no-regex-spaces": ["error"],
"no-restricted-globals": ["error"],
"no-restricted-imports": ["error"],
"no-restricted-modules": ["error"],
"no-restricted-properties": [
"error",
{
"message": "'log' is too general, use an appropriate level when logging.",
"object": "console",
"property": "log"
}
],
"no-restricted-syntax": ["error"],
"no-return-assign": ["error"],
"no-return-await": ["error"],
"no-script-url": ["error"],
"no-self-assign": [
"error",
{
"props": false
}
],
"no-self-compare": ["error"],
"no-sequences": ["error"],
"no-shadow": ["error"],
"no-shadow-restricted-names": ["error"],
"no-spaced-func": ["error"],
"no-sparse-arrays": ["error"],
"no-sync": ["error"],
"no-tabs": ["error"],
"no-template-curly-in-string": ["error"],
"no-ternary": ["off"],
"no-this-before-super": ["error"],
"no-throw-literal": ["error"],
"no-trailing-spaces": ["error"],
"no-undef": ["error"],
"no-undef-init": ["error"],
"no-undefined": ["error"],
"no-underscore-dangle": ["error"],
"no-unexpected-multiline": ["error"],
"no-unmodified-loop-condition": ["error"],
"no-unneeded-ternary": ["error"],
"no-unreachable": ["error"],
"no-unsafe-finally": ["error"],
"no-unsafe-negation": ["error"],
"no-unused-expressions": ["error"],
"no-unused-labels": ["error"],
"no-unused-vars": ["error"],
"no-use-before-define": ["error"],
"no-useless-call": ["error"],
"no-useless-computed-key": ["error"],
"no-useless-concat": ["error"],
"no-useless-constructor": ["error"],
"no-useless-escape": ["error"],
"no-useless-rename": [
"error",
{
"ignoreDestructuring": false,
"ignoreExport": false,
"ignoreImport": false
}
],
"no-useless-return": ["error"],
"no-var": ["error"],
"no-void": ["error"],
"no-warning-comments": ["error"],
"no-whitespace-before-property": ["error"],
"no-with": ["error"],
"nonblock-statement-body-position": [
"error",
"below"
],
"object-curly-newline": ["error"],
"object-curly-spacing": ["error"],
"object-property-newline": ["error"],
"object-shorthand": ["error"],
"one-var": ["off"],
"one-var-declaration-per-line": ["error"],
"operator-assignment": ["error"],
"operator-linebreak": [
"error",
"none"
],
"padded-blocks": ["off"],
"padding-line-between-statements": ["error"],
"prefer-arrow-callback": ["error"],
"prefer-const": ["error"],
"prefer-destructuring": ["off"],
"prefer-numeric-literals": ["error"],
"prefer-promise-reject-errors": ["off"],
"prefer-reflect": ["error"],
"prefer-rest-params": ["error"],
"prefer-spread": ["error"],
"prefer-template": ["error"],
"quote-props": ["error"],
"quotes": ["error"],
"radix": [
"error",
"as-needed"
],
"require-await": ["error"],
"require-jsdoc": ["off"],
"require-yield": ["error"],
"rest-spread-spacing": [
"error",
"never"
],
"semi": ["error"],
"semi-spacing": ["error"],
"semi-style": [
"error",
"last"
],
"sort-imports": ["error"],
"sort-keys": ["error"],
"sort-vars": ["error"],
"space-before-blocks": ["error"],
"space-before-function-paren": ["off"],
"space-in-parens": ["error"],
"space-infix-ops": ["error"],
"space-unary-ops": ["error"],
"spaced-comment": ["error"],
"strict": ["error"],
"switch-colon-spacing": [
"error",
{
"after": true,
"before": false
}
],
"symbol-description": ["error"],
"template-curly-spacing": ["error"],
"template-tag-spacing": ["error"],
"unicode-bom": [
"error",
"never"
],
"use-isnan": ["error"],
"valid-jsdoc": ["error"],
"valid-typeof": ["error"],
"vars-on-top": ["error"],
"wrap-iife": [
"error",
"any"
],
"wrap-regex": ["error"],
"yield-star-spacing": [
"error",
"before"
],
"yoda": [
"error",
"never"
]
}
ecmaVersion: 8,
sourceType: "module",
},
rules: {
"accessor-pairs": [
"error",
{
getWithoutSet: false,
setWithoutGet: true,
},
],
"array-bracket-newline": ["error"],
"array-bracket-spacing": ["error"],
"array-callback-return": ["error"],
"array-element-newline": ["error"],
"arrow-body-style": ["error"],
"arrow-parens": ["error"],
"arrow-spacing": ["error"],
"block-scoped-var": ["error"],
"block-spacing": ["error"],
"brace-style": ["error"],
"callback-return": ["error"],
camelcase: ["error"],
"capitalized-comments": ["error"],
"class-methods-use-this": ["error"],
"comma-dangle": ["error"],
"comma-spacing": ["error"],
"comma-style": ["error", "last"],
complexity: ["error"],
"computed-property-spacing": ["error", "never"],
"consistent-return": ["error"],
"consistent-this": ["error"],
"constructor-super": ["error"],
curly: ["error"],
"default-case": ["error"],
"dot-location": ["error", "property"],
"dot-notation": ["error"],
"eol-last": ["error"],
eqeqeq: ["error"],
"for-direction": ["error"],
"func-call-spacing": ["error"],
"func-name-matching": ["error"],
"func-names": ["error", "never"],
"func-style": ["error"],
"function-paren-newline": ["error"],
"generator-star-spacing": ["error", "before"],
"getter-return": [
"error",
{
allowImplicit: false,
},
],
"global-require": ["error"],
"guard-for-in": ["error"],
"handle-callback-err": ["error"],
"id-blacklist": ["error"],
"id-length": ["error"],
"id-match": ["error"],
"implicit-arrow-linebreak": ["error", "beside"],
indent: [
"error",
numSpaces,
{
SwitchCase: 1,
},
],
"init-declarations": ["error"],
"jsx-quotes": ["error"],
"key-spacing": ["error"],
"keyword-spacing": ["error"],
"line-comment-position": ["error"],
"linebreak-style": ["error", "windows"],
"lines-around-comment": ["error"],
"lines-between-class-members": ["error"],
"max-depth": ["error"],
"max-len": ["error", maxLineLength],
"max-lines": [
"error",
{
skipBlankLines: true,
skipComments: true,
},
],
"max-nested-callbacks": ["error"],
"max-params": ["error"],
"max-statements": ["error"],
"max-statements-per-line": ["error"],
"multiline-comment-style": ["off", "starred-block"],
"multiline-ternary": ["error", "never"],
"new-cap": ["error"],
"new-parens": ["error"],
// TODO: configure this...
"newline-before-return": ["error"],
"newline-per-chained-call": ["error"],
"no-alert": ["error"],
"no-array-constructor": ["error"],
"no-await-in-loop": ["error"],
"no-bitwise": ["error"],
"no-buffer-constructor": ["error"],
"no-caller": ["error"],
"no-case-declarations": ["error"],
"no-catch-shadow": ["error"],
"no-class-assign": ["error"],
"no-compare-neg-zero": ["error"],
"no-cond-assign": ["error", "except-parens"],
"no-confusing-arrow": ["error"],
"no-console": ["error"],
"no-const-assign": ["error"],
"no-constant-condition": [
"error",
{
checkLoops: false,
},
],
"no-continue": ["off"],
"no-control-regex": ["error"],
"no-debugger": ["error"],
"no-delete-var": ["error"],
"no-div-regex": ["error"],
"no-dupe-args": ["error"],
"no-dupe-class-members": ["error"],
"no-dupe-keys": ["error"],
"no-duplicate-case": ["error"],
"no-duplicate-imports": [
"error",
{
includeExports: true,
},
],
"no-else-return": ["error"],
"no-empty": [
"error",
{
allowEmptyCatch: false,
},
],
"no-empty-character-class": ["error"],
"no-empty-function": ["error"],
"no-empty-pattern": ["error"],
"no-eq-null": ["error"],
"no-eval": ["error"],
"no-ex-assign": ["error"],
"no-extend-native": ["error"],
"no-extra-bind": ["error"],
"no-extra-boolean-cast": ["error"],
"no-extra-label": ["error"],
"no-extra-parens": [
"error",
"all",
{
conditionalAssign: false,
},
],
"no-extra-semi": ["error"],
"no-fallthrough": ["error"],
"no-floating-decimal": ["error"],
"no-func-assign": ["error"],
"no-global-assign": ["error"],
"no-implicit-coercion": ["error"],
"no-implicit-globals": ["error"],
"no-implied-eval": ["error"],
"no-inline-comments": ["error"],
"no-inner-declarations": ["error", "both"],
"no-invalid-regexp": ["error"],
"no-invalid-this": ["error"],
"no-irregular-whitespace": [
"error",
{
skipComments: false,
skipRegExps: false,
skipStrings: false,
skipTemplates: false,
},
],
"no-iterator": ["error"],
"no-label-var": ["error"],
"no-labels": ["error"],
"no-lone-blocks": ["error"],
"no-lonely-if": ["error"],
"no-loop-func": ["error"],
"no-magic-numbers": [
"error",
{
ignore: [-1, 0, 1],
ignoreArrayIndexes: true,
},
],
"no-mixed-operators": ["error"],
"no-mixed-requires": ["error"],
"no-mixed-spaces-and-tabs": ["error"],
"no-multi-assign": ["error"],
"no-multi-spaces": ["error"],
"no-multi-str": ["error"],
"no-multiple-empty-lines": [
"error",
{
max: 1,
},
],
"no-native-reassign": ["error"],
"no-negated-condition": ["error"],
"no-negated-in-lhs": ["error"],
"no-nested-ternary": ["error"],
"no-new": ["error"],
"no-new-func": ["error"],
"no-new-object": ["error"],
"no-new-require": ["error"],
"no-new-symbol": ["error"],
"no-new-wrappers": ["error"],
"no-obj-calls": ["error"],
"no-octal": ["error"],
"no-octal-escape": ["error"],
"no-param-reassign": ["error"],
"no-path-concat": ["error"],
"no-plusplus": [
"error",
{
allowForLoopAfterthoughts: true,
},
],
"no-process-env": ["error"],
"no-process-exit": ["error"],
"no-proto": ["error"],
"no-prototype-builtins": ["error"],
"no-redeclare": ["error"],
"no-regex-spaces": ["error"],
"no-restricted-globals": ["error"],
"no-restricted-imports": ["error"],
"no-restricted-modules": ["error"],
"no-restricted-properties": [
"error",
{
message: "'log' is too general, use an appropriate level when logging.",
object: "console",
property: "log",
},
],
"no-restricted-syntax": ["error"],
"no-return-assign": ["error"],
"no-return-await": ["error"],
"no-script-url": ["error"],
"no-self-assign": [
"error",
{
props: false,
},
],
"no-self-compare": ["error"],
"no-sequences": ["error"],
"no-shadow": ["error"],
"no-shadow-restricted-names": ["error"],
"no-spaced-func": ["error"],
"no-sparse-arrays": ["error"],
"no-sync": ["error"],
"no-tabs": ["error"],
"no-template-curly-in-string": ["error"],
"no-ternary": ["off"],
"no-this-before-super": ["error"],
"no-throw-literal": ["error"],
"no-trailing-spaces": ["error"],
"no-undef": ["error"],
"no-undef-init": ["error"],
"no-undefined": ["error"],
"no-underscore-dangle": ["error"],
"no-unexpected-multiline": ["error"],
"no-unmodified-loop-condition": ["error"],
"no-unneeded-ternary": ["error"],
"no-unreachable": ["error"],
"no-unsafe-finally": ["error"],
"no-unsafe-negation": ["error"],
"no-unused-expressions": ["error"],
"no-unused-labels": ["error"],
"no-unused-vars": ["error"],
"no-use-before-define": ["error"],
"no-useless-call": ["error"],
"no-useless-computed-key": ["error"],
"no-useless-concat": ["error"],
"no-useless-constructor": ["error"],
"no-useless-escape": ["error"],
"no-useless-rename": [
"error",
{
ignoreDestructuring: false,
ignoreExport: false,
ignoreImport: false,
},
],
"no-useless-return": ["error"],
"no-var": ["error"],
"no-void": ["error"],
"no-warning-comments": ["error"],
"no-whitespace-before-property": ["error"],
"no-with": ["error"],
"nonblock-statement-body-position": ["error", "below"],
"object-curly-newline": ["error"],
"object-curly-spacing": ["error"],
"object-property-newline": ["error"],
"object-shorthand": ["error"],
"one-var": ["off"],
"one-var-declaration-per-line": ["error"],
"operator-assignment": ["error"],
"operator-linebreak": ["error", "none"],
"padded-blocks": ["off"],
"padding-line-between-statements": ["error"],
"prefer-arrow-callback": ["error"],
"prefer-const": ["error"],
"prefer-destructuring": ["off"],
"prefer-numeric-literals": ["error"],
"prefer-promise-reject-errors": ["off"],
"prefer-reflect": ["error"],
"prefer-rest-params": ["error"],
"prefer-spread": ["error"],
"prefer-template": ["error"],
"quote-props": ["error"],
quotes: ["error"],
radix: ["error", "as-needed"],
"require-await": ["error"],
"require-jsdoc": ["off"],
"require-yield": ["error"],
"rest-spread-spacing": ["error", "never"],
semi: ["error"],
"semi-spacing": ["error"],
"semi-style": ["error", "last"],
"sort-imports": ["error"],
"sort-keys": ["error"],
"sort-vars": ["error"],
"space-before-blocks": ["error"],
"space-before-function-paren": ["off"],
"space-in-parens": ["error"],
"space-infix-ops": ["error"],
"space-unary-ops": ["error"],
"spaced-comment": ["error"],
strict: ["error"],
"switch-colon-spacing": [
"error",
{
after: true,
before: false,
},
],
"symbol-description": ["error"],
"template-curly-spacing": ["error"],
"template-tag-spacing": ["error"],
"unicode-bom": ["error", "never"],
"use-isnan": ["error"],
"valid-jsdoc": ["error"],
"valid-typeof": ["error"],
"vars-on-top": ["error"],
"wrap-iife": ["error", "any"],
"wrap-regex": ["error"],
"yield-star-spacing": ["error", "before"],
yoda: ["error", "never"],
},
};

View File

@@ -8,66 +8,74 @@ const path = require("path");
const exec = require("child_process").exec;
const semver = require("./semver");
const getPackageJson = () => new Promise((resolve, reject) => {
const getPackageJson = () =>
new Promise((resolve, reject) => {
try {
/* eslint-disable-next-line global-require */
resolve(require(path.resolve(process.cwd(), "package.json")));
/* eslint-disable-next-line global-require */
resolve(require(path.resolve(process.cwd(), "package.json")));
} catch (error) {
reject(error);
reject(error);
}
});
});
const getEngines = (data) => new Promise((resolve, reject) => {
const getEngines = (data) =>
new Promise((resolve, reject) => {
let versions = null;
if (data.engines) {
versions = data.engines;
versions = data.engines;
}
if (versions) {
resolve(versions);
resolve(versions);
} else {
reject("Missing or improper 'engines' property in 'package.json'");
reject("Missing or improper 'engines' property in 'package.json'");
}
});
});
const checkNpmVersion = (engines) => new Promise((resolve, reject) => {
const checkNpmVersion = (engines) =>
new Promise((resolve, reject) => {
exec("npm -v", (error, stdout, stderr) => {
if (error) {
reject(`Unable to find NPM version\n${stderr}`);
}
if (error) {
reject(`Unable to find NPM version\n${stderr}`);
}
const npmVersion = stdout.trim();
const engineVersion = engines.npm || ">=0";
const npmVersion = stdout.trim();
const engineVersion = engines.npm || ">=0";
if (semver.satisfies(npmVersion, engineVersion)) {
resolve();
} else {
reject(`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`);
}
if (semver.satisfies(npmVersion, engineVersion)) {
resolve();
} else {
reject(
`Incorrect npm version\n'package.json' specifies "${engineVersion}", you are currently running "${npmVersion}".`,
);
}
});
});
});
const checkNodeVersion = (engines) => new Promise((resolve, reject) => {
const checkNodeVersion = (engines) =>
new Promise((resolve, reject) => {
const nodeVersion = process.version.substring(1);
if (semver.satisfies(nodeVersion, engines.node)) {
resolve(engines);
resolve(engines);
} else {
reject(`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`);
reject(
`Incorrect node version\n'package.json' specifies "${engines.node}", you are currently running "${process.version}".`,
);
}
});
});
getPackageJson()
.then(getEngines)
.then(checkNodeVersion)
.then(checkNpmVersion)
.then(
() => true,
(error) => {
// Specifically disable these as the error message gets lost in the normal unhandled output.
/* eslint-disable no-console, no-process-exit */
console.error(error);
process.exit(1);
}
);
.then(getEngines)
.then(checkNodeVersion)
.then(checkNpmVersion)
.then(
() => true,
(error) => {
// Specifically disable these as the error message gets lost in the normal unhandled output.
/* eslint-disable no-console, no-process-exit */
console.error(error);
process.exit(1);
},
);

File diff suppressed because it is too large Load Diff

View File

@@ -8,11 +8,11 @@ import { Factions } from "../Faction/Factions";
import { numeralWrapper } from "../ui/numeralFormat";
import { Money } from "../ui/React/Money";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
interface IConstructorParams {
export interface IConstructorParams {
info: string | JSX.Element;
stats?: JSX.Element;
stats?: JSX.Element | null;
isSpecial?: boolean;
moneyCost: number;
name: string;
@@ -369,7 +369,7 @@ export class Augmentation {
info: string | JSX.Element;
// Description of the stats, often autogenerated, sometimes manually written.
stats: JSX.Element;
stats: JSX.Element | null;
// Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs)
isSpecial = false;
@@ -507,8 +507,9 @@ export class Augmentation {
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult;
}
if (params.stats) this.stats = params.stats;
else this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
if (params.stats === undefined)
this.stats = generateStatsDescription(this.mults, params.programs, params.startingMoney);
else this.stats = params.stats;
}
// Adds this Augmentation to the specified Factions
@@ -532,6 +533,7 @@ export class Augmentation {
console.warn(`Invalid Faction object in addToAllFactions(). Key value: ${fac}`);
continue;
}
if (facObj.getInfo().special) continue;
facObj.augmentations.push(this.name);
}
}

View File

@@ -1,2 +0,0 @@
export declare function isRepeatableAug(aug: Augmentation): boolean;
export declare function installAugmentations(): void;

View File

@@ -1,6 +1,6 @@
import { Augmentation } from "./Augmentation";
import { Augmentation, IConstructorParams } from "./Augmentation";
import { Augmentations } from "./Augmentations";
import { PlayerOwnedAugmentation } from "./PlayerOwnedAugmentation";
import { PlayerOwnedAugmentation, IPlayerOwnedAugmentation } from "./PlayerOwnedAugmentation";
import { AugmentationNames } from "./data/AugmentationNames";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
@@ -11,20 +11,20 @@ import { prestigeAugmentation } from "../Prestige";
import { Programs } from "../Programs/Programs";
import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
import { dialogBoxCreate } from "../../utils/DialogBox";
import { clearObject } from "../../utils/helpers/clearObject";
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { clearObject } from "../utils/helpers/clearObject";
import { WHRNG } from "../Casino/RNG";
import React from "react";
function AddToAugmentations(aug) {
var name = aug.name;
function AddToAugmentations(aug: Augmentation): void {
const name = aug.name;
Augmentations[name] = aug;
}
function getRandomBonus() {
var bonuses = [
function getRandomBonus(): any {
const bonuses = [
{
bonuses: {
hacking_chance_mult: 1.25,
@@ -111,8 +111,8 @@ function getRandomBonus() {
return bonuses[Math.floor(bonuses.length * randomNumber.random())];
}
function initAugmentations() {
for (var name in Factions) {
function initAugmentations(): void {
for (const name in Factions) {
if (Factions.hasOwnProperty(name)) {
Factions[name].augmentations = [];
}
@@ -124,7 +124,7 @@ function initAugmentations() {
//Time-Based Augment Test
const randomBonuses = getRandomBonus();
const UnstableCircadianModulatorParams = {
const UnstableCircadianModulatorParams: IConstructorParams = {
name: AugmentationNames.UnstableCircadianModulator,
moneyCost: 5e9,
repCost: 3.625e5,
@@ -133,7 +133,7 @@ function initAugmentations() {
"unpredictable results based on your circadian rhythm.",
};
Object.keys(randomBonuses.bonuses).forEach(
(key) => (UnstableCircadianModulatorParams[key] = randomBonuses.bonuses[key]),
(key) => ((UnstableCircadianModulatorParams as any)[key] = randomBonuses.bonuses[key]),
);
const UnstableCircadianModulator = new Augmentation(UnstableCircadianModulatorParams);
@@ -211,7 +211,7 @@ function initAugmentations() {
name: AugmentationNames.Targeting3,
moneyCost: 1.15e8,
repCost: 2.75e4,
info: "The latest version of the 'Augmented Targeting' implant adds the ability to " + "lock-on and track threats.",
info: "The latest version of the 'Augmented Targeting' implant adds the ability to lock-on and track threats.",
prereqs: [AugmentationNames.Targeting2],
dexterity_mult: 1.3,
});
@@ -1555,7 +1555,7 @@ function initAugmentations() {
repCost: 2.5e6,
moneyCost: 0,
info: "It's time to leave the cave.",
stats: <></>,
stats: null,
});
RedPill.addToFactions(["Daedalus"]);
if (augmentationExists(AugmentationNames.TheRedPill)) {
@@ -1595,7 +1595,7 @@ function initAugmentations() {
"exactly the implant does, but they promise that it will greatly " +
"enhance your abilities.",
hacking_grow_mult: 3,
stats: <></>,
stats: null,
});
HiveMind.addToFactions(["ECorp"]);
if (augmentationExists(AugmentationNames.HiveMind)) {
@@ -2044,6 +2044,28 @@ function initAugmentations() {
}
AddToAugmentations(SNA);
const NeuroreceptorManager = new Augmentation({
name: AugmentationNames.NeuroreceptorManager,
repCost: 0.75e5,
moneyCost: 5.5e8,
info:
"A brain implant carefully assembled around the synapses, which " +
"micromanages the activity and levels of various neuroreceptor " +
"chemicals and modulates electrical acvitiy to optimize concentration, " +
"allowing the user to multitask much more effectively.",
stats: (
<>
This augmentation removes the penalty for not focusing on actions such as working in a job or working for a
faction.
</>
),
});
NeuroreceptorManager.addToFactions(["Tian Di Hui"]);
if (augmentationExists(AugmentationNames.NeuroreceptorManager)) {
delete Augmentations[AugmentationNames.NeuroreceptorManager];
}
AddToAugmentations(NeuroreceptorManager);
// Special Bladeburner Augmentations
const BladeburnersFactionName = "Bladeburners";
if (factionExists(BladeburnersFactionName)) {
@@ -2344,12 +2366,151 @@ function initAugmentations() {
resetAugmentation(BladesSimulacrum);
}
// Special CotMG Augmentations
const ChurchOfTheMachineGodFactionName = "Church of the Machine God";
if (factionExists(ChurchOfTheMachineGodFactionName)) {
const StaneksGift1 = new Augmentation({
name: AugmentationNames.StaneksGift1,
repCost: 0,
moneyCost: 0,
info:
'Allison "Mother" Stanek imparts you with her gift. An ' +
"experimental Augmentation implanted at the base of the neck. " +
"It allows you to overclock your entire system by carefully " +
"changing the configuration.",
isSpecial: true,
hacking_chance_mult: 0.9,
hacking_speed_mult: 0.9,
hacking_money_mult: 0.9,
hacking_grow_mult: 0.9,
hacking_mult: 0.9,
strength_mult: 0.9,
defense_mult: 0.9,
dexterity_mult: 0.9,
agility_mult: 0.9,
charisma_mult: 0.9,
hacking_exp_mult: 0.9,
strength_exp_mult: 0.9,
defense_exp_mult: 0.9,
dexterity_exp_mult: 0.9,
agility_exp_mult: 0.9,
charisma_exp_mult: 0.9,
company_rep_mult: 0.9,
faction_rep_mult: 0.9,
crime_money_mult: 0.9,
crime_success_mult: 0.9,
hacknet_node_money_mult: 0.9,
hacknet_node_purchase_cost_mult: 1.1,
hacknet_node_ram_cost_mult: 1.1,
hacknet_node_core_cost_mult: 1.1,
hacknet_node_level_cost_mult: 1.1,
work_money_mult: 0.9,
stats: <>Its unstable nature decreases all your stats by 10%</>,
});
StaneksGift1.addToFactions([ChurchOfTheMachineGodFactionName]);
resetAugmentation(StaneksGift1);
const StaneksGift2 = new Augmentation({
name: AugmentationNames.StaneksGift2,
repCost: 1000,
moneyCost: 0,
info:
'TODO, something about Mother being bullshit and you get more control over her "gift"<br><br>' +
"The penalty for the gift is only 5%",
prereqs: [AugmentationNames.StaneksGift1],
isSpecial: true,
hacking_chance_mult: 0.95 / 0.9,
hacking_speed_mult: 0.95 / 0.9,
hacking_money_mult: 0.95 / 0.9,
hacking_grow_mult: 0.95 / 0.9,
hacking_mult: 0.95 / 0.9,
strength_mult: 0.95 / 0.9,
defense_mult: 0.95 / 0.9,
dexterity_mult: 0.95 / 0.9,
agility_mult: 0.95 / 0.9,
charisma_mult: 0.95 / 0.9,
hacking_exp_mult: 0.95 / 0.9,
strength_exp_mult: 0.95 / 0.9,
defense_exp_mult: 0.95 / 0.9,
dexterity_exp_mult: 0.95 / 0.9,
agility_exp_mult: 0.95 / 0.9,
charisma_exp_mult: 0.95 / 0.9,
company_rep_mult: 0.95 / 0.9,
faction_rep_mult: 0.95 / 0.9,
crime_money_mult: 0.95 / 0.9,
crime_success_mult: 0.95 / 0.9,
hacknet_node_money_mult: 0.95 / 0.9,
hacknet_node_purchase_cost_mult: 1.05 / 1.1,
hacknet_node_ram_cost_mult: 1.05 / 1.1,
hacknet_node_core_cost_mult: 1.05 / 1.1,
hacknet_node_level_cost_mult: 1.05 / 1.1,
work_money_mult: 0.95 / 0.9,
stats: null,
});
StaneksGift2.addToFactions([ChurchOfTheMachineGodFactionName]);
resetAugmentation(StaneksGift2);
const StaneksGift3 = new Augmentation({
name: AugmentationNames.StaneksGift3,
repCost: 10000,
moneyCost: 0,
info:
"TODO, learn more about Allisons scheme, gain full control over the gift.<br><br>" +
"Finally freed from the penalty of the gift.",
prereqs: [AugmentationNames.StaneksGift2],
isSpecial: true,
hacking_chance_mult: 1 / 0.95,
hacking_speed_mult: 1 / 0.95,
hacking_money_mult: 1 / 0.95,
hacking_grow_mult: 1 / 0.95,
hacking_mult: 1 / 0.95,
strength_mult: 1 / 0.95,
defense_mult: 1 / 0.95,
dexterity_mult: 1 / 0.95,
agility_mult: 1 / 0.95,
charisma_mult: 1 / 0.95,
hacking_exp_mult: 1 / 0.95,
strength_exp_mult: 1 / 0.95,
defense_exp_mult: 1 / 0.95,
dexterity_exp_mult: 1 / 0.95,
agility_exp_mult: 1 / 0.95,
charisma_exp_mult: 1 / 0.95,
company_rep_mult: 1 / 0.95,
faction_rep_mult: 1 / 0.95,
crime_money_mult: 1 / 0.95,
crime_success_mult: 1 / 0.95,
hacknet_node_money_mult: 1 / 0.95,
hacknet_node_purchase_cost_mult: 1 / 1.05,
hacknet_node_ram_cost_mult: 1 / 1.05,
hacknet_node_core_cost_mult: 1 / 1.05,
hacknet_node_level_cost_mult: 1 / 1.05,
work_money_mult: 1 / 0.95,
stats: null,
});
StaneksGift3.addToFactions([ChurchOfTheMachineGodFactionName]);
resetAugmentation(StaneksGift3);
const StaneksGiftAscension4 = new Augmentation({
name: AugmentationNames.StaneksGift4,
repCost: 500000000,
moneyCost: 0,
info:
"Allow Allison to install an Ascension port in her Gift. Allowing you to connect with the Machine God.<br><br>" +
"(hydro notes: Finishes the BN, eventually)",
prereqs: [AugmentationNames.StaneksGift3],
isSpecial: true,
stats: null,
});
StaneksGiftAscension4.addToFactions([ChurchOfTheMachineGodFactionName]);
resetAugmentation(StaneksGiftAscension4);
}
// Update costs based on how many have been purchased
mult = Math.pow(
CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][SourceFileFlags[11]],
Player.queuedAugmentations.length,
);
for (var name in Augmentations) {
for (const name in Augmentations) {
if (Augmentations.hasOwnProperty(name)) {
Augmentations[name].baseCost *= mult;
}
@@ -2359,29 +2520,26 @@ function initAugmentations() {
}
//Resets an Augmentation during (re-initizliation)
function resetAugmentation(newAugObject) {
function resetAugmentation(newAugObject: Augmentation): void {
if (!(newAugObject instanceof Augmentation)) {
throw new Error("Invalid argument 'newAugObject' passed into resetAugmentation");
}
var name = newAugObject.name;
const name = newAugObject.name;
if (augmentationExists(name)) {
delete Augmentations[name];
}
AddToAugmentations(newAugObject);
}
function applyAugmentation(aug, reapply = false) {
function applyAugmentation(aug: IPlayerOwnedAugmentation, reapply = false): void {
Augmentations[aug.name].owned = true;
const augObj = Augmentations[aug.name];
// Apply multipliers
for (const mult in augObj.mults) {
if (Player[mult] == null) {
console.warn(`Augmentation has unrecognized multiplier property: ${mult}`);
} else {
Player[mult] *= augObj.mults[mult];
}
const v = Player.getMult(mult) * augObj.mults[mult];
Player.setMult(mult, v);
}
// Special logic for NeuroFlux Governor
@@ -2400,12 +2558,12 @@ function applyAugmentation(aug, reapply = false) {
// Push onto Player's Augmentation list
if (!reapply) {
var ownedAug = new PlayerOwnedAugmentation(aug.name);
const ownedAug = new PlayerOwnedAugmentation(aug.name);
Player.augmentations.push(ownedAug);
}
}
function installAugmentations() {
function installAugmentations(): boolean {
if (Player.queuedAugmentations.length == 0) {
dialogBoxCreate("You have not purchased any Augmentations to install!");
return false;
@@ -2443,13 +2601,14 @@ function installAugmentations() {
"<br>You wake up in your home...you feel different...",
);
prestigeAugmentation();
return true;
}
function augmentationExists(name) {
function augmentationExists(name: string): boolean {
return Augmentations.hasOwnProperty(name);
}
export function isRepeatableAug(aug) {
export function isRepeatableAug(aug: Augmentation): boolean {
const augName = aug instanceof Augmentation ? aug.name : aug;
if (augName === AugmentationNames.NeuroFluxGovernor) {

View File

@@ -1,6 +1,118 @@
import { IMap } from "../../types";
export const AugmentationNames: IMap<string> = {
export const AugmentationNames: {
Targeting1: string;
Targeting2: string;
Targeting3: string;
SyntheticHeart: string;
SynfibrilMuscle: string;
CombatRib1: string;
CombatRib2: string;
CombatRib3: string;
NanofiberWeave: string;
SubdermalArmor: string;
WiredReflexes: string;
GrapheneBoneLacings: string;
BionicSpine: string;
GrapheneBionicSpine: string;
BionicLegs: string;
GrapheneBionicLegs: string;
SpeechProcessor: string;
TITN41Injection: string;
EnhancedSocialInteractionImplant: string;
BitWire: string;
ArtificialBioNeuralNetwork: string;
ArtificialSynapticPotentiation: string;
EnhancedMyelinSheathing: string;
SynapticEnhancement: string;
NeuralRetentionEnhancement: string;
DataJack: string;
ENM: string;
ENMCore: string;
ENMCoreV2: string;
ENMCoreV3: string;
ENMAnalyzeEngine: string;
ENMDMA: string;
Neuralstimulator: string;
NeuralAccelerator: string;
CranialSignalProcessorsG1: string;
CranialSignalProcessorsG2: string;
CranialSignalProcessorsG3: string;
CranialSignalProcessorsG4: string;
CranialSignalProcessorsG5: string;
NeuronalDensification: string;
NeuroreceptorManager: string;
NuoptimalInjectorImplant: string;
SpeechEnhancement: string;
FocusWire: string;
PCDNI: string;
PCDNIOptimizer: string;
PCDNINeuralNetwork: string;
PCMatrix: string;
ADRPheromone1: string;
ADRPheromone2: string;
ShadowsSimulacrum: string;
HacknetNodeCPUUpload: string;
HacknetNodeCacheUpload: string;
HacknetNodeNICUpload: string;
HacknetNodeKernelDNI: string;
HacknetNodeCoreDNI: string;
NeuroFluxGovernor: string;
Neurotrainer1: string;
Neurotrainer2: string;
Neurotrainer3: string;
Hypersight: string;
LuminCloaking1: string;
LuminCloaking2: string;
HemoRecirculator: string;
SmartSonar: string;
PowerRecirculator: string;
QLink: string;
TheRedPill: string;
SPTN97: string;
HiveMind: string;
CordiARCReactor: string;
SmartJaw: string;
Neotra: string;
Xanipher: string;
nextSENS: string;
OmniTekInfoLoad: string;
PhotosyntheticCells: string;
Neurolink: string;
TheBlackHand: string;
UnstableCircadianModulator: string;
CRTX42AA: string;
Neuregen: string;
CashRoot: string;
NutriGen: string;
INFRARet: string;
DermaForce: string;
GrapheneBrachiBlades: string;
GrapheneBionicArms: string;
BrachiBlades: string;
BionicArms: string;
SNA: string;
HydroflameLeftArm: string;
EsperEyewear: string;
EMS4Recombination: string;
OrionShoulder: string;
HyperionV1: string;
HyperionV2: string;
GolemSerum: string;
VangelisVirus: string;
VangelisVirus3: string;
INTERLINKED: string;
BladeRunner: string;
BladeArmor: string;
BladeArmorPowerCells: string;
BladeArmorEnergyShielding: string;
BladeArmorUnibeam: string;
BladeArmorOmnibeam: string;
BladeArmorIPU: string;
BladesSimulacrum: string;
StaneksGift1: string;
StaneksGift2: string;
StaneksGift3: string;
StaneksGift4: string;
} = {
Targeting1: "Augmented Targeting I",
Targeting2: "Augmented Targeting II",
Targeting3: "Augmented Targeting III",
@@ -41,6 +153,7 @@ export const AugmentationNames: IMap<string> = {
CranialSignalProcessorsG4: "Cranial Signal Processors - Gen IV",
CranialSignalProcessorsG5: "Cranial Signal Processors - Gen V",
NeuronalDensification: "Neuronal Densification",
NeuroreceptorManager: "Neuroreceptor Management Implant",
NuoptimalInjectorImplant: "Nuoptimal Nootropic Injector Implant",
SpeechEnhancement: "Speech Enhancement",
FocusWire: "FocusWire",
@@ -86,7 +199,7 @@ export const AugmentationNames: IMap<string> = {
NutriGen: "NutriGen Implant",
INFRARet: "INFRARET Enhancement",
DermaForce: "DermaForce Particle Barrier",
GrapheneBrachiBlades: "Graphene BranchiBlades Upgrade",
GrapheneBrachiBlades: "Graphene BrachiBlades Upgrade",
GrapheneBionicArms: "Graphene Bionic Arms Upgrade",
BrachiBlades: "BrachiBlades",
BionicArms: "Bionic Arms",
@@ -110,6 +223,11 @@ export const AugmentationNames: IMap<string> = {
BladeArmorIPU: "BLADE-51b Tesla Armor: IPU Upgrade",
BladesSimulacrum: "The Blade's Simulacrum",
StaneksGift1: "Stanek's Gift - Genesis",
StaneksGift2: "Stanek's Gift - Awakening",
StaneksGift3: "Stanek's Gift - Serenity",
StaneksGift4: "Stanek's Gift - Ascension",
//Wasteland Augs
//PepBoy: "P.E.P-Boy", Plasma Energy Projection System
//PepBoyForceField Generates plasma force fields

View File

@@ -2,92 +2,98 @@
* Root React component for the Augmentations UI page that display all of your
* owned and purchased Augmentations and Source-Files.
*/
import * as React from "react";
import React, { useState, useEffect } from "react";
import { InstalledAugmentationsAndSourceFiles } from "./InstalledAugmentationsAndSourceFiles";
import { InstalledAugmentations } from "./InstalledAugmentations";
import { PlayerMultipliers } from "./PlayerMultipliers";
import { PurchasedAugmentations } from "./PurchasedAugmentations";
import { SourceFiles } from "./SourceFiles";
import { Player } from "../../Player";
import { StdButton } from "../../ui/React/StdButton";
import { canGetBonus } from "../../ExportBonus";
import { use } from "../../ui/Context";
type IProps = {
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
interface IProps {
exportGameFn: () => void;
installAugmentationsFn: () => void;
};
type IState = {
rerender: boolean;
};
export class AugmentationsRoot extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
rerender: false,
};
this.export = this.export.bind(this);
}
export(): void {
this.props.exportGameFn();
this.setState({
rerender: !this.state.rerender,
});
}
render(): React.ReactNode {
function exportBonusStr(): string {
if (canGetBonus()) return "(+1 favor to all factions)";
return "";
}
return (
<>
<div className="augmentations-content">
<h1>Purchased Augmentations</h1>
<p>
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
install them.
</p>
<p>WARNING: Installing your Augmentations resets most of your progress, including:</p>
<br />
<p>- Stats/Skill levels and Experience</p>
<p>- Money</p>
<p>- Scripts on every computer but your home computer</p>
<p>- Purchased servers</p>
<p>- Hacknet Nodes</p>
<p>- Faction/Company reputation</p>
<p>- Stocks</p>
<br />
<p>
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but
you will lose all programs besides NUKE.exe)
</p>
<StdButton
onClick={this.props.installAugmentationsFn}
text="Install Augmentations"
tooltip="'I never asked for this'"
/>
<StdButton
addClasses="flashing-button"
onClick={this.export}
text={`Backup Save ${exportBonusStr()}`}
tooltip="It's always a good idea to backup/export your save!"
/>
<PurchasedAugmentations />
<h1>Installed Augmentations</h1>
<p>
{`List of all Augmentations ${Player.sourceFiles.length > 0 ? "and Source Files " : ""} ` +
`that have been installed. You have gained the effects of these.`}
</p>
<InstalledAugmentationsAndSourceFiles />
<br /> <br />
<PlayerMultipliers />
</div>
</>
);
}
}
export function AugmentationsRoot(props: IProps): React.ReactElement {
const player = use.Player();
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((o) => !o);
}
useEffect(() => {
const id = setInterval(rerender, 200);
return () => clearInterval(id);
}, []);
function doExport(): void {
props.exportGameFn();
rerender();
}
function exportBonusStr(): string {
if (canGetBonus()) return "(+1 favor to all factions)";
return "";
}
return (
<>
<Typography variant="h4">Augmentations</Typography>
<Box mx={2}>
<Typography>
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
install them.
</Typography>
<Typography>WARNING: Installing your Augmentations resets most of your progress, including:</Typography>
<br />
<Typography>- Stats/Skill levels and Experience</Typography>
<Typography>- Money</Typography>
<Typography>- Scripts on every computer but your home computer</Typography>
<Typography>- Purchased servers</Typography>
<Typography>- Hacknet Nodes</Typography>
<Typography>- Faction/Company reputation</Typography>
<Typography>- Stocks</Typography>
<br />
<Typography>
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but you
will lose all programs besides NUKE.exe)
</Typography>
</Box>
<Typography variant="h4" color="primary">
Purchased Augmentations
</Typography>
<Box mx={2}>
<Tooltip title={<Typography>'I never asked for this'</Typography>}>
<span>
<Button disabled={player.queuedAugmentations.length === 0} onClick={props.installAugmentationsFn}>
Install Augmentations
</Button>
</span>
</Tooltip>
<Tooltip title={<Typography>It's always a good idea to backup/export your save!</Typography>}>
<Button sx={{ mx: 2 }} onClick={doExport} color="error">
Backup Save {exportBonusStr()}
</Button>
</Tooltip>
<PurchasedAugmentations />
</Box>
<Typography variant="h4">Installed Augmentations</Typography>
<Box mx={2}>
<Typography>
List of all Augmentations that have been installed. You have gained the effects of these.
</Typography>
<InstalledAugmentations />
</Box>
<PlayerMultipliers />
<SourceFiles />
</>
);
}

View File

@@ -1,19 +1,28 @@
/**
* React Component for displaying a list of the player's installed Augmentations
* on the Augmentations UI
* React Component for displaying all of the player's installed Augmentations and
* Source-Files.
*
* It also contains 'configuration' buttons that allow you to change how the
* Augs/SF's are displayed
*/
import * as React from "react";
import { Player } from "../../Player";
import { Augmentations } from "../../Augmentation/Augmentations";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Settings } from "../../Settings/Settings";
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import React, { useState } from "react";
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
import { Augmentations } from "../../Augmentation/Augmentations";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Settings } from "../../Settings/Settings";
import { use } from "../../ui/Context";
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
import List from "@mui/material/List";
export function InstalledAugmentations(): React.ReactElement {
const sourceAugs = Player.augmentations.slice();
const setRerender = useState(true)[1];
const player = use.Player();
const sourceAugs = player.augmentations.slice();
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
sourceAugs.sort((aug1, aug2) => {
@@ -21,20 +30,42 @@ export function InstalledAugmentations(): React.ReactElement {
});
}
const augs = sourceAugs.map((e) => {
const aug = Augmentations[e.name];
function rerender(): void {
setRerender((old) => !old);
}
let level = null;
if (e.name === AugmentationNames.NeuroFluxGovernor) {
level = e.level;
}
function sortByAcquirementTime(): void {
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
rerender();
}
return (
<li key={e.name}>
<AugmentationAccordion aug={aug} level={level} />
</li>
);
});
function sortInOrder(): void {
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
rerender();
}
return <>{augs}</>;
return (
<>
<Tooltip title={"Sorts the Augmentations alphabetically in numeral order"}>
<Button onClick={sortInOrder}>Sort in Order</Button>
</Tooltip>
<Tooltip title={"Sorts the Augmentations based on when you acquired them (same as default)"}>
<Button sx={{ mx: 2 }} onClick={sortByAcquirementTime}>
Sort by Acquirement Time
</Button>
</Tooltip>
<List dense>
{sourceAugs.map((e) => {
const aug = Augmentations[e.name];
let level = null;
if (e.name === AugmentationNames.NeuroFluxGovernor) {
level = e.level;
}
return <AugmentationAccordion key={aug.name} aug={aug} level={level} />;
})}
</List>
</>
);
}

View File

@@ -1,115 +0,0 @@
/**
* React Component for displaying all of the player's installed Augmentations and
* Source-Files.
*
* It also contains 'configuration' buttons that allow you to change how the
* Augs/SF's are displayed
*/
import * as React from "react";
import { InstalledAugmentations } from "./InstalledAugmentations";
import { ListConfiguration } from "./ListConfiguration";
import { OwnedSourceFiles } from "./OwnedSourceFiles";
import { SourceFileMinus1 } from "./SourceFileMinus1";
import { Settings } from "../../Settings/Settings";
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
type IProps = {
// nothing special.
};
type IState = {
rerenderFlag: boolean;
};
export class InstalledAugmentationsAndSourceFiles extends React.Component<IProps, IState> {
listRef: React.RefObject<HTMLUListElement>;
constructor(props: IProps) {
super(props);
this.state = {
rerenderFlag: false,
};
this.collapseAllHeaders = this.collapseAllHeaders.bind(this);
this.expandAllHeaders = this.expandAllHeaders.bind(this);
this.sortByAcquirementTime = this.sortByAcquirementTime.bind(this);
this.sortInOrder = this.sortInOrder.bind(this);
this.listRef = React.createRef();
}
collapseAllHeaders(): void {
const ul = this.listRef.current;
if (ul == null) {
return;
}
const tickers = ul.getElementsByClassName("accordion-header");
for (let i = 0; i < tickers.length; ++i) {
const ticker = tickers[i];
if (!(ticker instanceof HTMLButtonElement)) {
continue;
}
if (ticker.classList.contains("active")) {
ticker.click();
}
}
}
expandAllHeaders(): void {
const ul = this.listRef.current;
if (ul == null) {
return;
}
const tickers = ul.getElementsByClassName("accordion-header");
for (let i = 0; i < tickers.length; ++i) {
const ticker = tickers[i];
if (!(ticker instanceof HTMLButtonElement)) {
continue;
}
if (!ticker.classList.contains("active")) {
ticker.click();
}
}
}
rerender(): void {
this.setState((prevState) => {
return {
rerenderFlag: !prevState.rerenderFlag,
};
});
}
sortByAcquirementTime(): void {
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.AcquirementTime;
this.rerender();
}
sortInOrder(): void {
Settings.OwnedAugmentationsOrder = OwnedAugmentationsOrderSetting.Alphabetically;
this.rerender();
}
render(): React.ReactNode {
return (
<>
<ListConfiguration
collapseAllButtonsFn={this.collapseAllHeaders}
expandAllButtonsFn={this.expandAllHeaders}
sortByAcquirementTimeFn={this.sortByAcquirementTime}
sortInOrderFn={this.sortInOrder}
/>
<ul className="augmentations-list" ref={this.listRef}>
<SourceFileMinus1 />
<OwnedSourceFiles />
<InstalledAugmentations />
</ul>
</>
);
}
}

View File

@@ -1,33 +0,0 @@
/**
* React Component for configuring the way installed augmentations and
* Source-Files are displayed in the Augmentations UI
*/
import * as React from "react";
import { StdButton } from "../../ui/React/StdButton";
type IProps = {
collapseAllButtonsFn: () => void;
expandAllButtonsFn: () => void;
sortByAcquirementTimeFn: () => void;
sortInOrderFn: () => void;
};
export function ListConfiguration(props: IProps): React.ReactElement {
return (
<>
<StdButton onClick={props.expandAllButtonsFn} text="Expand All" />
<StdButton onClick={props.collapseAllButtonsFn} text="Collapse All" />
<StdButton
onClick={props.sortInOrderFn}
text="Sort in Order"
tooltip="Sorts the Augmentations alphabetically and Source-Files in numeral order"
/>
<StdButton
onClick={props.sortByAcquirementTimeFn}
text="Sort by Acquirement Time"
tooltip="Sorts the Augmentations and Source-Files based on when you acquired them (same as default)"
/>
</>
);
}

View File

@@ -20,20 +20,18 @@ export function OwnedSourceFiles(): React.ReactElement {
});
}
const sfs = sourceSfs.map((e) => {
const srcFileKey = "SourceFile" + e.n;
const sfObj = SourceFiles[srcFileKey];
if (sfObj == null) {
console.error(`Invalid source file number: ${e.n}`);
return null;
}
return (
<>
{sourceSfs.map((e) => {
const srcFileKey = "SourceFile" + e.n;
const sfObj = SourceFiles[srcFileKey];
if (sfObj == null) {
console.error(`Invalid source file number: ${e.n}`);
return null;
}
return (
<li key={e.n}>
<SourceFileAccordion level={e.lvl} sf={sfObj} />
</li>
);
});
return <>{sfs}</>;
return <SourceFileAccordion key={e.n} level={e.lvl} sf={sfObj} />;
})}
</>
);
}

View File

@@ -6,6 +6,11 @@ import * as React from "react";
import { Player } from "../../Player";
import { numeralWrapper } from "../../ui/numeralFormat";
import { Augmentations } from "../Augmentations";
import { Table, TableCell } from "../../ui/React/Table";
import TableBody from "@mui/material/TableBody";
import TableRow from "@mui/material/TableRow";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
function calculateAugmentedStats(): any {
const augP: any = {};
@@ -19,62 +24,73 @@ function calculateAugmentedStats(): any {
return augP;
}
export function PlayerMultipliers(): React.ReactElement {
const mults = calculateAugmentedStats();
function MultiplierTable(rows: any[]): React.ReactElement {
function improvements(r: number): JSX.Element[] {
let elems: JSX.Element[] = [];
if (r) {
elems = [<td key="2">&nbsp;{"=>"}&nbsp;</td>, <td key="3">{numeralWrapper.formatPercentage(r)}</td>];
}
return elems;
}
function Improvements({ r }: { r: number }): React.ReactElement {
if (r) {
return (
<table>
<tbody>
{rows.map((r: any) => (
<tr key={r[0]}>
<td key="0">
<span>{r[0]} multiplier:&nbsp;</span>
</td>
<td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatPercentage(r[1])}
</td>
{improvements(r[2])}
</tr>
))}
</tbody>
</table>
<>
<TableCell key="2">
<Typography>&nbsp;{"=>"}&nbsp;</Typography>
</TableCell>
<TableCell key="3">
<Typography>{numeralWrapper.formatPercentage(r)}</Typography>
</TableCell>
</>
);
}
return <></>;
}
function MultiplierTable({ rows }: { rows: [string, number, number][] }): React.ReactElement {
return (
<Table size="small" padding="none">
<TableBody>
{rows.map((r: any) => (
<TableRow key={r[0]}>
<TableCell key="0">
<Typography noWrap>{r[0]} multiplier:&nbsp;</Typography>
</TableCell>
<TableCell key="1" style={{ textAlign: "right" }}>
<Typography noWrap>{numeralWrapper.formatPercentage(r[1])}</Typography>
</TableCell>
<Improvements r={r[2]} />
</TableRow>
))}
</TableBody>
</Table>
);
}
export function PlayerMultipliers(): React.ReactElement {
const mults = calculateAugmentedStats();
function BladeburnerMults(): React.ReactElement {
if (!Player.canAccessBladeburner()) return <></>;
return (
<>
{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 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,
],
])}
<MultiplierTable
rows={[
[
"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 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 />
</>
);
@@ -82,99 +98,116 @@ export function PlayerMultipliers(): React.ReactElement {
return (
<>
<p>
<strong>
<u>Multipliers:</u>
</strong>
</p>
<br />
{MultiplierTable([
["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 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],
])}
<br />
<Typography variant="h4">Multipliers</Typography>
<Box mx={2}>
<MultiplierTable
rows={[
["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 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],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
{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 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
rows={[
[
"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 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([
["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],
["Salary ", Player.work_money_mult, Player.work_money_mult * mults.work_money_mult],
])}
<br />
<MultiplierTable
rows={[
["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],
["Salary ", Player.work_money_mult, Player.work_money_mult * mults.work_money_mult],
]}
/>
<br />
{MultiplierTable([
["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],
])}
<br />
<MultiplierTable
rows={[
["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],
]}
/>
<br />
<BladeburnerMults />
<BladeburnerMults />
</Box>
</>
);
}

View File

@@ -9,6 +9,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Player } from "../../Player";
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
import List from "@mui/material/List";
export function PurchasedAugmentations(): React.ReactElement {
const augs: React.ReactElement[] = [];
@@ -29,12 +30,8 @@ export function PurchasedAugmentations(): React.ReactElement {
level = ownedAug.level;
}
augs.push(
<li key={`${ownedAug.name}${ownedAug.level}`}>
<AugmentationAccordion aug={aug} level={level} />
</li>,
);
augs.push(<AugmentationAccordion key={aug.name} aug={aug} level={level} />);
}
return <ul className="augmentations-list">{augs}</ul>;
return <List dense>{augs}</List>;
}

View File

@@ -2,14 +2,22 @@
* React Component for displaying a list of the player's Source-Files
* on the Augmentations UI
*/
import * as React from "react";
import React, { useState } from "react";
import { Player } from "../../Player";
import { Exploit, ExploitName } from "../../Exploits/Exploit";
import { BBAccordion } from "../../ui/React/BBAccordion";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemText from "@mui/material/ListItemText";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
import Collapse from "@mui/material/Collapse";
import ExpandMore from "@mui/icons-material/ExpandMore";
import ExpandLess from "@mui/icons-material/ExpandLess";
export function SourceFileMinus1(): React.ReactElement {
const [open, setOpen] = useState(false);
const exploits = Player.exploits;
if (exploits.length === 0) {
@@ -17,33 +25,35 @@ export function SourceFileMinus1(): React.ReactElement {
}
return (
<li key={-1}>
<BBAccordion
headerContent={
<>
Source-File -1: Exploits in the BitNodes
<br />
Level {exploits.length} / ?
</>
}
panelContent={
<>
<p>
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 />
<Box component={Paper}>
<ListItemButton onClick={() => setOpen((old) => !old)}>
<ListItemText
primary={
<Typography style={{ whiteSpace: "pre-wrap" }}>
Source-File -1: Exploits in the BitNodes
<br />
Level {exploits.length} / ?
</Typography>
}
/>
{open ? <ExpandLess color="primary" /> : <ExpandMore color="primary" />}
</ListItemButton>
<Collapse in={open} unmountOnExit>
<Box m={4}>
<Typography>
This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web ecosystem.
</Typography>
<Typography>It increases all of the player's multipliers by 0.1%</Typography>
<br />
<p>You have found the following exploits:</p>
<ul>
{exploits.map((c: Exploit) => (
<li key={c}>* {ExploitName(c)}</li>
))}
</ul>
</>
}
/>
</li>
<Typography>You have found the following exploits:</Typography>
<Box mx={2}>
{exploits.map((c: Exploit) => (
<Typography key={c}>* {ExploitName(c)}</Typography>
))}
</Box>
</Box>
</Collapse>
</Box>
);
}

View File

@@ -0,0 +1,21 @@
import React from "react";
import { SourceFileMinus1 } from "./SourceFileMinus1";
import { OwnedSourceFiles } from "./OwnedSourceFiles";
import List from "@mui/material/List";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
export function SourceFiles(): React.ReactElement {
return (
<>
<Typography variant="h4">Source Files</Typography>
<Box mx={2}>
<List dense>
<SourceFileMinus1 />
<OwnedSourceFiles />
</List>
</Box>
</>
);
}

View File

@@ -16,8 +16,11 @@ class BitNode {
// BitNode number
number: number;
constructor(n: number, name: string, desc = "", info: JSX.Element = <></>) {
difficulty: 0 | 1 | 2;
constructor(n: number, difficulty: 0 | 1 | 2, name: string, desc = "", info: JSX.Element = <></>) {
this.number = n;
this.difficulty = difficulty;
this.name = name;
this.desc = desc;
this.info = info;
@@ -28,6 +31,7 @@ export const BitNodes: IMap<BitNode> = {};
BitNodes["BitNode1"] = new BitNode(
1,
0,
"Source Genesis",
"The original BitNode",
(
@@ -54,6 +58,7 @@ BitNodes["BitNode1"] = new BitNode(
);
BitNodes["BitNode2"] = new BitNode(
2,
0,
"Rise of the Underworld",
"From the shadows, they rose", //Gangs
(
@@ -101,6 +106,7 @@ BitNodes["BitNode2"] = new BitNode(
);
BitNodes["BitNode3"] = new BitNode(
3,
0,
"Corporatocracy",
"The Price of Civilization",
(
@@ -140,6 +146,7 @@ BitNodes["BitNode3"] = new BitNode(
);
BitNodes["BitNode4"] = new BitNode(
4,
1,
"The Singularity",
"The Man and the Machine",
(
@@ -164,6 +171,7 @@ BitNodes["BitNode4"] = new BitNode(
);
BitNodes["BitNode5"] = new BitNode(
5,
1,
"Artificial Intelligence",
"Posthuman",
(
@@ -211,6 +219,7 @@ BitNodes["BitNode5"] = new BitNode(
);
BitNodes["BitNode6"] = new BitNode(
6,
1,
"Bladeburners",
"Like Tears in Rain",
(
@@ -255,6 +264,7 @@ BitNodes["BitNode6"] = new BitNode(
);
BitNodes["BitNode7"] = new BitNode(
7,
2,
"Bladeburners 2079",
"More human than humans",
(
@@ -303,6 +313,7 @@ BitNodes["BitNode7"] = new BitNode(
);
BitNodes["BitNode8"] = new BitNode(
8,
2,
"Ghost of Wall Street",
"Money never sleeps",
(
@@ -347,6 +358,7 @@ BitNodes["BitNode8"] = new BitNode(
);
BitNodes["BitNode9"] = new BitNode(
9,
2,
"Hacktocracy",
"Hacknet Unleashed",
(
@@ -384,11 +396,21 @@ BitNodes["BitNode9"] = new BitNode(
<br />
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
Augmentations)
<br />
<br />
This Source-File also increases your hacknet multipliers by:
<br />
Level 1: 8%
<br />
Level 2: 12%
<br />
Level 3: 14%
</>
),
);
BitNodes["BitNode10"] = new BitNode(
10,
2,
"Digital Carbon",
"Your body is not who you are",
(
@@ -428,6 +450,7 @@ BitNodes["BitNode10"] = new BitNode(
);
BitNodes["BitNode11"] = new BitNode(
11,
1,
"The Big Crash",
"Okay. Sell it all.",
(
@@ -492,6 +515,7 @@ BitNodes["BitNode11"] = new BitNode(
);
BitNodes["BitNode12"] = new BitNode(
12,
0,
"The Recursion",
"Repeat.",
(
@@ -506,19 +530,49 @@ BitNodes["BitNode12"] = new BitNode(
</>
),
);
BitNodes["BitNode13"] = new BitNode(
13,
2,
"They're lunatics",
"1 step back, 2 steps forward",
(
<>
With the invention of Augmentations in the 2040s a religious group known as the Church of the Machine God has
rallied far more support than anyone would have hoped.
<br />
<br />
Their leader, Allison "Mother" Stanek is said to have created her own Augmentation whose power goes beyond any
other. Find her in Chongquing and gain her trust.
<br />
<br />
In this BitNode:
<br />
<br />
Every is significantly reduced
<br />
Stanek's Gift power is significantly increased.
<br />
<br />
Destroying this BitNode will give you Source-File 13, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File lets the Church of the Machine God appear in other BitNodes.
<br />
<br />
Each level of this Source-File increases the size of Stanek's Gift.
</>
),
);
// Books: Frontera, Shiner
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["BitNode15"] = new BitNode(15, "", "COMING SOON");
BitNodes["BitNode16"] = new BitNode(16, "", "COMING SOON");
BitNodes["BitNode17"] = new BitNode(17, "", "COMING SOON");
BitNodes["BitNode18"] = new BitNode(18, "", "COMING SOON");
BitNodes["BitNode19"] = new BitNode(19, "", "COMING SOON");
BitNodes["BitNode20"] = new BitNode(20, "", "COMING SOON");
BitNodes["BitNode21"] = new BitNode(21, "", "COMING SOON");
BitNodes["BitNode22"] = new BitNode(22, "", "COMING SOON");
BitNodes["BitNode23"] = new BitNode(23, "", "COMING SOON");
BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON");
BitNodes["BitNode14"] = new BitNode(14, 2, "", "COMING SOON");
BitNodes["BitNode15"] = new BitNode(15, 2, "", "COMING SOON");
BitNodes["BitNode16"] = new BitNode(16, 2, "", "COMING SOON");
BitNodes["BitNode17"] = new BitNode(17, 2, "", "COMING SOON");
BitNodes["BitNode18"] = new BitNode(18, 2, "", "COMING SOON");
BitNodes["BitNode19"] = new BitNode(19, 2, "", "COMING SOON");
BitNodes["BitNode20"] = new BitNode(20, 2, "", "COMING SOON");
BitNodes["BitNode21"] = new BitNode(21, 2, "", "COMING SOON");
BitNodes["BitNode22"] = new BitNode(22, 2, "", "COMING SOON");
BitNodes["BitNode23"] = new BitNode(23, 2, "", "COMING SOON");
BitNodes["BitNode24"] = new BitNode(24, 2, "", "COMING SOON");
export function initBitNodeMultipliers(p: IPlayer): void {
if (p.bitNodeN == null) {
@@ -529,6 +583,8 @@ export function initBitNodeMultipliers(p: IPlayer): void {
BitNodeMultipliers[mult] = 1;
}
}
// Special case.
BitNodeMultipliers.StaneksGiftExtraSize = 0;
switch (p.bitNodeN) {
case 1: // Source Genesis (every multiplier is 1)
@@ -769,6 +825,47 @@ export function initBitNodeMultipliers(p: IPlayer): void {
BitNodeMultipliers.BladeburnerSkillCost = inc;
break;
}
case 13: {
BitNodeMultipliers.DaedalusAugsRequirement = 100;
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
BitNodeMultipliers.StrengthLevelMultiplier = 0.2;
BitNodeMultipliers.DefenseLevelMultiplier = 0.2;
BitNodeMultipliers.DexterityLevelMultiplier = 0.2;
BitNodeMultipliers.AgilityLevelMultiplier = 0.2;
BitNodeMultipliers.CharismaLevelMultiplier = 0.2;
BitNodeMultipliers.ServerMaxMoney = 0.15;
BitNodeMultipliers.ServerStartingMoney = 0.75;
BitNodeMultipliers.ServerStartingSecurity = 2;
BitNodeMultipliers.ScriptHackMoney = 0.2;
BitNodeMultipliers.CompanyWorkMoney = 0.2;
BitNodeMultipliers.CrimeMoney = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.CodingContractMoney = 0.2;
BitNodeMultipliers.CompanyWorkExpGain = 0.1;
BitNodeMultipliers.ClassGymExpGain = 0.1;
BitNodeMultipliers.FactionWorkExpGain = 0.1;
BitNodeMultipliers.HackExpGain = 0.1;
BitNodeMultipliers.CrimeExpGain = 0.1;
BitNodeMultipliers.FactionWorkRepGain = 0.4;
BitNodeMultipliers.FourSigmaMarketDataCost = 10;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 10;
BitNodeMultipliers.CorporationValuation = 0.001;
BitNodeMultipliers.BladeburnerRank = 0.1;
BitNodeMultipliers.BladeburnerSkillCost = 5;
BitNodeMultipliers.GangKarmaRequirement = 20;
BitNodeMultipliers.StaneksGiftPowerMultiplier = 2;
BitNodeMultipliers.StaneksGiftExtraSize = 1;
break;
}
default:
console.warn("Player.bitNodeN invalid");
break;

View File

@@ -212,6 +212,16 @@ interface IBitNodeMultipliers {
*/
StrengthLevelMultiplier: number;
/**
* Influences the power of the gift.
*/
StaneksGiftPowerMultiplier: number;
/**
* Influences the size of the gift.
*/
StaneksGiftExtraSize: number;
// Index signature
[key: string]: number;
}
@@ -274,4 +284,7 @@ export const BitNodeMultipliers: IBitNodeMultipliers = {
DaedalusAugsRequirement: 1,
GangKarmaRequirement: 1,
StaneksGiftPowerMultiplier: 1,
StaneksGiftExtraSize: 0,
};

View File

@@ -0,0 +1,33 @@
import React, { useState, useEffect } from "react";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
export const BitFlumeEvent = new EventEmitter<[]>();
export function BitFlumeModal(): React.ReactElement {
const router = use.Router();
const [open, setOpen] = useState(false);
function flume(): void {
router.toBitVerse(true, false);
setOpen(false);
}
useEffect(() => BitFlumeEvent.subscribe(() => setOpen(true)), []);
return (
<Modal open={open} onClose={() => setOpen(false)}>
<Typography>
WARNING: USING THIS PROGRAM WILL CAUSE YOU TO LOSE ALL OF YOUR PROGRESS ON THE CURRENT BITNODE.
<br />
<br />
Do you want to travel to the BitNode Nexus? This allows you to reset the current BitNode and select a new one.
</Typography>
<br />
<br />
<Button onClick={flume}>Travel to the BitVerse</Button>
</Modal>
);
}

View File

@@ -1,30 +0,0 @@
import React from "react";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { IRouter } from "../../ui/Router";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
player: IPlayer;
router: IRouter;
popupId: string;
}
export function BitFlumePopup(props: IProps): React.ReactElement {
function flume(): void {
props.router.toBitVerse(true, false);
removePopup(props.popupId);
}
return (
<>
WARNING: USING THIS PROGRAM WILL CAUSE YOU TO LOSE ALL OF YOUR PROGRESS ON THE CURRENT BITNODE.
<br />
<br />
Do you want to travel to the BitNode Nexus? This allows you to reset the current BitNode and select a new one.
<br />
<br />
<button className="std-button" onClick={flume}>
Travel to the BitVerse
</button>
</>
);
}

View File

@@ -2,11 +2,43 @@ import React, { useState } from "react";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { IRouter } from "../../ui/Router";
import { BitNodes } from "../BitNode";
import { enterBitNode } from "../../RedPill";
import { PortalPopup } from "./PortalPopup";
import { createPopup } from "../../ui/React/createPopup";
import { enterBitNode, setRedPillFlag } from "../../RedPill";
import { PortalModal } from "./PortalModal";
import { CinematicText } from "../../ui/React/CinematicText";
import { use } from "../../ui/Context";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
const useStyles = makeStyles(() =>
createStyles({
level0: {
color: "red",
"&:hover": {
color: "#fff",
},
},
level1: {
color: "yellow",
"&:hover": {
color: "#fff",
},
},
level2: {
color: "#48d1cc",
"&:hover": {
color: "#fff",
},
},
level3: {
color: "blue",
"&:hover": {
color: "#fff",
},
},
}),
);
interface IPortalProps {
n: number;
@@ -16,51 +48,53 @@ interface IPortalProps {
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
function BitNodePortal(props: IPortalProps): React.ReactElement {
const router = use.Router();
const [portalOpen, setPortalOpen] = useState(false);
const classes = useStyles();
const bitNode = BitNodes[`BitNode${props.n}`];
if (bitNode == null) {
return <>O</>;
}
let cssClass;
let cssClass = classes.level0;
if (props.n === 12 && props.level >= 2) {
// Repeating BitNode
cssClass = "level-2";
} else {
cssClass = `level-${props.level}`;
cssClass = classes.level2;
} else if (props.level === 1) {
cssClass = classes.level1;
} else if (props.level === 3) {
cssClass = classes.level3;
}
function openPortalPopup(): void {
const popupId = "bitverse-portal-popup";
createPopup(popupId, PortalPopup, {
n: props.n,
level: props.level,
enter: props.enter,
router: router,
destroyedBitNode: props.destroyedBitNode,
flume: props.flume,
popupId: popupId,
});
if (props.level === 2) {
cssClass = classes.level2;
}
return (
<button
className={`bitnode ${cssClass} tooltip`}
aria-label={`enter-bitnode-${bitNode.number.toString()}`}
onClick={openPortalPopup}
>
<strong>O</strong>
<span className="tooltiptext">
<strong>
BitNode-{bitNode.number.toString()}
<br />
{bitNode.name}
</strong>
<br />
{bitNode.desc}
<br />
</span>
</button>
<>
<Tooltip
title={
<Typography>
<strong>
BitNode-{bitNode.number.toString()}: {bitNode.name}
</strong>
<br />
{bitNode.desc}
</Typography>
}
>
<span onClick={() => setPortalOpen(true)} className={cssClass}>
<b>O</b>
</span>
</Tooltip>
<PortalModal
open={portalOpen}
onClose={() => setPortalOpen(false)}
n={props.n}
level={props.level}
enter={props.enter}
destroyedBitNode={props.destroyedBitNode}
flume={props.flume}
/>
</>
);
}
@@ -71,6 +105,7 @@ interface IProps {
}
export function BitverseRoot(props: IProps): React.ReactElement {
setRedPillFlag(true);
const player = use.Player();
const enter = enterBitNode;
const destroyed = player.bitNodeN;
@@ -114,32 +149,32 @@ export function BitverseRoot(props: IProps): React.ReactElement {
return (
// prettier-ignore
<div className="noselect">
<pre> O </pre>
<pre> | O O | O O | </pre>
<pre> O | | / __| \ | | O </pre>
<pre> O | O | | O / | O | | O | O </pre>
<pre> | | | | |_/ |/ | \_ \_| | | | | </pre>
<pre> O | | | O | | O__/ | / \__ | | O | | | O </pre>
<pre> | | | | | | | / /| O / \| | | | | | | </pre>
<pre>O | | | \| | O / _/ | / O | |/ | | | O</pre>
<pre>| | | |O / | | O / | O O | | \ O| | | |</pre>
<pre>| | |/ \/ / __| | |/ \ | \ | |__ \ \/ \| | |</pre>
<pre> \| O | |_/ |\| \ O \__| \_| | O |/ </pre>
<pre> | | |_/ | | \| / | \_| | | </pre>
<pre> \| / \| | / / \ |/ </pre>
<pre> | <BitNodePortal n={10} level={nextSourceFileFlags[10]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | / | <BitNodePortal n={11} level={nextSourceFileFlags[11]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | </pre>
<pre> <BitNodePortal n={9} level={nextSourceFileFlags[9]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | | | | | | <BitNodePortal n={12} level={nextSourceFileFlags[12]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </pre>
<pre> | | | / / \ \ | | | </pre>
<pre> \| | / <BitNodePortal n={7} level={nextSourceFileFlags[7]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> / \ <BitNodePortal n={8} level={nextSourceFileFlags[8]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \ | |/ </pre>
<pre> \ | / / | | \ \ | / </pre>
<pre> \ \JUMP <BitNodePortal n={5} level={nextSourceFileFlags[5]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} />3R | | | | | | R3<BitNodePortal n={6} level={nextSourceFileFlags[6]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> PMUJ/ / </pre>
<pre> \|| | | | | | | | | ||/ </pre>
<pre> \| \_ | | | | | | _/ |/ </pre>
<pre> \ \| / \ / \ |/ / </pre>
<pre> <BitNodePortal n={1} level={nextSourceFileFlags[1]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> |/ <BitNodePortal n={2} level={nextSourceFileFlags[2]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | <BitNodePortal n={3} level={nextSourceFileFlags[3]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \| <BitNodePortal n={4} level={nextSourceFileFlags[4]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </pre>
<pre> | | | | | | | | </pre>
<pre> \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ </pre>
<>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | O O | O O | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O | | / __| \ | | O </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O | O | | O / | O | | O | O </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | | | |_/ |/ | \_ \_| | | | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O | | | O | | O__/ | / \__ | | O | | | O </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | | | | | | / /| O / \| | | | | | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>O | | | \| | O / _/ | / O | |/ | | | O</Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>| | | |O / | | O / | O O | | \ O| | | |</Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>| | |/ \/ / __| | |/ \ | \ | |__ \ \/ \| | |</Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| O | |_/ |\| \ <BitNodePortal n={13} level={nextSourceFileFlags[13]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \__| \_| | O |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | |_/ | | \| / | \_| | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| / \| | / / \ |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | <BitNodePortal n={10} level={nextSourceFileFlags[10]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | / | <BitNodePortal n={11} level={nextSourceFileFlags[11]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> <BitNodePortal n={9} level={nextSourceFileFlags[9]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | | | | | | <BitNodePortal n={12} level={nextSourceFileFlags[12]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | | / / \ \ | | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| | / <BitNodePortal n={7} level={nextSourceFileFlags[7]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> / \ <BitNodePortal n={8} level={nextSourceFileFlags[8]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \ | |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ | / / | | \ \ | / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ \JUMP <BitNodePortal n={5} level={nextSourceFileFlags[5]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} />3R | | | | | | R3<BitNodePortal n={6} level={nextSourceFileFlags[6]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> PMUJ/ / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \|| | | | | | | | | ||/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| \_ | | | | | | _/ |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ \| / \ / \ |/ / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> <BitNodePortal n={1} level={nextSourceFileFlags[1]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> |/ <BitNodePortal n={2} level={nextSourceFileFlags[2]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | <BitNodePortal n={3} level={nextSourceFileFlags[3]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \| <BitNodePortal n={4} level={nextSourceFileFlags[4]} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | | | | | | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ </Typography>
<br />
<br />
<br />
@@ -167,7 +202,7 @@ export function BitverseRoot(props: IProps): React.ReactElement {
"> ",
"> (Enter a new BitNode using the image above)",
]} />
</div>
</>
);
return <></>;

View File

@@ -0,0 +1,55 @@
import React from "react";
import { BitNodes } from "../BitNode";
import { IRouter } from "../../ui/Router";
import { use } from "../../ui/Context";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps {
open: boolean;
onClose: () => void;
n: number;
level: number;
destroyedBitNode: number;
flume: boolean;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
export function PortalModal(props: IProps): React.ReactElement {
const router = use.Router();
const bitNodeKey = "BitNode" + props.n;
const bitNode = BitNodes[bitNodeKey];
if (bitNode == null) throw new Error(`Could not find BitNode object for number: ${props.n}`);
const maxSourceFileLevel = props.n === 12 ? "∞" : "3";
const newLevel = Math.min(props.level + 1, props.n === 12 ? Infinity : 3);
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography variant="h4">
BitNode-{props.n}: {bitNode.name}
</Typography>
<br />
<Typography>
Source-File Level: {props.level} / {maxSourceFileLevel}
</Typography>
<br />
<br />
<Typography> Difficulty: {["easy", "normal", "hard"][bitNode.difficulty]}</Typography>
<br />
<br />
<Typography>{bitNode.info}</Typography>
<br />
<br />
<Button
onClick={() => {
props.enter(router, props.flume, props.destroyedBitNode, props.n);
props.onClose();
}}
>
Enter BN{props.n}.{newLevel}
</Button>
</Modal>
);
}

View File

@@ -1,46 +0,0 @@
import React from "react";
import { BitNodes } from "../BitNode";
import { IRouter } from "../../ui/Router";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
n: number;
level: number;
destroyedBitNode: number;
flume: boolean;
router: IRouter;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
popupId: string;
}
export function PortalPopup(props: IProps): React.ReactElement {
const bitNodeKey = "BitNode" + props.n;
const bitNode = BitNodes[bitNodeKey];
if (bitNode == null) throw new Error(`Could not find BitNode object for number: ${props.n}`);
const maxSourceFileLevel = props.n === 12 ? "∞" : "3";
const newLevel = Math.min(props.level + 1, props.n === 12 ? Infinity : 3);
return (
<>
<h1>
BitNode-{props.n}: {bitNode.name}
</h1>
<br />
Source-File Level: {props.level} / {maxSourceFileLevel}
<br />
<br />
{bitNode.info}
<br />
<br />
<button
className="std-button"
onClick={() => {
props.enter(props.router, props.flume, props.destroyedBitNode, props.n);
removePopup(props.popupId);
}}
>
Enter BN{props.n}.{newLevel}
</button>
</>
);
}

View File

@@ -1,7 +1,7 @@
import { Player } from "../Player";
import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { addOffset } from "../../utils/helpers/addOffset";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { getRandomInt } from "../utils/helpers/getRandomInt";
import { addOffset } from "../utils/helpers/addOffset";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
import { BladeburnerConstants } from "./data/Constants";
import { IBladeburner } from "./IBladeburner";
import { IAction, ISuccessChanceParams } from "./IAction";
@@ -20,7 +20,6 @@ class StatsMultiplier {
export interface IActionParams {
name?: string;
desc?: string;
level?: number;
maxLevel?: number;
autoLevel?: boolean;
@@ -43,7 +42,6 @@ export interface IActionParams {
export class Action implements IAction {
name = "";
desc = "";
// Difficulty scales with level. See getDifficulty() method
level = 1;
@@ -100,7 +98,6 @@ export class Action implements IAction {
constructor(params: IActionParams | null = null) {
// | null = null
if (params && params.name) this.name = params.name;
if (params && params.desc) this.desc = params.desc;
if (params && params.baseDifficulty) this.baseDifficulty = addOffset(params.baseDifficulty, 10);
if (params && params.difficultyFac) this.difficultyFac = params.difficultyFac;

View File

@@ -1,5 +1,5 @@
import { IActionIdentifier } from "./IActionIdentifier";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
interface IParams {
name?: string;

View File

@@ -1,5 +1,5 @@
import { Operation, IOperationParams } from "./Operation";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
export class BlackOperation extends Operation {
constructor(params: IOperationParams | null = null) {

View File

@@ -1,763 +0,0 @@
import { BlackOperation } from "./BlackOperation";
import { IMap } from "../types";
export const BlackOperations: IMap<BlackOperation> = {};
(function () {
BlackOperations["Operation Typhoon"] = new BlackOperation({
name: "Operation Typhoon",
desc:
"Obadiah Zenyatta is the leader of a RedWater PMC. It has long " +
"been known among the intelligence community that Zenyatta, along " +
"with the rest of the PMC, is a Synthoid.<br><br>" +
"The goal of Operation Typhoon is to find and eliminate " +
"Zenyatta and RedWater by any means necessary. After the task " +
"is completed, the actions must be covered up from the general public.",
baseDifficulty: 2000,
reqdRank: 2.5e3,
rankGain: 50,
rankLoss: 10,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Zero"] = new BlackOperation({
name: "Operation Zero",
desc:
"AeroCorp is one of the world's largest defense contractors. " +
"Its leader, Steve Watataki, is thought to be a supporter of " +
"Synthoid rights. He must be removed.<br><br>" +
"The goal of Operation Zero is to covertly infiltrate AeroCorp and " +
"uncover any incriminating evidence or " +
"information against Watataki that will cause him to be removed " +
"from his position at AeroCorp. Incriminating evidence can be " +
"fabricated as a last resort. Be warned that AeroCorp has some of " +
"the most advanced security measures in the world.",
baseDifficulty: 2500,
reqdRank: 5e3,
rankGain: 60,
rankLoss: 15,
hpLoss: 50,
weights: {
hack: 0.2,
str: 0.15,
def: 0.15,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true,
});
BlackOperations["Operation X"] = new BlackOperation({
name: "Operation X",
desc:
"We have recently discovered an underground publication " +
"group called Samizdat. Even though most of their publications " +
"are nonsensical conspiracy theories, the average human is " +
"gullible enough to believe them. Many of their works discuss " +
"Synthoids and pose a threat to society. The publications are spreading " +
"rapidly in China and other Eastern countries.<br><br>" +
"Samizdat has done a good job of keeping hidden and anonymous. " +
"However, we've just received intelligence that their base of " +
"operations is in Ishima's underground sewer systems. Your task is to " +
"investigate the sewer systems, and eliminate Samizdat. They must " +
"never publish anything again.",
baseDifficulty: 3000,
reqdRank: 7.5e3,
rankGain: 75,
rankLoss: 15,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Titan"] = new BlackOperation({
name: "Operation Titan",
desc:
"Several months ago Titan Laboratories' Bioengineering department " +
"was infiltrated by Synthoids. As far as we know, Titan Laboratories' " +
"management has no knowledge about this. We don't know what the " +
"Synthoids are up to, but the research that they could " +
"be conducting using Titan Laboraties' vast resources is potentially " +
"very dangerous.<br><br>" +
"Your goal is to enter and destroy the Bioengineering department's " +
"facility in Aevum. The task is not just to retire the Synthoids there, but " +
"also to destroy any information or research at the facility that " +
"is relevant to the Synthoids and their goals.",
baseDifficulty: 4000,
reqdRank: 10e3,
rankGain: 100,
rankLoss: 20,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Ares"] = new BlackOperation({
name: "Operation Ares",
desc:
"One of our undercover agents, Agent Carter, has informed us of a " +
"massive weapons deal going down in Dubai between rogue Russian " +
"militants and a radical Synthoid community. These weapons are next-gen " +
"plasma and energy weapons. It is critical for the safety of humanity " +
"that this deal does not happen.<br><br>" +
"Your task is to intercept the deal. Leave no survivors.",
baseDifficulty: 5000,
reqdRank: 12.5e3,
rankGain: 125,
rankLoss: 20,
hpLoss: 200,
weights: {
hack: 0,
str: 0.25,
def: 0.25,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Archangel"] = new BlackOperation({
name: "Operation Archangel",
desc:
"Our analysts have discovered that the popular Red Rabbit brothel in " +
"Amsterdam is run and 'staffed' by MK-VI Synthoids. Intelligence " +
"suggests that the profit from this brothel is used to fund a large " +
"black market arms trafficking operation.<br><br>" +
"The goal of this operation is to take out the leaders that are running " +
"the Red Rabbit brothel. Try to limit the number of other casualties, " +
"but do what you must to complete the mission.",
baseDifficulty: 7500,
reqdRank: 15e3,
rankGain: 200,
rankLoss: 20,
hpLoss: 25,
weights: {
hack: 0,
str: 0.2,
def: 0.2,
dex: 0.3,
agi: 0.3,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Juggernaut"] = new BlackOperation({
name: "Operation Juggernaut",
desc:
"The CIA has just encountered a new security threat. A new " +
"criminal group, lead by a shadowy operative who calls himself " +
"Juggernaut, has been smuggling drugs and weapons (including " +
"suspected bioweapons) into Sector-12. We also have reason " +
"to believe the tried to break into one of Universal Energy's " +
"facilities in order to cause a city-wide blackout. The CIA " +
"suspects that Juggernaut is a heavily-augmented Synthoid, and " +
"have thus enlisted our help.<br><br>" +
"Your mission is to eradicate Juggernaut and his followers.",
baseDifficulty: 10e3,
reqdRank: 20e3,
rankGain: 300,
rankLoss: 40,
hpLoss: 300,
weights: {
hack: 0,
str: 0.25,
def: 0.25,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Red Dragon"] = new BlackOperation({
name: "Operation Red Dragon",
desc:
"The Tetrads criminal organization is suspected of " +
"reverse-engineering the MK-VI Synthoid design. We believe " +
"they altered and possibly improved the design and began " +
"manufacturing their own Synthoid models in order to bolster " +
"their criminal activities.<br><br>" +
"Your task is to infiltrate and destroy the Tetrads' base of operations " +
"in Los Angeles. Intelligence tells us that their base houses " +
"one of their Synthoid manufacturing units.",
baseDifficulty: 12.5e3,
reqdRank: 25e3,
rankGain: 500,
rankLoss: 50,
hpLoss: 500,
weights: {
hack: 0.05,
str: 0.2,
def: 0.2,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation K"] = new BlackOperation({
name: "Operation K",
desc:
"CODE RED SITUATION. Our intelligence tells us that VitaLife " +
"has discovered a new android cloning technology. This technology " +
"is supposedly capable of cloning Synthoid, not only physically " +
"but also their advanced AI modules. We do not believe that " +
"VitaLife is trying to use this technology illegally or " +
"maliciously, but if any Synthoids were able to infiltrate the " +
"corporation and take advantage of this technology then the " +
"results would be catastrophic.<br><br>" +
"We do not have the power or jurisdiction to shutdown this down " +
"through legal or political means, so we must resort to a covert " +
"operation. Your goal is to destroy this technology and eliminate " +
"anyone who was involved in its creation.",
baseDifficulty: 15e3,
reqdRank: 30e3,
rankGain: 750,
rankLoss: 60,
hpLoss: 1000,
weights: {
hack: 0.05,
str: 0.2,
def: 0.2,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Deckard"] = new BlackOperation({
name: "Operation Deckard",
desc:
"Despite your success in eliminating VitaLife's new android-replicating " +
"technology in Operation K, we've discovered that a small group of " +
"MK-VI Synthoids were able to make off with the schematics and design " +
"of the technology before the Operation. It is almost a certainty that " +
"these Synthoids are some of the rogue MK-VI ones from the Synthoid Uprising.<br><br>" +
"The goal of Operation Deckard is to hunt down these Synthoids and retire " +
"them. I don't need to tell you how critical this mission is.",
baseDifficulty: 20e3,
reqdRank: 40e3,
rankGain: 1e3,
rankLoss: 75,
hpLoss: 200,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Tyrell"] = new BlackOperation({
name: "Operation Tyrell",
desc:
"A week ago Blade Industries reported a small break-in at one " +
"of their Aevum Augmentation storage facitilities. We figured out " +
"that The Dark Army was behind the heist, and didn't think any more " +
"of it. However, we've just discovered that several known MK-VI Synthoids " +
"were part of that break-in group.<br><br>" +
"We cannot have Synthoids upgrading their already-enhanced abilities " +
"with Augmentations. Your task is to hunt down the associated Dark Army " +
"members and eliminate them.",
baseDifficulty: 25e3,
reqdRank: 50e3,
rankGain: 1.5e3,
rankLoss: 100,
hpLoss: 500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Wallace"] = new BlackOperation({
name: "Operation Wallace",
desc:
"Based on information gathered from Operation Tyrell, we've discovered " +
"that The Dark Army was well aware that there were Synthoids amongst " +
"their ranks. Even worse, we believe that The Dark Army is working " +
"together with other criminal organizations such as The Syndicate and " +
"that they are planning some sort of large-scale takeover of multiple major " +
"cities, most notably Aevum. We suspect that Synthoids have infiltrated " +
"the ranks of these criminal factions and are trying to stage another " +
"Synthoid uprising.<br><br>" +
"The best way to deal with this is to prevent it before it even happens. " +
"The goal of Operation Wallace is to destroy the Dark Army and " +
"Syndicate factions in Aevum immediately. Leave no survivors.",
baseDifficulty: 30e3,
reqdRank: 75e3,
rankGain: 2e3,
rankLoss: 150,
hpLoss: 1500,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({
name: "Operation Shoulder of Orion",
desc:
"China's Solaris Space Systems is secretly launching the first " +
"manned spacecraft in over a decade using Synthoids. We believe " +
"China is trying to establish the first off-world colonies.<br><br>" +
"The mission is to prevent this launch without instigating an " +
"international conflict. When you accept this mission you will be " +
"officially disavowed by the NSA and the national government until after you " +
"successfully return. In the event of failure, all of the operation's " +
"team members must not let themselves be captured alive.",
baseDifficulty: 35e3,
reqdRank: 100e3,
rankGain: 2.5e3,
rankLoss: 500,
hpLoss: 1500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true,
});
BlackOperations["Operation Hyron"] = new BlackOperation({
name: "Operation Hyron",
desc:
"Our intelligence tells us that Fulcrum Technologies is developing " +
"a quantum supercomputer using human brains as core " +
"processors. This supercomputer " +
"is rumored to be able to store vast amounts of data and " +
"perform computations unmatched by any other supercomputer on the " +
"planet. But more importantly, the use of organic human brains " +
"means that the supercomputer may be able to reason abstractly " +
"and become self-aware.<br><br>" +
"I do not need to remind you why sentient-level AIs pose a serious " +
"threat to all of mankind.<br><br>" +
"The research for this project is being conducted at one of Fulcrum " +
"Technologies secret facilities in Aevum, codenamed 'Alpha Ranch'. " +
"Infiltrate the compound, delete and destroy the work, and then find and kill the " +
"project lead.",
baseDifficulty: 40e3,
reqdRank: 125e3,
rankGain: 3e3,
rankLoss: 1e3,
hpLoss: 500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Morpheus"] = new BlackOperation({
name: "Operation Morpheus",
desc:
"DreamSense Technologies is an advertising company that uses " +
"special technology to transmit their ads into the peoples " +
"dreams and subconcious. They do this using broadcast transmitter " +
"towers. Based on information from our agents and informants in " +
"Chonqging, we have reason to believe that one of the broadcast " +
"towers there has been compromised by Synthoids and is being used " +
"to spread pro-Synthoid propaganda.<br><br>" +
"The mission is to destroy this broadcast tower. Speed and " +
"stealth are of the upmost important for this.",
baseDifficulty: 45e3,
reqdRank: 150e3,
rankGain: 4e3,
rankLoss: 1e3,
hpLoss: 100,
weights: {
hack: 0.05,
str: 0.15,
def: 0.15,
dex: 0.3,
agi: 0.3,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true,
});
BlackOperations["Operation Ion Storm"] = new BlackOperation({
name: "Operation Ion Storm",
desc:
"Our analysts have uncovered a gathering of MK-VI Synthoids " +
"that have taken up residence in the Sector-12 Slums. We " +
"don't know if they are rogue Synthoids from the Uprising, " +
"but we do know that they have been stockpiling " +
"weapons, money, and other resources. This makes them dangerous.<br><br>" +
"This is a full-scale assault operation to find and retire all of these " +
"Synthoids in the Sector-12 Slums.",
baseDifficulty: 50e3,
reqdRank: 175e3,
rankGain: 5e3,
rankLoss: 1e3,
hpLoss: 5000,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Annihilus"] = new BlackOperation({
name: "Operation Annihilus",
desc:
"Our superiors have ordered us to eradicate everything and everyone " +
"in an underground facility located in Aevum. They tell us " +
"that the facility houses many dangerous Synthoids and " +
"belongs to a terrorist organization called " +
"'The Covenant'. We have no prior intelligence about this " +
"organization, so you are going in blind.",
baseDifficulty: 55e3,
reqdRank: 200e3,
rankGain: 7.5e3,
rankLoss: 1e3,
hpLoss: 10e3,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Ultron"] = new BlackOperation({
name: "Operation Ultron",
desc:
"OmniTek Incorporated, the original designer and manufacturer of Synthoids, " +
"has notified us of a malfunction in their AI design. This malfunction, " +
"when triggered, causes MK-VI Synthoids to become radicalized and seek out " +
"the destruction of humanity. They say that this bug affects all MK-VI Synthoids, " +
"not just the rogue ones from the Uprising.<br><br>" +
"OmniTek has also told us they they believe someone has triggered this " +
"malfunction in a large group of MK-VI Synthoids, and that these newly-radicalized Synthoids " +
"are now amassing in Volhaven to form a terrorist group called Ultron.<br><br>" +
"Intelligence suggests Ultron is heavily armed and that their members are " +
"augmented. We believe Ultron is making moves to take control of " +
"and weaponize DeltaOne's Tactical High-Energy Satellite Laser Array (THESLA).<br><br>" +
"Your task is to find and destroy Ultron.",
baseDifficulty: 60e3,
reqdRank: 250e3,
rankGain: 10e3,
rankLoss: 2e3,
hpLoss: 10e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Centurion"] = new BlackOperation({
name: "Operation Centurion",
desc:
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)<br><br>" +
"Throughout all of humanity's history, we have relied on " +
"technology to survive, conquer, and progress. Its advancement became our primary goal. " +
"And at the peak of human civilization technology turned into " +
"power. Global, absolute power.<br><br>" +
"It seems that the universe is not without a sense of irony.<br><br>" +
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",
baseDifficulty: 70e3,
reqdRank: 300e3,
rankGain: 15e3,
rankLoss: 5e3,
hpLoss: 10e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
});
BlackOperations["Operation Vindictus"] = new BlackOperation({
name: "Operation Vindictus",
desc:
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)<br><br>" +
"The bits are all around us. The daemons that hold the Node " +
"together can manifest themselves in many different ways.<br><br>" +
"D)@#)($M)C0293c40($*)@#D0JUMP3Rm0C<*@#)*$)#02c94830c(#$*D)",
baseDifficulty: 75e3,
reqdRank: 350e3,
rankGain: 20e3,
rankLoss: 20e3,
hpLoss: 20e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
});
BlackOperations["Operation Daedalus"] = new BlackOperation({
name: "Operation Daedalus",
desc: "Yesterday we obeyed kings and bent our neck to emperors. " + "Today we kneel only to truth.",
baseDifficulty: 80e3,
reqdRank: 400e3,
rankGain: 40e3,
rankLoss: 10e3,
hpLoss: 100e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
});
})();

View File

@@ -0,0 +1,571 @@
import { BlackOperation } from "./BlackOperation";
import { IMap } from "../types";
export const BlackOperations: IMap<BlackOperation> = {};
(function () {
BlackOperations["Operation Typhoon"] = new BlackOperation({
name: "Operation Typhoon",
baseDifficulty: 2000,
reqdRank: 2.5e3,
rankGain: 50,
rankLoss: 10,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Zero"] = new BlackOperation({
name: "Operation Zero",
baseDifficulty: 2500,
reqdRank: 5e3,
rankGain: 60,
rankLoss: 15,
hpLoss: 50,
weights: {
hack: 0.2,
str: 0.15,
def: 0.15,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true,
});
BlackOperations["Operation X"] = new BlackOperation({
name: "Operation X",
baseDifficulty: 3000,
reqdRank: 7.5e3,
rankGain: 75,
rankLoss: 15,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Titan"] = new BlackOperation({
name: "Operation Titan",
baseDifficulty: 4000,
reqdRank: 10e3,
rankGain: 100,
rankLoss: 20,
hpLoss: 100,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Ares"] = new BlackOperation({
name: "Operation Ares",
baseDifficulty: 5000,
reqdRank: 12.5e3,
rankGain: 125,
rankLoss: 20,
hpLoss: 200,
weights: {
hack: 0,
str: 0.25,
def: 0.25,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Archangel"] = new BlackOperation({
name: "Operation Archangel",
baseDifficulty: 7500,
reqdRank: 15e3,
rankGain: 200,
rankLoss: 20,
hpLoss: 25,
weights: {
hack: 0,
str: 0.2,
def: 0.2,
dex: 0.3,
agi: 0.3,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Juggernaut"] = new BlackOperation({
name: "Operation Juggernaut",
baseDifficulty: 10e3,
reqdRank: 20e3,
rankGain: 300,
rankLoss: 40,
hpLoss: 300,
weights: {
hack: 0,
str: 0.25,
def: 0.25,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Red Dragon"] = new BlackOperation({
name: "Operation Red Dragon",
baseDifficulty: 12.5e3,
reqdRank: 25e3,
rankGain: 500,
rankLoss: 50,
hpLoss: 500,
weights: {
hack: 0.05,
str: 0.2,
def: 0.2,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation K"] = new BlackOperation({
name: "Operation K",
baseDifficulty: 15e3,
reqdRank: 30e3,
rankGain: 750,
rankLoss: 60,
hpLoss: 1000,
weights: {
hack: 0.05,
str: 0.2,
def: 0.2,
dex: 0.25,
agi: 0.25,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Deckard"] = new BlackOperation({
name: "Operation Deckard",
baseDifficulty: 20e3,
reqdRank: 40e3,
rankGain: 1e3,
rankLoss: 75,
hpLoss: 200,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Tyrell"] = new BlackOperation({
name: "Operation Tyrell",
baseDifficulty: 25e3,
reqdRank: 50e3,
rankGain: 1.5e3,
rankLoss: 100,
hpLoss: 500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Wallace"] = new BlackOperation({
name: "Operation Wallace",
baseDifficulty: 30e3,
reqdRank: 75e3,
rankGain: 2e3,
rankLoss: 150,
hpLoss: 1500,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Shoulder of Orion"] = new BlackOperation({
name: "Operation Shoulder of Orion",
baseDifficulty: 35e3,
reqdRank: 100e3,
rankGain: 2.5e3,
rankLoss: 500,
hpLoss: 1500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true,
});
BlackOperations["Operation Hyron"] = new BlackOperation({
name: "Operation Hyron",
baseDifficulty: 40e3,
reqdRank: 125e3,
rankGain: 3e3,
rankLoss: 1e3,
hpLoss: 500,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Morpheus"] = new BlackOperation({
name: "Operation Morpheus",
baseDifficulty: 45e3,
reqdRank: 150e3,
rankGain: 4e3,
rankLoss: 1e3,
hpLoss: 100,
weights: {
hack: 0.05,
str: 0.15,
def: 0.15,
dex: 0.3,
agi: 0.3,
cha: 0,
int: 0.05,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isStealth: true,
});
BlackOperations["Operation Ion Storm"] = new BlackOperation({
name: "Operation Ion Storm",
baseDifficulty: 50e3,
reqdRank: 175e3,
rankGain: 5e3,
rankLoss: 1e3,
hpLoss: 5000,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Annihilus"] = new BlackOperation({
name: "Operation Annihilus",
baseDifficulty: 55e3,
reqdRank: 200e3,
rankGain: 7.5e3,
rankLoss: 1e3,
hpLoss: 10e3,
weights: {
hack: 0,
str: 0.24,
def: 0.24,
dex: 0.24,
agi: 0.24,
cha: 0,
int: 0.04,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Ultron"] = new BlackOperation({
name: "Operation Ultron",
baseDifficulty: 60e3,
reqdRank: 250e3,
rankGain: 10e3,
rankLoss: 2e3,
hpLoss: 10e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
isKill: true,
});
BlackOperations["Operation Centurion"] = new BlackOperation({
name: "Operation Centurion",
baseDifficulty: 70e3,
reqdRank: 300e3,
rankGain: 15e3,
rankLoss: 5e3,
hpLoss: 10e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
});
BlackOperations["Operation Vindictus"] = new BlackOperation({
name: "Operation Vindictus",
baseDifficulty: 75e3,
reqdRank: 350e3,
rankGain: 20e3,
rankLoss: 20e3,
hpLoss: 20e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
});
BlackOperations["Operation Daedalus"] = new BlackOperation({
name: "Operation Daedalus",
baseDifficulty: 80e3,
reqdRank: 400e3,
rankGain: 40e3,
rankLoss: 10e3,
hpLoss: 100e3,
weights: {
hack: 0.1,
str: 0.2,
def: 0.2,
dex: 0.2,
agi: 0.2,
cha: 0,
int: 0.1,
},
decays: {
hack: 0.6,
str: 0.8,
def: 0.8,
dex: 0.8,
agi: 0.8,
cha: 0,
int: 0.75,
},
});
})();

View File

@@ -1,4 +1,4 @@
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../utils/JSONReviver";
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../utils/JSONReviver";
import { IBladeburner } from "./IBladeburner";
import { IActionIdentifier } from "./IActionIdentifier";
import { ActionIdentifier } from "./ActionIdentifier";
@@ -9,7 +9,7 @@ import { BlackOperation } from "./BlackOperation";
import { Operation } from "./Operation";
import { Contract } from "./Contract";
import { GeneralActions } from "./GeneralActions";
import { formatNumber } from "../../utils/StringHelperFunctions";
import { formatNumber } from "../utils/StringHelperFunctions";
import { Skills } from "./Skills";
import { Skill } from "./Skill";
import { City } from "./City";
@@ -17,21 +17,21 @@ import { IAction } from "./IAction";
import { IPlayer } from "../PersonObjects/IPlayer";
import { IRouter } from "../ui/Router";
import { ConsoleHelpText } from "./data/Help";
import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
import { getRandomInt } from "../utils/helpers/getRandomInt";
import { BladeburnerConstants } from "./data/Constants";
import { numeralWrapper } from "../ui/numeralFormat";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { addOffset } from "../../utils/helpers/addOffset";
import { addOffset } from "../utils/helpers/addOffset";
import { Faction } from "../Faction/Faction";
import { Factions, factionExists } from "../Faction/Factions";
import { calculateHospitalizationCost } from "../Hospital/Hospital";
import { redPillFlag } from "../RedPill";
import { dialogBoxCreate } from "../../utils/DialogBox";
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { Settings } from "../Settings/Settings";
import { Augmentations } from "../Augmentation/Augmentations";
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
import { getTimestamp } from "../../utils/helpers/getTimestamp";
import { getTimestamp } from "../utils/helpers/getTimestamp";
import { joinFaction } from "../Faction/FactionHelpers";
import { WorkerScript } from "../Netscript/WorkerScript";
@@ -1586,11 +1586,6 @@ export class Bladeburner implements IBladeburner {
create(): void {
this.contracts["Tracking"] = new Contract({
name: "Tracking",
desc:
"Identify and locate Synthoids. This contract involves reconnaissance " +
"and information-gathering ONLY. Do NOT engage. Stealth is of the utmost importance.<br><br>" +
"Successfully completing Tracking contracts will slightly improve your Synthoid population estimate for " +
"whatever city you are currently in.",
baseDifficulty: 125,
difficultyFac: 1.02,
rewardFac: 1.041,
@@ -1619,10 +1614,6 @@ export class Bladeburner implements IBladeburner {
});
this.contracts["Bounty Hunter"] = new Contract({
name: "Bounty Hunter",
desc:
"Hunt down and capture fugitive Synthoids. These Synthoids are wanted alive.<br><br>" +
"Successfully completing a Bounty Hunter contract will lower the population in your " +
"current city, and will also increase its chaos level.",
baseDifficulty: 250,
difficultyFac: 1.04,
rewardFac: 1.085,
@@ -1651,10 +1642,6 @@ export class Bladeburner implements IBladeburner {
});
this.contracts["Retirement"] = new Contract({
name: "Retirement",
desc:
"Hunt down and retire (kill) rogue Synthoids.<br><br>" +
"Successfully completing a Retirement contract will lower the population in your current " +
"city, and will also increase its chaos level.",
baseDifficulty: 200,
difficultyFac: 1.03,
rewardFac: 1.065,
@@ -1684,12 +1671,6 @@ export class Bladeburner implements IBladeburner {
this.operations["Investigation"] = new Operation({
name: "Investigation",
desc:
"As a field agent, investigate and identify Synthoid " +
"populations, movements, and operations.<br><br>Successful " +
"Investigation ops will increase the accuracy of your " +
"synthoid data.<br><br>" +
"You will NOT lose HP from failed Investigation ops.",
baseDifficulty: 400,
difficultyFac: 1.03,
rewardFac: 1.07,
@@ -1719,11 +1700,6 @@ export class Bladeburner implements IBladeburner {
});
this.operations["Undercover Operation"] = new Operation({
name: "Undercover Operation",
desc:
"Conduct undercover operations to identify hidden " +
"and underground Synthoid communities and organizations.<br><br>" +
"Successful Undercover ops will increase the accuracy of your synthoid " +
"data.",
baseDifficulty: 500,
difficultyFac: 1.04,
rewardFac: 1.09,
@@ -1754,7 +1730,6 @@ export class Bladeburner implements IBladeburner {
});
this.operations["Sting Operation"] = new Operation({
name: "Sting Operation",
desc: "Conduct a sting operation to bait and capture particularly " + "notorious Synthoid criminals.",
baseDifficulty: 650,
difficultyFac: 1.04,
rewardFac: 1.095,
@@ -1785,10 +1760,6 @@ export class Bladeburner implements IBladeburner {
});
this.operations["Raid"] = new Operation({
name: "Raid",
desc:
"Lead an assault on a known Synthoid community. Note that " +
"there must be an existing Synthoid community in your current city " +
"in order for this Operation to be successful.",
baseDifficulty: 800,
difficultyFac: 1.045,
rewardFac: 1.1,
@@ -1819,10 +1790,6 @@ export class Bladeburner implements IBladeburner {
});
this.operations["Stealth Retirement Operation"] = new Operation({
name: "Stealth Retirement Operation",
desc:
"Lead a covert operation to retire Synthoids. The " +
"objective is to complete the task without " +
"drawing any attention. Stealth and discretion are key.",
baseDifficulty: 1000,
difficultyFac: 1.05,
rewardFac: 1.11,
@@ -1854,10 +1821,6 @@ export class Bladeburner implements IBladeburner {
});
this.operations["Assassination"] = new Operation({
name: "Assassination",
desc:
"Assassinate Synthoids that have been identified as " +
"important, high-profile social and political leaders " +
"in the Synthoid communities.",
baseDifficulty: 1500,
difficultyFac: 1.06,
rewardFac: 1.14,
@@ -1900,7 +1863,7 @@ export class Bladeburner implements IBladeburner {
if (this.action.type !== ActionTypes["Idle"]) {
let msg = "Your Bladeburner action was cancelled because you started doing something else.";
if (this.automateEnabled) {
msg += `<br><br>Your automation was disabled as well. You will have to re-enable it through the Bladeburner console`;
msg += `<br /><br />Your automation was disabled as well. You will have to re-enable it through the Bladeburner console`;
this.automateEnabled = false;
}
if (!Settings.SuppressBladeburnerPopup) {
@@ -1997,6 +1960,18 @@ export class Bladeburner implements IBladeburner {
break;
}
}
const gen = [
"Training",
"Recruitment",
"FieldAnalysis",
"Field Analysis",
"Diplomacy",
"Hyperbolic Regeneration Chamber",
];
if (gen.includes(res.type)) {
res.type = "General";
}
if (res.type == null) {
res.type = "Idle";
}

View File

@@ -1,7 +1,7 @@
import { BladeburnerConstants } from "./data/Constants";
import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { addOffset } from "../../utils/helpers/addOffset";
import { getRandomInt } from "../utils/helpers/getRandomInt";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
import { addOffset } from "../utils/helpers/addOffset";
interface IChangePopulationByCountParams {
estChange: number;

View File

@@ -1,6 +1,6 @@
import { IBladeburner } from "./IBladeburner";
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 {
constructor(params: IActionParams | null = null) {

View File

@@ -1,54 +0,0 @@
import { Action } from "./Action";
import { IMap } from "../types";
export const GeneralActions: IMap<Action> = {};
(function () {
// General Actions
let actionName;
actionName = "Training";
GeneralActions[actionName] = new Action({
name: actionName,
desc:
"Improve your abilities at the Bladeburner unit's specialized training " +
"center. Doing this gives experience for all combat stats and also " +
"increases your max stamina.",
});
actionName = "Field Analysis";
GeneralActions[actionName] = new Action({
name: actionName,
desc:
"Mine and analyze Synthoid-related data. This improves the " +
"Bladeburner's unit intelligence on Synthoid locations and " +
"activities. Completing this action will improve the accuracy " +
"of your Synthoid population estimated in the current city.<br><br>" +
"Does NOT require stamina.",
});
actionName = "Recruitment";
GeneralActions[actionName] = new Action({
name: actionName,
desc:
"Attempt to recruit members for your Bladeburner team. These members " +
"can help you conduct operations.<br><br>" +
"Does NOT require stamina.",
});
actionName = "Diplomacy";
GeneralActions[actionName] = new Action({
name: actionName,
desc:
"Improve diplomatic relations with the Synthoid population. " +
"Completing this action will reduce the Chaos level in your current city.<br><br>" +
"Does NOT require stamina.",
});
actionName = "Hyperbolic Regeneration Chamber";
GeneralActions[actionName] = new Action({
name: actionName,
desc:
"Enter cryogenic stasis using the Bladeburner division's hi-tech Regeneration Chamber. " +
"This will slowly heal your wounds and slightly increase your stamina.<br><br>",
});
})();

View File

@@ -0,0 +1,33 @@
import { Action } from "./Action";
import { IMap } from "../types";
export const GeneralActions: IMap<Action> = {};
(function () {
// General Actions
let actionName;
actionName = "Training";
GeneralActions[actionName] = new Action({
name: actionName,
});
actionName = "Field Analysis";
GeneralActions[actionName] = new Action({
name: actionName,
});
actionName = "Recruitment";
GeneralActions[actionName] = new Action({
name: actionName,
});
actionName = "Diplomacy";
GeneralActions[actionName] = new Action({
name: actionName,
});
actionName = "Hyperbolic Regeneration Chamber";
GeneralActions[actionName] = new Action({
name: actionName,
});
})();

View File

@@ -18,7 +18,6 @@ export interface ISuccessChanceParams {
export interface IAction {
name: string;
desc: string;
// Difficulty scales with level. See getDifficulty() method
level: number;

View File

@@ -1,7 +1,7 @@
import { IBladeburner } from "./IBladeburner";
import { BladeburnerConstants } from "./data/Constants";
import { Action, IActionParams } from "./Action";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
export interface IOperationParams extends IActionParams {
reqdRank?: number;

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