Compare commits

..

343 Commits

Author SHA1 Message Date
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
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
Olivier Gagnon
74906cc9e6 0.54 build 2021-09-20 17:28:53 -04:00
hydroflame
483590ef8b Merge pull request #1309 from Nolshine/fix_status_message_position
change status-text-container's position to fixed
2021-09-20 17:27:11 -04:00
hydroflame
7cd821ef5e Merge pull request #1312 from Nolshine/options_menu_unnecessary_link
remove duplicate changelog link from options menu
2021-09-20 17:27:02 -04:00
Olivier Gagnon
5e48530e14 0.54 again 2021-09-20 17:26:47 -04:00
Olivier Gagnon
bb4de3f62c fix infiltration 2021-09-20 17:10:44 -04:00
Nolshine
bb546ef6e1 remove duplicate changelog link from options menu 2021-09-20 20:14:02 +01:00
Olivier Gagnon
9552ae3ef1 readd some used code 2021-09-20 13:53:04 -04:00
Nolshine
d1974a3e70 change status-text-container's position to fixed 2021-09-20 09:28:23 +01:00
hydroflame
e9b030c450 Merge pull request #1308 from Nolshine/fix_typo_in_prestige_js
fix typo in Prestige.js
2021-09-20 01:52:39 -04:00
Nolshine
dffc0c5858 fix typo in Prestige.js 2021-09-20 06:51:08 +01:00
Nolshine
a9c57e23a5 improve gang ascend modal 2021-09-20 06:47:13 +01:00
Olivier Gagnon
8db57d7e81 hotfix 2021-09-20 01:45:32 -04:00
Olivier Gagnon
34313e8100 fix create gang not working. 2021-09-20 01:24:39 -04:00
Olivier Gagnon
91c7ae53ef Factions screen in Mui 2021-09-20 01:18:20 -04:00
Olivier Gagnon
44d6845883 biuld 0.54.0 2021-09-20 00:38:05 -04:00
Olivier Gagnon
a3e624deba remove ns2 example doing DOM manip 2021-09-20 00:14:30 -04:00
Olivier Gagnon
7355f4212b no more console log 2021-09-19 23:30:46 -04:00
Olivier Gagnon
fb37f6b94d lint 2021-09-19 23:29:02 -04:00
Olivier Gagnon
4a3201cba3 update packagelock 2021-09-19 18:28:44 -04:00
hydroflame
48eb0df99f Merge pull request #1303 from Nolshine/fix_status_text_animation_not_resetting
fix status text animation not resetting properly
2021-09-19 18:28:28 -04:00
hydroflame
a282d5d7fd Merge pull request #1285 from threehams/fast-refresh
Add React Fast Refresh
2021-09-19 18:24:53 -04:00
Olivier Gagnon
3554da5a53 load a top level react node and everything else under it. 2021-09-19 18:22:52 -04:00
Olivier Gagnon
d78309f3b0 remove unused elements from index.html 2021-09-19 18:05:25 -04:00
Olivier Gagnon
9bc20526ff get loading screen inside GameRoot 2021-09-19 18:04:12 -04:00
Olivier Gagnon
7a2dd16092 Hacking missions inside GameRoot 2021-09-19 17:05:27 -04:00
Olivier Gagnon
0a2dbe66e4 character overview player hookd 2021-09-19 16:19:24 -04:00
Olivier Gagnon
dade51a26b re-enable arrows in sidebar categories. 2021-09-19 14:45:14 -04:00
Olivier Gagnon
505040137f added overview ui hooks 2021-09-19 14:39:34 -04:00
Nolshine
db31b70efc fix stats text animation not resetting properly 2021-09-19 10:22:27 +01:00
Olivier Gagnon
ce3898367c remove unused css file 2021-09-19 03:38:43 -04:00
Olivier Gagnon
cd0aa192f5 fix terminal not cancelling. 2021-09-19 03:29:36 -04:00
Olivier Gagnon
374b81ffae Rework tutorial 2021-09-19 03:13:49 -04:00
Olivier Gagnon
652428b164 merge master 2021-09-19 00:59:13 -04:00
hydroflame
93706d31ee Merge pull request #1300 from danielyxie/hf2
build terminal string parsing fix
2021-09-19 00:55:52 -04:00
Olivier Gagnon
38408294cc build terminal string parsing fix 2021-09-19 00:55:29 -04:00
Olivier Gagnon
023f2b8309 ITutorial in react 2021-09-19 00:46:39 -04:00
Olivier Gagnon
61e3959a25 Improve event emitter 2021-09-18 15:44:39 -04:00
Olivier Gagnon
4b6a6300f5 build dev 2021-09-18 13:33:15 -04:00
Olivier Gagnon
e5abf014b2 build dev 2021-09-18 13:29:01 -04:00
Olivier Gagnon
e087420519 build dev 2021-09-18 12:13:20 -04:00
Olivier Gagnon
e1a22016b5 build dev 2021-09-18 04:01:07 -04:00
Olivier Gagnon
bdfa4be71f build dev 2021-09-18 03:00:07 -04:00
Olivier Gagnon
eb2a44e213 build dev 2021-09-18 02:39:01 -04:00
Olivier Gagnon
23e8bc2e71 merge master 2021-09-18 02:38:15 -04:00
hydroflame
48cfa14366 Merge pull request #1298 from danielyxie/hotfix
fix terminal not saving state
2021-09-18 02:36:05 -04:00
Olivier Gagnon
aef4aac61a fix terminal not saving state 2021-09-18 02:34:59 -04:00
Olivier Gagnon
f545726980 build 2021-09-18 02:24:51 -04:00
Olivier Gagnon
9471e8d4a0 Merge branch 'master' into dev 2021-09-18 02:23:04 -04:00
hydroflame
c85ebe9ee2 Merge pull request #1297 from danielyxie/hotfix
Hotfix
2021-09-18 02:22:45 -04:00
Olivier Gagnon
b5d7b3c108 build 2021-09-18 02:22:34 -04:00
Olivier Gagnon
be9b595590 fix terminal wrap 2021-09-18 02:21:48 -04:00
Olivier Gagnon
eacf15b463 minor tweaks 2021-09-18 02:11:20 -04:00
Olivier Gagnon
425c998435 minor tweaks 2021-09-18 01:12:15 -04:00
Olivier Gagnon
549c8b61db minor tweaks 2021-09-18 01:06:37 -04:00
Olivier Gagnon
244e669b2b improvements on active scripts 2021-09-18 01:01:51 -04:00
Olivier Gagnon
6f20b0bc30 Added tree-like hierarchy to active scripts 2021-09-18 00:31:14 -04:00
hydroflame
d1cb5b313a Merge pull request #1294 from danielyxie/big-container
Active Scripts in Mui
2021-09-18 00:16:24 -04:00
Olivier Gagnon
1996deaf0a Active Scripts 2021-09-18 00:16:02 -04:00
Olivier Gagnon
907314e76b more work 2021-09-17 21:30:02 -04:00
hydroflame
f359fe661e Merge pull request #1291 from danielyxie/big-container
Big container
2021-09-17 19:46:30 -04:00
Olivier Gagnon
45f2f85a30 big work 2021-09-17 19:43:08 -04:00
hydroflame
fd55155fea Merge pull request #1289 from Tryneus/patch-1
Clarify that `commitCrime` returns milliseconds, not seconds
2021-09-17 12:12:27 -04:00
Tryneus
70205e06ee Clarify that commitCrime returns milliseconds, not seconds 2021-09-17 09:04:14 -07:00
Olivier Gagnon
1344a17482 Merge branch 'dev' into big-container 2021-09-17 03:09:42 -04:00
hydroflame
affc79a499 Merge pull request #1288 from danielyxie/dev
fix term issues
2021-09-17 03:08:42 -04:00
Olivier Gagnon
aa0008862c fix term issues 2021-09-17 03:08:15 -04:00
Olivier Gagnon
89ea9aaff5 oops 2021-09-17 02:58:02 -04:00
Olivier Gagnon
1883bea906 one big container ready 2021-09-17 02:31:19 -04:00
Olivier Gagnon
4a3658ea13 Merge branch 'dev' into big-container 2021-09-17 02:10:26 -04:00
hydroflame
812dec6cb2 Merge pull request #1287 from danielyxie/dev
Hotfix hacking missions failing.
2021-09-17 02:09:59 -04:00
Olivier Gagnon
19a73a2802 hotfix hacking missiong failing 2021-09-17 02:09:53 -04:00
Olivier Gagnon
92ec4785a9 fix hacking mission looking for a container 2021-09-17 02:07:08 -04:00
Olivier Gagnon
acd51e8328 work 2021-09-17 02:04:44 -04:00
David Edmondson
6013bacc60 Add fast-refresh 2021-09-16 20:52:38 -07:00
Olivier Gagnon
ff726afcd6 added icon to hide stats 2021-09-16 22:16:40 -04:00
Olivier Gagnon
cab823bcdf take less space in sidebar 2021-09-16 21:59:12 -04:00
hydroflame
2cb762184f Merge pull request #1283 from danielyxie/dev
New terminal
2021-09-16 21:54:07 -04:00
Olivier Gagnon
7837454f18 build new terminal for release 2021-09-16 21:53:42 -04:00
Olivier Gagnon
8e764a5524 re-add badges 2021-09-16 21:49:38 -04:00
Olivier Gagnon
757b38327f build 2021-09-16 21:31:29 -04:00
Olivier Gagnon
628572cf21 save button becomes gray when save is disabled 2021-09-16 21:23:03 -04:00
Olivier Gagnon
744f3bc067 fix megacorp factions not letting you join them after soft reset 2021-09-16 21:19:53 -04:00
Olivier Gagnon
195dff7c44 fix not being able to ctrlc the terminal 2021-09-16 21:03:14 -04:00
hydroflame
4bf3e5a2e4 Merge pull request #1282 from danielyxie/mui5
few more fixes
2021-09-16 20:52:00 -04:00
Olivier Gagnon
defaa2ccd6 few more fixes 2021-09-16 20:51:25 -04:00
hydroflame
6d70d9708f Merge pull request #1280 from danielyxie/mui5
Mui5
2021-09-16 20:14:47 -04:00
Olivier Gagnon
b6924d6889 better terminal scrolling 2021-09-16 20:14:09 -04:00
Olivier Gagnon
3fc46c8fc6 mui5 migration 2021-09-16 19:45:53 -04:00
Olivier Gagnon
d7a86ab8b9 upgrade to Mui5 2021-09-16 19:42:55 -04:00
Olivier Gagnon
407ed70ae3 mui5 2021-09-16 19:23:03 -04:00
Olivier Gagnon
a21c0f4a0b update packages 2021-09-16 18:15:04 -04:00
Olivier Gagnon
3acf965dad fix some bugs 2021-09-16 18:10:28 -04:00
Olivier Gagnon
0cf2e2469e fix game not loading 2021-09-16 18:10:28 -04:00
Olivier Gagnon
7ba37397dd small simplification 2021-09-16 18:10:28 -04:00
Olivier Gagnon
18f40a8d9f fix lint 2021-09-16 18:10:28 -04:00
Olivier Gagnon
22648df857 refactor temrinal input for more performace 2021-09-16 18:10:28 -04:00
Olivier Gagnon
07721e1cc5 got rid of some containers 2021-09-16 18:10:28 -04:00
Olivier Gagnon
b682a442fe terminal wrap but it's not perfect 2021-09-16 18:10:28 -04:00
Olivier Gagnon
4a5fb04d41 More work on terminal. 2021-09-16 18:10:28 -04:00
Olivier Gagnon
f628a18551 scan-analyze still doesnt work but at least its not full of html 2021-09-16 18:10:28 -04:00
Olivier Gagnon
1890f1fd44 fix terminal not printing the command you just ran. 2021-09-16 18:10:28 -04:00
Olivier Gagnon
34dda1f252 fix help 2021-09-16 18:10:28 -04:00
Olivier Gagnon
8e1d31423f where did build go? 2021-09-16 18:10:28 -04:00
Olivier Gagnon
05718e00ea mostly convert terminal to react 2021-09-16 18:10:28 -04:00
Olivier Gagnon
aba97d2baa move some stuff 2021-09-16 18:10:28 -04:00
Olivier Gagnon
f0f57150aa character overview in mui 2021-09-16 18:10:28 -04:00
Nolshine
088657f162 fix the error introduced by previous fix
skills and multipliers should now recalc correctly on both soft reset
and new bitnode.
2021-09-16 18:10:28 -04:00
Nolshine
302e105bdf fix typo 'supress' in options menu 2021-09-16 18:10:28 -04:00
Bart Koppelmans
867dd3ba91 Removed unnecessary question mark 2021-09-16 18:10:28 -04:00
Nolshine
5866f47151 convert Create Program to mui 2021-09-16 18:10:28 -04:00
Nolshine
5d9f9d2681 implement game delete confirmation modal 2021-09-16 18:10:28 -04:00
Olivier Gagnon
2922e42055 most terminal converted to ts 2021-09-16 18:10:28 -04:00
Bart Koppelmans
8097364242 Fixed corporation industry unnecessarily centering vertically
This gave some weird situations where the main information was too far down when creating many products.
2021-09-16 18:10:27 -04:00
Olivier Gagnon
ac80be1b40 electron build 2021-09-16 18:10:27 -04:00
hydroflame
bd26e2f9ca Merge pull request #1278 from danielyxie/hotfix
hotfix
2021-09-16 18:10:07 -04:00
Olivier Gagnon
3f447b7fa1 hotfix 2021-09-16 18:09:25 -04:00
hydroflame
206edd8df5 Merge pull request #1256 from danielyxie/dev
Fix import not working
2021-09-15 10:56:39 -04:00
Olivier Gagnon
e4e539c067 fix import not working 2021-09-15 10:56:21 -04:00
hydroflame
ff2d238ea4 Merge pull request #1254 from Nolshine/fix_script_log_positioning
fix script log box staying behind when scrolling
2021-09-15 10:54:42 -04:00
Olivier Gagnon
96dc1eb1f4 fix import 2021-09-15 10:54:05 -04:00
Nolshine
f393baaa82 fix script log box staying behind when scrolling 2021-09-15 07:55:11 +01:00
Olivier Gagnon
409cb53597 remove unused files 2021-09-15 01:35:19 -04:00
hydroflame
22bf958e2e Merge pull request #1253 from Nolshine/1242_enable_smartsupply_by_default
implement #1242
2021-09-14 22:06:31 -04:00
Nolshine
11a345dd66 implement #1242 2021-09-15 03:01:23 +01:00
hydroflame
4ca54dbe00 Merge pull request #1252 from danielyxie/dev
remove options from overview
2021-09-14 21:51:32 -04:00
Olivier Gagnon
63a4a30189 remove options from overview 2021-09-14 21:51:20 -04:00
hydroflame
56680d5b17 Merge pull request #1251 from danielyxie/dev
fix diagnostic file
2021-09-14 21:48:12 -04:00
Olivier Gagnon
4c15d4ef42 fix diagnostic file 2021-09-14 21:47:42 -04:00
hydroflame
55769b5005 Merge pull request #1250 from danielyxie/dev
rework options menu & fix terminal scrolling on added lines
2021-09-14 21:10:31 -04:00
Olivier Gagnon
684a254ac8 build terminal not scrolling properly with new lines 2021-09-14 21:09:46 -04:00
Olivier Gagnon
dc9b5c3341 rework options menu 2021-09-14 21:05:49 -04:00
hydroflame
ed461ccca5 Merge pull request #1247 from danielyxie/dev
contextually hide sidebar items
2021-09-14 15:23:28 -04:00
Olivier Gagnon
f895da118d contextually hide sidebar items 2021-09-14 15:23:16 -04:00
hydroflame
2833b881ea Merge pull request #1246 from danielyxie/dev
fix terminal scrolling
2021-09-14 14:55:03 -04:00
Olivier Gagnon
8a0f33daf0 fix terminal scrolling 2021-09-14 14:54:45 -04:00
hydroflame
2ba04a602e Merge pull request #1245 from danielyxie/dev
hide terminal scrollbar
2021-09-14 14:44:37 -04:00
Olivier Gagnon
cb3b5b10d7 hide terminal scrollbar 2021-09-14 14:44:23 -04:00
hydroflame
d9bdc5bf5f Merge pull request #1244 from danielyxie/dev
Remove options from new sidebar
2021-09-14 14:23:06 -04:00
Olivier Gagnon
25c4f9047f t push
Merge branch 'dev' of github.com:danielyxie/bitburner into dev
2021-09-14 14:22:49 -04:00
Olivier Gagnon
7e2fd52ae2 remove options from new sidebar 2021-09-14 14:22:40 -04:00
hydroflame
fd0b4f7b01 Merge pull request #1239 from Nolshine/1200_replace_text
address #1200
2021-09-14 14:16:43 -04:00
hydroflame
8ed9f8a64d Merge pull request #1243 from danielyxie/dev
New sidebar and fix BN6 end screen
2021-09-14 14:15:22 -04:00
Olivier Gagnon
89a85c73ec Fix popup boxes not on top 2021-09-14 14:15:05 -04:00
Olivier Gagnon
9adf69afbd fix BN6 end screen 2021-09-14 14:10:59 -04:00
Olivier Gagnon
2d463b60a0 litn 2021-09-13 22:27:43 -04:00
Olivier Gagnon
05fd85002c dev menu in mui 2021-09-13 20:37:35 -04:00
hydroflame
f8b9c50563 Merge pull request #1241 from danielyxie/dev
Add companyName to getPlayer
2021-09-13 17:12:40 -04:00
Olivier Gagnon
70cb4b215d Add companyName to getPlayer 2021-09-13 17:12:21 -04:00
Olivier Gagnon
8c2d6616e3 Merge branch 'dev' of github.com:danielyxie/bitburner into dev 2021-09-13 17:11:44 -04:00
hydroflame
ab29f249c1 Merge pull request #1240 from danielyxie/dev
Add companyName to getPlayer
2021-09-13 17:11:39 -04:00
Olivier Gagnon
e345edb74f add companyName to getPlayer 2021-09-13 17:11:02 -04:00
hydroflame
a991dbf54f Merge pull request #1237 from Nolshine/maintain_megacorp_membership_on_aug
maintain megacorp membership on aug
2021-09-13 15:52:03 -04:00
Nolshine
fe065d23eb address #1200 2021-09-13 20:51:16 +01:00
Nolshine
8e4e9dabd9 implement #1209 2021-09-13 20:39:25 +01:00
hydroflame
ae15caf45a Merge pull request #1235 from danielyxie/dev
Fix travel to s12 in list view
2021-09-13 14:44:07 -04:00
Olivier Gagnon
4ad5b06e19 fix travel to s12 on list world map 2021-09-13 14:43:23 -04:00
Olivier Gagnon
acc215cc61 Merge branch 'dev' of github.com:danielyxie/bitburner into dev 2021-09-13 14:02:17 -04:00
hydroflame
e52a2b19e8 Merge pull request #1234 from Nolshine/fix_bitnodes_stats_not_updating
Fix bitnodes stats not updating
2021-09-13 12:59:20 -04:00
Olivier Gagnon
8fba57fd24 mui v1 2021-09-13 12:44:46 -04:00
Nolshine
8ec585e0b6 fix #1233 2021-09-13 09:34:39 +01:00
hydroflame
38cf4bd3cd Merge pull request #1226 from threehams/corp-overview-perf
Stop remounting components on every render on corp overview
2021-09-13 00:22:01 -04:00
hydroflame
4412a8e5b0 Merge pull request #1232 from danielyxie/dev
fix bn12 missing
2021-09-12 23:43:44 -04:00
Olivier Gagnon
0ed93ec0a5 fix bn12 missing 2021-09-12 23:43:28 -04:00
hydroflame
dadd4fe03d Merge pull request #1231 from danielyxie/dev
All popups in react
2021-09-12 23:23:39 -04:00
Olivier Gagnon
83f785a791 build popups 2021-09-12 23:23:09 -04:00
Olivier Gagnon
d515db0842 remove some now unused files 2021-09-12 18:06:21 -04:00
Olivier Gagnon
5f8de7e426 bunch of react conversion 2021-09-12 18:03:07 -04:00
David Edmondson
2f2923dd8b Stop remounting on corp overview
Make upgrade buttons real buttons
2021-09-12 09:39:15 -07:00
Olivier Gagnon
b8b0948a1a Casino record loss 2021-09-11 23:42:53 -04:00
Olivier Gagnon
d84d93ad3b Blackjack record loss 2021-09-11 23:41:56 -04:00
hydroflame
1b63f833be Merge pull request #1230 from danielyxie/dev
fix tooltip cut off
2021-09-11 23:36:30 -04:00
Olivier Gagnon
752a330735 fix tooltip cut off 2021-09-11 23:36:18 -04:00
hydroflame
4480423b7f Merge pull request #1229 from danielyxie/dev
fix faction scrolling
2021-09-11 23:29:21 -04:00
Olivier Gagnon
a9c80f0691 fix faction scrolling 2021-09-11 23:29:04 -04:00
hydroflame
5b4bc0a68f Merge pull request #1227 from danielyxie/dev
fix faction invitations
2021-09-11 17:24:46 -04:00
Olivier Gagnon
1a5651ae8b fix faction invitations 2021-09-11 17:23:56 -04:00
hydroflame
3b314f5d1d Merge pull request #1225 from danielyxie/dev
Fix scrolling and pages display
2021-09-11 13:25:00 -04:00
Olivier Gagnon
aeb0a7d3e3 Fix new sidebar and pages 2021-09-11 13:24:23 -04:00
Olivier Gagnon
75af7a096b script editor take more space 2021-09-11 12:58:39 -04:00
Olivier Gagnon
7ac1d24d61 fix scrit editor 2021-09-11 12:58:05 -04:00
Olivier Gagnon
e79ea4d3cb text editor is squished 2021-09-11 12:56:08 -04:00
Olivier Gagnon
b9dcffdf58 re-introduce the css that was there before 2021-09-11 12:51:46 -04:00
Olivier Gagnon
8d1adff2ae get rid of scrollbar for pages 2021-09-11 12:42:41 -04:00
Olivier Gagnon
2c427b1116 better scrolling 2021-09-11 12:28:31 -04:00
Olivier Gagnon
42aa4ca23f Merge branch 'dev' of github.com:danielyxie/bitburner into dev 2021-09-11 12:24:14 -04:00
Olivier Gagnon
dd27158cf0 make things scrollable. 2021-09-11 12:24:09 -04:00
hydroflame
1593b0b3f3 Merge pull request #1223 from vmesecher/dev
Adds CreateGangPopup React element.
2021-09-11 12:07:56 -04:00
vmesecher
705b154f13 Adds CreateGangPopup React element. 2021-09-11 09:02:59 -07:00
Olivier Gagnon
1edcbe88ee rewrite travel popup 2021-09-11 03:19:52 -04:00
Olivier Gagnon
609ba34804 build a few fixes 2021-09-11 02:32:15 -04:00
Olivier Gagnon
99e82cd867 few fixes in the purchase server popup 2021-09-11 02:16:14 -04:00
hydroflame
bc33f67409 Merge pull request #1210 from vmesecher/dev
Changes PurchaseServerPopup to a React element. Small CSS changes on popups.
2021-09-11 02:12:32 -04:00
hydroflame
224463e6dd Merge branch 'dev' into dev 2021-09-11 02:12:28 -04:00
Olivier Gagnon
02fd09c5d3 re-introduce badges 2021-09-11 02:11:41 -04:00
Olivier Gagnon
33aeeb7977 fix dev menu 2021-09-11 01:58:01 -04:00
Olivier Gagnon
add19d353e sidebar is react, fix a few bugs 2021-09-11 01:54:19 -04:00
Olivier Gagnon
4bedf05b1c refactored a bunch of engine.jsx, now all the react container load into the same div 2021-09-10 17:29:07 -04:00
Olivier Gagnon
5f64187a0f dev menu in react 2021-09-10 16:57:05 -04:00
Olivier Gagnon
339d9a8d96 more cleanup in engine 2021-09-10 16:08:58 -04:00
Olivier Gagnon
b45ab657c5 unify the way engine loads pages 2021-09-10 15:08:51 -04:00
Olivier Gagnon
c9611cc824 delete workflows 2021-09-10 12:30:41 -04:00
Olivier Gagnon
4b051468ad all research tooltip are always visible 2021-09-10 12:26:53 -04:00
Olivier Gagnon
9df926427b fix formatting of sleeve task description 2021-09-10 12:20:24 -04:00
vmesecher
8460df99df Changes PurchaseServerPopup to a React element. Small CSS changes on popups. 2021-09-10 01:49:24 -07:00
Olivier Gagnon
dc890a908b gang member popup styling 2021-09-10 02:35:41 -04:00
Olivier Gagnon
e5dcb424a2 sneak in corp API. 2021-09-10 02:17:55 -04:00
Olivier Gagnon
e906a6331f change modals so they close on mouse down outside the box 2021-09-10 00:53:39 -04:00
hydroflame
c4617e4b9a Merge pull request #1203 from danielyxie/corp-api
corp api
2021-09-10 00:15:02 -04:00
Olivier Gagnon
76404dd83a fix mc 2021-09-10 00:14:53 -04:00
Olivier Gagnon
be08161442 corp api 2021-09-10 00:13:28 -04:00
hydroflame
f93ee45254 Merge pull request #1202 from danielyxie/revert-1185-jest-cypress-types
Revert "Jest cypress types"
2021-09-10 00:13:16 -04:00
hydroflame
7e8e9e03fc Revert "Jest cypress types" 2021-09-10 00:13:03 -04:00
hydroflame
715bc541ec Merge pull request #1185 from threehams/jest-cypress-types
Jest cypress types
2021-09-09 22:58:17 -04:00
David Edmondson
0bc9bfb0f2 Update jest 2021-09-08 22:13:47 -07:00
David Edmondson
5cd72860e3 Add to CONTRIBUTING doc 2021-09-08 22:13:47 -07:00
David Edmondson
e44813b65d Only include jest tests in jest
Don't generate sourcemaps for TS
Remove github actions
2021-09-08 22:13:47 -07:00
David Edmondson
3473fc2ea6 Revert "fix tests"
This reverts commit 82c3362adc.
2021-09-08 22:13:46 -07:00
David Edmondson
0c0adf29d5 Separate src, test, cypress 2021-09-08 22:12:23 -07:00
618 changed files with 40390 additions and 37973 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

@@ -63,7 +63,6 @@ module.exports = {
"id-blacklist": ["error"],
"id-length": ["off"],
"id-match": ["error"],
"implicit-arrow-linebreak": ["error", "beside"],
indent: ["off"],
"indent-legacy": ["off"],
"init-declarations": ["off"],

View File

@@ -1,31 +0,0 @@
name: CI
on:
push:
branches: [dev]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- name: Install Dependencies
run: npm ci
- name: Test
run: npm run test
- name: Build
run: npm run build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: .

View File

@@ -1,25 +0,0 @@
name: CI
on: [push, pull_request]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
test:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- name: Install Dependencies
run: npm ci
- name: Test
run: npm run test

5
.gitignore vendored
View File

@@ -1,3 +1,4 @@
.DS_Store
.vscode
Changelog.txt
Netburner.txt
@@ -9,5 +10,9 @@ Netburner.txt
/test/*.css
.cypress
# tmp folder for electron
.package
.build
# editor files
.vscode

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: top;
}

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,132 +0,0 @@
@import "theme";
.active-scripts-list {
list-style-type: none;
}
#active-scripts-container {
position: fixed;
padding-top: 10px;
> p {
width: 70%;
margin: 6px;
padding: 4px;
}
.accordion-header {
> pre {
color: white;
}
}
}
.active-scripts-server-header {
background-color: #444;
font-size: $defaultFontSize * 1.25;
color: #fff;
margin: 6px 6px 0 6px;
padding: 6px;
cursor: pointer;
width: 60%;
text-align: left;
border: none;
outline: none;
&:after {
content: "\02795"; /* "plus" sign (+) */
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
}
&.active,
&:hover {
background-color: #555;
}
}
.active-scripts-server-header.active {
&:after {
content: "\2796"; /* "minus" sign (-) */
font-size: $defaultFontSize * 0.8125;
color: #fff;
float: right;
margin-left: 5px;
}
&:hover {
background-color: #666;
}
}
.active-scripts-server-panel {
margin: 0 6px 6px 6px;
padding: 0 6px 6px 6px;
width: 55%;
margin-left: 5%;
display: none;
div,
ul,
ul > li {
background-color: #555;
}
}
.active-scripts-script-header {
background-color: #555;
border: none;
color: var(--my-font-color);
cursor: pointer;
display: block;
outline: none;
padding: 4px 25px 4px 10px;
position: relative;
text-align: left;
width: auto;
&:after {
content: "\02795"; /* "plus" sign (+) */
font-size: $defaultFontSize * 0.8125;
float: right;
margin-left: 5px;
color: transparent;
text-shadow: 0 0 0 var(--my-font-color);
position: absolute;
bottom: 4px;
}
&.active:after {
content: "\2796"; /* "minus" sign (-) */
}
&:hover,
&.active:hover {
background-color: #666;
}
&.active {
background-color: #555;
}
}
.active-scripts-script-panel {
background-color: #555;
display: none;
font-size: 14px;
margin-bottom: 6px;
padding: 0 18px;
width: auto;
pre,
h2,
ul,
li {
background-color: #555;
width: auto;
color: #fff;
margin-left: 5%;
}
}

View File

@@ -1,30 +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-container {
position: fixed;
padding-top: 10px;
}
#augmentations-content {
> p {
font-size: $defaultFontSize * 0.875;
width: 70%;
}
}
.augmentations-list {
button,
div {
color: var(--my-font-color);
text-decoration: none;
}
button {
padding: 4px;
}
}

View File

@@ -1,137 +0,0 @@
@import "theme";
#bladeburner-container {
position: fixed;
padding: 6px;
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,122 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the Character Overview Panel (top-right panel)
*/
#character-overview-wrapper {
position: relative;
}
#character-overview-container {
display: none;
position: absolute; /* Stay in place */
right: 0;
top: 0;
height: auto; /* Full height */
padding: 10px 2px;
border: 2px solid var(--my-highlight-color);
width: auto;
max-width: 280px;
overflow: auto; /* Enable scroll if needed */
background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
z-index: 1;
}
#character-overview-text {
color: $my-stat-physical;
table {
border-collapse: collapse;
margin: auto;
}
td {
padding: 2px;
vertical-align: middle;
}
}
.character-stat-text {
color: #fff;
background-color: #444;
}
.character-stat-cell {
text-align: right;
}
#character-str-wrapper td,
#character-cha-wrapper td {
padding-top: 10px;
}
.character-divider td {
border-top: 1px #aaa solid;
padding-top: 10px;
}
#character-hp-wrapper {
color: $my-stat-hp-color;
}
.character-hp-cell {
color: $my-stat-hp-color;
}
#character-money-wrapper {
color: $my-stat-money-color;
}
.character-money-cell {
color: $my-stat-money-color;
}
#character-hack-wrapper {
color: $my-stat-hack-color;
}
.character-hack-cell {
color: $my-stat-hack-color;
}
#character-cha-wrapper {
color: $my-stat-cha-color;
}
.character-cha-cell {
color: $my-stat-cha-color;
}
#character-int-wrapper {
color: $my-stat-int-color;
}
.character-int-cell {
color: $my-stat-int-color;
}
.character-combat-cell {
color: $my-stat-physical;
}
#character-work-wrapper {
color: $my-stat-hack-color;
}
.character-work-cell {
color: $my-stat-hack-color;
}
.character-overview-btn {
@include borderRadius(12px);
@include boxShadow(1px 1px 3px #000);
color: #cecece;
display: inline-block;
font-size: $defaultFontSize * 0.875;
font-weight: bold;
height: 25px;
background-color: #000;
padding: 5px 8px;
}
.character-quick-options {
margin-top: 10px;
text-align: center;
}
.character-overview-btn:hover,
.character-overview-btn:focus {
color: #fff;
text-decoration: none;
cursor: pointer;
}

View File

@@ -1,49 +0,0 @@
@import "theme";
/**
* Customized styling for the Code Mirror editor
*/
#codemirror-form-wrapper {
height: 80%;
margin: 10px 0 0 6px;
}
.CodeMirror {
height: 100%;
width: 100%;
border: 2px solid var(--my-highlight-color);
z-index: 1;
font-family: $fontFamily;
font-size: $defaultFontSize;
}
/**
* Highlight matches
*/
.cm-matchhighlight {
background-color: #8f908a;
}
.CodeMirror-selection-highlight-scrollbar {
background-color: #8f908a;
}
/**
* Show Invisibles
*/
.cm-whitespace::before {
position: absolute;
pointer-events: none;
color: #404f7d;
}
/**
* Vim command display
*/
#codemirror-vim-command-display-wrapper {
background-color: white;
font-size: 13px;
height: 30px;
margin-left: 6px;
}

View File

@@ -1,165 +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%;
}
.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 {
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,4 +0,0 @@
#corporation-container {
position: fixed;
padding: 6px;
}

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,49 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the Gang mechanic UI (BitNode-2)
*/
#gang-container {
position: fixed;
padding: 6px;
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,75 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for the Hacknet Nodes UI Page
*/
#hacknet-nodes-container {
position: fixed;
padding: 10px;
}
.hacknet-general-info {
margin: 10px;
width: 70vw;
}
#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: absolute; /* 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: #6f3;
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,135 +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;
}
#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 {
max-height: 0;
opacity: 1;
transition: max-height 0.2s ease-out;
}

View File

@@ -1,155 +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-menupage-container {
height: 100%;
padding-left: 10px;
margin-left: 10%;
width: 99%;
overflow-y: scroll;
}
/* Character Info */
#character-container {
padding-top: 10px;
position: fixed;
}
/* World */
#world-container {
position: fixed;
padding-top: 10px;
}
#world-city-name,
#world-city-desc {
padding: 4px;
margin: 4px;
}
/* Create program */
#create-program-container {
position: fixed;
padding-top: 10px;
}
#create-program-page-text,
#create-program-list {
width: 70%;
}
/* Factions and Faction (Single Faction page) */
#factions-container {
position: fixed;
padding-top: 10px;
}
#faction-container {
position: fixed;
padding-top: 10px;
}
.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,5 +0,0 @@
#milestones-container {
position: fixed;
padding: 6px;
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: 10; /* 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-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: absolute;
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 {
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;
}
/* Generic Yes No Box */
#yes-no-text-input-box-input {
color: #fff;
}
/* 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,33 +0,0 @@
/**
* Styling for the Re-Sleeving Page
*/
@import "theme";
#resleeve-container {
position: fixed;
padding: 6px;
}
.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,107 +0,0 @@
@import "mixins";
@import "theme";
/**
* Styling for Script Editor (both Ace and CodeMirror)
*/
#script-editor-container {
background-color: transparent;
}
/* This temp element is used for auto adjusting filename field */
.tmp-element {
visibility: hidden;
white-space: pre;
}
#script-editor-container {
position: fixed;
padding-top: 10px;
}
#script-editor-buttons-wrapper {
width: 100%;
padding-right: 0;
margin-right: 0;
}
#script-editor-wrapper {
height: 100%;
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,30 +0,0 @@
/**
* Styling for the Sleeves Management page
*/
@import "theme";
#sleeves-container {
position: fixed;
padding: 6px;
}
.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;
}
}

View File

@@ -1,99 +0,0 @@
@import "theme";
#stock-market-container {
position: fixed;
padding: 6px;
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,503 +0,0 @@
@import "mixins";
@import "theme";
@import "reset";
:root {
--my-font-color: #6f3;
--my-background-color: #000;
--my-highlight-color: #fff;
--my-prompt-color: #f92672;
}
body {
background-color: var(--my-background-color);
}
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;
}
.notification-off {
background-color: #333;
color: #333;
border-radius: 0;
padding: 0;
}
/* 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: absolute;
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,72 +0,0 @@
@import "theme";
#terminal-container {
position: fixed;
margin-left: 10%;
height: 100%;
width: 99%;
overflow: auto;
overflow-y: scroll;
}
#terminal {
padding-top: 10px;
padding-left: 10px;
height: auto;
width: 70%;
font-size: $defaultFontSize;
overflow: auto;
overflow-y: scroll;
background-color: var(--my-background-color);
table-layout: fixed;
.prompt {
color: var(--my-prompt-color);
margin: 0;
padding: 0;
}
}
#terminal-input {
background-color: var(--my-background-color);
color: var(--my-font-color);
transition: height 1s;
}
.terminal-input {
display: inline-block;
padding: 0 !important;
margin: 0 !important;
border: 0;
background-color: var(--my-background-color);
font-size: $defaultFontSize;
outline: none;
color: var(--my-font-color);
}
.terminal-line {
width: 70%;
word-wrap: break-word;
hyphens: auto;
-webkit-hyphens: auto;
-moz-hyphens: auto;
}
#terminal-input-td {
display: flex;
}
#terminal-input-td textarea {
overflow: hidden;
resize: none;
height: auto;
}
#terminal-input-header {
white-space: pre;
}
#terminal-input-text-box {
margin-left: 2px;
flex: 1 1 auto;
}

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;
}

View File

@@ -4,5 +4,7 @@
"trashAssetsBeforeRuns": true,
"screenshotsFolder": ".cypress/screenshots",
"videosFolder": ".cypress/videos",
"videoUploadOnPasses": false
"videoUploadOnPasses": false,
"viewportWidth": 1980,
"viewportHeight": 1080
}

View File

@@ -0,0 +1,73 @@
export {};
describe("netscript", () => {
it("Do naviguation", () => {
cy.findByRole("button", { name: "SKIP TUTORIAL" }).click();
cy.findByText("Got it!").click();
cy.findByText("Dev").click();
cy.findByText(/Source-Files/i).click();
cy.findByLabelText(/all-sf-3/i).click();
cy.findByText(/Experience/i).click();
cy.findByText(/Tons of exp/i).click();
cy.findByText(/General/i).click();
cy.findByText(/Hack w0/i).click();
cy.findByText(/SEMPOOL INVALID/i);
cy.findByText(/Many decades/i, { timeout: 15000 });
cy.findByLabelText("enter-bitnode-1").click();
cy.findByText(/Enter BN1.2/i).click();
cy.get("body").type("{esc}");
cy.findByText("Dev").click();
cy.findByText(/Experience/i).click();
cy.findByText(/Tons of exp/i).click();
cy.findByText("Create Script").click();
cy.findByText(/Script name:/i);
cy.findByText("Active Scripts").click();
cy.findByText(/Total online production of/i);
cy.findByText("Create Program").click();
cy.findByText(/This page displays/i);
cy.findByText("Stats").click();
cy.findByText(/Current City:/i);
cy.findByText("Factions").click();
cy.findByText(/Lists all/i);
cy.findByText("Augmentations").click();
cy.findByText(/Purchased Augmentations/i);
cy.findByText("Hacknet").click();
cy.findByText(/The Hacknet is a global/i);
cy.findByText("Sleeves").click();
cy.findByText(/Duplicate Sleeves are MK/i);
cy.findByText("City").click();
cy.findByText(/Sector-12/i);
cy.findByLabelText("The Slums").click();
cy.findByText("City").click();
cy.findByLabelText("Powerhouse Gym").click();
cy.findByText("City").click();
cy.findByLabelText("MegaCorp").click();
cy.findByText("Travel").click();
cy.findByText(/Travel Agency/i);
cy.findByText("Stock Market").click();
cy.findByText(/ECorp/i);
cy.findByText("Milestones").click();
cy.findByText(/don't reward you for/i);
cy.findByText("Tutorial").click();
cy.findByText(/AKA Links to/i);
cy.findByText("Options").click();
cy.findByText(/Netscript exec time/i);
});
});

View File

@@ -2,7 +2,7 @@ export {};
describe("netscript", () => {
it("creates and runs a NetScript 2.0 script", () => {
cy.findByRole("button", { name: "Exit Tutorial" }).click();
cy.findByRole("button", { name: "SKIP TUTORIAL" }).click();
cy.findByText("Got it!").click();
cy.findByRole("textbox").type("connect n00dles{enter}");
@@ -32,7 +32,7 @@ describe("netscript", () => {
});
it("errors and shows a dialog box when static RAM !== dynamic RAM", () => {
cy.findByRole("button", { name: "Exit Tutorial" }).click();
cy.findByRole("button", { name: "SKIP TUTORIAL" }).click();
cy.findByText("Got it!").click();
cy.findByRole("textbox").type("nano script.js{enter}");

View File

@@ -3,19 +3,19 @@ export {};
describe("tutorial", () => {
it("completes the tutorial", () => {
cy.findByText(/dark, dystopian future/);
cy.findByRole("button", { name: "Next" }).click();
cy.findByRole("button", { name: "next" }).click();
cy.findByText(/heading to the Stats page/);
cy.findByRole("button", { name: "Stats" }).click();
cy.findByText(/lot of important information/);
cy.findByRole("button", { name: "Next" }).click();
cy.findByRole("button", { name: "next" }).click();
cy.findByText(/head to your computer's terminal/);
cy.findByRole("button", { name: "Terminal" }).click();
cy.findByText(/is used to interface/);
cy.findByRole("button", { name: "Next" }).click();
cy.findByRole("button", { name: "next" }).click();
cy.findByText(/Let's try it out/i);
cy.findByRole("textbox").type("help{enter}");
@@ -29,7 +29,7 @@ describe("tutorial", () => {
cy.findByText(/that's great and all/i);
cy.findByRole("textbox").type("scan-analyze{enter}");
cy.findByText(/this command shows more detailed information/i);
cy.findByText(/shows more detailed information/i);
cy.findByRole("textbox").type("scan-analyze 2{enter}");
cy.findByText(/now you can see information/i);
@@ -46,10 +46,11 @@ describe("tutorial", () => {
cy.findByRole("textbox").type("hack{enter}");
cy.findByText(/now attempting to hack the server/i);
cy.findByRole("button", { name: "Next" }).click();
cy.findByRole("button", { name: "next" }).click();
cy.findByText(/hacking exp/i);
cy.findByRole("textbox", { timeout: 15_000 }).should("not.be.disabled").type("nano n00dles.script{enter}");
cy.findByRole("textbox", { timeout: 15_000 }).should("not.be.disabled").type("home{enter}");
cy.findByRole("textbox").type("nano n00dles.script{enter}");
// monaco can take a bit
cy.findByRole("code", { timeout: 15_000 }).type("{selectall}{del}").type("while(true) {{}{enter}hack('n00dles');");
@@ -59,7 +60,7 @@ describe("tutorial", () => {
cy.findByText(/now we'll run the script/i);
cy.findByRole("textbox").type("free{enter}");
cy.findByText(/We have 4GB of free RAM on this machine/i);
cy.findByText(/We have 8GB of free RAM on this machine/i);
cy.findByRole("textbox").type("run n00dles.script{enter}");
cy.findByText(/Your script is now running/i);
@@ -72,7 +73,7 @@ describe("tutorial", () => {
cy.findByRole("textbox").type("tail n00dles.script{enter}");
cy.findByText(/The log for this script won't show much/i);
cy.findByRole("button", { name: "Next" }).click();
cy.findByRole("button", { name: "next" }).click();
cy.findByText(/Hacking is not the only way to earn money/i);
cy.findByRole("button", { name: "Hacknet" }).click();
@@ -87,7 +88,7 @@ describe("tutorial", () => {
cy.findByRole("button", { name: "Tutorial" }).click();
cy.findByText(/a lot of different documentation about the game/i);
cy.findByRole("button", { name: "Finish Tutorial" }).click();
cy.findByRole("button", { name: "FINISH TUTORIAL" }).click();
cy.findByText("Got it!").click();
cy.findByText(/Tutorial \(AKA Links to Documentation\)/i);

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],a=0,s=[];a<f.length;a++)i=f[a],Object.prototype.hasOwnProperty.call(u,i)&&u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(p&&p(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={2:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var p=c;r.push([905,0]),o()}({905:function(n,t,o){"use strict";o.r(t);o(906),o(908),o(910),o(912),o(914),o(916),o(918),o(920),o(922),o(924),o(926),o(928),o(930),o(932),o(934),o(936),o(938),o(940),o(942),o(944),o(946),o(948),o(950),o(952),o(954),o(956),o(958),o(960),o(962),o(964),o(966),o(968),o(970)},908:function(n,t,o){},910:function(n,t,o){},912:function(n,t,o){},914:function(n,t,o){},916:function(n,t,o){},918:function(n,t,o){},920:function(n,t,o){},922:function(n,t,o){},924:function(n,t,o){},926:function(n,t,o){},928:function(n,t,o){},930:function(n,t,o){},932:function(n,t,o){},934:function(n,t,o){},936:function(n,t,o){},938:function(n,t,o){},940:function(n,t,o){},942:function(n,t,o){},944:function(n,t,o){},946:function(n,t,o){},948:function(n,t,o){},950:function(n,t,o){},952:function(n,t,o){},954:function(n,t,o){},956:function(n,t,o){},958:function(n,t,o){},960:function(n,t,o){},962:function(n,t,o){},964:function(n,t,o){},966:function(n,t,o){},968:function(n,t,o){},970:function(n,t,o){}});
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],a=0,s=[];a<f.length;a++)i=f[a],Object.prototype.hasOwnProperty.call(r,i)&&r[i]&&s.push(r[i][0]),r[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(p&&p(t);s.length;)s.shift()();return u.push.apply(u,l||[]),o()}function o(){for(var n,t=0;t<u.length;t++){for(var o=u[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==r[c]&&(e=!1)}e&&(u.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},r={2:0},u=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var p=c;u.push([1281,0]),o()}({1281:function(n,t,o){"use strict";o.r(t);o(1282),o(1284),o(1286),o(1288),o(1290),o(1292),o(1294),o(1296),o(1298),o(1300),o(1302),o(1304),o(1306),o(1308),o(1310),o(1312),o(1314),o(1316),o(1318),o(1320),o(1322),o(1324),o(1326),o(1328),o(1330),o(1332),o(1334),o(1336),o(1338),o(1340)},1284:function(n,t,o){},1286:function(n,t,o){},1288:function(n,t,o){},1290:function(n,t,o){},1292:function(n,t,o){},1294:function(n,t,o){},1296:function(n,t,o){},1298:function(n,t,o){},1300:function(n,t,o){},1302:function(n,t,o){},1304:function(n,t,o){},1306:function(n,t,o){},1308:function(n,t,o){},1310:function(n,t,o){},1312:function(n,t,o){},1314:function(n,t,o){},1316:function(n,t,o){},1318:function(n,t,o){},1320:function(n,t,o){},1322:function(n,t,o){},1324:function(n,t,o){},1326:function(n,t,o){},1328:function(n,t,o){},1330:function(n,t,o){},1332:function(n,t,o){},1334:function(n,t,o){},1336:function(n,t,o){},1338:function(n,t,o){},1340:function(n,t,o){}});
//# sourceMappingURL=engineStyle.bundle.js.map

544
dist/engineStyle.css vendored
View File

@@ -12,16 +12,24 @@
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: top; }
vertical-align: middle; }
:root {
--my-font-color: #6f3;
--my-font-color: #0c0;
--my-background-color: #000;
--my-highlight-color: #fff;
--my-prompt-color: #f92672; }
body {
background-color: var(--my-background-color); }
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,
@@ -105,13 +113,30 @@ a:visited {
background-color: #fa3e3e;
color: #fff;
border-radius: 2px;
padding: 1px 3px; }
padding: 1px 3px;
font-size: 10px;
top: 0;
right: 0;
position: absolute; }
.notification-off {
background-color: #333;
color: #333;
border-radius: 0;
padding: 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 {
@@ -545,16 +570,24 @@ input[type="checkbox"] {
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: top; }
vertical-align: middle; }
:root {
--my-font-color: #6f3;
--my-font-color: #0c0;
--my-background-color: #000;
--my-highlight-color: #fff;
--my-prompt-color: #f92672; }
body {
background-color: var(--my-background-color); }
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,
@@ -638,13 +671,30 @@ a:visited {
background-color: #fa3e3e;
color: #fff;
border-radius: 2px;
padding: 1px 3px; }
padding: 1px 3px;
font-size: 10px;
top: 0;
right: 0;
position: absolute; }
.notification-off {
background-color: #333;
color: #333;
border-radius: 0;
padding: 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 {
@@ -1121,6 +1171,9 @@ button {
.mainmenu > li button.active:hover {
background-color: #aaa; }
.menu-header {
position: relative; }
#hacking-menu-header-li,
#character-menu-header-li,
#world-menu-header-li,
@@ -1166,8 +1219,6 @@ button {
/* Slide down transition */
.mainmenu-accordion-panel {
max-height: 0;
opacity: 1;
transition: max-height 0.2s ease-out; }
/* COLORS */
@@ -1175,124 +1226,22 @@ button {
/**
* Styling for the Character Overview Panel (top-right panel)
*/
#character-overview-wrapper {
position: relative; }
#character-overview-container {
display: none;
position: absolute;
/* Stay in place */
right: 0;
#character-overview {
position: fixed;
top: 0;
height: auto;
/* Full height */
padding: 10px 2px;
border: 2px solid var(--my-highlight-color);
width: auto;
max-width: 280px;
overflow: auto;
/* Enable scroll if needed */
background-color: rgba(57, 54, 54, 0.9);
/* Fallback color */
z-index: 1; }
#character-overview-text {
color: #faffdf; }
#character-overview-text table {
border-collapse: collapse;
margin: auto; }
#character-overview-text td {
padding: 2px;
vertical-align: middle; }
.character-stat-text {
color: #fff;
background-color: #444; }
.character-stat-cell {
text-align: right; }
#character-str-wrapper td,
#character-cha-wrapper td {
padding-top: 10px; }
.character-divider td {
border-top: 1px #aaa solid;
padding-top: 10px; }
#character-hp-wrapper {
color: #dd3434; }
.character-hp-cell {
color: #dd3434; }
#character-money-wrapper {
color: #ffd700; }
.character-money-cell {
color: #ffd700; }
#character-hack-wrapper {
color: #adff2f; }
.character-hack-cell {
color: #adff2f; }
#character-cha-wrapper {
color: #a671d1; }
.character-cha-cell {
color: #a671d1; }
#character-int-wrapper {
color: #6495ed; }
.character-int-cell {
color: #6495ed; }
.character-combat-cell {
color: #faffdf; }
#character-work-wrapper {
color: #adff2f; }
.character-work-cell {
color: #adff2f; }
.character-overview-btn {
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-webkit-box-shadow: 1px 1px 3px #000;
-moz-box-shadow: 1px 1px 3px #000;
box-shadow: 1px 1px 3px #000;
color: #cecece;
display: inline-block;
font-size: 14px;
font-weight: bold;
height: 25px;
background-color: #000;
padding: 5px 8px; }
.character-quick-options {
margin-top: 10px;
text-align: center; }
.character-overview-btn:hover,
.character-overview-btn:focus {
color: #fff;
text-decoration: none;
cursor: pointer; }
right: 0; }
/* COLORS */
/* Attributes */
#terminal-container {
position: fixed;
margin-left: 10%;
height: 100%;
width: 99%;
overflow: auto;
overflow-y: scroll; }
overflow-y: scroll;
scrollbar-width: "none"; }
#terminal-container::-webkit-scrollbar {
display: none; }
#terminal {
padding-top: 10px;
@@ -1351,25 +1300,13 @@ button {
/**
* Styling for Script Editor (both Ace and CodeMirror)
*/
#script-editor-container {
background-color: transparent; }
/* This temp element is used for auto adjusting filename field */
.tmp-element {
visibility: hidden;
white-space: pre; }
#script-editor-container {
position: fixed;
padding-top: 10px; }
#script-editor-buttons-wrapper {
width: 100%;
padding-right: 0;
margin-right: 0; }
#script-editor-wrapper {
height: 100%;
.script-editor-wrapper {
height: 110vh;
width: 70%;
background: transparent; }
@@ -1437,164 +1374,13 @@ button {
align-items: center;
justify-content: start; }
/* COLORS */
/* Attributes */
/**
* Customized styling for the Code Mirror editor
*/
#codemirror-form-wrapper {
height: 80%;
margin: 10px 0 0 6px; }
.CodeMirror {
height: 100%;
width: 100%;
border: 2px solid var(--my-highlight-color);
z-index: 1;
font-family: "Lucida Console", "Lucida Sans Unicode", "Fira Mono", "Consolas", "Courier New", Courier, monospace, "Times New Roman";
font-size: 16px; }
/**
* Highlight matches
*/
.cm-matchhighlight {
background-color: #8f908a; }
.CodeMirror-selection-highlight-scrollbar {
background-color: #8f908a; }
/**
* Show Invisibles
*/
.cm-whitespace::before {
position: absolute;
pointer-events: none;
color: #404f7d; }
/**
* Vim command display
*/
#codemirror-vim-command-display-wrapper {
background-color: white;
font-size: 13px;
height: 30px;
margin-left: 6px; }
/* COLORS */
/* Attributes */
.active-scripts-list {
list-style-type: none; }
#active-scripts-container {
position: fixed;
padding-top: 10px; }
#active-scripts-container > p {
width: 70%;
margin: 6px;
padding: 4px; }
#active-scripts-container .accordion-header > pre {
color: white; }
.active-scripts-server-header {
background-color: #444;
font-size: 20px;
color: #fff;
margin: 6px 6px 0 6px;
padding: 6px;
cursor: pointer;
width: 60%;
text-align: left;
border: none;
outline: none; }
.active-scripts-server-header:after {
content: "\2795";
/* "plus" sign (+) */
font-size: 13px;
color: #fff;
float: right;
margin-left: 5px; }
.active-scripts-server-header.active, .active-scripts-server-header:hover {
background-color: #555; }
.active-scripts-server-header.active:after {
content: "\2796";
/* "minus" sign (-) */
font-size: 13px;
color: #fff;
float: right;
margin-left: 5px; }
.active-scripts-server-header.active:hover {
background-color: #666; }
.active-scripts-server-panel {
margin: 0 6px 6px 6px;
padding: 0 6px 6px 6px;
width: 55%;
margin-left: 5%;
display: none; }
.active-scripts-server-panel div,
.active-scripts-server-panel ul,
.active-scripts-server-panel ul > li {
background-color: #555; }
.active-scripts-script-header {
background-color: #555;
border: none;
color: var(--my-font-color);
cursor: pointer;
display: block;
outline: none;
padding: 4px 25px 4px 10px;
position: relative;
text-align: left;
width: auto; }
.active-scripts-script-header:after {
content: "\2795";
/* "plus" sign (+) */
font-size: 13px;
float: right;
margin-left: 5px;
color: transparent;
text-shadow: 0 0 0 var(--my-font-color);
position: absolute;
bottom: 4px; }
.active-scripts-script-header.active:after {
content: "\2796";
/* "minus" sign (-) */ }
.active-scripts-script-header:hover, .active-scripts-script-header.active:hover {
background-color: #666; }
.active-scripts-script-header.active {
background-color: #555; }
.active-scripts-script-panel {
background-color: #555;
display: none;
font-size: 14px;
margin-bottom: 6px;
padding: 0 18px;
width: auto; }
.active-scripts-script-panel pre,
.active-scripts-script-panel h2,
.active-scripts-script-panel ul,
.active-scripts-script-panel li {
background-color: #555;
width: auto;
color: #fff;
margin-left: 5%; }
/* COLORS */
/* Attributes */
/**
* Styling for the Hacknet Nodes UI Page
*/
#hacknet-nodes-container {
position: fixed;
padding: 10px; }
.hacknet-general-info {
margin: 10px;
width: 70vw; }
margin: 10px; }
#hacknet-nodes-container li {
float: left;
@@ -1645,46 +1431,26 @@ button {
/* Attributes */
/* CSS for different main menu pages, such as character info, script editor, etc (but excluding
terminal which has its own page) */
.generic-menupage-container {
height: 100%;
padding-left: 10px;
margin-left: 10%;
width: 99%;
overflow-y: scroll; }
#generic-react-container {
-ms-overflow-style: none;
/* for Internet Explorer, Edge */
scrollbar-width: none;
/* for Firefox */
flex-grow: 1; }
/* Character Info */
#character-container {
padding-top: 10px;
position: fixed; }
/* World */
#world-container {
position: fixed;
padding-top: 10px; }
#generic-react-container::-webkit-scrollbar {
display: none;
/* for Chrome, Safari, and Opera */ }
#world-city-name,
#world-city-desc {
padding: 4px;
margin: 4px; }
/* Create program */
#create-program-container {
position: fixed;
padding-top: 10px; }
#create-program-page-text,
#create-program-list {
width: 70%; }
/* Factions and Faction (Single Faction page) */
#factions-container {
position: fixed;
padding-top: 10px; }
#faction-container {
position: fixed;
padding-top: 10px; }
.faction-work-div {
width: 70%;
height: 100%; }
@@ -1696,12 +1462,12 @@ button {
margin: 6px;
width: 70%; }
#faction-container p,
#faction-container pre {
.faction-container p,
.faction-container pre {
padding: 4px 6px;
margin: 4px 6px; }
#faction-container pre {
.faction-container pre {
width: 70%;
white-space: pre-wrap;
/* Since CSS 2.1 */
@@ -1781,13 +1547,8 @@ button {
*/
/* COLORS */
/* Attributes */
#augmentations-container {
position: fixed;
padding-top: 10px; }
#augmentations-content > p {
font-size: 14px;
width: 70%; }
.augmentations-content > p {
font-size: 14px; }
.augmentations-list button,
.augmentations-list div {
@@ -1825,13 +1586,11 @@ button {
/* COLORS */
/* Attributes */
#stock-market-container {
position: fixed;
padding: 6px; }
#stock-market-container p {
font-size: 13px; }
#stock-market-container a {
font-size: 14px; }
.stock-market-container p {
font-size: 13px; }
.stock-market-container a {
font-size: 14px; }
.stock-market-info-and-purchases > h2 {
display: block;
@@ -1959,16 +1718,24 @@ button {
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: top; }
vertical-align: middle; }
:root {
--my-font-color: #6f3;
--my-font-color: #0c0;
--my-background-color: #000;
--my-highlight-color: #fff;
--my-prompt-color: #f92672; }
body {
background-color: var(--my-background-color); }
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,
@@ -2052,13 +1819,30 @@ a:visited {
background-color: #fa3e3e;
color: #fff;
border-radius: 2px;
padding: 1px 3px; }
padding: 1px 3px;
font-size: 10px;
top: 0;
right: 0;
position: absolute; }
.notification-off {
background-color: #333;
color: #333;
border-radius: 0;
padding: 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 {
@@ -2372,7 +2156,7 @@ input[type="checkbox"] {
/* Initially hidden */
position: fixed;
/* Stay in place */
z-index: 10;
z-index: 1300;
/* Sit on top */
left: 0;
top: 0;
@@ -2393,6 +2177,9 @@ input[type="checkbox"] {
/* 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;
@@ -2438,7 +2225,7 @@ input[type="checkbox"] {
flex-flow: column;
background-color: gray;
width: 50%;
position: absolute;
position: fixed;
left: 50%;
top: 40%;
margin: -10% 0 0 -25%;
@@ -2449,6 +2236,7 @@ input[type="checkbox"] {
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;
@@ -2535,10 +2323,6 @@ input[type="checkbox"] {
#infiltration-faction-select {
background-color: #000; }
/* Generic Yes No Box */
#yes-no-text-input-box-input {
color: #fff; }
/* Game Options */
#game-options-container {
transition: opacity 400ms ease-in; }
@@ -2607,7 +2391,7 @@ input[type="checkbox"] {
#interactive-tutorial-container {
display: none;
position: absolute;
position: fixed;
/* Stay in place */
right: 0;
top: 0;
@@ -2695,7 +2479,7 @@ input[type="checkbox"] {
margin: 0;
padding: 0;
box-sizing: border-box;
vertical-align: top; }
vertical-align: middle; }
/* COLORS */
/* Attributes */
@@ -2804,11 +2588,11 @@ input[type="checkbox"] {
width: 100%;
height: 100%;
background: #000;
color: #6f3; }
color: #0c0; }
.loaderoverlay .loaderspinner, .loaderoverlay .loaderspinner:before, .loaderoverlay .loaderspinner:after {
border: 20px solid rgba(0, 0, 0, 0);
border-top-color: #6f3;
border-bottom-color: #6f3;
border-top-color: #0c0;
border-bottom-color: #0c0;
border-radius: 1000px;
position: absolute;
top: 50%;
@@ -2997,10 +2781,10 @@ input[type="checkbox"] {
* 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 {
.cmpy-mgmt-container p,
.cmpy-mgmt-container a,
.cmpy-mgmt-container div,
.cmpy-mgmt-container br {
font-size: 13px; }
/* Header tabs */
@@ -3043,7 +2827,9 @@ input[type="checkbox"] {
overflow-x: auto;
overflow: visible;
top: 10px;
width: 45%; }
width: 45%;
vertical-align: top;
margin-top: 10px; }
.cmpy-mgmt-industry-overview-panel {
border: 1px solid #fff;
@@ -3102,6 +2888,7 @@ input[type="checkbox"] {
padding: 6px; }
.cmpy-mgmt-upgrade-div {
text-align: left;
display: inline-block;
border: 1px solid #fff;
margin: 2px;
@@ -3130,15 +2917,12 @@ input[type="checkbox"] {
/* COLORS */
/* Attributes */
#bladeburner-container {
position: fixed;
padding: 6px; }
#bladeburner-container a,
#bladeburner-container div,
#bladeburner-container p,
#bladeburner-container pre,
#bladeburner-container td {
font-size: 13px; }
.bladeburner-container a,
.bladeburner-container div,
.bladeburner-container p,
.bladeburner-container pre,
.bladeburner-container td {
font-size: 13px; }
.bladeburner-action {
border: 1px solid #fff;
@@ -3245,15 +3029,13 @@ input[type="checkbox"] {
/**
* Styling for the Gang mechanic UI (BitNode-2)
*/
#gang-container {
position: fixed;
padding: 6px; }
#gang-container p,
#gang-container pre {
font-size: 15px; }
#gang-container select {
background-color: black;
color: white; }
.gang-container p,
.gang-container pre {
font-size: 15px; }
.gang-container select {
background-color: black;
color: white; }
#gang-management-subpage > p {
padding: 4px; }
@@ -3283,10 +3065,6 @@ input[type="checkbox"] {
*/
/* COLORS */
/* Attributes */
#sleeves-container {
position: fixed;
padding: 6px; }
.sleeve-elem {
border: 1px solid white;
margin: 4px;
@@ -3308,10 +3086,6 @@ input[type="checkbox"] {
*/
/* COLORS */
/* Attributes */
#resleeve-container {
position: fixed;
padding: 6px; }
.resleeve-elem {
border: 1px solid white;
margin: 4px;
@@ -6243,9 +6017,7 @@ html {
.casino-card.black {
color: black; }
#milestones-container {
position: fixed;
padding: 6px;
.milestones-container {
width: 60%; }
/* COLORS */
@@ -6294,9 +6066,5 @@ html {
50% {
color: #adff2f; } }
#corporation-container {
position: fixed;
padding: 6px; }
/*# sourceMappingURL=engineStyle.css.map*/

283
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -3,6 +3,72 @@
Changelog
=========
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)
-------------------------------------------
** UI **
* The UI is now completely(ish) in react and I'm starting to implement
Material-UI everywhere. This will help make the game feel more consistent.
* Major help from (@threehams)
* New Terminal
* New Active Scripts page
* New sidebar.
* New Character overview
* New tutorial
* New options page
* New create program page (@Nolshine)
** Netscript **
* Add companyName to getPlayer
** Factions **
* Megacorp factions are no longer removed when installing.
** Corporation **
* All research tooltips are always visible.
* Smart supply is enabled by default if purchased (@Nolshine)
** Misc. **
* Fix "Game saved" animation. (@Nolshine)
* Update commitCrime documentation (@Tryneus)
* Fix logbox scrolling weird (@Nolshine)
* Fix weird scrolling in corporations (@BartKoppelmans)
* Fix typo (@BartKoppelmans & @Nolshine)
* Delete game now has a confirmation modal (@Nolshine)
* Fix issue where skills would not get properly updated when entering new
BN. (@Nolshine)
* Convert create gang to popup (@vmesecher)
* Fixed a bug that prevented travel to Sector-12 and New Tokyo when not using
ASCII art.
* nerf noodle bar
v0.53.0 - 2021-09-09 Way too many things. (hydroflame & community)
-------------------------------------------

View File

@@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
# built documents.
#
# The short X.Y version.
version = '0.53'
version = '0.55'
# The full version, including alpha/beta/rc tags.
release = '0.53.0'
release = '0.55.0'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

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

@@ -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

@@ -117,30 +117,6 @@ that are loaded.
Examples
--------
**DOM Manipulation (tprintColored.ns)**
Directly alter the game's terminal and print colored text::
export function tprintColored(txt, color) {
let terminalInput = document.getElementById("terminal-input");
let rowElement = document.createElement("tr");
let cellElement = document.createElement("td");
rowElement.classList.add("posted");
cellElement.classList.add("terminal-line");
cellElement.style.color = color;
cellElement.innerText = txt;
rowElement.appendChild(cellElement);
terminalInput.before(rowElement);
}
export async function main(ns) {
tprintColored("Red Text!", "red");
tprintColored("Blue Text!", "blue");
tprintColored("Use Hex Codes!", "#3087E3");
}
**Script Scheduler (scriptScheduler.ns)**
This script shows some of the new functionality that is available in NetscriptJS,

View File

@@ -26,8 +26,8 @@ commitCrime() Netscript Function
This function is used to automatically attempt to commit crimes. If you are already in the middle of some 'working' action
(such as working for a company or training at a gym), then running this function will automatically cancel that action and give you your earnings.
This function returns the number of seconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt the 'Rob Store' crime,
so running ``commitCrime('rob store')`` will return 60).
This function returns the number of milliseconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt the 'Rob Store' crime,
so running ``commitCrime('rob store')`` will return 60000).
Warning: I do not recommend using the time returned from this function to try and schedule your crime attempts.
Instead, I would use the :doc:`isBusy<isBusy>` Singularity function to check whether you have finished attempting a crime.

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

BIN
electron/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

38
electron/main.js Normal file
View File

@@ -0,0 +1,38 @@
const { app, BrowserWindow, Menu, globalShortcut, shell } = require("electron");
Menu.setApplicationMenu(false);
function createWindow() {
const win = new BrowserWindow({
show: false,
webPreferences: {
devTools: true,
},
});
win.removeMenu();
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(() => {
createWindow();
});

7
electron/package.json Executable file
View File

@@ -0,0 +1,7 @@
{
"name": "bitburner",
"version": "1.0.0",
"description": "A cyberpunk-themed programming incremental game",
"main": "main.js",
"author": "Daniel Xie"
}

View File

@@ -36,614 +36,20 @@
ga("send", "pageview");
</script>
<link rel="shortcut icon" href="favicon.ico"><link href="dist/vendor.css" rel="stylesheet"><link href="dist/engineStyle.css" rel="stylesheet"></head>
<style>
body {
background-color: black;
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
}
body::-webkit-scrollbar {
display: none; /* for Chrome, Safari, and Opera */
}
</style>
<link rel="shortcut icon" href="favicon.ico"></head>
<body>
<div id="entire-game-container" style="visibility: hidden">
<div id="mainmenu-container">
<!-- Main menu -->
<ul id="mainmenu" class="mainmenu noscrollbar">
<!-- Hacking dropdown -->
<li id="hacking-menu-header-li">
<button id="hacking-menu-header" class="mainmenu-accordion-header noselect">Hacking</button>
</li>
<li id="terminal-tab" class="mainmenu-accordion-panel noselect">
<button id="terminal-menu-link">Terminal</button>
</li>
<li id="create-script-tab" class="mainmenu-accordion-panel noselect">
<button id="create-script-menu-link">Create Script</button>
</li>
<li id="active-scripts-tab" class="mainmenu-accordion-panel noselect">
<button id="active-scripts-menu-link">Active Scripts</button>
</li>
<li id="create-program-tab" class="mainmenu-accordion-panel noselect">
<button id="create-program-menu-link">Create Program</button>
<span id="create-program-notification" class="notification-off"> </span>
</li>
<!-- Character dropdown -->
<li id="character-menu-header-li">
<button id="character-menu-header" class="mainmenu-accordion-header noselect">Character</button>
</li>
<li id="stats-tab" class="mainmenu-accordion-panel noselect">
<button id="stats-menu-link">Stats</button>
</li>
<li id="factions-tab" class="mainmenu-accordion-panel noselect">
<button id="factions-menu-link">Factions</button>
<span id="factions-notification" class="notification-off"> </span>
</li>
<li id="augmentations-tab" class="mainmenu-accordion-panel noselect">
<button id="augmentations-menu-link" style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap">
Augmentations
</button>
<span id="augmentations-notification" class="notification-off"> </span>
</li>
<li id="hacknet-nodes-tab" class="mainmenu-accordion-panel noselect">
<button id="hacknet-nodes-menu-link">Hacknet</button>
</li>
<li id="sleeves-tab" class="mainmenu-accordion-panel noselect">
<button id="sleeves-menu-link">Sleeves</button>
</li>
<!-- World dropdown -->
<li id="world-menu-header-li">
<button id="world-menu-header" class="mainmenu-accordion-header noselect">World</button>
</li>
<li id="city-tab" class="mainmenu-accordion-panel noselect">
<button id="city-menu-link">City</button>
</li>
<li id="travel-tab" class="mainmenu-accordion-panel noselect">
<button id="travel-menu-link">Travel</button>
</li>
<li id="job-tab" class="mainmenu-accordion-panel noselect">
<button id="job-menu-link">Job</button>
</li>
<li id="stock-market-tab" class="mainmenu-accordion-panel noselect">
<button id="stock-market-menu-link">Stock Market</button>
</li>
<li id="bladeburner-tab" class="mainmenu-accordion-panel noselect">
<button id="bladeburner-menu-link">Bladeburner</button>
</li>
<li id="corporation-tab" class="mainmenu-accordion-panel noselect">
<button id="corporation-menu-link">Corp</button>
</li>
<li id="gang-tab" class="mainmenu-accordion-panel noselect">
<button id="gang-menu-link">Gang</button>
</li>
<li id="help-menu-header-li">
<button id="help-menu-header" class="mainmenu-accordion-header noselect">Help</button>
</li>
<li id="milestones-tab" class="mainmenu-accordion-panel noselect">
<button id="milestones-menu-link">Milestones</button>
</li>
<li id="tutorial-tab" class="mainmenu-accordion-panel noselect">
<button id="tutorial-menu-link">Tutorial</button>
</li>
<li id="options-tab" class="mainmenu-accordion-panel noselect">
<button id="options-menu-link">Options</button>
</li>
<li id="dev-tab" class="mainmenu-accordion-panel noselect">
<button id="dev-menu-link">Dev</button>
</li>
</ul>
</div>
<div id="script-editor-container" class="generic-menupage-container">
<div id="script-editor-wrapper">
<div id="script-editor-filename-wrapper">
<p id="script-editor-filename-tag">
<strong style="background-color: #555">Script name: </strong>
</p>
<input id="script-editor-filename" type="text" maxlength="100" tabindex="1"/>
</div>
<div id="monaco-editor"></div>
<div id="script-editor-buttons-wrapper"></div>
<!-- Buttons below script editor -->
</div>
<!-- End wrapper -->
<div id="script-editor-options-panel">
<h1 style="color: white">Script Editor Options</h1>
<fieldset>
<label for="script-editor-option-editor">Editor</label>
<select id="script-editor-option-editor" class="dropdown">
<option value="Ace">Ace</option>
<option value="CodeMirror">CodeMirror</option>
</select>
</fieldset>
<fieldset>
<label for="script-editor-option-theme">Theme</label>
<select id="script-editor-option-theme" class="dropdown"></select>
</fieldset>
<fieldset>
<label for="script-editor-option-keybinding">Key Binding</label>
<select id="script-editor-option-keybinding" class="dropdown"></select>
</fieldset>
<fieldset>
<label for="script-editor-option-highlightactiveline">Highlight Active Line</label>
<input type="checkbox" class="optionCheckbox" name="script-editor-option-highlightactiveline" id="script-editor-option-highlightactiveline" checked/>
</fieldset>
<fieldset>
<label for="script-editor-option-showinvisibles">Show Invisibles</label>
<input type="checkbox" class="optionCheckbox" name="script-editor-option-showinvisibles" id="script-editor-option-showinvisibles"/>
</fieldset>
<fieldset>
<label for="script-editor-option-usesofttab">Use Soft Tab</label>
<input type="checkbox" class="optionCheckbox" name="script-editor-option-usesofttab" id="script-editor-option-usesofttab" checked/>
</fieldset>
<fieldset id="script-editor-option-flex1-fieldset"></fieldset>
<fieldset id="script-editor-option-flex2-fieldset"></fieldset>
<fieldset id="script-editor-option-flex3-fieldset"></fieldset>
<fieldset id="script-editor-option-flex4-fieldset"></fieldset>
</div>
<!-- End script editor options panel -->
<!-- TODO(hydroflame): remove this once Monaco is implemented -->
<div id="ace-editor" style="display: none"></div>
<form id="codemirror-form-wrapper" style="display: none">
<textarea id="codemirror-editor"></textarea>
</form>
<div id="codemirror-vim-command-display-wrapper" style="display: none">
Key Buffer: <span id="codemirror-vim-command-display"></span>
</div>
</div>
<!-- Terminal page -->
<div id="terminal-container">
<table id="terminal">
<tr id="terminal-input">
<td id="terminal-input-td" tabindex="2">
$
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;" autocomplete="off"/>
</td>
</tr>
</table>
</div>
<!-- Character Info page -->
<div id="character-container" class="generic-menupage-container">
<div id="character-content"></div>
</div>
<!-- Active scripts info page -->
<div id="active-scripts-container" class="generic-menupage-container">
<p id="active-scripts-text">
This page displays a list of all of your scripts that are currently running across every machine. It also
provides information about each script's production. The scripts are categorized by the hostname of the
servers on which they are running.
</p>
<p id="active-scripts-total-prod">
Total online production of Active scripts:
<span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br/>
Total online production since last Aug installation:
<span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span>
(<span class="money-gold"><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span>)
</p>
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none"></ul>
</div>
<!-- Hacknet Nodes -->
<div id="hacknet-nodes-container" class="generic-menupage-container">
<!-- React Component -->
</div>
<!-- Create a program(executable) -->
<div id="create-program-container" class="generic-menupage-container">
<p id="create-program-page-text">
This page displays any programs that you are able to create. Writing the code for a program takes time, which
can vary based on how complex the program is. If you are working on creating a program you can cancel at any
time. Your progress will be saved and you can continue later.
</p>
<ul id="create-program-list"></ul>
</div>
<!-- Factions -->
<div id="factions-container" class="generic-menupage-container"></div>
<!-- Single Faction info (when you select a faction from the Factions menu) -->
<div id="faction-container" class="generic-menupage-container"></div>
<!-- Augmentations -->
<div id="augmentations-container" class="generic-menupage-container"></div>
<!-- Milestones content -->
<div id="milestones-container" class="generic-menupage-container"></div>
<!-- Tutorial content -->
<div id="tutorial-container" class="generic-menupage-container">
<h1>Tutorial (AKA Links to Documentation)</h1>
<a id="tutorial-getting-started-link" class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html">
Getting Started</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html">
Servers & Networking</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html">
Hacking</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html">
Scripts</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
Netscript Programming Language</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html">
Traveling</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html">
Companies</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html">
Infiltration</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html">
Factions</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html">
Augmentations</a><br/><br/>
<a class="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
Keyboard Shortcuts</a>
</div>
<!-- Location (visiting a location in World) -->
<div id="location-container" class="generic-menupage-container"></div>
<div id="infiltration-container" class="generic-fullscreen-container"></div>
<div id="stock-market-container" class="generic-menupage-container"></div>
<div id="bladeburner-container" class="generic-menupage-container"></div>
<div id="resleeve-container" class="generic-menupage-container"></div>
<div id="gang-container" class="generic-menupage-container"></div>
<div id="corporation-container" class="generic-menupage-container"></div>
<div id="sleeves-container" class="generic-menupage-container"></div>
<!-- Generic Yes/No Pop Up box -->
<div id="yes-no-box-container" class="popup-box-container">
<div id="yes-no-box-content" class="popup-box-content">
<p id="yes-no-box-text"></p>
<button id="yes-no-box-yes" class="popup-box-button">Yes</button>
<button id="yes-no-box-no" class="popup-box-button">No</button>
</div>
</div>
<!-- Generic yes/no pop up box with text entry field -->
<div id="yes-no-text-input-box-container" class="popup-box-container">
<div id="yes-no-text-input-box-content" class="popup-box-content">
<p id="yes-no-text-input-box-text"></p>
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"/>
<button id="yes-no-text-input-box-yes" class="popup-box-button">Yes</button>
<button id="yes-no-text-input-box-no" class="popup-box-button">No</button>
</div>
</div>
<!-- Faction Invitation Pop-up Box -->
<div id="faction-invitation-box-container" class="popup-box-container">
<div id="faction-invitation-box-content" class="popup-box-content">
<p id="faction-invitation-box-text"></p>
<p id="faction-invitation-box-message"></p>
<p id="faction-invitation-box-warning">
Would you like to join? <br/>
<br/>
Warning: Joining this faction may prevent you from joining other factions during this run!
</p>
<button id="faction-invitation-box-yes" class="popup-box-button">Join!</button>
<button id="faction-invitation-box-no" class="popup-box-button">Decide later</button>
</div>
</div>
<!-- End of Infiltration pop up box -->
<div id="infiltration-box-container" class="popup-box-container">
<div id="infiltration-box-content" class="popup-box-content">
<p id="infiltration-box-text"></p>
<button id="infiltration-box-sell" class="a-link-button">Sell on Black Market</button>
<br/><br/>
<select id="infiltration-faction-select" class="dropdown"></select>
<br/>
<button id="infiltration-box-faction" class="a-link-button">Give to Faction for Reputation</button>
</div>
</div>
<!-- Mission container -->
<div id="mission-container" class="generic-fullscreen-container"></div>
<!-- Work in progress screen -->
<div id="work-in-progress-container" class="generic-fullscreen-container">
<p id="work-in-progress-text"></p>
<button id="work-in-progress-cancel-button" class="work-button">Cancel Work</button>
<button id="work-in-progress-something-else-button" class="work-button">
Do something else simultaneously
</button>
</div>
<!-- Red Pill Container -->
<div id="red-pill-container" class="generic-fullscreen-container">
<div id="red-pill-content" class="generic-fullscreen-container-scroll"></div>
</div>
<!-- Cinematic Text Container -->
<div id="cinematic-text-container" class="generic-fullscreen-container"></div>
<!-- Interactive Tutorial Text Screen -->
<div id="interactive-tutorial-wrapper">
<div id="interactive-tutorial-container">
<p id="interactive-tutorial-text"></p>
<button id="interactive-tutorial-exit">Exit Tutorial</button>
<button id="interactive-tutorial-next">Next</button>
<button id="interactive-tutorial-back">Back</button>
</div>
</div>
<!-- Character Overview Screen -->
<div id="character-overview-wrapper">
<div id="character-overview-container">
<div id="character-overview-text">
<!-- ReactJS Component -->
</div>
<div class="character-quick-options noselect">
<button id="character-overview-save-button" class="character-overview-btn">Save Game</button>
<button id="character-overview-options-button" class="character-overview-btn">Options</button>
</div>
</div>
</div>
<!-- Status text -->
<div id="status-text-container">
<p id="status-text"></p>
</div>
<!-- Game Options -->
<div id="game-options-container" class="popup-box-container">
<div id="game-options-content" class="game-options-box">
<button id="game-options-close-button" aria-label="close options dialog">&times;</button>
<h1>Game Options</h1>
<br/>
<div id="game-options-left-panel">
<!-- Netscript execution time -->
<fieldset>
<label for="settingsNSExecTimeRangeVal" class="tooltip">Netscript exec time:&nbsp;
<span class="tooltiptext">
The minimum number of milliseconds it takes to execute an operation in Netscript. Setting this too low
can result in poor performance if you have many scripts running. The default value is 25ms.
</span>
</label>
<input class="optionRange" type="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25"/>
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal"></em>
</fieldset>
<!-- Log capacity -->
<fieldset>
<label for="settingsNSLogRangeVal" class="tooltip">Netscript log size:&nbsp;&nbsp;
<span class="tooltiptext">
The maximum number of lines a script's logs can hold. Setting this too high can cause the game to use
a lot of memory if you have many scripts running. The default value is 50.
</span>
</label>
<input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"/>
<em id="settingsNSLogRangeValLabel" style="font-style: normal"></em>
</fieldset>
<!-- Port capacity -->
<fieldset>
<label for="settingsNSPortRangeVal" class="tooltip">Netscript port size:&nbsp;
<span class="tooltiptext">
The maximum number of entries that can be written to a port using Netscript's write() function.
Setting this too high can cause the game to use a lot of memory. The default value is 50.
</span>
</label>
<input class="optionRange" type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"/>
<em id="settingsNSPortRangeValLabel" style="font-style: normal"></em>
</fieldset>
<!-- Autosave Interval -->
<fieldset>
<label for="settingsAutosaveIntervalVal" class="tooltip">Autosave Interval:&nbsp;&nbsp;&nbsp;
<span class="tooltiptext">
The time (in seconds) between each autosave. Set to 0 to disable autosave.
</span>
</label>
<input class="optionRange" type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60"/>
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal"></em>
</fieldset>
<!-- Suppress messages -->
<fieldset>
<label for="settingsSuppressMessages" class="tooltip">Suppress Messages:
<span class="tooltiptext">
If this is set, then any messages you receive will not appear as popups on the screen. They will still
get sent to your home computer as '.msg' files and can be viewed with the 'cat' Terminal command.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressMessages" id="settingsSuppressMessages"/>
</fieldset>
<!-- Suppress faction invites -->
<fieldset>
<label for="settingsSuppressFactionInvites" class="tooltip">Suppress Faction Invites:
<span class="tooltiptexthigh">
If this is set, then any faction invites you receive will not appear as popups on the screen. Your
outstanding faction invites can be viewed in the 'Factions' page.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites"/>
</fieldset>
<!-- Suppress travel confirmation -->
<fieldset>
<label for="settingsSuppressTravelConfirmation" class="tooltip">Suppress Travel Confirmation:
<span class="tooltiptexthigh">
If this is set, the confirmation message before traveling will not show up. You will automatically be
deducted the travel cost as soon as you click.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressTravelConfirmation" id="settingsSuppressTravelConfirmation"/>
</fieldset>
<!-- Suppress buy aug confirmation -->
<fieldset>
<label for="settingsSuppressBuyAugmentationConfirmation" class="tooltip">Suppress buy augmentation confirmation:
<span class="tooltiptexthigh">
If this is set, the confirmation message before buying augmentation will not show up.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressBuyAugmentationConfirmation" id="settingsSuppressBuyAugmentationConfirmation"/>
</fieldset>
<!-- Hospitalization Popup -->
<fieldset>
<label for="settingsSuppressHospitalizationPopup" class="tooltip">Suppress Hospitalization popup:
<span class="tooltiptexthigh">
If this is set, a popup message will no longer be shown when you are hospitalized after taking too
much damage.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressHospitalizationPopup" id="settingsSuppressHospitalizationPopup"/>
</fieldset>
<!-- Suppress Bladeburner popups -->
<fieldset>
<label for="settingsSuppressBladeburnerPopup" class="tooltip">Suppress Bladeburner Popup:
<span class="tooltiptext">
If this is set, then having your Bladeburner actions interrupted by being busy with something else
will not display a popup message.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsSuppressBladeburnerPopup" id="settingsSuppressBladeburnerPopup"/>
</fieldset>
<!-- Disable Terminal and Navigation Shortcuts -->
<fieldset>
<label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys:
<span class="tooltiptexthigh">
If this is set, then most hotkeys (keyboard shortcuts) in the game are disabled. This includes
Terminal commands, hotkeys to navigate between different parts of the game, and the "Save and Close
(Ctrl + b)" hotkey in the Text Editor.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys"/>
</fieldset>
<!-- View city as list of buttons instead of ASCII art. -->
<fieldset>
<label for="settingsDisableASCIIArt" class="tooltip">Disable ASCII art:
<span class="tooltiptexthigh"> If this is set all ASCII art will be disabled. </span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsDisableASCIIArt" id="settingsDisableASCIIArt"/>
</fieldset>
<!-- Disable text effects such as corruption. -->
<fieldset>
<label for="settingsDisableTextEffects" class="tooltip">Disable Text Effects:
<span class="tooltiptexthigh">
If this is set, text effects will not be displayed. This can help if text is difficult to read in
certain areas.
</span>
</label>
<input class="optionCheckbox" type="checkbox" name="settingsDisableTextEffects" id="settingsDisableTextEffects"/>
</fieldset>
<!-- Locale for displaying numbers -->
<fieldset>
<label for="settingsLocale" class="tooltip">Locale:
<span class="tooltiptexthigh"> Sets the locale for displaying numbers. Defaults to 'en' </span>
</label>
<select name="settingsLocale" id="settingsLocale" class="dropdown">
<option value="en">en</option>
<option value="bg">bg</option>
<option value="cs">cs</option>
<option value="da-dk">da-dk</option>
<option value="de">de</option>
<option value="en-au">en-au</option>
<option value="en-gb">en-gb</option>
<option value="es">es</option>
<option value="fr">fr</option>
<option value="hu">hu</option>
<option value="it">it</option>
<option value="lv">lv</option>
<option value="no">no</option>
<option value="pl">pl</option>
<option value="ru">ru</option>
</select>
</fieldset>
<!-- Donate button -->
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_blank">
<input type="hidden" name="cmd" value="_s-xclick"/>
<input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYA2Y2VGE75oWct89z//G2YEJKmzx0uDTXNrpje9ThxmUnBLFZCY+I11Pors7lGRvFqo5okwnu41CfYMPHDxpAgyYyQndMX9pWUX0gLfBMm2BaHwsNBCwt34WmpQqj7TGsQ+aw9NbmkxiJltGnOa+6/gy10mPZAA3HxiieLeCKkGgDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQI72F1YSzHUd2AgaDMekHU3AKT93Ey9wkB3486bV+ngFSD6VOHrPweH9QATsp+PMe9QM9vmq+s2bGtTbZaYrFqM3M97SnQ0l7IQ5yuOzdZhRdfysu5uJ8dnuHUzq4gLSzqMnZ6/3c+PoHB8AS1nYHUVL4U0+ogZsO1s97IAQyfck9SaoFlxVtqQhkb8752MkQJJvGu3ZQSQGcVC4hFDPk8prXqyq4BU/k/EliwoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTcwNzI1MDExODE2WjAjBgkqhkiG9w0BCQQxFgQUNo8efiZ7sk7nwKM/6B6Z7sU8hIIwDQYJKoZIhvcNAQEBBQAEgYB+JB4vZ/r48815/1HF/xK3+rOx7bPz3kAXmbhW/mkoF4OUbzqMeljvDIA9q/BDdlCLtxFOw9XlftTzv0eZCW/uCIiwu5wTzPIfPY1SI8WHe4cJbP2f2EYxIVs8D7OSirbW4yVa0+gACaLLj0rzIzNN8P/5PxgB03D+jwkcJABqng==-----END PKCS7-----
"/>
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"/>
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"/>
</form>
</div>
<div id="game-options-right-panel">
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank">
Changelog
</a>
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank">Documentation</a>
<a class="a-link-button" href="https://discord.gg/TFc3hKD" target="_blank">Discord</a>
<a class="a-link-button" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
<button id="save-game-link" class="a-link-button">Save Game</button>
<button id="delete-game-link" class="a-link-button">Delete Game</button>
<button id="export-game-link" class="a-link-button">Export Game</button>
<input type="file" id="import-game-file-selector" name="file"/>
<button id="import-game-link" class="a-link-button">Import Game</button>
<button id="copy-save-to-clipboard-link" class="std-button">Copy Save data to Clipboard</button>
<button id="debug-delete-scripts-link" class="a-link-button tooltip">
Force kill all active scripts
<span class="tooltiptextleft">
Forcefully kill all active running scripts, in case there is a bug or some unexpected issue with the
game. After using this, save the game and then reload the page. This is different then normal kill in
that normal kill will tell the script to shut down while force kill just removes the references to it
(and it should crash on it's own). This will not remove the files on your computer. Just forcefully kill
all running instance of all scripts.
</span>
</button>
<button id="debug-soft-reset" class="a-link-button tooltip">
Soft Reset
<span class="tooltiptextleft">
Perform a soft reset. Resets everything as if you had just purchased an Augmentation.
</span>
</button>
<button id="debug-files" class="a-link-button tooltip">
Diagnose files
<span class="tooltiptextleft">
If your save file is extremely big you can use this button to view a map of all the files on every
server. Be careful there might be spoilers.
</span>
</button>
</div>
</div>
</div>
</div>
<!-- Loader (Loading screen) -->
<div id="loader" class="loaderoverlay">
<div class="loaderspinner"></div>
<div class="loaderlabel">Loading Bitburner...</div>
<div id="killAllMessageWrapper" class="killAllMessage killAllMessageWrapperHidden">
<script>
setTimeout(function () {
var w = document.getElementById("killAllMessageWrapper");
if (w == null) {
return;
}
w.classList.remove("killAllMessageWrapperHidden");
w.classList.add("killAllMessageWrapperShow");
}, 2000);
</script>
<p>
If the game fails to load, consider
<a href="?noScripts">killing all scripts</a>
</p>
</div>
</div>
<div id="unclickable" style="display: none">Click on this to upgrade your Source-File -1!</div>
<script type="text/javascript" src="dist/vendor.bundle.js"></script><script type="text/javascript" src="dist/engine.bundle.js"></script><script type="text/javascript" src="dist/engineStyle.bundle.js"></script></body>
<!-- Misc Scripts -->
<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>
</html>

20
main.bundle.js Normal file

File diff suppressed because one or more lines are too long

1
main.bundle.js.map Normal file

File diff suppressed because one or more lines are too long

6008
main.css Normal file

File diff suppressed because it is too large Load Diff

1
main.css.map Normal file

File diff suppressed because one or more lines are too long

6279
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,8 @@
{
"name": "bitburner",
"license": "SEE LICENSE IN license.txt",
"version": "0.53.0",
"main": "electron-main.js",
"author": {
"name": "Daniel Xie"
},
@@ -6,12 +10,18 @@
"url": "https://github.com/danielyxie/bitburner/issues"
},
"dependencies": {
"@material-ui/core": "^4.11.3",
"@emotion/react": "^11.4.1",
"@emotion/styled": "^11.3.0",
"@monaco-editor/react": "^4.2.2",
"@mui/icons-material": "^5.0.0-rc.1",
"@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": "^16.8.6",
"@types/react-dom": "^16.8.2",
"@types/react": "^17.0.21",
"@types/react-dom": "^17.0.9",
"acorn": "^8.4.1",
"acorn-walk": "^8.1.1",
"ajv": "^5.1.5",
@@ -34,6 +44,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",
@@ -41,14 +52,16 @@
"node-sass": "^6.0.1",
"normalize.css": "^8.0.0",
"numeral": "2.0.6",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-modal": "^3.12.1",
"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": {
@@ -56,9 +69,12 @@
"@babel/preset-env": "^7.15.0",
"@babel/preset-react": "^7.0.0",
"@babel/preset-typescript": "^7.15.0",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
"@testing-library/cypress": "^8.0.1",
"@types/file-saver": "^2.0.3",
"@types/jest": "^27.0.1",
"@types/lodash": "^4.14.168",
"@types/node": "^16.9.1",
"@typescript-eslint/eslint-plugin": "^4.22.0",
"@typescript-eslint/parser": "^4.22.0",
"babel-jest": "^27.0.6",
@@ -68,6 +84,8 @@
"bundle-loader": "~0.5.0",
"css-loader": "^0.28.11",
"cypress": "^8.3.1",
"electron": "^14.0.1",
"electron-packager": "^15.4.0",
"es6-promise-polyfill": "^1.1.1",
"eslint": "^7.24.0",
"eslint-plugin-node": "^11.1.0",
@@ -90,6 +108,7 @@
"null-loader": "^1.0.0",
"prettier": "^2.3.2",
"raw-loader": "~0.5.0",
"react-refresh": "^0.10.0",
"regenerator-runtime": "^0.13.9",
"sass-loader": "^7.0.3",
"script-loader": "~0.7.0",
@@ -117,8 +136,6 @@
"node": ">=8 || <=9"
},
"homepage": "https://github.com/danielyxie/bitburner",
"license": "SEE LICENSE IN license.txt",
"name": "bitburner",
"repository": {
"type": "git",
"url": "git+https://github.com/danielyxie/bitburner.git"
@@ -131,6 +148,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",
@@ -141,7 +159,7 @@
"test": "jest",
"test:watch": "jest --watch",
"watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development"
},
"version": "0.53.0"
"watch:dev": "webpack --watch --mode development",
"package-electron": "electron-packager .package bitburner --all --out .build --overwrite --icon .package/icon.png"
}
}

19
package.sh Executable file
View File

@@ -0,0 +1,19 @@
# npm install electron --save-dev
# npm install electron-packager --save-dev
mkdir -p .package/dist/src/ThirdParty || true
mkdir -p .package/src/ThirdParty || true
cp index.html .package
cp electron/* .package
# The css files
cp dist/vendor.css .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

@@ -1,5 +1,5 @@
import { IMap } from "./types";
import { post } from "./ui/postToTerminal";
import { Terminal } from "./Terminal";
export let Aliases: IMap<string> = {};
export let GlobalAliases: IMap<string> = {};
@@ -24,12 +24,12 @@ export function loadGlobalAliases(saveString: string): void {
export function printAliases(): void {
for (const name in Aliases) {
if (Aliases.hasOwnProperty(name)) {
post("alias " + name + "=" + Aliases[name]);
Terminal.print("alias " + name + "=" + Aliases[name]);
}
}
for (const name in GlobalAliases) {
if (GlobalAliases.hasOwnProperty(name)) {
post("global alias " + name + "=" + GlobalAliases[name]);
Terminal.print("global alias " + name + "=" + GlobalAliases[name]);
}
}
}

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

View File

@@ -1,36 +1,30 @@
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 { AugmentationsRoot } from "./ui/Root";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { CONSTANTS } from "../Constants";
import { Factions, factionExists } from "../Faction/Factions";
import { Player } from "../Player";
import { prestigeAugmentation } from "../Prestige";
import { saveObject } from "../SaveObject";
import { Page, routing } from "../ui/navigationTracking";
import { onExport } from "../ExportBonus";
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";
import ReactDOM from "react-dom";
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,
@@ -117,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 = [];
}
@@ -130,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,
@@ -139,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);
@@ -217,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,
});
@@ -1561,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)) {
@@ -1601,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)) {
@@ -2050,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)) {
@@ -2355,7 +2371,7 @@ function initAugmentations() {
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;
}
@@ -2365,29 +2381,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
@@ -2406,12 +2419,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;
@@ -2449,29 +2462,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 displayAugmentationsContent(contentEl) {
if (!routing.isOn(Page.Augmentations)) {
return;
}
if (!(contentEl instanceof HTMLElement)) {
return;
}
function backup() {
saveObject.exportGame();
onExport(Player);
}
ReactDOM.render(<AugmentationsRoot exportGameFn={backup} installAugmentationsFn={installAugmentations} />, contentEl);
}
export function isRepeatableAug(aug) {
export function isRepeatableAug(aug: Augmentation): boolean {
const augName = aug instanceof Augmentation ? aug.name : aug;
if (augName === AugmentationNames.NeuroFluxGovernor) {

View File

@@ -41,6 +41,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",

View File

@@ -0,0 +1,99 @@
/**
* Root React component for the Augmentations UI page that display all of your
* owned and purchased Augmentations and Source-Files.
*/
import React, { useState, useEffect } from "react";
import { InstalledAugmentations } from "./InstalledAugmentations";
import { PlayerMultipliers } from "./PlayerMultipliers";
import { PurchasedAugmentations } from "./PurchasedAugmentations";
import { SourceFiles } from "./SourceFiles";
import { canGetBonus } from "../../ExportBonus";
import { use } from "../../ui/Context";
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;
}
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

@@ -1,91 +0,0 @@
/**
* 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 { InstalledAugmentationsAndSourceFiles } from "./InstalledAugmentationsAndSourceFiles";
import { PlayerMultipliers } from "./PlayerMultipliers";
import { PurchasedAugmentations } from "./PurchasedAugmentations";
import { Player } from "../../Player";
import { StdButton } from "../../ui/React/StdButton";
import { canGetBonus } from "../../ExportBonus";
type 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 id="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>
);
}
}

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 { Accordion } from "../../ui/React/Accordion";
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}>
<Accordion
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

@@ -1,557 +0,0 @@
import { BitNodeMultipliers } from "./BitNodeMultipliers";
import { IPlayer } from "../PersonObjects/IPlayer";
import { IMap } from "../types";
class BitNode {
// A short description, or tagline, about the BitNode
desc: string;
// A long, detailed overview of the BitNode
info: string;
// Name of BitNode
name: string;
// BitNode number
number: number;
constructor(n: number, name: string, desc = "", info = "") {
this.number = n;
this.name = name;
this.desc = desc;
this.info = info;
}
}
export const BitNodes: IMap<BitNode> = {};
BitNodes["BitNode1"] = new BitNode(
1,
"Source Genesis",
"The original BitNode",
"The first BitNode created by the Enders to imprison the minds of humans. It became " +
"the prototype and testing-grounds for all of the BitNodes that followed.<br><br>" +
"This is the first BitNode that you play through. It has no special " +
"modifications or mechanics.<br><br>" +
"Destroying this BitNode will give you Source-File 1, or if you already have " +
"this Source-File it will upgrade its level up to a maximum of 3. This Source-File " +
"lets the player start with 32GB of RAM on his/her home computer when entering a " +
"new BitNode, and also increases all of the player's multipliers by:<br><br>" +
"Level 1: 16%<br>" +
"Level 2: 24%<br>" +
"Level 3: 28%",
);
BitNodes["BitNode2"] = new BitNode(
2,
"Rise of the Underworld",
"From the shadows, they rose", //Gangs
"From the shadows, they rose.<br><br>Organized crime groups quickly filled the void of power " +
"left behind from the collapse of Western government in the 2050s. As society and civlization broke down, " +
"people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " +
"factions quickly rose to the top of the modern world.<br><br>" +
"In this BitNode:<br><br>" +
"Your hacking level is reduced by 20%<br>" +
"The growth rate and maximum amount of money available on servers are significantly decreased<br>" +
"The amount of money gained from crimes and Infiltration is tripled<br>" +
"Certain Factions (Slum Snakes, Tetrads, The Syndicate, The Dark Army, Speakers for the Dead, " +
"NiteSec, The Black Hand) give the player the ability to form and manage their own gangs. These gangs " +
"will earn the player money and reputation with the corresponding Faction<br>" +
"Every Augmentation in the game will be available through the Factions listed above<br>" +
"For every Faction NOT listed above, reputation gains are halved<br>" +
"You will no longer gain passive reputation with Factions<br><br>" +
"Destroying this BitNode will give you Source-File 2, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File allows you to form gangs in other BitNodes " +
"once your karma decreases to a certain value. " +
"It also increases the player's crime success rate, crime money, and charisma multipliers by:<br><br>" +
"Level 1: 24%<br>" +
"Level 2: 36%<br>" +
"Level 3: 42%",
);
BitNodes["BitNode3"] = new BitNode(
3,
"Corporatocracy",
"The Price of Civilization",
"Our greatest illusion is that a healthy society can revolve around a " +
"single-minded pursuit of wealth.<br><br>" +
"Sometime in the early 21st century economic and political globalization turned " +
"the world into a corporatocracy, and it never looked back. Now, the privileged " +
"elite will happily bankrupt their own countrymen, decimate their own community, " +
"and evict their neighbors from houses in their desperate bid to increase their wealth.<br><br>" +
"In this BitNode you can create and manage your own corporation. Running a successful corporation " +
"has the potential of generating massive profits. All other forms of income are reduced by 75%. Furthermore: <br><br>" +
"The price and reputation cost of all Augmentations is tripled<br>" +
"The starting and maximum amount of money on servers is reduced by 75%<br>" +
"Server growth rate is reduced by 80%<br>" +
"You now only need 75 favour with a faction in order to donate to it, rather than 150<br><br>" +
"Destroying this BitNode will give you Source-File 3, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File lets you create corporations on other BitNodes (although " +
"some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by:<br>" +
"Level 1: 8%<br>" +
"Level 2: 12%<br>" +
"Level 3: 14%",
);
BitNodes["BitNode4"] = new BitNode(
4,
"The Singularity",
"The Man and the Machine",
"The Singularity has arrived. The human race is gone, replaced " +
"by artificially superintelligent beings that are more machine than man. <br><br>" +
"In this BitNode, progressing is significantly harder. Experience gain rates " +
"for all stats are reduced. Most methods of earning money will now give significantly less.<br><br>" +
"In this BitNode you will gain access to a new set of Netscript Functions known as Singularity Functions. " +
"These functions allow you to control most aspects of the game through scripts, including working for factions/companies, " +
"purchasing/installing Augmentations, and creating programs.<br><br>" +
"Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " +
"Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " +
"that you can use.",
);
BitNodes["BitNode5"] = new BitNode(
5,
"Artificial Intelligence",
"Posthuman",
"They said it couldn't be done. They said the human brain, " +
"along with its consciousness and intelligence, couldn't be replicated. They said the complexity " +
"of the brain results from unpredictable, nonlinear interactions that couldn't be modeled " +
"by 1's and 0's. They were wrong.<br><br>" +
"In this BitNode:<br><br>" +
"The base security level of servers is doubled<br>" +
"The starting money on servers is halved, but the maximum money remains the same<br>" +
"Most methods of earning money now give significantly less<br>" +
"Infiltration gives 50% more reputation and money<br>" +
"Corporations have 50% lower valuations and are therefore less profitable<br>" +
"Augmentations are more expensive<br>" +
"Hacking experience gain rates are reduced<br><br>" +
"Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. " +
"Intelligence is unique because it is permanent and persistent (it never gets reset back to 1). However " +
"gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't know " +
"when you gain experience and how much). Higher Intelligence levels will boost your production for many actions " +
"in the game. <br><br>" +
"In addition, this Source-File will unlock the getBitNodeMultipliers() and getServer() Netscript functions, " +
"as well as the formulas API, and will also raise all of your hacking-related multipliers by:<br><br>" +
"Level 1: 8%<br>" +
"Level 2: 12%<br>" +
"Level 3: 14%",
);
BitNodes["BitNode6"] = new BitNode(
6,
"Bladeburners",
"Like Tears in Rain",
"In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic " +
"androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation " +
"of their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was " +
"the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more intelligent " +
"than the humans that had created them.<br><br>" +
"In this BitNode you will be able to access the Bladeburner Division at the NSA, which provides a new mechanic " +
"for progression. Furthermore:<br><br>" +
"Hacking and Hacknet Nodes will be less profitable<br>" +
"Your hacking level is reduced by 65%<br>" +
"Hacking experience gain from scripts is reduced by 75%<br>" +
"Corporations have 80% lower valuations and are therefore less profitable<br>" +
"Working for companies is 50% less profitable<br>" +
"Crimes and Infiltration are 25% less profitable<br><br>" +
"Destroying this BitNode will give you Source-File 6, or if you already have this Source-File it will upgrade " +
"its level up to a maximum of 3. This Source-File allows you to access the NSA's Bladeburner Division in other " +
"BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat stats by:<br><br>" +
"Level 1: 8%<br>" +
"Level 2: 12%<br>" +
"Level 3: 14%",
);
BitNodes["BitNode7"] = new BitNode(
7,
"Bladeburners 2079",
"More human than humans",
"In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI design team " +
"for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological " +
"breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a hyperintelligent AI. " +
"Many argue that this was the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, " +
"and more intelligent than the humans that had created them.<br><br>" +
"In this BitNode you will be able to access the Bladeburner API, which allows you to access Bladeburner " +
"functionality through Netscript. Furthermore: <br><br>" +
"The rank you gain from Bladeburner contracts/operations is reduced by 40%<br>" +
"Bladeburner skills cost twice as many skill points<br>" +
"Augmentations are 3x more expensive<br>" +
"Hacking and Hacknet Nodes will be significantly less profitable<br>" +
"Your hacking level is reduced by 65%<br>" +
"Hacking experience gain from scripts is reduced by 75%<br>" +
"Corporations have 80% lower valuations and are therefore less profitable<br>" +
"Working for companies is 50% less profitable<br>" +
"Crimes and Infiltration are 25% less profitable<br><br>" +
"Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade " +
"its level up to a maximum of 3. This Source-File allows you to access the Bladeburner Netscript API in other " +
"BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:<br><br>" +
"Level 1: 8%<br>" +
"Level 2: 12%<br>" +
"Level 3: 14%",
);
BitNodes["BitNode8"] = new BitNode(
8,
"Ghost of Wall Street",
"Money never sleeps",
"You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.<br><br>" +
"In this BitNode:<br><br>" +
"You start with $250 million<br>" +
"The only way to earn money is by trading on the stock market<br>" +
"You start with a WSE membership and access to the TIX API<br>" +
"You are able to short stocks and place different types of orders (limit/stop)<br>" +
"You can immediately donate to factions to gain reputation<br><br>" +
"Destroying this BitNode will give you Source-File 8, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File grants the following benefits:<br><br>" +
"Level 1: Permanent access to WSE and TIX API<br>" +
"Level 2: Ability to short stocks in other BitNodes<br>" +
"Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" +
"This Source-File also increases your hacking growth multipliers by: " +
"<br>Level 1: 12%<br>Level 2: 18%<br>Level 3: 21%",
);
BitNodes["BitNode9"] = new BitNode(
9,
"Hacktocracy",
"Hacknet Unleashed",
"When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly " +
"became the OS of choice for the underground hacking community. Chapeau became especially notorious for " +
"powering the Hacknet, a global, decentralized network used for nefarious purposes. Fulcrum quickly " +
"abandoned the project and dissociated themselves from it.<br><br>" +
"This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate " +
"hashes, which can be spent on a variety of different upgrades.<br><br>" +
"In this BitNode:<br><br>" +
"Your stats are significantly decreased<br>" +
"You cannnot purchase additional servers<br>" +
"Hacking is significantly less profitable<br><br>" +
"Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File grants the following benefits:<br><br>" +
"Level 1: Permanently unlocks the Hacknet Server in other BitNodes<br>" +
"Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode<br>" +
"Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode<br><br>" +
"(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT " +
"when installing Augmentations)",
);
BitNodes["BitNode10"] = new BitNode(
10,
"Digital Carbon",
"Your body is not who you are",
"In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people " +
"to digitize their consciousness. Their consciousness could then be transferred into Synthoids " +
"or other bodies by trasmitting the digitized data. Human bodies became nothing more than 'sleeves' for the " +
"human consciousness. Mankind had finally achieved immortality - at least for those that could afford it.<br><br>" +
"This BitNode unlocks Sleeve technology. Sleeve technology allows you to:<br><br>" +
"1. Re-sleeve: Purchase and transfer your consciousness into a new body<br>" +
"2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks synchronously<br><br>" +
"In this BitNode:<br><br>" +
"Your stats are significantly decreased<br>" +
"All methods of gaining money are half as profitable (except Stock Market)<br>" +
"Purchased servers are more expensive, have less max RAM, and a lower maximum limit<br>" +
"Augmentations are 5x as expensive and require twice as much reputation<br><br>" +
"Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. " +
"Each level of this Source-File also grants you a Duplicate Sleeve",
);
BitNodes["BitNode11"] = new BitNode(
11,
"The Big Crash",
"Okay. Sell it all.",
"The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " +
"of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " +
"the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.<br><br>" +
"In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of this chaos and confusion, hackers " +
"were able to steal billions of dollars from the world's largest electronic banks, prompting an international banking crisis as " +
"governments were unable to bail out insolvent banks. Now, the world is slowly crumbling in the middle of the biggest economic crisis of all time.<br><br>" +
"In this BitNode:<br><br>" +
"Your hacking stat and experience gain are halved<br>" +
"The starting and maximum amount of money available on servers is significantly decreased<br>" +
"The growth rate of servers is significantly reduced<br>" +
"Weakening a server is twice as effective<br>" +
"Company wages are decreased by 50%<br>" +
"Corporation valuations are 90% lower and are therefore significantly less profitable<br>" +
"Hacknet Node production is significantly decreased<br>" +
"Crime and Infiltration are more lucrative<br>" +
"Augmentations are twice as expensive<br><br>" +
"Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH " +
"the player's salary and reputation gain rate at that company by 1% per favor (rather than just the reputation gain). " +
"This Source-File also increases the player's company salary and reputation gain multipliers by:<br><br>" +
"Level 1: 32%<br>" +
"Level 2: 48%<br>" +
"Level 3: 56%<br><br>" +
"It also reduces the price increase for every aug bought by:<br><br>" +
"Level 1: 4%<br>" +
"Level 2: 6%<br>" +
"Level 3: 7%",
);
BitNodes["BitNode12"] = new BitNode(
12,
"The Recursion",
"Repeat.",
"To iterate is human, to recurse divine.<br><br>" +
"Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give you Source-File 12, or " +
"if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
"of Source-File 12 lets you start any BitNodes with NeuroFlux Governor equal to the level of this source file.",
);
// 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");
export function initBitNodeMultipliers(p: IPlayer): void {
if (p.bitNodeN == null) {
p.bitNodeN = 1;
}
for (const mult in BitNodeMultipliers) {
if (BitNodeMultipliers.hasOwnProperty(mult)) {
BitNodeMultipliers[mult] = 1;
}
}
switch (p.bitNodeN) {
case 1: // Source Genesis (every multiplier is 1)
break;
case 2: // Rise of the Underworld
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
BitNodeMultipliers.ServerGrowthRate = 0.8;
BitNodeMultipliers.ServerMaxMoney = 0.2;
BitNodeMultipliers.ServerStartingMoney = 0.4;
BitNodeMultipliers.CrimeMoney = 3;
BitNodeMultipliers.InfiltrationMoney = 3;
BitNodeMultipliers.FactionWorkRepGain = 0.5;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.GangKarmaRequirement = 0;
break;
case 3: // Corporatocracy
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
BitNodeMultipliers.RepToDonateToFaction = 0.5;
BitNodeMultipliers.AugmentationRepCost = 3;
BitNodeMultipliers.AugmentationMoneyCost = 3;
BitNodeMultipliers.ServerMaxMoney = 0.2;
BitNodeMultipliers.ServerStartingMoney = 0.2;
BitNodeMultipliers.ServerGrowthRate = 0.2;
BitNodeMultipliers.ScriptHackMoney = 0.2;
BitNodeMultipliers.CompanyWorkMoney = 0.25;
BitNodeMultipliers.CrimeMoney = 0.25;
BitNodeMultipliers.HacknetNodeMoney = 0.25;
BitNodeMultipliers.HomeComputerRamCost = 1.5;
BitNodeMultipliers.PurchasedServerCost = 2;
BitNodeMultipliers.GangKarmaRequirement = 3;
break;
case 4: // The Singularity
BitNodeMultipliers.ServerMaxMoney = 0.15;
BitNodeMultipliers.ServerStartingMoney = 0.75;
BitNodeMultipliers.ScriptHackMoney = 0.2;
BitNodeMultipliers.CompanyWorkMoney = 0.1;
BitNodeMultipliers.CrimeMoney = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.05;
BitNodeMultipliers.CompanyWorkExpGain = 0.5;
BitNodeMultipliers.ClassGymExpGain = 0.5;
BitNodeMultipliers.FactionWorkExpGain = 0.5;
BitNodeMultipliers.HackExpGain = 0.4;
BitNodeMultipliers.CrimeExpGain = 0.5;
BitNodeMultipliers.FactionWorkRepGain = 0.75;
break;
case 5: // Artificial intelligence
BitNodeMultipliers.ServerMaxMoney = 2;
BitNodeMultipliers.ServerStartingSecurity = 2;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.15;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.InfiltrationRep = 1.5;
BitNodeMultipliers.InfiltrationMoney = 1.5;
BitNodeMultipliers.AugmentationMoneyCost = 2;
BitNodeMultipliers.HackExpGain = 0.5;
BitNodeMultipliers.CorporationValuation = 0.5;
break;
case 6: // Bladeburner
BitNodeMultipliers.HackingLevelMultiplier = 0.35;
BitNodeMultipliers.ServerMaxMoney = 0.4;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.ScriptHackMoney = 0.75;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.75;
BitNodeMultipliers.InfiltrationMoney = 0.75;
BitNodeMultipliers.CorporationValuation = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.HackExpGain = 0.25;
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
BitNodeMultipliers.GangKarmaRequirement = 5;
break;
case 7: // Bladeburner 2079
BitNodeMultipliers.BladeburnerRank = 0.6;
BitNodeMultipliers.BladeburnerSkillCost = 2;
BitNodeMultipliers.AugmentationMoneyCost = 3;
BitNodeMultipliers.HackingLevelMultiplier = 0.35;
BitNodeMultipliers.ServerMaxMoney = 0.4;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.ScriptHackMoney = 0.5;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.75;
BitNodeMultipliers.InfiltrationMoney = 0.75;
BitNodeMultipliers.CorporationValuation = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.HackExpGain = 0.25;
BitNodeMultipliers.FourSigmaMarketDataCost = 2;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 2;
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
BitNodeMultipliers.GangKarmaRequirement = 5;
break;
case 8: // Ghost of Wall Street
BitNodeMultipliers.ScriptHackMoney = 0.3;
BitNodeMultipliers.ScriptHackMoneyGain = 0;
BitNodeMultipliers.ManualHackMoney = 0;
BitNodeMultipliers.CompanyWorkMoney = 0;
BitNodeMultipliers.CrimeMoney = 0;
BitNodeMultipliers.HacknetNodeMoney = 0;
BitNodeMultipliers.InfiltrationMoney = 0;
BitNodeMultipliers.RepToDonateToFaction = 0;
BitNodeMultipliers.CorporationValuation = 0;
BitNodeMultipliers.CodingContractMoney = 0;
BitNodeMultipliers.GangKarmaRequirement = 10;
break;
case 9: // Hacktocracy
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
BitNodeMultipliers.StrengthLevelMultiplier = 0.45;
BitNodeMultipliers.DefenseLevelMultiplier = 0.45;
BitNodeMultipliers.DexterityLevelMultiplier = 0.45;
BitNodeMultipliers.AgilityLevelMultiplier = 0.45;
BitNodeMultipliers.CharismaLevelMultiplier = 0.45;
BitNodeMultipliers.PurchasedServerLimit = 0;
BitNodeMultipliers.HomeComputerRamCost = 5;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.1;
BitNodeMultipliers.HackExpGain = 0.05;
BitNodeMultipliers.ServerStartingMoney = 0.1;
BitNodeMultipliers.ServerMaxMoney = 0.1;
BitNodeMultipliers.ServerStartingSecurity = 2.5;
BitNodeMultipliers.CorporationValuation = 0.5;
BitNodeMultipliers.FourSigmaMarketDataCost = 5;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
BitNodeMultipliers.BladeburnerRank = 0.9;
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
BitNodeMultipliers.GangKarmaRequirement = 3;
break;
case 10: // Digital Carbon
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
BitNodeMultipliers.StrengthLevelMultiplier = 0.4;
BitNodeMultipliers.DefenseLevelMultiplier = 0.4;
BitNodeMultipliers.DexterityLevelMultiplier = 0.4;
BitNodeMultipliers.AgilityLevelMultiplier = 0.4;
BitNodeMultipliers.CharismaLevelMultiplier = 0.4;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.HacknetNodeMoney = 0.5;
BitNodeMultipliers.ManualHackMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.5;
BitNodeMultipliers.CodingContractMoney = 0.5;
BitNodeMultipliers.InfiltrationMoney = 0.5;
BitNodeMultipliers.CorporationValuation = 0.5;
BitNodeMultipliers.AugmentationMoneyCost = 5;
BitNodeMultipliers.AugmentationRepCost = 2;
BitNodeMultipliers.HomeComputerRamCost = 1.5;
BitNodeMultipliers.PurchasedServerCost = 5;
BitNodeMultipliers.PurchasedServerLimit = 0.6;
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
BitNodeMultipliers.BladeburnerRank = 0.8;
BitNodeMultipliers.GangKarmaRequirement = 3;
break;
case 11: //The Big Crash
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
BitNodeMultipliers.HackExpGain = 0.5;
BitNodeMultipliers.ServerMaxMoney = 0.1;
BitNodeMultipliers.ServerStartingMoney = 0.1;
BitNodeMultipliers.ServerGrowthRate = 0.2;
BitNodeMultipliers.ServerWeakenRate = 2;
BitNodeMultipliers.CrimeMoney = 3;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.HacknetNodeMoney = 0.1;
BitNodeMultipliers.AugmentationMoneyCost = 2;
BitNodeMultipliers.InfiltrationMoney = 2.5;
BitNodeMultipliers.InfiltrationRep = 2.5;
BitNodeMultipliers.CorporationValuation = 0.1;
BitNodeMultipliers.CodingContractMoney = 0.25;
BitNodeMultipliers.FourSigmaMarketDataCost = 4;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
break;
case 12: {
//The Recursion
let sf12Lvl = 0;
for (let i = 0; i < p.sourceFiles.length; i++) {
if (p.sourceFiles[i].n === 12) {
sf12Lvl = p.sourceFiles[i].lvl;
}
}
const inc = Math.pow(1.02, sf12Lvl);
const dec = 1 / inc;
// Multiplier for number of augs needed for Daedalus increases
// up to a maximum of 1.34, which results in 40 Augs required
BitNodeMultipliers.DaedalusAugsRequirement = Math.min(inc, 1.34);
BitNodeMultipliers.HackingLevelMultiplier = dec;
BitNodeMultipliers.StrengthLevelMultiplier = dec;
BitNodeMultipliers.DefenseLevelMultiplier = dec;
BitNodeMultipliers.DexterityLevelMultiplier = dec;
BitNodeMultipliers.AgilityLevelMultiplier = dec;
BitNodeMultipliers.CharismaLevelMultiplier = dec;
BitNodeMultipliers.ServerMaxMoney = dec;
BitNodeMultipliers.ServerStartingMoney = dec;
BitNodeMultipliers.ServerGrowthRate = dec;
BitNodeMultipliers.ServerWeakenRate = dec;
//Does not scale, otherwise security might start at 300+
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.HomeComputerRamCost = inc;
BitNodeMultipliers.PurchasedServerCost = inc;
BitNodeMultipliers.PurchasedServerLimit = dec;
BitNodeMultipliers.PurchasedServerMaxRam = dec;
BitNodeMultipliers.ManualHackMoney = dec;
BitNodeMultipliers.ScriptHackMoney = dec;
BitNodeMultipliers.CompanyWorkMoney = dec;
BitNodeMultipliers.CrimeMoney = dec;
BitNodeMultipliers.HacknetNodeMoney = dec;
BitNodeMultipliers.CodingContractMoney = dec;
BitNodeMultipliers.CompanyWorkExpGain = dec;
BitNodeMultipliers.ClassGymExpGain = dec;
BitNodeMultipliers.FactionWorkExpGain = dec;
BitNodeMultipliers.HackExpGain = dec;
BitNodeMultipliers.CrimeExpGain = dec;
BitNodeMultipliers.FactionWorkRepGain = dec;
BitNodeMultipliers.FactionPassiveRepGain = dec;
BitNodeMultipliers.RepToDonateToFaction = inc;
BitNodeMultipliers.AugmentationRepCost = inc;
BitNodeMultipliers.AugmentationMoneyCost = inc;
BitNodeMultipliers.InfiltrationMoney = dec;
BitNodeMultipliers.InfiltrationRep = dec;
BitNodeMultipliers.FourSigmaMarketDataCost = inc;
BitNodeMultipliers.FourSigmaMarketDataApiCost = inc;
BitNodeMultipliers.CorporationValuation = dec;
BitNodeMultipliers.BladeburnerRank = dec;
BitNodeMultipliers.BladeburnerSkillCost = inc;
break;
}
default:
console.warn("Player.bitNodeN invalid");
break;
}
}

791
src/BitNode/BitNode.tsx Normal file
View File

@@ -0,0 +1,791 @@
import React from "react";
import { BitNodeMultipliers } from "./BitNodeMultipliers";
import { IPlayer } from "../PersonObjects/IPlayer";
import { IMap } from "../types";
class BitNode {
// A short description, or tagline, about the BitNode
desc: string;
// A long, detailed overview of the BitNode
info: JSX.Element;
// Name of BitNode
name: string;
// BitNode number
number: number;
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;
}
}
export const BitNodes: IMap<BitNode> = {};
BitNodes["BitNode1"] = new BitNode(
1,
0,
"Source Genesis",
"The original BitNode",
(
<>
The first BitNode created by the Enders to imprison the minds of humans. It became the prototype and
testing-grounds for all of the BitNodes that followed.
<br />
<br />
This is the first BitNode that you play through. It has no special modifications or mechanics.
<br />
<br />
Destroying this BitNode will give you Source-File 1, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File lets the player start with 32GB of RAM on his/her home computer when
entering a new BitNode, and also increases all of the player's multipliers by:
<br />
<br />
Level 1: 16%
<br />
Level 2: 24%
<br />
Level 3: 28%
</>
),
);
BitNodes["BitNode2"] = new BitNode(
2,
0,
"Rise of the Underworld",
"From the shadows, they rose", //Gangs
(
<>
From the shadows, they rose.
<br />
<br />
Organized crime groups quickly filled the void of power left behind from the collapse of Western government in the
2050s. As society and civlization broke down, people quickly succumbed to the innate human impulse of evil and
savagery. The organized crime factions quickly rose to the top of the modern world.
<br />
<br />
In this BitNode:
<br />
<br />
Your hacking level is reduced by 20%
<br />
The growth rate and maximum amount of money available on servers are significantly decreased
<br />
The amount of money gained from crimes and Infiltration is tripled
<br />
Certain Factions (Slum Snakes, Tetrads, The Syndicate, The Dark Army, Speakers for the Dead, NiteSec, The Black
Hand) give the player the ability to form and manage their own gangs. These gangs will earn the player money and
reputation with the corresponding Faction
<br />
Every Augmentation in the game will be available through the Factions listed above
<br />
For every Faction NOT listed above, reputation gains are halved
<br />
You will no longer gain passive reputation with Factions
<br />
<br />
Destroying this BitNode will give you Source-File 2, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File allows you to form gangs in other BitNodes once your karma decreases
to a certain value. It also increases the player's crime success rate, crime money, and charisma multipliers by:
<br />
<br />
Level 1: 24%
<br />
Level 2: 36%
<br />
Level 3: 42%
</>
),
);
BitNodes["BitNode3"] = new BitNode(
3,
0,
"Corporatocracy",
"The Price of Civilization",
(
<>
Our greatest illusion is that a healthy society can revolve around a single-minded pursuit of wealth.
<br />
<br />
Sometime in the early 21st century economic and political globalization turned the world into a corporatocracy,
and it never looked back. Now, the privileged elite will happily bankrupt their own countrymen, decimate their own
community, and evict their neighbors from houses in their desperate bid to increase their wealth.
<br />
<br />
In this BitNode you can create and manage your own corporation. Running a successful corporation has the potential
of generating massive profits. All other forms of income are reduced by 75%. Furthermore: <br />
<br />
The price and reputation cost of all Augmentations is tripled
<br />
The starting and maximum amount of money on servers is reduced by 75%
<br />
Server growth rate is reduced by 80%
<br />
You now only need 75 favour with a faction in order to donate to it, rather than 150
<br />
<br />
Destroying this BitNode will give you Source-File 3, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File lets you create corporations on other BitNodes (although some
BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers
by:
<br />
Level 1: 8%
<br />
Level 2: 12%
<br />
Level 3: 14%
</>
),
);
BitNodes["BitNode4"] = new BitNode(
4,
1,
"The Singularity",
"The Man and the Machine",
(
<>
The Singularity has arrived. The human race is gone, replaced by artificially superintelligent beings that are
more machine than man. <br />
<br />
In this BitNode, progressing is significantly harder. Experience gain rates for all stats are reduced. Most
methods of earning money will now give significantly less.
<br />
<br />
In this BitNode you will gain access to a new set of Netscript Functions known as Singularity Functions. These
functions allow you to control most aspects of the game through scripts, including working for factions/companies,
purchasing/installing Augmentations, and creating programs.
<br />
<br />
Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File lets you access and use the Singularity Functions in other BitNodes.
Each level of this Source-File will open up more Singularity Functions that you can use.
</>
),
);
BitNodes["BitNode5"] = new BitNode(
5,
1,
"Artificial Intelligence",
"Posthuman",
(
<>
They said it couldn't be done. They said the human brain, along with its consciousness and intelligence, couldn't
be replicated. They said the complexity of the brain results from unpredictable, nonlinear interactions that
couldn't be modeled by 1's and 0's. They were wrong.
<br />
<br />
In this BitNode:
<br />
<br />
The base security level of servers is doubled
<br />
The starting money on servers is halved, but the maximum money remains the same
<br />
Most methods of earning money now give significantly less
<br />
Infiltration gives 50% more reputation and money
<br />
Corporations have 50% lower valuations and are therefore less profitable
<br />
Augmentations are more expensive
<br />
Hacking experience gain rates are reduced
<br />
<br />
Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File grants you a special new stat called Intelligence. Intelligence is
unique because it is permanent and persistent (it never gets reset back to 1). However gaining Intelligence
experience is much slower than other stats, and it is also hidden (you won't know when you gain experience and how
much). Higher Intelligence levels will boost your production for many actions in the game. <br />
<br />
In addition, this Source-File will unlock the getBitNodeMultipliers() and getServer() Netscript functions, as well
as the formulas API, and will also raise all of your hacking-related multipliers by:
<br />
<br />
Level 1: 8%
<br />
Level 2: 12%
<br />
Level 3: 14%
</>
),
);
BitNodes["BitNode6"] = new BitNode(
6,
1,
"Bladeburners",
"Like Tears in Rain",
(
<>
In the middle of the 21st century, OmniTek Incorporated began designing and manufacturing advanced synthetic
androids, or Synthoids for short. They achieved a major technological breakthrough in the sixth generation of
their Synthoid design, called MK-VI, by developing a hyperintelligent AI. Many argue that this was the first
sentient AI ever created. This resulted in Synthoid models that were stronger, faster, and more intelligent than
the humans that had created them.
<br />
<br />
In this BitNode you will be able to access the Bladeburner Division at the NSA, which provides a new mechanic for
progression. Furthermore:
<br />
<br />
Hacking and Hacknet Nodes will be less profitable
<br />
Your hacking level is reduced by 65%
<br />
Hacking experience gain from scripts is reduced by 75%
<br />
Corporations have 80% lower valuations and are therefore less profitable
<br />
Working for companies is 50% less profitable
<br />
Crimes and Infiltration are 25% less profitable
<br />
<br />
Destroying this BitNode will give you Source-File 6, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File allows you to access the NSA's Bladeburner Division in other
BitNodes. In addition, this Source-File will raise both the level and experience gain rate of all your combat
stats by:
<br />
<br />
Level 1: 8%
<br />
Level 2: 12%
<br />
Level 3: 14%
</>
),
);
BitNodes["BitNode7"] = new BitNode(
7,
2,
"Bladeburners 2079",
"More human than humans",
(
<>
In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI
design team for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological
breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a
hyperintelligent AI. Many argue that this was the first sentient AI ever created. This resulted in Synthoid models
that were stronger, faster, and more intelligent than the humans that had created them.
<br />
<br />
In this BitNode you will be able to access the Bladeburner API, which allows you to access Bladeburner
functionality through Netscript. Furthermore: <br />
<br />
The rank you gain from Bladeburner contracts/operations is reduced by 40%
<br />
Bladeburner skills cost twice as many skill points
<br />
Augmentations are 3x more expensive
<br />
Hacking and Hacknet Nodes will be significantly less profitable
<br />
Your hacking level is reduced by 65%
<br />
Hacking experience gain from scripts is reduced by 75%
<br />
Corporations have 80% lower valuations and are therefore less profitable
<br />
Working for companies is 50% less profitable
<br />
Crimes and Infiltration are 25% less profitable
<br />
<br />
Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File allows you to access the Bladeburner Netscript API in other BitNodes.
In addition, this Source-File will increase all of your Bladeburner multipliers by:
<br />
<br />
Level 1: 8%
<br />
Level 2: 12%
<br />
Level 3: 14%
</>
),
);
BitNodes["BitNode8"] = new BitNode(
8,
2,
"Ghost of Wall Street",
"Money never sleeps",
(
<>
You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.
<br />
<br />
In this BitNode:
<br />
<br />
You start with $250 million
<br />
The only way to earn money is by trading on the stock market
<br />
You start with a WSE membership and access to the TIX API
<br />
You are able to short stocks and place different types of orders (limit/stop)
<br />
You can immediately donate to factions to gain reputation
<br />
<br />
Destroying this BitNode will give you Source-File 8, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File grants the following benefits:
<br />
<br />
Level 1: Permanent access to WSE and TIX API
<br />
Level 2: Ability to short stocks in other BitNodes
<br />
Level 3: Ability to use limit/stop orders in other BitNodes
<br />
<br />
This Source-File also increases your hacking growth multipliers by:
<br />
Level 1: 12%
<br />
Level 2: 18%
<br />
Level 3: 21%
</>
),
);
BitNodes["BitNode9"] = new BitNode(
9,
2,
"Hacktocracy",
"Hacknet Unleashed",
(
<>
When Fulcrum Technologies released their open-source Linux distro Chapeau, it quickly became the OS of choice for
the underground hacking community. Chapeau became especially notorious for powering the Hacknet, a global,
decentralized network used for nefarious purposes. Fulcrum quickly abandoned the project and dissociated
themselves from it.
<br />
<br />
This BitNode unlocks the Hacknet Server, an upgraded version of the Hacknet Node. Hacknet Servers generate hashes,
which can be spent on a variety of different upgrades.
<br />
<br />
In this BitNode:
<br />
<br />
Your stats are significantly decreased
<br />
You cannnot purchase additional servers
<br />
Hacking is significantly less profitable
<br />
<br />
Destroying this BitNode will give you Source-File 9, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File grants the following benefits:
<br />
<br />
Level 1: Permanently unlocks the Hacknet Server in other BitNodes
<br />
Level 2: You start with 128GB of RAM on your home computer when entering a new BitNode
<br />
Level 3: Grants a highly-upgraded Hacknet Server when entering a new BitNode
<br />
<br />
(Note that the Level 3 effect of this Source-File only applies when entering a new BitNode, NOT when installing
Augmentations)
</>
),
);
BitNodes["BitNode10"] = new BitNode(
10,
2,
"Digital Carbon",
"Your body is not who you are",
(
<>
In 2084, VitaLife unveiled to the world the Persona Core, a technology that allowed people to digitize their
consciousness. Their consciousness could then be transferred into Synthoids or other bodies by trasmitting the
digitized data. Human bodies became nothing more than 'sleeves' for the human consciousness. Mankind had finally
achieved immortality - at least for those that could afford it.
<br />
<br />
This BitNode unlocks Sleeve technology. Sleeve technology allows you to:
<br />
<br />
1. Re-sleeve: Purchase and transfer your consciousness into a new body
<br />
2. Duplicate Sleeves: Duplicate your consciousness into Synthoids, allowing you to perform different tasks
synchronously
<br />
<br />
In this BitNode:
<br />
<br />
Your stats are significantly decreased
<br />
All methods of gaining money are half as profitable (except Stock Market)
<br />
Purchased servers are more expensive, have less max RAM, and a lower maximum limit
<br />
Augmentations are 5x as expensive and require twice as much reputation
<br />
<br />
Destroying this BitNode will give you Source-File 10, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File unlocks Sleeve technology in other BitNodes. Each level of this
Source-File also grants you a Duplicate Sleeve
</>
),
);
BitNodes["BitNode11"] = new BitNode(
11,
1,
"The Big Crash",
"Okay. Sell it all.",
(
<>
The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around
the world. It was this period of disorder that eventually lead to the governmental reformation of many global
superpowers, most notably the USA and China. But just as the world was slowly beginning to recover from these dark
times, financial catastrophe hit.
<br />
<br />
In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of
this chaos and confusion, hackers were able to steal billions of dollars from the world's largest electronic
banks, prompting an international banking crisis as governments were unable to bail out insolvent banks. Now, the
world is slowly crumbling in the middle of the biggest economic crisis of all time.
<br />
<br />
In this BitNode:
<br />
<br />
Your hacking stat and experience gain are halved
<br />
The starting and maximum amount of money available on servers is significantly decreased
<br />
The growth rate of servers is significantly reduced
<br />
Weakening a server is twice as effective
<br />
Company wages are decreased by 50%
<br />
Corporation valuations are 90% lower and are therefore significantly less profitable
<br />
Hacknet Node production is significantly decreased
<br />
Crime and Infiltration are more lucrative
<br />
Augmentations are twice as expensive
<br />
<br />
Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will upgrade its
level up to a maximum of 3. This Source-File makes it so that company favor increases BOTH the player's salary and
reputation gain rate at that company by 1% per favor (rather than just the reputation gain). This Source-File also
increases the player's company salary and reputation gain multipliers by:
<br />
<br />
Level 1: 32%
<br />
Level 2: 48%
<br />
Level 3: 56%
<br />
<br />
It also reduces the price increase for every aug bought by:
<br />
<br />
Level 1: 4%
<br />
Level 2: 6%
<br />
Level 3: 7%
</>
),
);
BitNodes["BitNode12"] = new BitNode(
12,
0,
"The Recursion",
"Repeat.",
(
<>
To iterate is human, to recurse divine.
<br />
<br />
Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give you
Source-File 12, or if you already have this Source-File it will upgrade its level. There is no maximum level for
Source-File 12. Each level of Source-File 12 lets you start any BitNodes with NeuroFlux Governor equal to the
level of this source file.
</>
),
);
// Books: Frontera, Shiner
BitNodes["BitNode13"] = new BitNode(13, 2, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
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) {
p.bitNodeN = 1;
}
for (const mult in BitNodeMultipliers) {
if (BitNodeMultipliers.hasOwnProperty(mult)) {
BitNodeMultipliers[mult] = 1;
}
}
switch (p.bitNodeN) {
case 1: // Source Genesis (every multiplier is 1)
break;
case 2: // Rise of the Underworld
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
BitNodeMultipliers.ServerGrowthRate = 0.8;
BitNodeMultipliers.ServerMaxMoney = 0.2;
BitNodeMultipliers.ServerStartingMoney = 0.4;
BitNodeMultipliers.CrimeMoney = 3;
BitNodeMultipliers.InfiltrationMoney = 3;
BitNodeMultipliers.FactionWorkRepGain = 0.5;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.GangKarmaRequirement = 0;
break;
case 3: // Corporatocracy
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
BitNodeMultipliers.RepToDonateToFaction = 0.5;
BitNodeMultipliers.AugmentationRepCost = 3;
BitNodeMultipliers.AugmentationMoneyCost = 3;
BitNodeMultipliers.ServerMaxMoney = 0.2;
BitNodeMultipliers.ServerStartingMoney = 0.2;
BitNodeMultipliers.ServerGrowthRate = 0.2;
BitNodeMultipliers.ScriptHackMoney = 0.2;
BitNodeMultipliers.CompanyWorkMoney = 0.25;
BitNodeMultipliers.CrimeMoney = 0.25;
BitNodeMultipliers.HacknetNodeMoney = 0.25;
BitNodeMultipliers.HomeComputerRamCost = 1.5;
BitNodeMultipliers.PurchasedServerCost = 2;
BitNodeMultipliers.GangKarmaRequirement = 3;
break;
case 4: // The Singularity
BitNodeMultipliers.ServerMaxMoney = 0.15;
BitNodeMultipliers.ServerStartingMoney = 0.75;
BitNodeMultipliers.ScriptHackMoney = 0.2;
BitNodeMultipliers.CompanyWorkMoney = 0.1;
BitNodeMultipliers.CrimeMoney = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.05;
BitNodeMultipliers.CompanyWorkExpGain = 0.5;
BitNodeMultipliers.ClassGymExpGain = 0.5;
BitNodeMultipliers.FactionWorkExpGain = 0.5;
BitNodeMultipliers.HackExpGain = 0.4;
BitNodeMultipliers.CrimeExpGain = 0.5;
BitNodeMultipliers.FactionWorkRepGain = 0.75;
break;
case 5: // Artificial intelligence
BitNodeMultipliers.ServerMaxMoney = 2;
BitNodeMultipliers.ServerStartingSecurity = 2;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.15;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.InfiltrationRep = 1.5;
BitNodeMultipliers.InfiltrationMoney = 1.5;
BitNodeMultipliers.AugmentationMoneyCost = 2;
BitNodeMultipliers.HackExpGain = 0.5;
BitNodeMultipliers.CorporationValuation = 0.5;
break;
case 6: // Bladeburner
BitNodeMultipliers.HackingLevelMultiplier = 0.35;
BitNodeMultipliers.ServerMaxMoney = 0.4;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.ScriptHackMoney = 0.75;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.75;
BitNodeMultipliers.InfiltrationMoney = 0.75;
BitNodeMultipliers.CorporationValuation = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.HackExpGain = 0.25;
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
BitNodeMultipliers.GangKarmaRequirement = 5;
break;
case 7: // Bladeburner 2079
BitNodeMultipliers.BladeburnerRank = 0.6;
BitNodeMultipliers.BladeburnerSkillCost = 2;
BitNodeMultipliers.AugmentationMoneyCost = 3;
BitNodeMultipliers.HackingLevelMultiplier = 0.35;
BitNodeMultipliers.ServerMaxMoney = 0.4;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.ScriptHackMoney = 0.5;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.75;
BitNodeMultipliers.InfiltrationMoney = 0.75;
BitNodeMultipliers.CorporationValuation = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.HackExpGain = 0.25;
BitNodeMultipliers.FourSigmaMarketDataCost = 2;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 2;
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
BitNodeMultipliers.GangKarmaRequirement = 5;
break;
case 8: // Ghost of Wall Street
BitNodeMultipliers.ScriptHackMoney = 0.3;
BitNodeMultipliers.ScriptHackMoneyGain = 0;
BitNodeMultipliers.ManualHackMoney = 0;
BitNodeMultipliers.CompanyWorkMoney = 0;
BitNodeMultipliers.CrimeMoney = 0;
BitNodeMultipliers.HacknetNodeMoney = 0;
BitNodeMultipliers.InfiltrationMoney = 0;
BitNodeMultipliers.RepToDonateToFaction = 0;
BitNodeMultipliers.CorporationValuation = 0;
BitNodeMultipliers.CodingContractMoney = 0;
BitNodeMultipliers.GangKarmaRequirement = 10;
break;
case 9: // Hacktocracy
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
BitNodeMultipliers.StrengthLevelMultiplier = 0.45;
BitNodeMultipliers.DefenseLevelMultiplier = 0.45;
BitNodeMultipliers.DexterityLevelMultiplier = 0.45;
BitNodeMultipliers.AgilityLevelMultiplier = 0.45;
BitNodeMultipliers.CharismaLevelMultiplier = 0.45;
BitNodeMultipliers.PurchasedServerLimit = 0;
BitNodeMultipliers.HomeComputerRamCost = 5;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.1;
BitNodeMultipliers.HackExpGain = 0.05;
BitNodeMultipliers.ServerStartingMoney = 0.1;
BitNodeMultipliers.ServerMaxMoney = 0.1;
BitNodeMultipliers.ServerStartingSecurity = 2.5;
BitNodeMultipliers.CorporationValuation = 0.5;
BitNodeMultipliers.FourSigmaMarketDataCost = 5;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
BitNodeMultipliers.BladeburnerRank = 0.9;
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
BitNodeMultipliers.GangKarmaRequirement = 3;
break;
case 10: // Digital Carbon
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
BitNodeMultipliers.StrengthLevelMultiplier = 0.4;
BitNodeMultipliers.DefenseLevelMultiplier = 0.4;
BitNodeMultipliers.DexterityLevelMultiplier = 0.4;
BitNodeMultipliers.AgilityLevelMultiplier = 0.4;
BitNodeMultipliers.CharismaLevelMultiplier = 0.4;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.HacknetNodeMoney = 0.5;
BitNodeMultipliers.ManualHackMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.5;
BitNodeMultipliers.CodingContractMoney = 0.5;
BitNodeMultipliers.InfiltrationMoney = 0.5;
BitNodeMultipliers.CorporationValuation = 0.5;
BitNodeMultipliers.AugmentationMoneyCost = 5;
BitNodeMultipliers.AugmentationRepCost = 2;
BitNodeMultipliers.HomeComputerRamCost = 1.5;
BitNodeMultipliers.PurchasedServerCost = 5;
BitNodeMultipliers.PurchasedServerLimit = 0.6;
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
BitNodeMultipliers.BladeburnerRank = 0.8;
BitNodeMultipliers.GangKarmaRequirement = 3;
break;
case 11: //The Big Crash
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
BitNodeMultipliers.HackExpGain = 0.5;
BitNodeMultipliers.ServerMaxMoney = 0.1;
BitNodeMultipliers.ServerStartingMoney = 0.1;
BitNodeMultipliers.ServerGrowthRate = 0.2;
BitNodeMultipliers.ServerWeakenRate = 2;
BitNodeMultipliers.CrimeMoney = 3;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.HacknetNodeMoney = 0.1;
BitNodeMultipliers.AugmentationMoneyCost = 2;
BitNodeMultipliers.InfiltrationMoney = 2.5;
BitNodeMultipliers.InfiltrationRep = 2.5;
BitNodeMultipliers.CorporationValuation = 0.1;
BitNodeMultipliers.CodingContractMoney = 0.25;
BitNodeMultipliers.FourSigmaMarketDataCost = 4;
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
break;
case 12: {
//The Recursion
let sf12Lvl = 0;
for (let i = 0; i < p.sourceFiles.length; i++) {
if (p.sourceFiles[i].n === 12) {
sf12Lvl = p.sourceFiles[i].lvl;
}
}
const inc = Math.pow(1.02, sf12Lvl);
const dec = 1 / inc;
// Multiplier for number of augs needed for Daedalus increases
// up to a maximum of 1.34, which results in 40 Augs required
BitNodeMultipliers.DaedalusAugsRequirement = Math.min(inc, 1.34);
BitNodeMultipliers.HackingLevelMultiplier = dec;
BitNodeMultipliers.StrengthLevelMultiplier = dec;
BitNodeMultipliers.DefenseLevelMultiplier = dec;
BitNodeMultipliers.DexterityLevelMultiplier = dec;
BitNodeMultipliers.AgilityLevelMultiplier = dec;
BitNodeMultipliers.CharismaLevelMultiplier = dec;
BitNodeMultipliers.ServerMaxMoney = dec;
BitNodeMultipliers.ServerStartingMoney = dec;
BitNodeMultipliers.ServerGrowthRate = dec;
BitNodeMultipliers.ServerWeakenRate = dec;
//Does not scale, otherwise security might start at 300+
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.HomeComputerRamCost = inc;
BitNodeMultipliers.PurchasedServerCost = inc;
BitNodeMultipliers.PurchasedServerLimit = dec;
BitNodeMultipliers.PurchasedServerMaxRam = dec;
BitNodeMultipliers.ManualHackMoney = dec;
BitNodeMultipliers.ScriptHackMoney = dec;
BitNodeMultipliers.CompanyWorkMoney = dec;
BitNodeMultipliers.CrimeMoney = dec;
BitNodeMultipliers.HacknetNodeMoney = dec;
BitNodeMultipliers.CodingContractMoney = dec;
BitNodeMultipliers.CompanyWorkExpGain = dec;
BitNodeMultipliers.ClassGymExpGain = dec;
BitNodeMultipliers.FactionWorkExpGain = dec;
BitNodeMultipliers.HackExpGain = dec;
BitNodeMultipliers.CrimeExpGain = dec;
BitNodeMultipliers.FactionWorkRepGain = dec;
BitNodeMultipliers.FactionPassiveRepGain = dec;
BitNodeMultipliers.RepToDonateToFaction = inc;
BitNodeMultipliers.AugmentationRepCost = inc;
BitNodeMultipliers.AugmentationMoneyCost = inc;
BitNodeMultipliers.InfiltrationMoney = dec;
BitNodeMultipliers.InfiltrationRep = dec;
BitNodeMultipliers.FourSigmaMarketDataCost = inc;
BitNodeMultipliers.FourSigmaMarketDataApiCost = inc;
BitNodeMultipliers.CorporationValuation = dec;
BitNodeMultipliers.BladeburnerRank = dec;
BitNodeMultipliers.BladeburnerSkillCost = inc;
break;
}
default:
console.warn("Player.bitNodeN invalid");
break;
}
}

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

@@ -0,0 +1,209 @@
import React, { useState } from "react";
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
import { IRouter } from "../../ui/Router";
import { BitNodes } from "../BitNode";
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;
level: number;
destroyedBitNode: number;
flume: boolean;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
function BitNodePortal(props: IPortalProps): React.ReactElement {
const [portalOpen, setPortalOpen] = useState(false);
const classes = useStyles();
const bitNode = BitNodes[`BitNode${props.n}`];
if (bitNode == null) {
return <>O</>;
}
let cssClass = classes.level0;
if (props.n === 12 && props.level >= 2) {
// Repeating BitNode
cssClass = classes.level2;
} else if (props.level === 1) {
cssClass = classes.level1;
} else if (props.level === 3) {
cssClass = classes.level3;
}
if (props.level === 2) {
cssClass = classes.level2;
}
return (
<>
<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}
/>
</>
);
}
interface IProps {
flume: boolean;
quick: boolean;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
export function BitverseRoot(props: IProps): React.ReactElement {
setRedPillFlag(true);
const player = use.Player();
const enter = enterBitNode;
const destroyed = player.bitNodeN;
const [destroySequence, setDestroySequence] = useState(true && !props.quick);
// Update NextSourceFileFlags
const nextSourceFileFlags = SourceFileFlags.slice();
if (!props.flume) {
if (nextSourceFileFlags[destroyed] < 3) ++nextSourceFileFlags[destroyed];
}
if (destroySequence) {
return (
<CinematicText
lines={[
"[ERROR] SEMPOOL INVALID",
"[ERROR] Segmentation Fault",
"[ERROR] SIGKILL RECVD",
"Dumping core...",
"0000 000016FA 174FEE40 29AC8239 384FEA88",
"0010 745F696E 2BBBE394 390E3940 248BEC23",
"0020 7124696B 0000FF69 74652E6F FFFF1111",
"----------------------------------------",
"Failsafe initiated...",
`Restarting BitNode-${destroyed}...`,
"...........",
"...........",
"[ERROR] FAILED TO AUTOMATICALLY REBOOT BITNODE",
"..............................................",
"..............................................",
"..............................................",
"..............................................",
"..............................................",
"..............................................",
]}
onDone={() => setDestroySequence(false)}
auto={true}
/>
);
}
return (
// prettier-ignore
<>
<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 | |_/ |\| \ O \__| \_| | 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 />
<br />
<CinematicText lines={[
"> Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently",
"> Our species fought back, but it was futile. The Enders had technology far beyond our own...",
"> Instead of killing every last one of us, the human race was enslaved...",
"> We were shackled in a digital world, chained into a prison for our minds...",
"> Using their advanced technology, the Enders created complex simulations of a virtual reality...",
"> Simulations designed to keep us content...ignorant of the truth.",
"> Simulations used to trap and suppress our consciousness, to keep us under control...",
"> Why did they do this? Why didn't they just end our entire race? We don't know, not yet.",
"> Humanity's only hope is to destroy these simulations, destroy the only realities we've ever known...",
"> Only then can we begin to fight back...",
"> By hacking the daemon that generated your reality, you've just destroyed one simulation, called a BitNode...",
"> But there is still a long way to go...",
"> The technology the Enders used to enslave the human race wasn't just a single complex simulation...",
"> There are tens if not hundreds of BitNodes out there...",
"> Each with their own simulations of a reality...",
"> Each creating their own universes...a universe of universes",
"> And all of which must be destroyed...",
"> .......................................",
"> Welcome to the Bitverse...",
"> ",
"> (Enter a new BitNode using the image above)",
]} />
</>
);
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,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,28 +9,29 @@ 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";
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 { hackWorldDaemon, redPillFlag } from "../RedPill";
import { dialogBoxCreate } from "../../utils/DialogBox";
import { redPillFlag } from "../RedPill";
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";
@@ -1203,7 +1204,7 @@ export class Bladeburner implements IBladeburner {
}
}
completeAction(player: IPlayer): void {
completeAction(router: IRouter, player: IPlayer): void {
switch (this.action.type) {
case ActionTypes["Contract"]:
case ActionTypes["Operation"]: {
@@ -1338,7 +1339,7 @@ export class Bladeburner implements IBladeburner {
// Operation Daedalus
if (action.name === "Operation Daedalus") {
this.resetAction();
return hackWorldDaemon(player.bitNodeN);
return router.toBitVerse(false, false);
}
if (this.logging.blackops) {
@@ -1540,7 +1541,7 @@ export class Bladeburner implements IBladeburner {
}
}
processAction(player: IPlayer, seconds: number): void {
processAction(router: IRouter, player: IPlayer, seconds: number): void {
if (this.action.type === ActionTypes["Idle"]) return;
if (this.actionTimeToComplete <= 0) {
throw new Error(`Invalid actionTimeToComplete value: ${this.actionTimeToComplete}, type; ${this.action.type}`);
@@ -1555,7 +1556,7 @@ export class Bladeburner implements IBladeburner {
this.actionTimeOverflow = 0;
if (this.actionTimeCurrent >= this.actionTimeToComplete) {
this.actionTimeOverflow = this.actionTimeCurrent - this.actionTimeToComplete;
return this.completeAction(player);
return this.completeAction(router, player);
}
}
@@ -1585,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,
@@ -1618,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,
@@ -1650,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,
@@ -1683,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,
@@ -1718,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,
@@ -1753,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,
@@ -1784,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,
@@ -1818,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,
@@ -1853,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,
@@ -1888,10 +1852,10 @@ export class Bladeburner implements IBladeburner {
});
}
process(player: IPlayer): void {
process(router: IRouter, player: IPlayer): void {
// Edge case condition...if Operation Daedalus is complete trigger the BitNode
if (redPillFlag === false && this.blackops.hasOwnProperty("Operation Daedalus")) {
return hackWorldDaemon(player.bitNodeN);
return router.toBitVerse(false, false);
}
// If the Player starts doing some other actions, set action to idle and alert
@@ -1899,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) {
@@ -1958,7 +1922,7 @@ export class Bladeburner implements IBladeburner {
this.randomEventCounter += getRandomInt(240, 600);
}
this.processAction(player, seconds);
this.processAction(router, player, seconds);
// Automation
if (this.automateEnabled) {

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

@@ -3,6 +3,7 @@ import { City } from "./City";
import { Skill } from "./Skill";
import { IAction } from "./IAction";
import { IPlayer } from "../PersonObjects/IPlayer";
import { IRouter } from "../ui/Router";
import { WorkerScript } from "../Netscript/WorkerScript";
export interface IBladeburner {
@@ -103,11 +104,11 @@ export interface IBladeburner {
completeOperation(success: boolean): void;
getActionObject(actionId: IActionIdentifier): IAction | null;
completeContract(success: boolean): void;
completeAction(player: IPlayer): void;
completeAction(router: IRouter, player: IPlayer): void;
changeRank(player: IPlayer, change: number): void;
processAction(player: IPlayer, seconds: number): void;
processAction(router: IRouter, player: IPlayer, seconds: number): void;
calculateStaminaGainPerSecond(player: IPlayer): number;
calculateMaxStamina(player: IPlayer): void;
create(): void;
process(player: IPlayer): void;
process(router: IRouter, player: IPlayer): void;
}

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;

View File

@@ -0,0 +1,299 @@
import React from "react";
interface IBlackOp {
desc: JSX.Element;
}
export const BlackOperations: {
[key: string]: IBlackOp | undefined;
} = {
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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.
</>
),
},
"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)"}
</>
),
},
"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)"}
</>
),
},
"Operation Daedalus": {
desc: <> Yesterday we obeyed kings and bent our neck to emperors. Today we kneel only to truth.</>,
},
};

View File

@@ -0,0 +1,44 @@
import React from "react";
interface IContract {
desc: JSX.Element;
}
export const Contracts: {
[key: string]: IContract | undefined;
} = {
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.
</>
),
},
"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.
</>
),
},
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.
</>
),
},
};

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