mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 14:59:16 +02:00
Compare commits
51 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db2bf79e3b | ||
|
|
6f330efc44 | ||
|
|
708c73fa0f | ||
|
|
c7febd5551 | ||
|
|
ddbdf66d00 | ||
|
|
e572c6dad8 | ||
|
|
ff097db1e2 | ||
|
|
ad12f0e551 | ||
|
|
93f8785ec6 | ||
|
|
69124e7146 | ||
|
|
8a42f6e49c | ||
|
|
2ac4cd41bb | ||
|
|
28584c8461 | ||
|
|
1eddddd14f | ||
|
|
42e9a368b4 | ||
|
|
40713a4112 | ||
|
|
8e79658e67 | ||
|
|
6efc3ec75e | ||
|
|
9840e1f4eb | ||
|
|
7cdca5e813 | ||
|
|
d170693da4 | ||
|
|
31a9c041b4 | ||
|
|
ce7c2c309c | ||
|
|
29abffd464 | ||
|
|
ae4b8228f7 | ||
|
|
04bc2bebdd | ||
|
|
8f30e60d08 | ||
|
|
e8aa1851c5 | ||
|
|
7232a786ed | ||
|
|
2507899762 | ||
|
|
26149d5a01 | ||
|
|
670394ca2f | ||
|
|
e0745d7757 | ||
|
|
dc79f7a940 | ||
|
|
bf4d841f88 | ||
|
|
4c30f107e3 | ||
|
|
c9fe8d9b65 | ||
|
|
29ea1281e0 | ||
|
|
3ec54bcdd8 | ||
|
|
4892f0bd79 | ||
|
|
62c571ef3a | ||
|
|
6c57d548ec | ||
|
|
6c0b5b3ed9 | ||
|
|
f288d982db | ||
|
|
101834fcaf | ||
|
|
642c7a107a | ||
|
|
63da8d709a | ||
|
|
753a1f1193 | ||
|
|
726c36f276 | ||
|
|
640795dbe9 | ||
|
|
802f28082d |
10
README_contribution.md
Normal file
10
README_contribution.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Deploying a new version
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
Update the following
|
||||||
|
- `src/Constants.ts` `Version` and `LatestUpdate`
|
||||||
|
- `package.json` `version`
|
||||||
|
- `doc/source/conf.py` `version` and `release`
|
||||||
|
- `doc/source/changelog.rst`
|
||||||
|
- post to discord
|
||||||
|
- post to reddit.com/r/Bitburner
|
||||||
@@ -184,5 +184,4 @@
|
|||||||
|
|
||||||
#infiltration-buttons .a-link-button {
|
#infiltration-buttons .a-link-button {
|
||||||
display: inline;
|
display: inline;
|
||||||
width: 25%;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,10 +356,27 @@ a:visited {
|
|||||||
color: $my-stat-cha-color;
|
color: $my-stat-cha-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reputation {
|
||||||
|
color: $light-yellow;
|
||||||
|
}
|
||||||
|
|
||||||
.smallfont {
|
.smallfont {
|
||||||
font-size: $defaultFontSize * 0.8125;
|
font-size: $defaultFontSize * 0.8125;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.samefont {
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noscrollbar {
|
||||||
|
-ms-overflow-style: none; /* IE and Edge */
|
||||||
|
scrollbar-width: none; /* Firefox */
|
||||||
|
}
|
||||||
|
|
||||||
|
.noscrollbar::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
input[type=checkbox] {
|
input[type=checkbox] {
|
||||||
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10);
|
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10);
|
||||||
}
|
}
|
||||||
@@ -395,4 +412,12 @@ input[type=checkbox] {
|
|||||||
height: 10px;
|
height: 10px;
|
||||||
background: var(--my-font-color);
|
background: var(--my-font-color);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.noselect {
|
||||||
|
-moz-user-select: -moz-none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
}
|
}
|
||||||
@@ -85,3 +85,45 @@
|
|||||||
.tooltip:hover .tooltiptextlow {
|
.tooltip:hover .tooltiptextlow {
|
||||||
visibility: visible;
|
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;
|
||||||
|
}
|
||||||
4
dist/engine.bundle.js
vendored
4
dist/engine.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/engineStyle.bundle.js
vendored
2
dist/engineStyle.bundle.js
vendored
@@ -1,2 +1,2 @@
|
|||||||
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],p=0,s=[];p<f.length;p++)i=f[p],u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(a&&a(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={1:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var a=c;r.push([377,0]),o()}({320:function(n,t,o){},322:function(n,t,o){},324:function(n,t,o){},326:function(n,t,o){},328:function(n,t,o){},330:function(n,t,o){},332:function(n,t,o){},334:function(n,t,o){},336:function(n,t,o){},338:function(n,t,o){},340:function(n,t,o){},342:function(n,t,o){},344:function(n,t,o){},346:function(n,t,o){},348:function(n,t,o){},350:function(n,t,o){},352:function(n,t,o){},354:function(n,t,o){},356:function(n,t,o){},358:function(n,t,o){},360:function(n,t,o){},362:function(n,t,o){},364:function(n,t,o){},366:function(n,t,o){},368:function(n,t,o){},370:function(n,t,o){},372:function(n,t,o){},374:function(n,t,o){},377:function(n,t,o){"use strict";o.r(t);o(376),o(374),o(372),o(370),o(368),o(366),o(364),o(362),o(360),o(358),o(356),o(354),o(352),o(350),o(348),o(346),o(344),o(342),o(340),o(338),o(336),o(334),o(332),o(330),o(328),o(326),o(324),o(322),o(320)}});
|
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],p=0,s=[];p<f.length;p++)i=f[p],u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(a&&a(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={1:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var a=c;r.push([396,0]),o()}({339:function(n,t,o){},341:function(n,t,o){},343:function(n,t,o){},345:function(n,t,o){},347:function(n,t,o){},349:function(n,t,o){},351:function(n,t,o){},353:function(n,t,o){},355:function(n,t,o){},357:function(n,t,o){},359:function(n,t,o){},361:function(n,t,o){},363:function(n,t,o){},365:function(n,t,o){},367:function(n,t,o){},369:function(n,t,o){},371:function(n,t,o){},373:function(n,t,o){},375:function(n,t,o){},377:function(n,t,o){},379:function(n,t,o){},381:function(n,t,o){},383:function(n,t,o){},385:function(n,t,o){},387:function(n,t,o){},389:function(n,t,o){},391:function(n,t,o){},393:function(n,t,o){},396:function(n,t,o){"use strict";o.r(t);o(395),o(393),o(391),o(389),o(387),o(385),o(383),o(381),o(379),o(377),o(375),o(373),o(371),o(369),o(367),o(365),o(363),o(361),o(359),o(357),o(355),o(353),o(351),o(349),o(347),o(345),o(343),o(341),o(339)}});
|
||||||
//# sourceMappingURL=engineStyle.bundle.js.map
|
//# sourceMappingURL=engineStyle.bundle.js.map
|
||||||
62
dist/engineStyle.css
vendored
62
dist/engineStyle.css
vendored
@@ -353,9 +353,24 @@ a:visited {
|
|||||||
.charisma-purple {
|
.charisma-purple {
|
||||||
color: #a671d1; }
|
color: #a671d1; }
|
||||||
|
|
||||||
|
.reputation {
|
||||||
|
color: #faffdf; }
|
||||||
|
|
||||||
.smallfont {
|
.smallfont {
|
||||||
font-size: 13px; }
|
font-size: 13px; }
|
||||||
|
|
||||||
|
.samefont {
|
||||||
|
font-size: inherit; }
|
||||||
|
|
||||||
|
.noscrollbar {
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
/* IE and Edge */
|
||||||
|
scrollbar-width: none;
|
||||||
|
/* Firefox */ }
|
||||||
|
|
||||||
|
.noscrollbar::-webkit-scrollbar {
|
||||||
|
display: none; }
|
||||||
|
|
||||||
input[type=checkbox] {
|
input[type=checkbox] {
|
||||||
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10); }
|
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10); }
|
||||||
|
|
||||||
@@ -387,6 +402,13 @@ input[type=checkbox] {
|
|||||||
background: var(--my-font-color);
|
background: var(--my-font-color);
|
||||||
cursor: pointer; }
|
cursor: pointer; }
|
||||||
|
|
||||||
|
.noselect {
|
||||||
|
-moz-user-select: -moz-none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none; }
|
||||||
|
|
||||||
/* COLORS */
|
/* COLORS */
|
||||||
/* Attributes */
|
/* Attributes */
|
||||||
/* Styling for tooltip-style elements */
|
/* Styling for tooltip-style elements */
|
||||||
@@ -460,6 +482,43 @@ input[type=checkbox] {
|
|||||||
.tooltip:hover .tooltiptextlow {
|
.tooltip:hover .tooltiptextlow {
|
||||||
visibility: visible; }
|
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; }
|
||||||
|
|
||||||
/* COLORS */
|
/* COLORS */
|
||||||
/* Attributes */
|
/* Attributes */
|
||||||
/**
|
/**
|
||||||
@@ -1315,8 +1374,7 @@ button {
|
|||||||
margin-top: 20px; }
|
margin-top: 20px; }
|
||||||
|
|
||||||
#infiltration-buttons .a-link-button {
|
#infiltration-buttons .a-link-button {
|
||||||
display: inline;
|
display: inline; }
|
||||||
width: 25%; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Styling for the Augmentations UI. This is the page that displays all of the
|
* Styling for the Augmentations UI. This is the page that displays all of the
|
||||||
|
|||||||
34
dist/vendor.bundle.js
vendored
34
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@@ -3,39 +3,156 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
v0.51.1 - 2021-04-06 Bugfixes because the author of the last patch sucks (it's hydroflame)
|
||||||
|
------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
**Netscript**
|
||||||
|
* 'getPlayer' returns players faction and tor
|
||||||
|
* 'hospitalization' is a new singularity function.
|
||||||
|
* 'gang.getMemberInformation' now returns more information.
|
||||||
|
* 'hacknet.hashCapacity' is a new hacknet function that returns the maximum hash capacity.
|
||||||
|
|
||||||
|
**Hospitalization**
|
||||||
|
* Now only cost at most 10% of your money.
|
||||||
|
|
||||||
|
**Bugfix**
|
||||||
|
* confirmation dialog box no longer use previous text
|
||||||
|
|
||||||
|
**Accessibility**
|
||||||
|
* The game is a little easier to handle for screen readers (yes, there's an
|
||||||
|
absolute legend playing this game with a screen reader)
|
||||||
|
* Infiltration use buttons instead of a-links
|
||||||
|
* New option to disable ASCII art. This will make the metro map and world
|
||||||
|
map display as a list of buttons.
|
||||||
|
|
||||||
|
**Misc.**
|
||||||
|
* 'fl1ght.exe' will no longer suggest the combat path. Related faction
|
||||||
|
requirements unchanged.
|
||||||
|
|
||||||
|
v0.51.0 - 2021-03-31 Formulas (hydroflame)
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
**Formulas API**
|
||||||
|
|
||||||
|
* A new API is introduced, this gives players access to various formulas used in the game.
|
||||||
|
It'll help you make more informed decisions.
|
||||||
|
|
||||||
|
**Netscript**
|
||||||
|
|
||||||
|
* 'getServer' is a new function meant to be used with the formulas API.
|
||||||
|
* 'getPlayer' is a new function meant to be used with the formulas API.
|
||||||
|
* 'getStats' and 'getCharacterInformation' are deprecated in favor of 'getPlayer'
|
||||||
|
* 'getCurrentServer' is a new function that returns the server the player is currently connected.
|
||||||
|
|
||||||
|
**Display**
|
||||||
|
|
||||||
|
* All money should now consistently be orange.
|
||||||
|
* All rep should now consistently be light-yellow.
|
||||||
|
* Most numbers should display consistently now (aka all money is formatted the same).
|
||||||
|
|
||||||
|
**Click to copy**
|
||||||
|
|
||||||
|
* Certain UI elements are now 'click-to-copy'
|
||||||
|
|
||||||
|
v0.50.2 - 2021-03-25 Everyone asked for this one. (hydroflame)
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
**BitNodeMultipliers**
|
||||||
|
|
||||||
|
* 'GangKarmaRequirements': a new multipler that influences how much karma is required to make a gang different bitnodes.
|
||||||
|
|
||||||
|
**Netscript**
|
||||||
|
|
||||||
|
* 'connect': a new singularity function that connects you to a server. (like the terminal command)
|
||||||
|
* 'manualHack': a new singularity function that performs a manual hack on the players current server.
|
||||||
|
* ns2 stack trace works on Firefox now.
|
||||||
|
|
||||||
|
**Misc.**
|
||||||
|
|
||||||
|
* New shortcut, Alt + b, brings you to bladeburner
|
||||||
|
* New shortcut, Alt + g, brings you to gang
|
||||||
|
|
||||||
|
v0.50.1 - 2021-03-22 (hydroflame)
|
||||||
|
---------------------------------
|
||||||
|
**Netscript**
|
||||||
|
|
||||||
|
* getTaskStats works
|
||||||
|
|
||||||
|
**Source-File -1**
|
||||||
|
|
||||||
|
* Added a new Exploit
|
||||||
|
|
||||||
|
**Factions**
|
||||||
|
|
||||||
|
* Augmentations offered by a Faction but already bought are in a separate list at the bottom of the page.
|
||||||
|
|
||||||
|
**Bug fixed**
|
||||||
|
|
||||||
|
* Fixed a bug where completing a maxed non-repeatable BitNode would make its color on the BitVerse like level 1.
|
||||||
|
|
||||||
|
**Misc.**
|
||||||
|
|
||||||
|
* Minor spacing in stats tables.
|
||||||
|
|
||||||
|
v0.50.0 - 2021-03-20 Intelligence (hydroflame)
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
**Intelligence**
|
||||||
|
|
||||||
|
* int exp gain and effect has been reworked. It is now much more easy to
|
||||||
|
acquire and far more powerful. The goal here is to feel like players have
|
||||||
|
another tool in their arsenal.
|
||||||
|
|
||||||
|
**Factions**
|
||||||
|
|
||||||
|
* Hacking factions no longer have hacking level requirements since their associated servers do.
|
||||||
|
|
||||||
|
**Misc.**
|
||||||
|
|
||||||
|
* Sleeve styling.
|
||||||
|
* number formatting
|
||||||
|
* remove wiki button in Hacking Missions.
|
||||||
|
* Fix NaN displayed when very very large numbers are reached.
|
||||||
|
|
||||||
v0.49.2 - 2021-03-13 (hydroflame)
|
v0.49.2 - 2021-03-13 (hydroflame)
|
||||||
-------
|
---------------------------------
|
||||||
|
|
||||||
|
**BN8**
|
||||||
|
|
||||||
BN8
|
|
||||||
* A new bitnode multipler has been added, it lets you reduce money from a
|
* A new bitnode multipler has been added, it lets you reduce money from a
|
||||||
server without gaining actually any money. This is important for BN8 where
|
server without gaining actually any money. This is important for BN8 where
|
||||||
hack/grow can influence the stock market. No money can be gained from
|
hack/grow can influence the stock market. No money can be gained from
|
||||||
hacking but server money can still be reduced.
|
hacking but server money can still be reduced.
|
||||||
|
|
||||||
Documentation
|
**Documentation**
|
||||||
|
|
||||||
* readthedocs should now be more consistent and many examples were added.
|
* readthedocs should now be more consistent and many examples were added.
|
||||||
|
|
||||||
Netscript
|
**Netscript**
|
||||||
|
|
||||||
* Ace editor will now correctly highlight all functions.
|
* Ace editor will now correctly highlight all functions.
|
||||||
* 'tFormat' is a new netscript function that returns a human readable
|
* 'tFormat' is a new netscript function that returns a human readable
|
||||||
representation of milliseconds. eg. "2 hours 15 minute 43 seconds"
|
representation of milliseconds. eg. "2 hours 15 minute 43 seconds"
|
||||||
|
|
||||||
Gang
|
**Gang**
|
||||||
|
|
||||||
* style improvements
|
* style improvements
|
||||||
|
|
||||||
Bladeburner
|
**Bladeburner**
|
||||||
|
|
||||||
* style improvements
|
* style improvements
|
||||||
* fix bug where 'skill list SKILL' would crash if skill is level 0.
|
* fix bug where 'skill list SKILL' would crash if skill is level 0.
|
||||||
|
|
||||||
Sleeve
|
**Sleeve**
|
||||||
|
|
||||||
* karma gain now scales with sync.
|
* karma gain now scales with sync.
|
||||||
|
|
||||||
Misc.
|
**Misc.**
|
||||||
Fix issue where the effective stats under Character>Stats were being calculated.
|
|
||||||
|
* Fix issue where the effective stats under Character>Stats were being calculated.
|
||||||
|
|
||||||
v0.49.0 - 2021-03-11 Source-File -1 (hydroflame)
|
v0.49.0 - 2021-03-11 Source-File -1 (hydroflame)
|
||||||
-------
|
------------------------------------------------
|
||||||
|
|
||||||
**Source-File -1**
|
**Source-File -1**
|
||||||
|
|
||||||
@@ -63,7 +180,7 @@ v0.49.0 - 2021-03-11 Source-File -1 (hydroflame)
|
|||||||
|
|
||||||
|
|
||||||
v0.48.0 - ASCII - 2021-03-07 (hydroflame)
|
v0.48.0 - ASCII - 2021-03-07 (hydroflame)
|
||||||
-------
|
-----------------------------------------
|
||||||
|
|
||||||
**ASCII**
|
**ASCII**
|
||||||
|
|
||||||
@@ -135,7 +252,7 @@ v0.47.2 - 7/15/2019
|
|||||||
* Added 'Solarized Dark' theme to CodeMirror editor
|
* Added 'Solarized Dark' theme to CodeMirror editor
|
||||||
* After Infiltration, you will now return to the company page rather than the city page
|
* After Infiltration, you will now return to the company page rather than the city page
|
||||||
* Bug fix: Stock Market UI should no longer crash for certain locale settings
|
* Bug fix: Stock Market UI should no longer crash for certain locale settings
|
||||||
* Bug fix: You can now properly remove unfinished programs (the *.exe-N%-INC files)
|
* Bug fix: You can now properly remove unfinished programs (the `*.exe-N%-INC` files)
|
||||||
* Bug fix: Fixed an issue that allowed you to increase money on servers with a 'maxMoney' of 0 (like CSEC)
|
* Bug fix: Fixed an issue that allowed you to increase money on servers with a 'maxMoney' of 0 (like CSEC)
|
||||||
* Bug fix: Scripts no longer persist if they were started with syntax/import errors
|
* Bug fix: Scripts no longer persist if they were started with syntax/import errors
|
||||||
* Bug fix: 'hack' and 'analyze' Terminal commands are now blocking
|
* Bug fix: 'hack' and 'analyze' Terminal commands are now blocking
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.47'
|
version = '0.51'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.47.0'
|
release = '0.51.1'
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -860,7 +860,7 @@ Random Tips
|
|||||||
.. Substitution definitions
|
.. Substitution definitions
|
||||||
.. |Alpha Enterprises| replace:: :code:`Alpha Enterprises`
|
.. |Alpha Enterprises| replace:: :code:`Alpha Enterprises`
|
||||||
.. |Augmentations tab| replace:: :code:`Augmentations` tab
|
.. |Augmentations tab| replace:: :code:`Augmentations` tab
|
||||||
.. |AutoLink| replace:: :code:`NUKE.exe`
|
.. |AutoLink| replace:: :code:`AutoLink.exe`
|
||||||
.. |BruteSSH| replace:: :code:`BruteSSH.exe`
|
.. |BruteSSH| replace:: :code:`BruteSSH.exe`
|
||||||
.. |City tab| replace:: :code:`City` tab
|
.. |City tab| replace:: :code:`City` tab
|
||||||
.. |CyberSec| replace:: :code:`CyberSec`
|
.. |CyberSec| replace:: :code:`CyberSec`
|
||||||
|
|||||||
@@ -30,4 +30,5 @@ to reach out to the developer!
|
|||||||
Gang API <netscript/netscriptgangapi>
|
Gang API <netscript/netscriptgangapi>
|
||||||
Coding Contract API <netscript/netscriptcodingcontractapi>
|
Coding Contract API <netscript/netscriptcodingcontractapi>
|
||||||
Sleeve API <netscript/netscriptsleeveapi>
|
Sleeve API <netscript/netscriptsleeveapi>
|
||||||
|
Formulas API <netscript/netscriptformulasapi>
|
||||||
Miscellaneous <netscript/netscriptmisc>
|
Miscellaneous <netscript/netscriptmisc>
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
getHackTime(), getGrowTime(), & getWeakenTime()
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
The :js:func:`getHackTime`, :js:func:`getGrowTime`, and :js:func:`getWeakenTime`
|
|
||||||
all take an additional third optional parameter for specifying a specific intelligence
|
|
||||||
level to see how that would affect the hack/grow/weaken times. This parameter
|
|
||||||
defaults to your current intelligence level.
|
|
||||||
|
|
||||||
(Intelligence is unlocked after obtaining Source-File 5).
|
|
||||||
|
|
||||||
The function signatures are then::
|
|
||||||
|
|
||||||
getHackTime(hostname/ip[, hackLvl=current level, intLvl=current level])
|
|
||||||
getGrowTime(hostname/ip[, hackLvl=current level, intLvl=current level])
|
|
||||||
getWeakenTime(hostname/ip[, hackLvl=current level, intLvl=current level])
|
|
||||||
39
doc/source/netscript/advancedfunctions/getServer.rst
Normal file
39
doc/source/netscript/advancedfunctions/getServer.rst
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
getServer() Netscript Function
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
.. js:function:: getServer()
|
||||||
|
|
||||||
|
:RAM cost: 4 GB
|
||||||
|
|
||||||
|
If you are not in BitNode-5, then you must have Source-File 5-1 in order to run this function.
|
||||||
|
|
||||||
|
This function is meant to be used in conjunction with the :doc:`formulas API<../netscriptformulasapi>`.
|
||||||
|
|
||||||
|
Returns an object with the Server's stats. The object has the following properties::
|
||||||
|
|
||||||
|
{
|
||||||
|
cpuCores
|
||||||
|
ftpPortOpen
|
||||||
|
hasAdminRights
|
||||||
|
hostname
|
||||||
|
httpPortOpen
|
||||||
|
ip
|
||||||
|
isConnectedTo
|
||||||
|
maxRam
|
||||||
|
organizationName
|
||||||
|
ramUsed
|
||||||
|
smtpPortOpen
|
||||||
|
sqlPortOpen
|
||||||
|
sshPortOpen
|
||||||
|
baseDifficulty
|
||||||
|
hackDifficulty
|
||||||
|
manuallyHacked
|
||||||
|
minDifficulty
|
||||||
|
moneyAvailable
|
||||||
|
moneyMax
|
||||||
|
numOpenPortsRequired
|
||||||
|
openPortCount
|
||||||
|
purchasedByPlayer
|
||||||
|
requiredHackingSkill
|
||||||
|
serverGrowth
|
||||||
|
}
|
||||||
22
doc/source/netscript/formulasapi/basic/calculateExp.rst
Normal file
22
doc/source/netscript/formulasapi/basic/calculateExp.rst
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
calculateExp() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: calculateExp(skillLevel[, mult])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number skillLevel: ``skillLevel`` to convert to exp.
|
||||||
|
:param number mult: Assume a specific skill multipler.
|
||||||
|
:returns: number of exp required to reach given ``skillLevel`` with that multiplier.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the amount of experience needed to reach level the given ``skillLevel``.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
nextHacking = getStats().hacking+1;
|
||||||
|
nextExp = formulas.basic.calculateExp(nextHacking);
|
||||||
|
missingExp = nextExp - getCharacterInformation().hackingExp;
|
||||||
|
tprint("Missing " + missingExp + " to reach next hacking level");
|
||||||
20
doc/source/netscript/formulasapi/basic/calculateSkill.rst
Normal file
20
doc/source/netscript/formulasapi/basic/calculateSkill.rst
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
calculateSkill() Netscript Function
|
||||||
|
===================================
|
||||||
|
|
||||||
|
.. js:function:: calculateSkill(exp[, mult])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number exp: ``exp`` to convert to skillLevel.
|
||||||
|
:param number mult: Assume a specific skill multipler.
|
||||||
|
:returns: skillLevel that ``exp`` would reach with that multiplier.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the skillLevel that the given amount of ``exp`` would reach.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
skillLevel = formulas.basic.calculateSkill(1000);
|
||||||
|
tprint("1000 exp would reach level " + skillLevel);
|
||||||
23
doc/source/netscript/formulasapi/basic/growPercent.rst
Normal file
23
doc/source/netscript/formulasapi/basic/growPercent.rst
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
growPercent() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: growPercent(server, threads, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server that receives the growth.
|
||||||
|
:param number threads: The number of thread that would be used.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The percentage growth this server would receive with these parameters.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates percentage of growth a server would receive with these parameters.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
tprint(growPercent(getServer(), 50, getPlayer()))
|
||||||
24
doc/source/netscript/formulasapi/basic/growTime.rst
Normal file
24
doc/source/netscript/formulasapi/basic/growTime.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
growTime() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: growTime(server, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server to grow.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The time it takes to grow this server. In seconds.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates the amount of time it takes to grow a server.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = getServer();
|
||||||
|
server.hackDifficulty = server.minDifficulty;
|
||||||
|
tprint(growTime(server, getPlayer()));
|
||||||
24
doc/source/netscript/formulasapi/basic/hackChance.rst
Normal file
24
doc/source/netscript/formulasapi/basic/hackChance.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
hackChance() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: hackChance(server, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server to hack.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The change to hack that server. between 0 and 1.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates percentage chance to hack a server.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = getServer();
|
||||||
|
server.hackDifficulty = server.minDifficulty;
|
||||||
|
tprint(hackChance(server, getPlayer()));
|
||||||
24
doc/source/netscript/formulasapi/basic/hackExp.rst
Normal file
24
doc/source/netscript/formulasapi/basic/hackExp.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
hackExp() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: hackExp(server, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server to hack.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The amount of exp that would be acquired if this server were to be hacked.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates the amount of exp obtained by hacking a server.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = getServer();
|
||||||
|
server.hackDifficulty = 99.9;
|
||||||
|
tprint(hackExp(server, getPlayer()));
|
||||||
25
doc/source/netscript/formulasapi/basic/hackPercent.rst
Normal file
25
doc/source/netscript/formulasapi/basic/hackPercent.rst
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
hackPercent() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: hackPercent(server, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server to hack.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The percentage of money hacked from a servers maximum money.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates the percentage of maximum money hacked from a server.
|
||||||
|
Multiply this by thread count to know calculate the percentage for more than 1 thread.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = getServer();
|
||||||
|
server.hackDifficulty = server.minDifficulty;
|
||||||
|
tprint(hackPercent(server, getPlayer()));
|
||||||
24
doc/source/netscript/formulasapi/basic/hackTime.rst
Normal file
24
doc/source/netscript/formulasapi/basic/hackTime.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
hackTime() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: hackTime(server, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server to hack.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The time it takes to hack this server. In seconds.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates the amount of time it takes to hack a server.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = getServer();
|
||||||
|
server.hackDifficulty = server.minDifficulty;
|
||||||
|
tprint(hackTime(server, getPlayer()));
|
||||||
24
doc/source/netscript/formulasapi/basic/weakenTime.rst
Normal file
24
doc/source/netscript/formulasapi/basic/weakenTime.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
weakenTime() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: weakenTime(server, player)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param server server: The server to weaken.
|
||||||
|
:param player player: The player.
|
||||||
|
:returns: The time it takes to weaken this server. In seconds.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||||
|
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||||
|
|
||||||
|
This function calculates the amount of time it takes to weaken a server.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = getServer();
|
||||||
|
server.hackDifficulty = server.minDifficulty;
|
||||||
|
tprint(weakenTime(server, getPlayer()));
|
||||||
26
doc/source/netscript/formulasapi/hacknetNodes/constants.rst
Normal file
26
doc/source/netscript/formulasapi/hacknetNodes/constants.rst
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
constants() Netscript Function
|
||||||
|
==============================
|
||||||
|
|
||||||
|
.. js:function:: constants()
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:returns: A structure with various constants related to hacknet nodes.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
MoneyGainPerLevel
|
||||||
|
BaseCost
|
||||||
|
LevelBaseCost
|
||||||
|
RamBaseCost
|
||||||
|
CoreBaseCost
|
||||||
|
PurchaseNextMult
|
||||||
|
UpgradeLevelMult
|
||||||
|
UpgradeRamMult
|
||||||
|
UpgradeCoreMult
|
||||||
|
MaxLevel
|
||||||
|
MaxRam
|
||||||
|
MaxCores
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
coreUpgradeCost() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: coreUpgradeCost(startingCores[, extraCores[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingCores: Number of core at the start the calculation.
|
||||||
|
:param number extraCores: Extra number of cores you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingCores`` to ``startingCores+extraCores``.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading cores from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetNodes.coreUpgradeCost(1, 5); // returns: 6355000
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
hacknetNodeCost() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: hacknetNodeCost(nodeN[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number nodeN: Number of the new node.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to buy your ``nodeN`` th node.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost purchasing a hacknet node.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetNodes.hacknetNodeCost(2); // returns: 1800
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
levelUpgradeCost() Netscript Function
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
.. js:function:: levelUpgradeCost(startingLevel[, extraLevels[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingLevel: Number of level at the start the calculation.
|
||||||
|
:param number extraLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingLevel`` to ``startingLevel+extraLevels``.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading levels from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetNodes.levelUpgradeCost(1, 5); // returns: 2816
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
moneyGainRate() Netscript Function
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
.. js:function:: moneyGainRate(level, ram, core[, mult])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number level: level of the node.
|
||||||
|
:param number ram: ram of the node.
|
||||||
|
:param number core: cores of the node.
|
||||||
|
:returns: Money per second that a node with those stats would gain per second.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the money rate of a node with the given stats.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
node = hacknet.getNodeStats(1);
|
||||||
|
currentRate = formulas.hacknetNodes.moneyGainRate(node.level, node.ram, node.cores);
|
||||||
|
levelRate = formulas.hacknetNodes.moneyGainRate(node.level+1, node.ram, node.cores);
|
||||||
|
ramRate = formulas.hacknetNodes.moneyGainRate(node.level, node.ram*2, node.cores);
|
||||||
|
coresRate = formulas.hacknetNodes.moneyGainRate(node.level, node.ram, node.cores+1);
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
ramUpgradeCost() Netscript Function
|
||||||
|
============================================
|
||||||
|
|
||||||
|
.. js:function:: ramUpgradeCost(startingRam[, extraRamLevels[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingRam: Amount of RAM at the start the calculation.
|
||||||
|
:param number extraRamLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingRam`` to ``startingRam+extraRamLevels``.
|
||||||
|
|
||||||
|
..note:: ``startingRam`` is the actual amount of ram, not the amount of levels of ram.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading levels from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetNodes.ramUpgradeCost(1, 5); // returns: 2095000
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
cacheUpgradeCost() Netscript Function
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
.. js:function:: cacheUpgradeCost(startingCache[, extraCacheLevels[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingCache: Cache level at the start the calculation.
|
||||||
|
:param number extraCacheLevels: Extra number of cache level you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingLevel`` to ``startingLevel+extraLevels``.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading cache from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetServers.cacheUpgradeCost(1, 5); // returns: 243170000
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
constants() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: constants()
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:returns: A structure with various constants related to hacknet servers.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
{
|
||||||
|
HashesPerLevel
|
||||||
|
BaseCost
|
||||||
|
RamBaseCost
|
||||||
|
CoreBaseCost
|
||||||
|
CacheBaseCost
|
||||||
|
PurchaseMult
|
||||||
|
UpgradeLevelMult
|
||||||
|
UpgradeRamMult
|
||||||
|
UpgradeCoreMult
|
||||||
|
UpgradeCacheMult
|
||||||
|
MaxServers
|
||||||
|
MaxLevel
|
||||||
|
MaxRam
|
||||||
|
MaxCores
|
||||||
|
MaxCache
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
coreUpgradeCost() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: coreUpgradeCost(startingCores[, extraCores[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingCores: Number of core at the start the calculation.
|
||||||
|
:param number extraCores: Extra number of cores you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingCores`` to ``startingCores+extraCores``.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading cores from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetServers.coreUpgradeCost(1, 5); // returns: 12015000
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
hacknetServerCost() Netscript Function
|
||||||
|
===============================================
|
||||||
|
|
||||||
|
.. js:function:: hacknetServerCost(serverN[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number serverN: Number of the new node.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to buy your ``serverN`` th node.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost purchasing a hacknet node.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetNodes.hacknetServerCost(2); // returns: 1800000
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
hashGainRate() Netscript Function
|
||||||
|
==========================================
|
||||||
|
|
||||||
|
.. js:function:: hashGainRate(level, ram, core[, mult])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number level: level of the server.
|
||||||
|
:param number ram: ram of the server.
|
||||||
|
:param number core: cores of the server.
|
||||||
|
:returns: Money per second that a server with those stats would gain per second.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the hash rate of a server with the given stats.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
server = hacknet.getNodeStats(1);
|
||||||
|
currentRate = formulas.hacknetNodes.hashGainRate(server.level, server.ram, server.cores);
|
||||||
|
levelRate = formulas.hacknetNodes.hashGainRate(server.level+1, server.ram, server.cores);
|
||||||
|
ramRate = formulas.hacknetNodes.hashGainRate(server.level, server.ram*2, server.cores);
|
||||||
|
coresRate = formulas.hacknetNodes.hashGainRate(server.level, server.ram, server.cores+1);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
hashUpgradeCost() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: hashUpgradeCost(upgName, level)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param string upgName: Name of the Hash upgrade.
|
||||||
|
:param number level: Level of the upgrade.
|
||||||
|
:returns: Amount of Hash.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates amount of Hash require to buy level ``level`` of upgrade ``upgName``.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetServers.hashUpgradeCost("Increase Maximum Money", 5); // returns: 250
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
levelUpgradeCost() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: levelUpgradeCost(startingLevel[, extraLevels[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingLevel: Number of level at the start the calculation.
|
||||||
|
:param number extraLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingLevel`` to ``startingLevel+extraLevels``.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading levels from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetServers.levelUpgradeCost(1, 5); // returns: 2792000
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
ramUpgradeCost() Netscript Function
|
||||||
|
=============================================
|
||||||
|
|
||||||
|
.. js:function:: ramUpgradeCost(startingRam[, extraRamLevels[, costMult]])
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param number startingRam: Amount of RAM at the start the calculation.
|
||||||
|
:param number extraRamLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||||
|
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||||
|
:returns: Money required to go from ``startingRam`` to ``startingRam+extraRamLevels``.
|
||||||
|
|
||||||
|
..note:: ``startingRam`` is the actual amount of ram, not the amount of levels of ram.
|
||||||
|
|
||||||
|
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||||
|
|
||||||
|
This function calculates the cost of upgrading levels from any level to any level.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
formulas.hacknetServers.ramUpgradeCost(1, 5); // returns: 15810000
|
||||||
18
doc/source/netscript/hacknetnodeapi/getHashUpgradeLevel.rst
Normal file
18
doc/source/netscript/hacknetnodeapi/getHashUpgradeLevel.rst
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
getHashUpgradeLevel() Netscript Function
|
||||||
|
========================================
|
||||||
|
|
||||||
|
.. js:function:: getHashUpgradeLevel(upgName)
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:param string upgName: Name of upgrade to spend hashes on. Must be an exact match.
|
||||||
|
:returns: level of the upgrade.
|
||||||
|
|
||||||
|
.. note:: This function is only applicable for Hacknet Servers (the upgraded version
|
||||||
|
of a Hacknet Node).
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code:: javascript
|
||||||
|
|
||||||
|
hacknet.getHashUpgradeLevel("Sell for Money"); // returns: 5
|
||||||
|
// "Sell for Money" was bought 5 times.
|
||||||
13
doc/source/netscript/hacknetnodeapi/getStudyMult.rst
Normal file
13
doc/source/netscript/hacknetnodeapi/getStudyMult.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
getStudyMult() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. js:function:: getStudyMult()
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:returns: The multiplier to studying that hash upgrades provide to the player.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code:: javascript
|
||||||
|
|
||||||
|
hacknet.getStudyMult(); // return: 1.4
|
||||||
13
doc/source/netscript/hacknetnodeapi/getTrainingMult.rst
Normal file
13
doc/source/netscript/hacknetnodeapi/getTrainingMult.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
getTrainingMul() Netscript Function
|
||||||
|
===================================
|
||||||
|
|
||||||
|
.. js:function:: getTrainingMul()
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:returns: The multiplier to training that hash upgrades provide to the player.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
.. code:: javascript
|
||||||
|
|
||||||
|
hacknet.getTrainingMult(); // return: 1.4
|
||||||
12
doc/source/netscript/hacknetnodeapi/hashCapacity.rst
Normal file
12
doc/source/netscript/hacknetnodeapi/hashCapacity.rst
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
hashCapacity() Netscript Function
|
||||||
|
=================================
|
||||||
|
|
||||||
|
.. warning:: This page contains spoilers for the game
|
||||||
|
|
||||||
|
.. js:function:: hashCapacity()
|
||||||
|
|
||||||
|
:RAM cost: 0 GB
|
||||||
|
:returns: The players maximum hash capacity.
|
||||||
|
|
||||||
|
.. note:: This function is only applicable for Hacknet Servers (the upgraded version of
|
||||||
|
a Hacknet Node).
|
||||||
@@ -9,4 +9,4 @@ they contain spoilers for the game.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
||||||
getBitNodeMultipliers() <advancedfunctions/getBitNodeMultipliers>
|
getBitNodeMultipliers() <advancedfunctions/getBitNodeMultipliers>
|
||||||
getHackTime(), getGrowTime(), & getWeakenTime() <advancedfunctions/getHackGrowWeakenTimes>
|
getServer() <advancedfunctions/getServer>
|
||||||
|
|||||||
61
doc/source/netscript/netscriptformulasapi.rst
Normal file
61
doc/source/netscript/netscriptformulasapi.rst
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
.. _netscriptformulas:
|
||||||
|
|
||||||
|
Netscript Formulas Functions
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. warning:: This page contains spoilers for the game.
|
||||||
|
|
||||||
|
The formulas API allow you to gain insight into the inner workings of the game.
|
||||||
|
These functions will allow you to make more informed decision.
|
||||||
|
|
||||||
|
All of these function cost 0 GB of ram to use. All these function require
|
||||||
|
Source-File 5-1 but some additionally need another source file level 1 to use.
|
||||||
|
|
||||||
|
|
||||||
|
basic formulas
|
||||||
|
--------------
|
||||||
|
|
||||||
|
These functions are under the ``formulas.basic.`` name space and available as
|
||||||
|
soon as you acquire Source-File 5-1
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
calculateSkill() <formulasapi/basic/calculateSkill>
|
||||||
|
calculateExp() <formulasapi/basic/calculateExp>
|
||||||
|
growTime() <formulasapi/basic/growTime>
|
||||||
|
hackTime() <formulasapi/basic/hackTime>
|
||||||
|
weakenTime() <formulasapi/basic/weakenTime>
|
||||||
|
growPercent() <formulasapi/basic/growPercent>
|
||||||
|
hackPercent() <formulasapi/basic/hackPercent>
|
||||||
|
hackChance() <formulasapi/basic/hackChance>
|
||||||
|
hackExp() <formulasapi/basic/hackExp>
|
||||||
|
|
||||||
|
|
||||||
|
hacknetNodes formulas
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
These functions are under the ``formulas.hacknetNodes.`` namespace and available as
|
||||||
|
soon as you acquire Source-File 5-1.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
hacknetNodeCost() <formulasapi/hacknetNodes/hacknetNodeCost>
|
||||||
|
moneyGainRate() <formulasapi/hacknetNodes/moneyGainRate>
|
||||||
|
levelUpgradeCost() <formulasapi/hacknetNodes/levelUpgradeCost>
|
||||||
|
ramUpgradeCost() <formulasapi/hacknetNodes/ramUpgradeCost>
|
||||||
|
coreUpgradeCost() <formulasapi/hacknetNodes/coreUpgradeCost>
|
||||||
|
constants() <formulasapi/hacknetNodes/constants>
|
||||||
|
|
||||||
|
hacknetServers formulas
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
These functions are under the ``formulas.hacknetServers.`` namespace.
|
||||||
|
These functions require Source-File 5-1 and Source-File 9-1 to be invoked.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
hacknetServerCost() <formulasapi/hacknetServers/hacknetServerCost>
|
||||||
|
hashGainRate() <formulasapi/hacknetServers/hashGainRate>
|
||||||
|
levelUpgradeCost() <formulasapi/hacknetServers/levelUpgradeCost>
|
||||||
|
ramUpgradeCost() <formulasapi/hacknetServers/ramUpgradeCost>
|
||||||
|
coreUpgradeCost() <formulasapi/hacknetServers/coreUpgradeCost>
|
||||||
|
cacheUpgradeCost() <formulasapi/hacknetServers/cacheUpgradeCost>
|
||||||
|
hashUpgradeCost() <formulasapi/hacknetServers/hashUpgradeCost>
|
||||||
|
constants() <formulasapi/hacknetServers/constants>
|
||||||
@@ -84,6 +84,7 @@ This includes information such as function signatures, what they do, and their r
|
|||||||
sprintf() <basicfunctions/sprintf>
|
sprintf() <basicfunctions/sprintf>
|
||||||
vsprintf() <basicfunctions/vsprintf>
|
vsprintf() <basicfunctions/vsprintf>
|
||||||
nFormat() <basicfunctions/nFormat>
|
nFormat() <basicfunctions/nFormat>
|
||||||
|
tFormat() <basicfunctions/tFormat>
|
||||||
prompt() <basicfunctions/prompt>
|
prompt() <basicfunctions/prompt>
|
||||||
wget() <basicfunctions/wget>
|
wget() <basicfunctions/wget>
|
||||||
getFavorToDonate() <basicfunctions/getFavorToDonate>
|
getFavorToDonate() <basicfunctions/getFavorToDonate>
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ In :ref:`netscriptjs`::
|
|||||||
ns.hacknet.getNodeStats(3).level;
|
ns.hacknet.getNodeStats(3).level;
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:caption: API Functions:
|
:caption: Hacknet Nodes API Functions:
|
||||||
|
|
||||||
numNodes() <hacknetnodeapi/numNodes>
|
numNodes() <hacknetnodeapi/numNodes>
|
||||||
maxNumNodes() <hacknetnodeapi/maxNumNodes>
|
maxNumNodes() <hacknetnodeapi/maxNumNodes>
|
||||||
@@ -36,14 +36,22 @@ In :ref:`netscriptjs`::
|
|||||||
upgradeLevel() <hacknetnodeapi/upgradeLevel>
|
upgradeLevel() <hacknetnodeapi/upgradeLevel>
|
||||||
upgradeRam() <hacknetnodeapi/upgradeRam>
|
upgradeRam() <hacknetnodeapi/upgradeRam>
|
||||||
upgradeCore() <hacknetnodeapi/upgradeCore>
|
upgradeCore() <hacknetnodeapi/upgradeCore>
|
||||||
upgradeCache() <hacknetnodeapi/upgradeCache>
|
|
||||||
getLevelUpgradeCost() <hacknetnodeapi/getLevelUpgradeCost>
|
getLevelUpgradeCost() <hacknetnodeapi/getLevelUpgradeCost>
|
||||||
getRamUpgradeCost() <hacknetnodeapi/getRamUpgradeCost>
|
getRamUpgradeCost() <hacknetnodeapi/getRamUpgradeCost>
|
||||||
getCoreUpgradeCost() <hacknetnodeapi/getCoreUpgradeCost>
|
getCoreUpgradeCost() <hacknetnodeapi/getCoreUpgradeCost>
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Hacknet Servers API Functions:
|
||||||
|
|
||||||
|
upgradeCache() <hacknetnodeapi/upgradeCache>
|
||||||
getCacheUpgradeCost() <hacknetnodeapi/getCacheUpgradeCost>
|
getCacheUpgradeCost() <hacknetnodeapi/getCacheUpgradeCost>
|
||||||
numHashes() <hacknetnodeapi/numHashes>
|
numHashes() <hacknetnodeapi/numHashes>
|
||||||
|
hashCapacity() <hacknetnodeapi/hashCapacity>
|
||||||
hashCost() <hacknetnodeapi/hashCost>
|
hashCost() <hacknetnodeapi/hashCost>
|
||||||
spendHashes() <hacknetnodeapi/spendHashes>
|
spendHashes() <hacknetnodeapi/spendHashes>
|
||||||
|
getHashUpgradeLevel() <hacknetnodeapi/getHashUpgradeLevel>
|
||||||
|
getTrainingMult() <hacknetnodeapi/getTrainingMult>
|
||||||
|
getStudyMult() <hacknetnodeapi/getStudyMult>
|
||||||
|
|
||||||
.. _netscript_hacknetnodeapi_referencingahacknetnode:
|
.. _netscript_hacknetnodeapi_referencingahacknetnode:
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,11 @@ level 3, then you will be able to access all of the Singularity Functions.
|
|||||||
travelToCity() <singularityfunctions/travelToCity>
|
travelToCity() <singularityfunctions/travelToCity>
|
||||||
purchaseTor() <singularityfunctions/purchaseTor>
|
purchaseTor() <singularityfunctions/purchaseTor>
|
||||||
purchaseProgram() <singularityfunctions/purchaseProgram>
|
purchaseProgram() <singularityfunctions/purchaseProgram>
|
||||||
getStats() <singularityfunctions/getStats>
|
getCurrentServer() <singularityfunctions/getCurrentServer>
|
||||||
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
connect() <singularityfunctions/connect>
|
||||||
|
manualHack() <singularityfunctions/manualHack>
|
||||||
|
getPlayer() <singularityfunctions/getPlayer>
|
||||||
|
hospitalize() <singularityfunctions/hospitalize>
|
||||||
isBusy() <singularityfunctions/isBusy>
|
isBusy() <singularityfunctions/isBusy>
|
||||||
stopAction() <singularityfunctions/stopAction>
|
stopAction() <singularityfunctions/stopAction>
|
||||||
upgradeHomeRam() <singularityfunctions/upgradeHomeRam>
|
upgradeHomeRam() <singularityfunctions/upgradeHomeRam>
|
||||||
@@ -55,3 +58,10 @@ level 3, then you will be able to access all of the Singularity Functions.
|
|||||||
purchaseAugmentation() <singularityfunctions/purchaseAugmentation>
|
purchaseAugmentation() <singularityfunctions/purchaseAugmentation>
|
||||||
installAugmentations() <singularityfunctions/installAugmentations>
|
installAugmentations() <singularityfunctions/installAugmentations>
|
||||||
softReset() <singularityfunctions/softReset>
|
softReset() <singularityfunctions/softReset>
|
||||||
|
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Deprecated:
|
||||||
|
|
||||||
|
getStats() <singularityfunctions/getStats>
|
||||||
|
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
||||||
20
doc/source/netscript/singularityfunctions/connect.rst
Normal file
20
doc/source/netscript/singularityfunctions/connect.rst
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
connect() Netscript Function
|
||||||
|
============================
|
||||||
|
|
||||||
|
.. js:function:: connect(hostname)
|
||||||
|
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
:param string hostname: hostname of the server to connect.
|
||||||
|
:returns: ``true`` if the connection was a success.
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
|
This function will connect you to the specified server if it's directly connected to the current server.
|
||||||
|
You can also pass in 'home' to return to your home server from anywhere.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
connect("joesguns");
|
||||||
|
connect("CSEC");
|
||||||
@@ -9,8 +9,12 @@ getAugmentationStats() Netscript Function
|
|||||||
|
|
||||||
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
|
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
ns.getAugmentationStats("Synfibril Muscle")
|
Examples:
|
||||||
{
|
|
||||||
strength_mult: 1.3,
|
.. code-block:: javascript
|
||||||
defense_mult: 1.3,
|
|
||||||
}
|
ns.getAugmentationStats("Synfibril Muscle")
|
||||||
|
{
|
||||||
|
strength_mult: 1.3,
|
||||||
|
defense_mult: 1.3,
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ getCharacterInformation() Netscript Function
|
|||||||
|
|
||||||
.. js:function:: getCharacterInformation()
|
.. js:function:: getCharacterInformation()
|
||||||
|
|
||||||
|
.. warning:: This function is deprecated.
|
||||||
|
|
||||||
:RAM cost: 0.5 GB
|
:RAM cost: 0.5 GB
|
||||||
|
|
||||||
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function.
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function.
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
getCurrentServer() Netscript Function
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
.. js:function:: getCurrentServer()
|
||||||
|
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
:returns: The hostname of the server the player is currently connected to.
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
103
doc/source/netscript/singularityfunctions/getPlayer.rst
Normal file
103
doc/source/netscript/singularityfunctions/getPlayer.rst
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
getPlayer() Netscript Function
|
||||||
|
==============================
|
||||||
|
|
||||||
|
.. js:function:: getPlayer()
|
||||||
|
|
||||||
|
:RAM cost: 0.5 GB
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function.
|
||||||
|
|
||||||
|
The result of this function can be passed to the :doc:`formulas API<../netscriptformulasapi>`.
|
||||||
|
|
||||||
|
Returns an object with the Player's stats. The object has the following properties::
|
||||||
|
|
||||||
|
{
|
||||||
|
hacking_skill
|
||||||
|
hp
|
||||||
|
max_hp
|
||||||
|
strength
|
||||||
|
defense
|
||||||
|
dexterity
|
||||||
|
agility
|
||||||
|
charisma
|
||||||
|
intelligence
|
||||||
|
hacking_chance_mult
|
||||||
|
hacking_speed_mult
|
||||||
|
hacking_money_mult
|
||||||
|
hacking_grow_mult
|
||||||
|
hacking_exp
|
||||||
|
strength_exp
|
||||||
|
defense_exp
|
||||||
|
dexterity_exp
|
||||||
|
agility_exp
|
||||||
|
charisma_exp
|
||||||
|
hacking_mult
|
||||||
|
strength_mult
|
||||||
|
defense_mult
|
||||||
|
dexterity_mult
|
||||||
|
agility_mult
|
||||||
|
charisma_mult
|
||||||
|
hacking_exp_mult
|
||||||
|
strength_exp_mult
|
||||||
|
defense_exp_mult
|
||||||
|
dexterity_exp_mult
|
||||||
|
agility_exp_mult
|
||||||
|
charisma_exp_mult
|
||||||
|
company_rep_mult
|
||||||
|
faction_rep_mult
|
||||||
|
money
|
||||||
|
city
|
||||||
|
location
|
||||||
|
crime_money_mult
|
||||||
|
crime_success_mult
|
||||||
|
isWorking
|
||||||
|
workType
|
||||||
|
currentWorkFactionName
|
||||||
|
currentWorkFactionDescription
|
||||||
|
workHackExpGainRate
|
||||||
|
workStrExpGainRate
|
||||||
|
workDefExpGainRate
|
||||||
|
workDexExpGainRate
|
||||||
|
workAgiExpGainRate
|
||||||
|
workChaExpGainRate
|
||||||
|
workRepGainRate
|
||||||
|
workMoneyGainRate
|
||||||
|
workMoneyLossRate
|
||||||
|
workHackExpGained
|
||||||
|
workStrExpGained
|
||||||
|
workDefExpGained
|
||||||
|
workDexExpGained
|
||||||
|
workAgiExpGained
|
||||||
|
workChaExpGained
|
||||||
|
workRepGained
|
||||||
|
workMoneyGained
|
||||||
|
createProgramName
|
||||||
|
createProgramReqLvl
|
||||||
|
className
|
||||||
|
crimeType
|
||||||
|
work_money_mult
|
||||||
|
hacknet_node_money_mult
|
||||||
|
hacknet_node_purchase_cost_mult
|
||||||
|
hacknet_node_ram_cost_mult
|
||||||
|
hacknet_node_core_cost_mult
|
||||||
|
hacknet_node_level_cost_mult
|
||||||
|
hasWseAccount
|
||||||
|
hasTixApiAccess
|
||||||
|
has4SData
|
||||||
|
has4SDataTixApi
|
||||||
|
bladeburner_max_stamina_mult
|
||||||
|
bladeburner_stamina_gain_mult
|
||||||
|
bladeburner_success_chance_mult
|
||||||
|
bitNodeN
|
||||||
|
totalPlaytime
|
||||||
|
playtimeSinceLastAug
|
||||||
|
playtimeSinceLastBitnode
|
||||||
|
jobs
|
||||||
|
factions
|
||||||
|
tor
|
||||||
|
}
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
player = getPlayer();
|
||||||
|
print('My charisma level is: ' + player.charisma);
|
||||||
@@ -3,6 +3,8 @@ getStats() Netscript Function
|
|||||||
|
|
||||||
.. js:function:: getStats()
|
.. js:function:: getStats()
|
||||||
|
|
||||||
|
.. warning:: This function is deprecated.
|
||||||
|
|
||||||
:RAM cost: 0.5 GB
|
:RAM cost: 0.5 GB
|
||||||
|
|
||||||
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function.
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this function.
|
||||||
|
|||||||
11
doc/source/netscript/singularityfunctions/hospitalize.rst
Normal file
11
doc/source/netscript/singularityfunctions/hospitalize.rst
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
hospitalize() Netscript Function
|
||||||
|
===================================
|
||||||
|
|
||||||
|
.. js:function:: hospitalize()
|
||||||
|
|
||||||
|
:RAM cost: 1 GB
|
||||||
|
:returns: The cost of your visit to the hospital.
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
|
Hospitalize yourself. Recovering all lost hp.
|
||||||
24
doc/source/netscript/singularityfunctions/manualHack.rst
Normal file
24
doc/source/netscript/singularityfunctions/manualHack.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
manualHack() Netscript Function
|
||||||
|
===============================
|
||||||
|
|
||||||
|
.. js:function:: manualHack()
|
||||||
|
|
||||||
|
:RAM cost: 2 GB
|
||||||
|
:returns: The amount of money stolen if the hack is successful, and zero otherwise
|
||||||
|
|
||||||
|
If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
|
This function will perform a manual hack on the server you are currently connected to.
|
||||||
|
This is typically required to join factions.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
.. code-block:: javascript
|
||||||
|
|
||||||
|
connect("CSEC");
|
||||||
|
manualHack();
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
For NS2 users:
|
||||||
|
|
||||||
|
This function is async.
|
||||||
@@ -3,6 +3,8 @@ softReset() Netscript Function
|
|||||||
|
|
||||||
.. js:function:: softReset()
|
.. js:function:: softReset()
|
||||||
|
|
||||||
|
:RAM cost: 5 GB
|
||||||
|
|
||||||
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
|
If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.
|
||||||
|
|
||||||
This function will perform a reset even if you don't have any augmentation installed.
|
This function will perform a reset even if you don't have any augmentation installed.
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ Alt + f Switch to 'Factions' page
|
|||||||
Alt + a Switch to 'Augmentations' page
|
Alt + a Switch to 'Augmentations' page
|
||||||
Alt + u Switch to 'Tutorial' page
|
Alt + u Switch to 'Tutorial' page
|
||||||
Alt + o Switch to 'Options' page
|
Alt + o Switch to 'Options' page
|
||||||
|
Alt + g Switch to 'Gang' page
|
||||||
|
Alt + b Switch to 'Bladeburner' page
|
||||||
========== ===========================================================================
|
========== ===========================================================================
|
||||||
|
|
||||||
Script Editor
|
Script Editor
|
||||||
|
|||||||
36
index.html
36
index.html
@@ -30,7 +30,7 @@
|
|||||||
<div id="entire-game-container" style="visibility:hidden;">
|
<div id="entire-game-container" style="visibility:hidden;">
|
||||||
<div id="mainmenu-container">
|
<div id="mainmenu-container">
|
||||||
<!-- Main menu -->
|
<!-- Main menu -->
|
||||||
<ul id="mainmenu" class="mainmenu">
|
<ul id="mainmenu" class="mainmenu noscrollbar">
|
||||||
<!-- Hacking dropdown -->
|
<!-- Hacking dropdown -->
|
||||||
<li id="hacking-menu-header-li">
|
<li id="hacking-menu-header-li">
|
||||||
<button id="hacking-menu-header" class="mainmenu-accordion-header"> Hacking </button>
|
<button id="hacking-menu-header" class="mainmenu-accordion-header"> Hacking </button>
|
||||||
@@ -261,16 +261,16 @@
|
|||||||
<div id="infiltration-left-panel">
|
<div id="infiltration-left-panel">
|
||||||
<p id="infiltration-level-text"> </p>
|
<p id="infiltration-level-text"> </p>
|
||||||
<div id="infiltration-buttons">
|
<div id="infiltration-buttons">
|
||||||
<a class="a-link-button tooltip" id="infiltration-kill"> </a>
|
<button class="a-link-button tooltip" id="infiltration-kill"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-knockout"> </a>
|
<button class="a-link-button tooltip" id="infiltration-knockout"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-stealthknockout"> </a>
|
<button class="a-link-button tooltip" id="infiltration-stealthknockout"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-assassinate"> </a>
|
<button class="a-link-button tooltip" id="infiltration-assassinate"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-hacksecurity"> </a>
|
<button class="a-link-button tooltip" id="infiltration-hacksecurity"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-destroysecurity"> </a>
|
<button class="a-link-button tooltip" id="infiltration-destroysecurity"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-sneak"> </a>
|
<button class="a-link-button tooltip" id="infiltration-sneak"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-pickdoor"> </a>
|
<button class="a-link-button tooltip" id="infiltration-pickdoor"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-bribe"> </a>
|
<button class="a-link-button tooltip" id="infiltration-bribe"> </button>
|
||||||
<a class="a-link-button tooltip" id="infiltration-escape"> </a>
|
<button class="a-link-button tooltip" id="infiltration-escape"> </button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="infiltration-right-panel">
|
<div id="infiltration-right-panel">
|
||||||
@@ -387,7 +387,7 @@
|
|||||||
<!-- Game Options -->
|
<!-- Game Options -->
|
||||||
<div id="game-options-container" class="popup-box-container">
|
<div id="game-options-container" class="popup-box-container">
|
||||||
<div id="game-options-content" class="game-options-box">
|
<div id="game-options-content" class="game-options-box">
|
||||||
<button id="game-options-close-button">×</button>
|
<button id="game-options-close-button" aria-label="close options dialog">×</button>
|
||||||
<h1> Game Options </h1>
|
<h1> Game Options </h1>
|
||||||
<br/>
|
<br/>
|
||||||
<div id="game-options-left-panel">
|
<div id="game-options-left-panel">
|
||||||
@@ -511,6 +511,16 @@
|
|||||||
<input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys">
|
<input class="optionCheckbox" type="checkbox" name="settingsDisableHotkeys" id="settingsDisableHotkeys">
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
<!-- View city as list of buttons instead of ASCII art. -->
|
||||||
|
<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>
|
||||||
|
|
||||||
<!-- Locale for displaying numbers -->
|
<!-- Locale for displaying numbers -->
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="settingsLocale" class="tooltip">Locale:
|
<label for="settingsLocale" class="tooltip">Locale:
|
||||||
@@ -590,6 +600,8 @@
|
|||||||
<p>If the game fails to load, consider <a href="?noScripts">killing all scripts</a></p>
|
<p>If the game fails to load, consider <a href="?noScripts">killing all scripts</a></p>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
<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 -->
|
<!-- Misc Scripts -->
|
||||||
|
|||||||
70
package-lock.json
generated
70
package-lock.json
generated
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "bitburner",
|
"name": "bitburner",
|
||||||
"version": "0.47.3",
|
"version": "0.49.2",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "0.47.3",
|
"version": "0.49.2",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "SEE LICENSE IN license.txt",
|
"license": "SEE LICENSE IN license.txt",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
"numeral": "2.0.6",
|
"numeral": "2.0.6",
|
||||||
"react": "^16.8.3",
|
"react": "^16.8.3",
|
||||||
"react-dom": "^16.8.3",
|
"react-dom": "^16.8.3",
|
||||||
|
"react-modal": "^3.12.1",
|
||||||
"sprintf-js": "^1.1.1",
|
"sprintf-js": "^1.1.1",
|
||||||
"tapable": "^1.0.0",
|
"tapable": "^1.0.0",
|
||||||
"uuid": "^3.2.1",
|
"uuid": "^3.2.1",
|
||||||
@@ -4571,6 +4572,11 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/exenv": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||||
|
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||||
|
},
|
||||||
"node_modules/exit": {
|
"node_modules/exit": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||||
@@ -11779,6 +11785,29 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz",
|
||||||
"integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA=="
|
"integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/react-lifecycles-compat": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||||
|
},
|
||||||
|
"node_modules/react-modal": {
|
||||||
|
"version": "3.12.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.12.1.tgz",
|
||||||
|
"integrity": "sha512-WGuXn7Fq31PbFJwtWmOk+jFtGC7E9tJVbFX0lts8ZoS5EPi9+WWylUJWLKKVm3H4GlQ7ZxY7R6tLlbSIBQ5oZA==",
|
||||||
|
"dependencies": {
|
||||||
|
"exenv": "^1.2.0",
|
||||||
|
"prop-types": "^15.5.10",
|
||||||
|
"react-lifecycles-compat": "^3.0.0",
|
||||||
|
"warning": "^4.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^0.14.0 || ^15.0.0 || ^16 || ^17",
|
||||||
|
"react-dom": "^0.14.0 || ^15.0.0 || ^16 || ^17"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/readable-stream": {
|
"node_modules/readable-stream": {
|
||||||
"version": "2.3.4",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
|
||||||
@@ -15999,6 +16028,14 @@
|
|||||||
"xml-name-validator": "3.0.0"
|
"xml-name-validator": "3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/warning": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||||
|
"dependencies": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||||
@@ -21422,6 +21459,11 @@
|
|||||||
"clone-regexp": "1.0.1"
|
"clone-regexp": "1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"exenv": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
|
||||||
|
"integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
|
||||||
|
},
|
||||||
"exit": {
|
"exit": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
|
||||||
@@ -27426,6 +27468,22 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.3.tgz",
|
||||||
"integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA=="
|
"integrity": "sha512-Y4rC1ZJmsxxkkPuMLwvKvlL1Zfpbcu+Bf4ZigkHup3v9EfdYhAlWAaVyA19olXq2o2mGn0w+dFKvk3pVVlYcIA=="
|
||||||
},
|
},
|
||||||
|
"react-lifecycles-compat": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
|
||||||
|
},
|
||||||
|
"react-modal": {
|
||||||
|
"version": "3.12.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.12.1.tgz",
|
||||||
|
"integrity": "sha512-WGuXn7Fq31PbFJwtWmOk+jFtGC7E9tJVbFX0lts8ZoS5EPi9+WWylUJWLKKVm3H4GlQ7ZxY7R6tLlbSIBQ5oZA==",
|
||||||
|
"requires": {
|
||||||
|
"exenv": "^1.2.0",
|
||||||
|
"prop-types": "^15.5.10",
|
||||||
|
"react-lifecycles-compat": "^3.0.0",
|
||||||
|
"warning": "^4.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"readable-stream": {
|
"readable-stream": {
|
||||||
"version": "2.3.4",
|
"version": "2.3.4",
|
||||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.4.tgz",
|
||||||
@@ -31040,6 +31098,14 @@
|
|||||||
"xml-name-validator": "3.0.0"
|
"xml-name-validator": "3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"warning": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
|
||||||
|
"requires": {
|
||||||
|
"loose-envify": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"watchpack": {
|
"watchpack": {
|
||||||
"version": "1.6.0",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
"numeral": "2.0.6",
|
"numeral": "2.0.6",
|
||||||
"react": "^16.8.3",
|
"react": "^16.8.3",
|
||||||
"react-dom": "^16.8.3",
|
"react-dom": "^16.8.3",
|
||||||
|
"react-modal": "^3.12.1",
|
||||||
"sprintf-js": "^1.1.1",
|
"sprintf-js": "^1.1.1",
|
||||||
"tapable": "^1.0.0",
|
"tapable": "^1.0.0",
|
||||||
"uuid": "^3.2.1",
|
"uuid": "^3.2.1",
|
||||||
@@ -120,5 +121,5 @@
|
|||||||
"watch": "webpack --watch --mode production",
|
"watch": "webpack --watch --mode production",
|
||||||
"watch:dev": "webpack --watch --mode development"
|
"watch:dev": "webpack --watch --mode development"
|
||||||
},
|
},
|
||||||
"version": "0.49.2"
|
"version": "0.51.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.InfiltrationMoney = 3;
|
BitNodeMultipliers.InfiltrationMoney = 3;
|
||||||
BitNodeMultipliers.FactionWorkRepGain = 0.5;
|
BitNodeMultipliers.FactionWorkRepGain = 0.5;
|
||||||
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 0;
|
||||||
break;
|
break;
|
||||||
case 3: // Corporatocracy
|
case 3: // Corporatocracy
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.8;
|
||||||
@@ -289,6 +290,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.HacknetNodeMoney = 0.25;
|
BitNodeMultipliers.HacknetNodeMoney = 0.25;
|
||||||
BitNodeMultipliers.HomeComputerRamCost = 1.5;
|
BitNodeMultipliers.HomeComputerRamCost = 1.5;
|
||||||
BitNodeMultipliers.PurchasedServerCost = 2;
|
BitNodeMultipliers.PurchasedServerCost = 2;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 3;
|
||||||
break;
|
break;
|
||||||
case 4: // The Singularity
|
case 4: // The Singularity
|
||||||
BitNodeMultipliers.ServerMaxMoney = 0.15;
|
BitNodeMultipliers.ServerMaxMoney = 0.15;
|
||||||
@@ -331,6 +333,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
BitNodeMultipliers.FactionPassiveRepGain = 0;
|
||||||
BitNodeMultipliers.HackExpGain = 0.25;
|
BitNodeMultipliers.HackExpGain = 0.25;
|
||||||
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 5;
|
||||||
break;
|
break;
|
||||||
case 7: // Bladeburner 2079
|
case 7: // Bladeburner 2079
|
||||||
BitNodeMultipliers.BladeburnerRank = 0.6;
|
BitNodeMultipliers.BladeburnerRank = 0.6;
|
||||||
@@ -351,6 +354,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.FourSigmaMarketDataCost = 2;
|
BitNodeMultipliers.FourSigmaMarketDataCost = 2;
|
||||||
BitNodeMultipliers.FourSigmaMarketDataApiCost = 2;
|
BitNodeMultipliers.FourSigmaMarketDataApiCost = 2;
|
||||||
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
BitNodeMultipliers.DaedalusAugsRequirement = 1.166; // Results in 35 Augs needed
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 5;
|
||||||
break;
|
break;
|
||||||
case 8: // Ghost of Wall Street
|
case 8: // Ghost of Wall Street
|
||||||
BitNodeMultipliers.ScriptHackMoney = 0.3;
|
BitNodeMultipliers.ScriptHackMoney = 0.3;
|
||||||
@@ -363,6 +367,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.RepToDonateToFaction = 0;
|
BitNodeMultipliers.RepToDonateToFaction = 0;
|
||||||
BitNodeMultipliers.CorporationValuation = 0;
|
BitNodeMultipliers.CorporationValuation = 0;
|
||||||
BitNodeMultipliers.CodingContractMoney = 0;
|
BitNodeMultipliers.CodingContractMoney = 0;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 10;
|
||||||
break;
|
break;
|
||||||
case 9: // Hacktocracy
|
case 9: // Hacktocracy
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
|
||||||
@@ -384,6 +389,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
|
BitNodeMultipliers.FourSigmaMarketDataApiCost = 4;
|
||||||
BitNodeMultipliers.BladeburnerRank = 0.9;
|
BitNodeMultipliers.BladeburnerRank = 0.9;
|
||||||
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
|
BitNodeMultipliers.BladeburnerSkillCost = 1.2;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 3;
|
||||||
break;
|
break;
|
||||||
case 10: // Digital Carbon
|
case 10: // Digital Carbon
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.2;
|
||||||
@@ -407,6 +413,7 @@ export function initBitNodeMultipliers(p: IPlayer) {
|
|||||||
BitNodeMultipliers.PurchasedServerLimit = 0.6;
|
BitNodeMultipliers.PurchasedServerLimit = 0.6;
|
||||||
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
|
BitNodeMultipliers.PurchasedServerMaxRam = 0.5;
|
||||||
BitNodeMultipliers.BladeburnerRank = 0.8;
|
BitNodeMultipliers.BladeburnerRank = 0.8;
|
||||||
|
BitNodeMultipliers.GangKarmaRequirement = 3;
|
||||||
break;
|
break;
|
||||||
case 11: //The Big Crash
|
case 11: //The Big Crash
|
||||||
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
||||||
|
|||||||
@@ -109,6 +109,11 @@ interface IBitNodeMultipliers {
|
|||||||
*/
|
*/
|
||||||
FourSigmaMarketDataCost: number;
|
FourSigmaMarketDataCost: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Influences how much negative karma is required to create a gang in this bitnode.
|
||||||
|
*/
|
||||||
|
GangKarmaRequirement: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Influences the experienced gained when hacking a server.
|
* Influences the experienced gained when hacking a server.
|
||||||
*/
|
*/
|
||||||
@@ -268,4 +273,5 @@ export const BitNodeMultipliers: IBitNodeMultipliers = {
|
|||||||
BladeburnerSkillCost: 1,
|
BladeburnerSkillCost: 1,
|
||||||
|
|
||||||
DaedalusAugsRequirement: 1,
|
DaedalusAugsRequirement: 1,
|
||||||
|
GangKarmaRequirement: 1,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Factions, factionExists } from "./Faction/Factions";
|
|||||||
import { joinFaction, displayFactionContent } from "./Faction/FactionHelpers";
|
import { joinFaction, displayFactionContent } from "./Faction/FactionHelpers";
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
import { hackWorldDaemon, redPillFlag } from "./RedPill";
|
import { hackWorldDaemon, redPillFlag } from "./RedPill";
|
||||||
|
import { calculateHospitalizationCost } from "./Hospital/Hospital";
|
||||||
|
|
||||||
import { Page, routing } from "./ui/navigationTracking";
|
import { Page, routing } from "./ui/navigationTracking";
|
||||||
import { numeralWrapper } from "./ui/numeralFormat";
|
import { numeralWrapper } from "./ui/numeralFormat";
|
||||||
@@ -50,6 +51,12 @@ import { createPopup } from "../utils/uiHelpers/createPopup";
|
|||||||
import { removeElement } from "../utils/uiHelpers/removeElement";
|
import { removeElement } from "../utils/uiHelpers/removeElement";
|
||||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||||
|
|
||||||
|
import { StatsTable } from "./ui/React/StatsTable";
|
||||||
|
import { CopyableText } from "./ui/React/CopyableText";
|
||||||
|
import { Money } from "./ui/React/Money";
|
||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
|
||||||
const stealthIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 166 132" style="fill:#adff2f;"><g><path d="M132.658-0.18l-24.321,24.321c-7.915-2.71-16.342-4.392-25.087-4.392c-45.84,0-83,46-83,46 s14.1,17.44,35.635,30.844L12.32,120.158l12.021,12.021L144.68,11.841L132.658-0.18z M52.033,80.445 c-2.104-4.458-3.283-9.438-3.283-14.695c0-19.054,15.446-34.5,34.5-34.5c5.258,0,10.237,1.179,14.695,3.284L52.033,80.445z"/><path d="M134.865,37.656l-18.482,18.482c0.884,3.052,1.367,6.275,1.367,9.612c0,19.055-15.446,34.5-34.5,34.5 c-3.337,0-6.56-0.483-9.611-1.367l-10.124,10.124c6.326,1.725,12.934,2.743,19.735,2.743c45.84,0,83-46,83-46 S153.987,50.575,134.865,37.656z"/></g></svg> `
|
const stealthIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 166 132" style="fill:#adff2f;"><g><path d="M132.658-0.18l-24.321,24.321c-7.915-2.71-16.342-4.392-25.087-4.392c-45.84,0-83,46-83,46 s14.1,17.44,35.635,30.844L12.32,120.158l12.021,12.021L144.68,11.841L132.658-0.18z M52.033,80.445 c-2.104-4.458-3.283-9.438-3.283-14.695c0-19.054,15.446-34.5,34.5-34.5c5.258,0,10.237,1.179,14.695,3.284L52.033,80.445z"/><path d="M134.865,37.656l-18.482,18.482c0.884,3.052,1.367,6.275,1.367,9.612c0,19.055-15.446,34.5-34.5,34.5 c-3.337,0-6.56-0.483-9.611-1.367l-10.124,10.124c6.326,1.725,12.934,2.743,19.735,2.743c45.84,0,83-46,83-46 S153.987,50.575,134.865,37.656z"/></g></svg> `
|
||||||
const killIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="-22 0 511 511.99561" style="fill:#adff2f;"><path d="m.496094 466.242188 39.902344-39.902344 45.753906 45.753906-39.898438 39.902344zm0 0"/><path d="m468.421875 89.832031-1.675781-89.832031-300.265625 300.265625 45.753906 45.753906zm0 0"/><path d="m95.210938 316.785156 16.84375 16.847656h.003906l83.65625 83.65625 22.753906-22.753906-100.503906-100.503906zm0 0"/><path d="m101.445312 365.300781-39.902343 39.902344 45.753906 45.753906 39.902344-39.902343-39.90625-39.902344zm0 0"/></svg>`
|
const killIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="-22 0 511 511.99561" style="fill:#adff2f;"><path d="m.496094 466.242188 39.902344-39.902344 45.753906 45.753906-39.898438 39.902344zm0 0"/><path d="m468.421875 89.832031-1.675781-89.832031-300.265625 300.265625 45.753906 45.753906zm0 0"/><path d="m95.210938 316.785156 16.84375 16.847656h.003906l83.65625 83.65625 22.753906-22.753906-100.503906-100.503906zm0 0"/><path d="m101.445312 365.300781-39.902343 39.902344 45.753906 45.753906 39.902344-39.902343-39.90625-39.902344zm0 0"/></svg>`
|
||||||
|
|
||||||
@@ -706,7 +713,7 @@ Bladeburner.prototype.completeAction = function() {
|
|||||||
if (isOperation && this.logging.ops) {
|
if (isOperation && this.logging.ops) {
|
||||||
this.log(action.name + " successfully completed! Gained " + formatNumber(gain, 3) + " rank");
|
this.log(action.name + " successfully completed! Gained " + formatNumber(gain, 3) + " rank");
|
||||||
} else if (!isOperation && this.logging.contracts) {
|
} else if (!isOperation && this.logging.contracts) {
|
||||||
this.log(action.name + " contract successfully completed! Gained " + formatNumber(gain, 3) + " rank and " + numeralWrapper.format(moneyGain, "$0.000a"));
|
this.log(action.name + " contract successfully completed! Gained " + formatNumber(gain, 3) + " rank and " + numeralWrapper.formatMoney(moneyGain));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isOperation ? this.completeOperation(true) : this.completeContract(true);
|
isOperation ? this.completeOperation(true) : this.completeContract(true);
|
||||||
@@ -722,9 +729,10 @@ Bladeburner.prototype.completeAction = function() {
|
|||||||
damage = action.hpLoss * difficultyMultiplier;
|
damage = action.hpLoss * difficultyMultiplier;
|
||||||
damage = Math.ceil(addOffset(damage, 10));
|
damage = Math.ceil(addOffset(damage, 10));
|
||||||
this.hpLost += damage;
|
this.hpLost += damage;
|
||||||
|
const cost = calculateHospitalizationCost(Player, damage);
|
||||||
if (Player.takeDamage(damage)) {
|
if (Player.takeDamage(damage)) {
|
||||||
++this.numHosp;
|
++this.numHosp;
|
||||||
this.moneyLost += (CONSTANTS.HospitalCostPerHp * Player.max_hp);
|
this.moneyLost += cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var logLossText = "";
|
var logLossText = "";
|
||||||
@@ -794,9 +802,10 @@ Bladeburner.prototype.completeAction = function() {
|
|||||||
if (action.hpLoss) {
|
if (action.hpLoss) {
|
||||||
damage = action.hpLoss * difficultyMultiplier;
|
damage = action.hpLoss * difficultyMultiplier;
|
||||||
damage = Math.ceil(addOffset(damage, 10));
|
damage = Math.ceil(addOffset(damage, 10));
|
||||||
|
const cost = calculateHospitalizationCost(Player, damage);
|
||||||
if (Player.takeDamage(damage)) {
|
if (Player.takeDamage(damage)) {
|
||||||
++this.numHosp;
|
++this.numHosp;
|
||||||
this.moneyLost += (CONSTANTS.HospitalCostPerHp * Player.max_hp);
|
this.moneyLost += cost;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
teamLossMax = Math.floor(teamCount);
|
teamLossMax = Math.floor(teamCount);
|
||||||
@@ -899,7 +908,7 @@ Bladeburner.prototype.completeAction = function() {
|
|||||||
this.stamina = Math.min(this.maxStamina, this.stamina + staminaGain);
|
this.stamina = Math.min(this.maxStamina, this.stamina + staminaGain);
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
if (this.logging.general) {
|
if (this.logging.general) {
|
||||||
this.log(`Rested in Hyperbolic Regeneration Chamber. Restored ${BladeburnerConstants.HrcHpGain} HP and gained ${numeralWrapper.format(staminaGain, "0.0")} stamina`);
|
this.log(`Rested in Hyperbolic Regeneration Chamber. Restored ${BladeburnerConstants.HrcHpGain} HP and gained ${numeralWrapper.formatStamina(staminaGain)} stamina`);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1211,10 +1220,7 @@ Bladeburner.prototype.initializeDomElementRefs = function() {
|
|||||||
overviewChaos: null,
|
overviewChaos: null,
|
||||||
overviewSkillPoints: null,
|
overviewSkillPoints: null,
|
||||||
overviewBonusTime: null,
|
overviewBonusTime: null,
|
||||||
overviewAugSuccessMult: null,
|
overviewAugMults: null,
|
||||||
overviewAugMaxStaminaMult: null,
|
|
||||||
overviewAugStaminaGainMult: null,
|
|
||||||
overviewAugAnalysisMult: null,
|
|
||||||
|
|
||||||
// Actions and Skills Content
|
// Actions and Skills Content
|
||||||
actionsAndSkillsDesc: null,
|
actionsAndSkillsDesc: null,
|
||||||
@@ -1256,7 +1262,7 @@ Bladeburner.prototype.createContent = function() {
|
|||||||
// Console
|
// Console
|
||||||
DomElems.consoleDiv = createElement("div", {
|
DomElems.consoleDiv = createElement("div", {
|
||||||
class:"bladeburner-console-div",
|
class:"bladeburner-console-div",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
if (DomElems.consoleInput instanceof Element) {
|
if (DomElems.consoleInput instanceof Element) {
|
||||||
DomElems.consoleInput.focus();
|
DomElems.consoleInput.focus();
|
||||||
}
|
}
|
||||||
@@ -1264,12 +1270,12 @@ Bladeburner.prototype.createContent = function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
DomElems.consoleTable = createElement("table", {class:"bladeburner-console-table"});
|
DomElems.consoleTable = createElement("table", {class:"bladeburner-console-table"});
|
||||||
DomElems.consoleInputRow = createElement("tr", {class:"bladeburner-console-input-row", id:"bladeubrner-console-input-row"});
|
DomElems.consoleInputRow = createElement("tr", {class:"bladeburner-console-input-row", id:"bladeburner-console-input-row"});
|
||||||
DomElems.consoleInputCell = createElement("td", {class:"bladeburner-console-input-cell"});
|
DomElems.consoleInputCell = createElement("td", {class:"bladeburner-console-input-cell"});
|
||||||
DomElems.consoleInputHeader = createElement("pre", {innerText:"> "});
|
DomElems.consoleInputHeader = createElement("pre", {innerText:"> "});
|
||||||
DomElems.consoleInput = createElement("input", {
|
DomElems.consoleInput = createElement("input", {
|
||||||
type:"text", class:"bladeburner-console-input", tabIndex:1,
|
type:"text", class:"bladeburner-console-input", tabIndex:1,
|
||||||
onfocus:()=>{DomElems.consoleInput.value = DomElems.consoleInput.value}
|
onfocus:() => {DomElems.consoleInput.value = DomElems.consoleInput.value}
|
||||||
});
|
});
|
||||||
|
|
||||||
DomElems.consoleInputCell.appendChild(DomElems.consoleInputHeader);
|
DomElems.consoleInputCell.appendChild(DomElems.consoleInputHeader);
|
||||||
@@ -1330,7 +1336,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
DomElems.overviewStaminaHelpTip = createElement("div", {
|
DomElems.overviewStaminaHelpTip = createElement("div", {
|
||||||
class:"help-tip",
|
class:"help-tip",
|
||||||
innerText:"?",
|
innerText:"?",
|
||||||
clickListener: ()=> {
|
clickListener: () => {
|
||||||
dialogBoxCreate("Performing actions will use up your stamina.<br><br>" +
|
dialogBoxCreate("Performing actions will use up your stamina.<br><br>" +
|
||||||
"Your max stamina is determined primarily by your agility stat.<br><br>" +
|
"Your max stamina is determined primarily by your agility stat.<br><br>" +
|
||||||
"Your stamina gain rate is determined by both your agility and your " +
|
"Your stamina gain rate is determined by both your agility and your " +
|
||||||
@@ -1358,7 +1364,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
|
|
||||||
DomElems.overviewEstPopHelpTip = createElement("div", {
|
DomElems.overviewEstPopHelpTip = createElement("div", {
|
||||||
innerText:"?", class:"help-tip",
|
innerText:"?", class:"help-tip",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
dialogBoxCreate("The success rate of your contracts/operations depends on " +
|
dialogBoxCreate("The success rate of your contracts/operations depends on " +
|
||||||
"the population of Synthoids in your current city. " +
|
"the population of Synthoids in your current city. " +
|
||||||
"The success rate that is shown to you is only an estimate, " +
|
"The success rate that is shown to you is only an estimate, " +
|
||||||
@@ -1397,10 +1403,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
DomElems.overviewSkillPoints = createElement("p", {display:"block"});
|
DomElems.overviewSkillPoints = createElement("p", {display:"block"});
|
||||||
|
|
||||||
|
|
||||||
DomElems.overviewAugSuccessMult = createElement("p", {display:"block"});
|
DomElems.overviewAugMults = createElement("div", {display:"block"});
|
||||||
DomElems.overviewAugMaxStaminaMult = createElement("p", {display:"block"});
|
|
||||||
DomElems.overviewAugStaminaGainMult = createElement("p", {display:"block"});
|
|
||||||
DomElems.overviewAugAnalysisMult = createElement("p", {display:"block"});
|
|
||||||
|
|
||||||
|
|
||||||
DomElems.overviewDiv.appendChild(DomElems.overviewRank);
|
DomElems.overviewDiv.appendChild(DomElems.overviewRank);
|
||||||
@@ -1418,21 +1421,18 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
DomElems.overviewDiv.appendChild(DomElems.overviewBonusTime);
|
DomElems.overviewDiv.appendChild(DomElems.overviewBonusTime);
|
||||||
DomElems.overviewDiv.appendChild(DomElems.overviewSkillPoints);
|
DomElems.overviewDiv.appendChild(DomElems.overviewSkillPoints);
|
||||||
appendLineBreaks(DomElems.overviewDiv, 1);
|
appendLineBreaks(DomElems.overviewDiv, 1);
|
||||||
DomElems.overviewDiv.appendChild(DomElems.overviewAugSuccessMult);
|
DomElems.overviewDiv.appendChild(DomElems.overviewAugMults);
|
||||||
DomElems.overviewDiv.appendChild(DomElems.overviewAugMaxStaminaMult);
|
|
||||||
DomElems.overviewDiv.appendChild(DomElems.overviewAugStaminaGainMult);
|
|
||||||
DomElems.overviewDiv.appendChild(DomElems.overviewAugAnalysisMult);
|
|
||||||
|
|
||||||
// Travel to new city button
|
// Travel to new city button
|
||||||
appendLineBreaks(DomElems.overviewDiv, 1);
|
appendLineBreaks(DomElems.overviewDiv, 1);
|
||||||
DomElems.overviewDiv.appendChild(createElement("a", {
|
DomElems.overviewDiv.appendChild(createElement("a", {
|
||||||
innerHTML:"Travel", class:"a-link-button", display:"inline-block",
|
innerHTML:"Travel", class:"a-link-button", display:"inline-block",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var popupId = "bladeburner-travel-popup-cancel-btn";
|
var popupId = "bladeburner-travel-popup-cancel-btn";
|
||||||
var popupArguments = [];
|
var popupArguments = [];
|
||||||
popupArguments.push(createElement("a", { // Cancel Button
|
popupArguments.push(createElement("a", { // Cancel Button
|
||||||
innerText:"Cancel", class:"a-link-button",
|
innerText:"Cancel", class:"a-link-button",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
removeElementById(popupId); return false;
|
removeElementById(popupId); return false;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -1451,7 +1451,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
*/
|
*/
|
||||||
class:"cmpy-mgmt-find-employee-option",
|
class:"cmpy-mgmt-find-employee-option",
|
||||||
innerText:BladeburnerConstants.CityNames[i],
|
innerText:BladeburnerConstants.CityNames[i],
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
inst.city = BladeburnerConstants.CityNames[i];
|
inst.city = BladeburnerConstants.CityNames[i];
|
||||||
removeElementById(popupId);
|
removeElementById(popupId);
|
||||||
inst.updateOverviewContent();
|
inst.updateOverviewContent();
|
||||||
@@ -1474,7 +1474,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
DomElems.overviewDiv.appendChild(createElement("a", {
|
DomElems.overviewDiv.appendChild(createElement("a", {
|
||||||
innerText:"Faction", class:"a-link-button", display:"inline-block",
|
innerText:"Faction", class:"a-link-button", display:"inline-block",
|
||||||
tooltip:"Apply to the Bladeburner Faction, or go to the faction page if you are already a member",
|
tooltip:"Apply to the Bladeburner Faction, or go to the faction page if you are already a member",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
if (bladeburnerFac.isMember) {
|
if (bladeburnerFac.isMember) {
|
||||||
Engine.loadFactionContent();
|
Engine.loadFactionContent();
|
||||||
displayFactionContent(bladeburnersFactionName);
|
displayFactionContent(bladeburnersFactionName);
|
||||||
@@ -1518,7 +1518,7 @@ Bladeburner.prototype.createActionAndSkillsContent = function() {
|
|||||||
DomElems.actionAndSkillsDiv.appendChild(createElement("a", {
|
DomElems.actionAndSkillsDiv.appendChild(createElement("a", {
|
||||||
innerText:buttons[i],
|
innerText:buttons[i],
|
||||||
class:currTab === buttons[i].toLowerCase() ? "bladeburner-nav-button-inactive" : "bladeburner-nav-button",
|
class:currTab === buttons[i].toLowerCase() ? "bladeburner-nav-button-inactive" : "bladeburner-nav-button",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
DomElems.currentTab = buttons[i].toLowerCase();
|
DomElems.currentTab = buttons[i].toLowerCase();
|
||||||
inst.createActionAndSkillsContent();
|
inst.createActionAndSkillsContent();
|
||||||
return false;
|
return false;
|
||||||
@@ -1770,23 +1770,26 @@ Bladeburner.prototype.updateOverviewContent = function() {
|
|||||||
if (!routing.isOn(Page.Bladeburner)) {return;}
|
if (!routing.isOn(Page.Bladeburner)) {return;}
|
||||||
DomElems.overviewRank.childNodes[0].nodeValue = "Rank: " + formatNumber(this.rank, 2);
|
DomElems.overviewRank.childNodes[0].nodeValue = "Rank: " + formatNumber(this.rank, 2);
|
||||||
DomElems.overviewStamina.innerText = "Stamina: " + formatNumber(this.stamina, 3) + " / " + formatNumber(this.maxStamina, 3);
|
DomElems.overviewStamina.innerText = "Stamina: " + formatNumber(this.stamina, 3) + " / " + formatNumber(this.maxStamina, 3);
|
||||||
DomElems.overviewGen1.innerHTML =
|
ReactDOM.render(<>
|
||||||
"Stamina Penalty: " + formatNumber((1-this.calculateStaminaPenalty())*100, 1) + "%<br><br>" +
|
Stamina Penalty: {formatNumber((1-this.calculateStaminaPenalty())*100, 1)}%<br /><br />
|
||||||
"Team Size: " + formatNumber(this.teamSize, 0) + "<br>" +
|
Team Size: {formatNumber(this.teamSize, 0)}<br />
|
||||||
"Team Members Lost: " + formatNumber(this.teamLost, 0) + "<br><br>" +
|
Team Members Lost: {formatNumber(this.teamLost, 0)}<br /><br />
|
||||||
"Num Times Hospitalized: " + this.numHosp + "<br>" +
|
Num Times Hospitalized: {this.numHosp}<br />
|
||||||
"Money Lost From Hospitalizations: " + numeralWrapper.format(this.moneyLost, "$0.000a") + "<br><br>" +
|
Money Lost From Hospitalizations: {Money(this.moneyLost)}<br /><br />
|
||||||
"Current City: " + this.city + "<br>";
|
Current City: {this.city}<br />
|
||||||
|
</>, DomElems.overviewGen1);
|
||||||
|
|
||||||
DomElems.overviewEstPop.childNodes[0].nodeValue = "Est. Synthoid Population: " + numeralWrapper.format(this.getCurrentCity().popEst, "0.000a");
|
DomElems.overviewEstPop.childNodes[0].nodeValue = "Est. Synthoid Population: " + numeralWrapper.formatPopulation(this.getCurrentCity().popEst);
|
||||||
DomElems.overviewEstComms.childNodes[0].nodeValue = "Est. Synthoid Communities: " + formatNumber(this.getCurrentCity().comms, 0);
|
DomElems.overviewEstComms.childNodes[0].nodeValue = "Est. Synthoid Communities: " + formatNumber(this.getCurrentCity().comms, 0);
|
||||||
DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos);
|
DomElems.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos);
|
||||||
DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0);
|
DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0);
|
||||||
DomElems.overviewBonusTime.childNodes[0].nodeValue = "Bonus time: " + convertTimeMsToTimeElapsedString(this.storedCycles/BladeburnerConstants.CyclesPerSecond*1000);
|
DomElems.overviewBonusTime.childNodes[0].nodeValue = "Bonus time: " + convertTimeMsToTimeElapsedString(this.storedCycles/BladeburnerConstants.CyclesPerSecond*1000);
|
||||||
DomElems.overviewAugSuccessMult.innerText = "Aug. Success Chance Mult: " + formatNumber(Player.bladeburner_success_chance_mult*100, 1) + "%";
|
ReactDOM.render(StatsTable([
|
||||||
DomElems.overviewAugMaxStaminaMult.innerText = "Aug. Max Stamina Mult: " + formatNumber(Player.bladeburner_max_stamina_mult*100, 1) + "%";
|
["Aug. Success Chance mult: ", formatNumber(Player.bladeburner_success_chance_mult*100, 1) + "%"],
|
||||||
DomElems.overviewAugStaminaGainMult.innerText = "Aug. Stamina Gain Mult: " + formatNumber(Player.bladeburner_stamina_gain_mult*100, 1) + "%";
|
["Aug. Max Stamina mult: ", formatNumber(Player.bladeburner_max_stamina_mult*100, 1) + "%"],
|
||||||
DomElems.overviewAugAnalysisMult.innerText = "Aug. Field Analysis Mult: " + formatNumber(Player.bladeburner_analysis_mult*100, 1) + "%";
|
["Aug. Stamina Gain mult: ", formatNumber(Player.bladeburner_stamina_gain_mult*100, 1) + "%"],
|
||||||
|
["Aug. Field Analysis mult: ", formatNumber(Player.bladeburner_analysis_mult*100, 1) + "%"],
|
||||||
|
]), DomElems.overviewAugMults);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bladeburner.prototype.updateActionAndSkillsContent = function() {
|
Bladeburner.prototype.updateActionAndSkillsContent = function() {
|
||||||
@@ -1902,7 +1905,7 @@ Bladeburner.prototype.updateGeneralActionsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("a", {
|
el.appendChild(createElement("a", {
|
||||||
innerText:"Start", class: "a-link-button",
|
innerText:"Start", class: "a-link-button",
|
||||||
margin:"3px", padding:"3px",
|
margin:"3px", padding:"3px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
this.action.type = ActionTypes[action.name];
|
this.action.type = ActionTypes[action.name];
|
||||||
this.action.name = action.name;
|
this.action.name = action.name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
@@ -1943,7 +1946,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("a", {
|
el.appendChild(createElement("a", {
|
||||||
innerText:"Start", class: "a-link-button",
|
innerText:"Start", class: "a-link-button",
|
||||||
padding:"3px", margin:"3px",
|
padding:"3px", margin:"3px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
this.action.type = ActionTypes.Contract;
|
this.action.type = ActionTypes.Contract;
|
||||||
this.action.name = action.name;
|
this.action.name = action.name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
@@ -1967,7 +1970,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
|||||||
padding:"2px", margin:"2px",
|
padding:"2px", margin:"2px",
|
||||||
tooltip: isActive ? "WARNING: changing the level will restart the contract" : "",
|
tooltip: isActive ? "WARNING: changing the level will restart the contract" : "",
|
||||||
display:"inline",
|
display:"inline",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
++action.level;
|
++action.level;
|
||||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||||
this.updateContractsUIElement(el, action);
|
this.updateContractsUIElement(el, action);
|
||||||
@@ -1979,7 +1982,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
|||||||
padding:"2px", margin:"2px",
|
padding:"2px", margin:"2px",
|
||||||
tooltip: isActive ? "WARNING: changing the level will restart the contract" : "",
|
tooltip: isActive ? "WARNING: changing the level will restart the contract" : "",
|
||||||
display:"inline",
|
display:"inline",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
--action.level;
|
--action.level;
|
||||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||||
this.updateContractsUIElement(el, action);
|
this.updateContractsUIElement(el, action);
|
||||||
@@ -1993,8 +1996,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
|||||||
display:"inline-block",
|
display:"inline-block",
|
||||||
innerHTML:action.desc + "\n\n" +
|
innerHTML:action.desc + "\n\n" +
|
||||||
`Estimated success chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` +
|
`Estimated success chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` +
|
||||||
|
"Time Required: " + convertTimeMsToTimeElapsedString(actionTime*1000) + "\n" +
|
||||||
"Time Required (s): " + formatNumber(actionTime, 0) + "\n" +
|
|
||||||
"Contracts remaining: " + Math.floor(action.count) + "\n" +
|
"Contracts remaining: " + Math.floor(action.count) + "\n" +
|
||||||
"Successes: " + action.successes + "\n" +
|
"Successes: " + action.successes + "\n" +
|
||||||
"Failures: " + action.failures,
|
"Failures: " + action.failures,
|
||||||
@@ -2042,7 +2044,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("a", {
|
el.appendChild(createElement("a", {
|
||||||
innerText:"Start", class: "a-link-button",
|
innerText:"Start", class: "a-link-button",
|
||||||
margin:"3px", padding:"3px",
|
margin:"3px", padding:"3px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
this.action.type = ActionTypes.Operation;
|
this.action.type = ActionTypes.Operation;
|
||||||
this.action.name = action.name;
|
this.action.name = action.name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
@@ -2053,7 +2055,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("a", {
|
el.appendChild(createElement("a", {
|
||||||
innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button",
|
innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button",
|
||||||
margin:"3px", padding:"3px",
|
margin:"3px", padding:"3px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var popupId = "bladeburner-operation-set-team-size-popup";
|
var popupId = "bladeburner-operation-set-team-size-popup";
|
||||||
var txt = createElement("p", {
|
var txt = createElement("p", {
|
||||||
innerText:"Enter the amount of team members you would like to take on these " +
|
innerText:"Enter the amount of team members you would like to take on these " +
|
||||||
@@ -2067,7 +2069,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
});
|
});
|
||||||
var setBtn = createElement("a", {
|
var setBtn = createElement("a", {
|
||||||
innerText:"Confirm", class:"a-link-button",
|
innerText:"Confirm", class:"a-link-button",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var num = Math.round(parseFloat(input.value));
|
var num = Math.round(parseFloat(input.value));
|
||||||
if (isNaN(num)) {
|
if (isNaN(num)) {
|
||||||
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric)")
|
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric)")
|
||||||
@@ -2081,7 +2083,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
});
|
});
|
||||||
var cancelBtn = createElement("a", {
|
var cancelBtn = createElement("a", {
|
||||||
innerText:"Cancel", class:"a-link-button",
|
innerText:"Cancel", class:"a-link-button",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
removeElementById(popupId);
|
removeElementById(popupId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2105,7 +2107,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
padding:"2px", margin:"2px",
|
padding:"2px", margin:"2px",
|
||||||
tooltip: isActive ? "WARNING: changing the level will restart the Operation" : "",
|
tooltip: isActive ? "WARNING: changing the level will restart the Operation" : "",
|
||||||
display:"inline",
|
display:"inline",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
++action.level;
|
++action.level;
|
||||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||||
this.updateOperationsUIElement(el, action);
|
this.updateOperationsUIElement(el, action);
|
||||||
@@ -2117,7 +2119,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
padding:"2px", margin:"2px",
|
padding:"2px", margin:"2px",
|
||||||
tooltip: isActive ? "WARNING: changing the level will restart the Operation" : "",
|
tooltip: isActive ? "WARNING: changing the level will restart the Operation" : "",
|
||||||
display:"inline",
|
display:"inline",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
--action.level;
|
--action.level;
|
||||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||||
this.updateOperationsUIElement(el, action);
|
this.updateOperationsUIElement(el, action);
|
||||||
@@ -2133,7 +2135,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
|||||||
display:"inline-block",
|
display:"inline-block",
|
||||||
innerHTML:action.desc + "\n\n" +
|
innerHTML:action.desc + "\n\n" +
|
||||||
`Estimated success chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` +
|
`Estimated success chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` +
|
||||||
"Time Required(s): " + formatNumber(actionTime, 0) + "\n" +
|
"Time Required: " + convertTimeMsToTimeElapsedString(actionTime*1000) + "\n" +
|
||||||
"Operations remaining: " + Math.floor(action.count) + "\n" +
|
"Operations remaining: " + Math.floor(action.count) + "\n" +
|
||||||
"Successes: " + action.successes + "\n" +
|
"Successes: " + action.successes + "\n" +
|
||||||
"Failures: " + action.failures,
|
"Failures: " + action.failures,
|
||||||
@@ -2194,7 +2196,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("a", { // Start button
|
el.appendChild(createElement("a", { // Start button
|
||||||
innerText:"Start", margin:"3px", padding:"3px",
|
innerText:"Start", margin:"3px", padding:"3px",
|
||||||
class:hasReqdRank ? "a-link-button" : "a-link-button-inactive",
|
class:hasReqdRank ? "a-link-button" : "a-link-button-inactive",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
this.action.type = ActionTypes.BlackOperation;
|
this.action.type = ActionTypes.BlackOperation;
|
||||||
this.action.name = action.name;
|
this.action.name = action.name;
|
||||||
this.startAction(this.action);
|
this.startAction(this.action);
|
||||||
@@ -2205,7 +2207,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("a", { // Set Team Size Button
|
el.appendChild(createElement("a", { // Set Team Size Button
|
||||||
innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button",
|
innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button",
|
||||||
margin:"3px", padding:"3px",
|
margin:"3px", padding:"3px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var popupId = "bladeburner-operation-set-team-size-popup";
|
var popupId = "bladeburner-operation-set-team-size-popup";
|
||||||
var txt = createElement("p", {
|
var txt = createElement("p", {
|
||||||
innerText:"Enter the amount of team members you would like to take on this " +
|
innerText:"Enter the amount of team members you would like to take on this " +
|
||||||
@@ -2219,7 +2221,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
|||||||
});
|
});
|
||||||
var setBtn = createElement("a", {
|
var setBtn = createElement("a", {
|
||||||
innerText:"Confirm", class:"a-link-button",
|
innerText:"Confirm", class:"a-link-button",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var num = Math.round(parseFloat(input.value));
|
var num = Math.round(parseFloat(input.value));
|
||||||
if (isNaN(num)) {
|
if (isNaN(num)) {
|
||||||
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric)")
|
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric)")
|
||||||
@@ -2233,7 +2235,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
|||||||
});
|
});
|
||||||
var cancelBtn = createElement("a", {
|
var cancelBtn = createElement("a", {
|
||||||
innerText:"Cancel", class:"a-link-button",
|
innerText:"Cancel", class:"a-link-button",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
removeElementById(popupId);
|
removeElementById(popupId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2256,7 +2258,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
|||||||
el.appendChild(createElement("p", {
|
el.appendChild(createElement("p", {
|
||||||
display:"inline-block",
|
display:"inline-block",
|
||||||
innerHTML:`Estimated Success Chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` +
|
innerHTML:`Estimated Success Chance: ${formatNumber(estimatedSuccessChance*100, 1)}% ${action.isStealth?stealthIcon:''}${action.isKill?killIcon:''}\n` +
|
||||||
"Time Required(s): " + formatNumber(actionTime, 0),
|
"Time Required: " + convertTimeMsToTimeElapsedString(actionTime*1000),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2269,9 +2271,15 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
|||||||
}
|
}
|
||||||
var pointCost = skill.calculateCost(currentLevel);
|
var pointCost = skill.calculateCost(currentLevel);
|
||||||
|
|
||||||
el.appendChild(createElement("h2", { // Header
|
const nameDiv = createElement("div");
|
||||||
innerText:skill.name + " (Lvl " + currentLevel + ")", display:"inline-block"
|
ReactDOM.render(React.createElement(CopyableText, {value: skill.name}, null), nameDiv);
|
||||||
}));
|
el.appendChild(nameDiv)
|
||||||
|
|
||||||
|
const h2 = createElement("h2", { // Header
|
||||||
|
display:"inline-block",
|
||||||
|
});
|
||||||
|
h2.appendChild(nameDiv);
|
||||||
|
el.appendChild(h2);
|
||||||
|
|
||||||
var canLevel = this.skillPoints >= pointCost;
|
var canLevel = this.skillPoints >= pointCost;
|
||||||
var maxLvl = skill.maxLvl ? currentLevel >= skill.maxLvl : false;
|
var maxLvl = skill.maxLvl ? currentLevel >= skill.maxLvl : false;
|
||||||
@@ -2279,7 +2287,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
|||||||
innerText:"Level", display:"inline-block",
|
innerText:"Level", display:"inline-block",
|
||||||
class: canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive",
|
class: canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive",
|
||||||
margin:"3px", padding:"3px",
|
margin:"3px", padding:"3px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
if (this.skillPoints < pointCost) {return;}
|
if (this.skillPoints < pointCost) {return;}
|
||||||
this.skillPoints -= pointCost;
|
this.skillPoints -= pointCost;
|
||||||
this.upgradeSkill(skill);
|
this.upgradeSkill(skill);
|
||||||
@@ -2288,6 +2296,10 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
appendLineBreaks(el, 2);
|
appendLineBreaks(el, 2);
|
||||||
|
el.appendChild(createElement("p", {
|
||||||
|
display:"block",
|
||||||
|
innerText:`Level: ${currentLevel}`,
|
||||||
|
}));
|
||||||
if (maxLvl) {
|
if (maxLvl) {
|
||||||
el.appendChild(createElement("p", {
|
el.appendChild(createElement("p", {
|
||||||
color:"red", display:"block",
|
color:"red", display:"block",
|
||||||
@@ -2315,7 +2327,7 @@ Bladeburner.prototype.postToConsole = function(input, saveToLogs=true) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (input == null || DomElems.consoleDiv == null) {return;}
|
if (input == null || DomElems.consoleDiv == null) {return;}
|
||||||
$("#bladeubrner-console-input-row").before('<tr><td class="bladeburner-console-line" style="color: var(--my-font-color); white-space:pre-wrap;">' + input + '</td></tr>');
|
$("#bladeburner-console-input-row").before('<tr><td class="bladeburner-console-line" style="color: var(--my-font-color); white-space:pre-wrap;">' + input + '</td></tr>');
|
||||||
|
|
||||||
if (DomElems.consoleTable.childNodes.length > MaxConsoleEntries) {
|
if (DomElems.consoleTable.childNodes.length > MaxConsoleEntries) {
|
||||||
DomElems.consoleTable.removeChild(DomElems.consoleTable.firstChild);
|
DomElems.consoleTable.removeChild(DomElems.consoleTable.firstChild);
|
||||||
@@ -214,6 +214,7 @@ export class Action {
|
|||||||
competence += (this.weights[stat] * Math.pow(effMultiplier*playerStatLvl, this.decays[stat]));
|
competence += (this.weights[stat] * Math.pow(effMultiplier*playerStatLvl, this.decays[stat]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
competence *= Player.getIntelligenceBonus(0.75);
|
||||||
competence *= inst.calculateStaminaPenalty();
|
competence *= inst.calculateStaminaPenalty();
|
||||||
|
|
||||||
competence *= this.getTeamSuccessBonus(inst);
|
competence *= this.getTeamSuccessBonus(inst);
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export const BladeburnerConstants: {
|
|||||||
ChaosThreshold: 50, // City chaos level after which it starts making tasks harder
|
ChaosThreshold: 50, // City chaos level after which it starts making tasks harder
|
||||||
|
|
||||||
BaseStatGain: 1, // Base stat gain per second
|
BaseStatGain: 1, // Base stat gain per second
|
||||||
BaseIntGain: 0.001, // Base intelligence stat gain
|
BaseIntGain: 0.003, // Base intelligence stat gain
|
||||||
|
|
||||||
ActionCountGrowthPeriod: 480, // Time (s) it takes for action count to grow by its specified value
|
ActionCountGrowthPeriod: 480, // Time (s) it takes for action count to grow by its specified value
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,23 @@
|
|||||||
import {
|
import {
|
||||||
CodingContract,
|
CodingContract,
|
||||||
CodingContractRewardType,
|
CodingContractRewardType,
|
||||||
CodingContractTypes
|
CodingContractTypes,
|
||||||
|
ICodingContractReward
|
||||||
} from "./CodingContracts";
|
} from "./CodingContracts";
|
||||||
import { Factions } from "./Faction/Factions";
|
import { Factions } from "./Faction/Factions";
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
import { AllServers } from "./Server/AllServers";
|
import { AllServers } from "./Server/AllServers";
|
||||||
import { GetServerByHostname } from "./Server/ServerHelpers";
|
import { GetServerByHostname } from "./Server/ServerHelpers";
|
||||||
import { SpecialServerNames } from "./Server/SpecialServerIps";
|
import { SpecialServerNames } from "./Server/SpecialServerIps";
|
||||||
|
import { Server } from "./Server/Server";
|
||||||
|
import { HacknetServer } from "./Hacknet/HacknetServer";
|
||||||
|
|
||||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||||
|
|
||||||
|
|
||||||
export function generateRandomContract() {
|
export function generateRandomContract() {
|
||||||
// First select a random problem type
|
// First select a random problem type
|
||||||
let problemType = getRandomProblemType();
|
const problemType = getRandomProblemType();
|
||||||
|
|
||||||
// Then select a random reward type. 'Money' will always be the last reward type
|
// Then select a random reward type. 'Money' will always be the last reward type
|
||||||
const reward = getRandomReward();
|
const reward = getRandomReward();
|
||||||
@@ -22,15 +25,15 @@ export function generateRandomContract() {
|
|||||||
// Choose random server
|
// Choose random server
|
||||||
const randServer = getRandomServer();
|
const randServer = getRandomServer();
|
||||||
|
|
||||||
let contractFn = getRandomFilename(randServer, reward);
|
const contractFn = getRandomFilename(randServer, reward);
|
||||||
let contract = new CodingContract(contractFn, problemType, reward);
|
const contract = new CodingContract(contractFn, problemType, reward);
|
||||||
|
|
||||||
randServer.addContract(contract);
|
randServer.addContract(contract);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateRandomContractOnHome() {
|
export function generateRandomContractOnHome() {
|
||||||
// First select a random problem type
|
// First select a random problem type
|
||||||
let problemType = getRandomProblemType();
|
const problemType = getRandomProblemType();
|
||||||
|
|
||||||
// Then select a random reward type. 'Money' will always be the last reward type
|
// Then select a random reward type. 'Money' will always be the last reward type
|
||||||
const reward = getRandomReward();
|
const reward = getRandomReward();
|
||||||
@@ -38,13 +41,19 @@ export function generateRandomContractOnHome() {
|
|||||||
// Choose random server
|
// Choose random server
|
||||||
const serv = Player.getHomeComputer();
|
const serv = Player.getHomeComputer();
|
||||||
|
|
||||||
let contractFn = getRandomFilename(serv, reward);
|
const contractFn = getRandomFilename(serv, reward);
|
||||||
let contract = new CodingContract(contractFn, problemType, reward);
|
const contract = new CodingContract(contractFn, problemType, reward);
|
||||||
|
|
||||||
serv.addContract(contract);
|
serv.addContract(contract);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateContract(params) {
|
export interface IGenerateContractParams {
|
||||||
|
problemType?: string;
|
||||||
|
server?: string;
|
||||||
|
fn?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateContract(params: IGenerateContractParams) {
|
||||||
// Problem Type
|
// Problem Type
|
||||||
let problemType;
|
let problemType;
|
||||||
const problemTypes = Object.keys(CodingContractTypes);
|
const problemTypes = Object.keys(CodingContractTypes);
|
||||||
@@ -62,7 +71,7 @@ export function generateContract(params) {
|
|||||||
if (params.server != null) {
|
if (params.server != null) {
|
||||||
server = GetServerByHostname(params.server);
|
server = GetServerByHostname(params.server);
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
server = AllServers[param.server];
|
server = AllServers[params.server];
|
||||||
}
|
}
|
||||||
if (server == null) {
|
if (server == null) {
|
||||||
server = getRandomServer();
|
server = getRandomServer();
|
||||||
@@ -84,7 +93,7 @@ export function generateContract(params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensures that a contract's reward type is valid
|
// Ensures that a contract's reward type is valid
|
||||||
function sanitizeRewardType(rewardType) {
|
function sanitizeRewardType(rewardType: CodingContractRewardType): CodingContractRewardType {
|
||||||
let type = rewardType; // Create copy
|
let type = rewardType; // Create copy
|
||||||
|
|
||||||
const factionsThatAllowHacking = Player.factions.filter((fac) => {
|
const factionsThatAllowHacking = Player.factions.filter((fac) => {
|
||||||
@@ -115,9 +124,11 @@ function getRandomProblemType() {
|
|||||||
return problemTypes[randIndex];
|
return problemTypes[randIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomReward() {
|
function getRandomReward(): ICodingContractReward {
|
||||||
let reward = {};
|
let reward: ICodingContractReward = {
|
||||||
reward.type = getRandomInt(0, CodingContractRewardType.Money);
|
name: "",
|
||||||
|
type: getRandomInt(0, CodingContractRewardType.Money),
|
||||||
|
};
|
||||||
reward.type = sanitizeRewardType(reward.type);
|
reward.type = sanitizeRewardType(reward.type);
|
||||||
|
|
||||||
// Add additional information based on the reward type
|
// Add additional information based on the reward type
|
||||||
@@ -155,7 +166,7 @@ function getRandomReward() {
|
|||||||
return reward;
|
return reward;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomServer() {
|
function getRandomServer(): Server | HacknetServer {
|
||||||
const servers = Object.keys(AllServers);
|
const servers = Object.keys(AllServers);
|
||||||
let randIndex = getRandomInt(0, servers.length - 1);
|
let randIndex = getRandomInt(0, servers.length - 1);
|
||||||
let randServer = AllServers[servers[randIndex]];
|
let randServer = AllServers[servers[randIndex]];
|
||||||
@@ -163,7 +174,7 @@ function getRandomServer() {
|
|||||||
// An infinite loop shouldn't ever happen, but to be safe we'll use
|
// An infinite loop shouldn't ever happen, but to be safe we'll use
|
||||||
// a for loop with a limited number of tries
|
// a for loop with a limited number of tries
|
||||||
for (let i = 0; i < 200; ++i) {
|
for (let i = 0; i < 200; ++i) {
|
||||||
if (!randServer.purchasedByPlayer && randServer.hostname !== SpecialServerNames.WorldDaemon) {
|
if (randServer instanceof Server && !randServer.purchasedByPlayer && randServer.hostname !== SpecialServerNames.WorldDaemon) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
randIndex = getRandomInt(0, servers.length - 1);
|
randIndex = getRandomInt(0, servers.length - 1);
|
||||||
@@ -173,11 +184,11 @@ function getRandomServer() {
|
|||||||
return randServer;
|
return randServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRandomFilename(server, reward) {
|
function getRandomFilename(server: Server | HacknetServer, reward: ICodingContractReward): string {
|
||||||
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||||
|
|
||||||
for (let i = 0; i < 1000; ++i) {
|
for (let i = 0; i < 1000; ++i) {
|
||||||
if (server.contracts.filter((c) => {return c.fn === contractFn}).length <= 0) { break; }
|
if (server.contracts.filter((c: CodingContract) => {return c.fn === contractFn}).length <= 0) { break; }
|
||||||
contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
import { IMap } from "./types";
|
import { IMap } from "./types";
|
||||||
|
|
||||||
export let CONSTANTS: IMap<any> = {
|
export let CONSTANTS: IMap<any> = {
|
||||||
Version: "0.49.0",
|
Version: "0.51.1",
|
||||||
|
|
||||||
/** Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
/** Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||||
* and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
* and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||||
@@ -75,14 +75,14 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
HospitalCostPerHp: 100e3,
|
HospitalCostPerHp: 100e3,
|
||||||
|
|
||||||
// Intelligence-related constants
|
// Intelligence-related constants
|
||||||
IntelligenceCrimeWeight: 0.05, // Weight for how much int affects crime success rates
|
IntelligenceCrimeWeight: 0.025, // Weight for how much int affects crime success rates
|
||||||
IntelligenceInfiltrationWeight: 0.1, // Weight for how much int affects infiltration success rates
|
IntelligenceInfiltrationWeight: 0.1, // Weight for how much int affects infiltration success rates
|
||||||
IntelligenceCrimeBaseExpGain: 0.001,
|
IntelligenceCrimeBaseExpGain: 0.05,
|
||||||
IntelligenceProgramBaseExpGain: 500, // Program required hack level divided by this to determine int exp gain
|
IntelligenceProgramBaseExpGain: 2.5, // Program required hack level divided by this to determine int exp gain
|
||||||
IntelligenceTerminalHackBaseExpGain: 200, // Hacking exp divided by this to determine int exp gain
|
IntelligenceTerminalHackBaseExpGain: 200, // Hacking exp divided by this to determine int exp gain
|
||||||
IntelligenceSingFnBaseExpGain: 0.002,
|
IntelligenceSingFnBaseExpGain: 1.5,
|
||||||
IntelligenceClassBaseExpGain: 0.000001,
|
IntelligenceClassBaseExpGain: 0.01,
|
||||||
IntelligenceHackingMissionBaseExpGain: 0.03, // Hacking Mission difficulty multiplied by this to get exp gain
|
IntelligenceHackingMissionBaseExpGain: 3, // Hacking Mission difficulty multiplied by this to get exp gain
|
||||||
|
|
||||||
// Hacking Missions
|
// Hacking Missions
|
||||||
// TODO Move this into Hacking Mission implementation
|
// TODO Move this into Hacking Mission implementation
|
||||||
@@ -228,34 +228,30 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
`
|
`
|
||||||
v0.49.2 - 2021-03-13
|
v0.51.1 - 2021-04-06 Bugfixes because the author of the last patch sucks (it's hydroflame)
|
||||||
-------
|
-------
|
||||||
|
|
||||||
BN8
|
|
||||||
* A new bitnode multipler has been added, it lets you reduce money from a
|
|
||||||
server without gaining actually any money. This is important for BN8 where
|
|
||||||
hack/grow can influence the stock market. No money can be gained from
|
|
||||||
hacking but server money can still be reduced.
|
|
||||||
|
|
||||||
Documentation
|
|
||||||
* readthedocs should now be more consistent and many examples were added.
|
|
||||||
|
|
||||||
Netscript
|
Netscript
|
||||||
* Ace editor will now correctly highlight all functions.
|
* 'getPlayer' returns players faction and tor
|
||||||
* 'tFormat' is a new netscript function that returns a human readable
|
* 'hospitalization' is a new singularity function.
|
||||||
representation of milliseconds. eg. "2 hours 15 minute 43 seconds"
|
* 'gang.getMemberInformation' now returns more information.
|
||||||
|
* 'hacknet.hashCapacity' is a new hacknet function that returns the maximum hash capacity.
|
||||||
|
|
||||||
Gang
|
Hospitalization
|
||||||
* style improvements
|
* Now only cost at most 10% of your money.
|
||||||
|
|
||||||
Bladeburner
|
Bugfix
|
||||||
* style improvements
|
* confirmation dialog box no longer use previous text
|
||||||
* fix bug where 'skill list SKILL' would crash if skill is level 0.
|
|
||||||
|
|
||||||
Sleeve
|
Accessibility
|
||||||
* karma gain now scales with sync.
|
* The game is a little easier to handle for screen readers (yes, there's an
|
||||||
|
absolute legend playing this game with a screen reader)
|
||||||
|
* Infiltration use buttons instead of a-links
|
||||||
|
* New option to disable ASCII art. This will make the metro map and world
|
||||||
|
map display as a list of buttons.
|
||||||
|
|
||||||
Misc.
|
Misc.
|
||||||
Fix issue where the effective stats under Character>Stats were being calculated.
|
* 'fl1ght.exe' will no longer suggest the combat path. Related faction
|
||||||
|
requirements unchanged.
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ import { Warehouse } from "./Warehouse";
|
|||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
import { Factions } from "../Faction/Factions";
|
import { Factions } from "../Faction/Factions";
|
||||||
import { showLiterature } from "../Literature";
|
import { showLiterature } from "../Literature/LiteratureHelpers";
|
||||||
|
import { LiteratureNames } from "../Literature/data/LiteratureNames";
|
||||||
import { createCityMap } from "../Locations/Cities";
|
import { createCityMap } from "../Locations/Cities";
|
||||||
import { CityName } from "../Locations/data/CityNames";
|
import { CityName } from "../Locations/data/CityNames";
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
@@ -1795,7 +1796,7 @@ OfficeSpace.prototype.findEmployees = function(parentRefs) {
|
|||||||
"Creativity: " + formatNumber(employee.cre, 1) + "<br>" +
|
"Creativity: " + formatNumber(employee.cre, 1) + "<br>" +
|
||||||
"Efficiency: " + formatNumber(employee.eff, 1) + "<br>" +
|
"Efficiency: " + formatNumber(employee.eff, 1) + "<br>" +
|
||||||
"Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s<br>",
|
"Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s<br>",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
office.hireEmployee(employee, parentRefs);
|
office.hireEmployee(employee, parentRefs);
|
||||||
removeElementById("cmpy-mgmt-hire-employee-popup");
|
removeElementById("cmpy-mgmt-hire-employee-popup");
|
||||||
return false;
|
return false;
|
||||||
@@ -1808,7 +1809,7 @@ OfficeSpace.prototype.findEmployees = function(parentRefs) {
|
|||||||
class:"a-link-button",
|
class:"a-link-button",
|
||||||
innerText:"Cancel",
|
innerText:"Cancel",
|
||||||
float:"right",
|
float:"right",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
removeElementById("cmpy-mgmt-hire-employee-popup");
|
removeElementById("cmpy-mgmt-hire-employee-popup");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1842,7 +1843,7 @@ OfficeSpace.prototype.hireEmployee = function(employee, parentRefs) {
|
|||||||
company.rerender();
|
company.rerender();
|
||||||
return yesNoTxtInpBoxClose();
|
return yesNoTxtInpBoxClose();
|
||||||
});
|
});
|
||||||
noBtn.addEventListener("click", ()=>{
|
noBtn.addEventListener("click", () => {
|
||||||
return yesNoTxtInpBoxClose();
|
return yesNoTxtInpBoxClose();
|
||||||
});
|
});
|
||||||
yesNoTxtInpBoxCreate("Give your employee a nickname!");
|
yesNoTxtInpBoxCreate("Give your employee a nickname!");
|
||||||
@@ -2075,14 +2076,14 @@ Corporation.prototype.getInvestment = function() {
|
|||||||
noBtn = yesNoBoxGetNoButton();
|
noBtn = yesNoBoxGetNoButton();
|
||||||
yesBtn.innerHTML = "Accept";
|
yesBtn.innerHTML = "Accept";
|
||||||
noBtn.innerHML = "Reject";
|
noBtn.innerHML = "Reject";
|
||||||
yesBtn.addEventListener("click", ()=>{
|
yesBtn.addEventListener("click", () => {
|
||||||
++this.fundingRound;
|
++this.fundingRound;
|
||||||
this.funds = this.funds.plus(funding);
|
this.funds = this.funds.plus(funding);
|
||||||
this.numShares -= investShares;
|
this.numShares -= investShares;
|
||||||
this.rerender();
|
this.rerender();
|
||||||
return yesNoBoxClose();
|
return yesNoBoxClose();
|
||||||
});
|
});
|
||||||
noBtn.addEventListener("click", ()=>{
|
noBtn.addEventListener("click", () => {
|
||||||
return yesNoBoxClose();
|
return yesNoBoxClose();
|
||||||
});
|
});
|
||||||
yesNoBoxCreate("An investment firm has offered you " + numeralWrapper.format(funding, '$0.000a') +
|
yesNoBoxCreate("An investment firm has offered you " + numeralWrapper.format(funding, '$0.000a') +
|
||||||
@@ -2107,7 +2108,7 @@ Corporation.prototype.goPublic = function() {
|
|||||||
var input = createElement("input", {
|
var input = createElement("input", {
|
||||||
type:"number",
|
type:"number",
|
||||||
placeholder: "Shares to issue",
|
placeholder: "Shares to issue",
|
||||||
onkeyup:(e)=>{
|
onkeyup:(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (e.keyCode === KEY.ENTER) {yesBtn.click();}
|
if (e.keyCode === KEY.ENTER) {yesBtn.click();}
|
||||||
}
|
}
|
||||||
@@ -2116,7 +2117,7 @@ Corporation.prototype.goPublic = function() {
|
|||||||
yesBtn = createElement("a", {
|
yesBtn = createElement("a", {
|
||||||
class:"a-link-button",
|
class:"a-link-button",
|
||||||
innerText:"Go Public",
|
innerText:"Go Public",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var numShares = Math.round(input.value);
|
var numShares = Math.round(input.value);
|
||||||
var initialSharePrice = this.determineValuation() / (this.totalShares);
|
var initialSharePrice = this.determineValuation() / (this.totalShares);
|
||||||
if (isNaN(numShares)) {
|
if (isNaN(numShares)) {
|
||||||
@@ -2142,7 +2143,7 @@ Corporation.prototype.goPublic = function() {
|
|||||||
var noBtn = createElement("a", {
|
var noBtn = createElement("a", {
|
||||||
class:"a-link-button",
|
class:"a-link-button",
|
||||||
innerText:"Cancel",
|
innerText:"Cancel",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
removeElementById(goPublicPopupId);
|
removeElementById(goPublicPopupId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2330,7 +2331,7 @@ Corporation.prototype.getStarterGuide = function() {
|
|||||||
// Check if player already has Corporation Handbook
|
// Check if player already has Corporation Handbook
|
||||||
let homeComp = Player.getHomeComputer(),
|
let homeComp = Player.getHomeComputer(),
|
||||||
hasHandbook = false,
|
hasHandbook = false,
|
||||||
handbookFn = "corporation-management-handbook.lit";
|
handbookFn = LiteratureNames.CorporationManagementHandbook;
|
||||||
for (let i = 0; i < homeComp.messages.length; ++i) {
|
for (let i = 0; i < homeComp.messages.length; ++i) {
|
||||||
if (isString(homeComp.messages[i]) && homeComp.messages[i] === handbookFn) {
|
if (isString(homeComp.messages[i]) && homeComp.messages[i] === handbookFn) {
|
||||||
hasHandbook = true;
|
hasHandbook = true;
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ export class Crime {
|
|||||||
chance /= CONSTANTS.MaxSkillLevel;
|
chance /= CONSTANTS.MaxSkillLevel;
|
||||||
chance /= this.difficulty;
|
chance /= this.difficulty;
|
||||||
chance *= p.crime_success_mult;
|
chance *= p.crime_success_mult;
|
||||||
|
chance *= p.getIntelligenceBonus(1);
|
||||||
|
|
||||||
return Math.min(chance, 1);
|
return Math.min(chance, 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const Crimes: IMap<Crime> = {
|
|||||||
dexterity_success_weight: 2,
|
dexterity_success_weight: 2,
|
||||||
agility_success_weight: 1,
|
agility_success_weight: 1,
|
||||||
|
|
||||||
intelligence_exp: 0.25 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 7.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Mug: new Crime("Mug", CONSTANTS.CrimeMug, 4e3, 36e3, 1/5, 0.25, {
|
Mug: new Crime("Mug", CONSTANTS.CrimeMug, 4e3, 36e3, 1/5, 0.25, {
|
||||||
@@ -45,7 +45,7 @@ export const Crimes: IMap<Crime> = {
|
|||||||
dexterity_success_weight: 1,
|
dexterity_success_weight: 1,
|
||||||
agility_success_weight: 1,
|
agility_success_weight: 1,
|
||||||
|
|
||||||
intelligence_exp: 0.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 15 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
DealDrugs: new Crime("Deal Drugs", CONSTANTS.CrimeDrugs, 10e3, 120e3, 1, 0.5, {
|
DealDrugs: new Crime("Deal Drugs", CONSTANTS.CrimeDrugs, 10e3, 120e3, 1, 0.5, {
|
||||||
@@ -66,7 +66,7 @@ export const Crimes: IMap<Crime> = {
|
|||||||
hacking_success_weight: 0.05,
|
hacking_success_weight: 0.05,
|
||||||
dexterity_success_weight: 1.25,
|
dexterity_success_weight: 1.25,
|
||||||
|
|
||||||
intelligence_exp: 2 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 60 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
TraffickArms: new Crime("Traffick Arms", CONSTANTS.CrimeTraffickArms, 40e3, 600e3, 2, 1, {
|
TraffickArms: new Crime("Traffick Arms", CONSTANTS.CrimeTraffickArms, 40e3, 600e3, 2, 1, {
|
||||||
@@ -110,7 +110,7 @@ export const Crimes: IMap<Crime> = {
|
|||||||
agility_success_weight: 2,
|
agility_success_weight: 2,
|
||||||
charisma_success_weight: 2,
|
charisma_success_weight: 2,
|
||||||
|
|
||||||
intelligence_exp: CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 16 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Kidnap: new Crime("Kidnap", CONSTANTS.CrimeKidnap, 120e3, 3.6e6, 5, 6, {
|
Kidnap: new Crime("Kidnap", CONSTANTS.CrimeKidnap, 120e3, 3.6e6, 5, 6, {
|
||||||
@@ -125,7 +125,7 @@ export const Crimes: IMap<Crime> = {
|
|||||||
dexterity_success_weight: 1,
|
dexterity_success_weight: 1,
|
||||||
agility_success_weight: 1,
|
agility_success_weight: 1,
|
||||||
|
|
||||||
intelligence_exp: 2 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 26 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
Assassination: new Crime("Assassination", CONSTANTS.CrimeAssassination, 300e3, 12e6, 8, 10, {
|
Assassination: new Crime("Assassination", CONSTANTS.CrimeAssassination, 300e3, 12e6, 8, 10, {
|
||||||
@@ -138,7 +138,7 @@ export const Crimes: IMap<Crime> = {
|
|||||||
dexterity_success_weight: 2,
|
dexterity_success_weight: 2,
|
||||||
agility_success_weight: 1,
|
agility_success_weight: 1,
|
||||||
|
|
||||||
intelligence_exp: 5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 65 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
|
|
||||||
kills: 1,
|
kills: 1,
|
||||||
}),
|
}),
|
||||||
@@ -158,6 +158,6 @@ export const Crimes: IMap<Crime> = {
|
|||||||
agility_success_weight: 1,
|
agility_success_weight: 1,
|
||||||
charisma_success_weight: 1,
|
charisma_success_weight: 1,
|
||||||
|
|
||||||
intelligence_exp: 10 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
intelligence_exp: 130 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
39
src/Crime/formulas/crime.ts
Normal file
39
src/Crime/formulas/crime.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { calculateIntelligenceBonus } from "../../PersonObjects/formulas/intelligence";
|
||||||
|
import { CONSTANTS } from "../../Constants";
|
||||||
|
|
||||||
|
export interface ICrime {
|
||||||
|
hacking_success_weight: number;
|
||||||
|
strength_success_weight: number;
|
||||||
|
defense_success_weight: number;
|
||||||
|
dexterity_success_weight: number;
|
||||||
|
agility_success_weight: number;
|
||||||
|
charisma_success_weight: number;
|
||||||
|
difficulty: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IPerson {
|
||||||
|
hacking_skill: number;
|
||||||
|
strength: number;
|
||||||
|
defense: number;
|
||||||
|
dexterity: number;
|
||||||
|
agility: number;
|
||||||
|
charisma: number;
|
||||||
|
intelligence: number;
|
||||||
|
crime_success_mult: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateCrimeSuccessChance(crime: ICrime, person: IPerson) {
|
||||||
|
let chance: number = (crime.hacking_success_weight * person.hacking_skill +
|
||||||
|
crime.strength_success_weight * person.strength +
|
||||||
|
crime.defense_success_weight * person.defense +
|
||||||
|
crime.dexterity_success_weight * person.dexterity +
|
||||||
|
crime.agility_success_weight * person.agility +
|
||||||
|
crime.charisma_success_weight * person.charisma +
|
||||||
|
CONSTANTS.IntelligenceCrimeWeight * person.intelligence);
|
||||||
|
chance /= CONSTANTS.MaxSkillLevel;
|
||||||
|
chance /= crime.difficulty;
|
||||||
|
chance *= person.crime_success_mult;
|
||||||
|
chance *= calculateIntelligenceBonus(person.intelligence);
|
||||||
|
|
||||||
|
return Math.min(chance, 1);
|
||||||
|
}
|
||||||
@@ -1,21 +1,24 @@
|
|||||||
|
import * as React from "react";
|
||||||
import { DarkWebItems } from "./DarkWebItems";
|
import { DarkWebItems } from "./DarkWebItems";
|
||||||
|
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
import { SpecialServerIps } from "../Server/SpecialServerIps";
|
import { SpecialServerIps } from "../Server/SpecialServerIps";
|
||||||
import { post } from "../ui/postToTerminal";
|
import { post, postElement } from "../ui/postToTerminal";
|
||||||
|
import { Money } from "../ui/React/Money";
|
||||||
|
|
||||||
import { isValidIPAddress } from "../../utils/helpers/isValidIPAddress";
|
import { isValidIPAddress } from "../../utils/helpers/isValidIPAddress";
|
||||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||||
|
import { numeralWrapper } from "../ui/numeralFormat";
|
||||||
|
|
||||||
//Posts a "help" message if connected to DarkWeb
|
//Posts a "help" message if connected to DarkWeb
|
||||||
export function checkIfConnectedToDarkweb() {
|
export function checkIfConnectedToDarkweb(): void {
|
||||||
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
||||||
var darkwebIp = SpecialServerIps["Darkweb Server"];
|
const darkwebIp = SpecialServerIps.getIp("Darkweb Server");
|
||||||
if (!isValidIPAddress(darkwebIp)) {return;}
|
if (!isValidIPAddress(darkwebIp)) {return;}
|
||||||
if (darkwebIp == Player.getCurrentServer().ip) {
|
if (darkwebIp == Player.getCurrentServer().ip) {
|
||||||
post("You are now connected to the dark web. From the dark web you can purchase illegal items. " +
|
post("You are now connected to the dark web. From the dark web you can purchase illegal items. " +
|
||||||
"Use the 'buy -l' command to display a list of all the items you can buy. Use 'buy [item-name] " +
|
"Use the 'buy -l' command to display a list of all the items you can buy. Use 'buy [item-name] " +
|
||||||
"to purchase an item");
|
"to purchase an item.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -23,7 +26,7 @@ export function checkIfConnectedToDarkweb() {
|
|||||||
//Handler for dark web commands. The terminal's executeCommand() function will pass
|
//Handler for dark web commands. The terminal's executeCommand() function will pass
|
||||||
//dark web-specific commands into this. It will pass in the raw split command array
|
//dark web-specific commands into this. It will pass in the raw split command array
|
||||||
//rather than the command string
|
//rather than the command string
|
||||||
export function executeDarkwebTerminalCommand(commandArray) {
|
export function executeDarkwebTerminalCommand(commandArray: string[]): void {
|
||||||
if (commandArray.length == 0) {return;}
|
if (commandArray.length == 0) {return;}
|
||||||
switch (commandArray[0]) {
|
switch (commandArray[0]) {
|
||||||
case "buy":
|
case "buy":
|
||||||
@@ -49,11 +52,11 @@ export function executeDarkwebTerminalCommand(commandArray) {
|
|||||||
function listAllDarkwebItems() {
|
function listAllDarkwebItems() {
|
||||||
for(const key in DarkWebItems) {
|
for(const key in DarkWebItems) {
|
||||||
const item = DarkWebItems[key];
|
const item = DarkWebItems[key];
|
||||||
post(item.toString());
|
postElement(<>{item.program} - {Money(item.price)} - {item.description}</>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buyDarkwebItem(itemName) {
|
function buyDarkwebItem(itemName: string): void {
|
||||||
itemName = itemName.toLowerCase();
|
itemName = itemName.toLowerCase();
|
||||||
|
|
||||||
// find the program that matches, if any
|
// find the program that matches, if any
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
import { numeralWrapper } from "../ui/numeralFormat";
|
||||||
|
|
||||||
export class DarkWebItem {
|
export class DarkWebItem {
|
||||||
program: string;
|
program: string;
|
||||||
@@ -10,9 +10,4 @@ export class DarkWebItem {
|
|||||||
this.price = price;
|
this.price = price;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Formats the item to print out to terminal (e.g. BruteSSH.exe -$500,000 - Opens up SSH Ports)
|
|
||||||
toString(): string {
|
|
||||||
return [this.program, "$" + formatNumber(this.price, 0), this.description].join(' - ');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import { createElement } from "../utils/uiHelpers/createElement";
|
|||||||
import { createOptionElement } from "../utils/uiHelpers/createOptionElement";
|
import { createOptionElement } from "../utils/uiHelpers/createOptionElement";
|
||||||
import { getSelectText } from "../utils/uiHelpers/getSelectData";
|
import { getSelectText } from "../utils/uiHelpers/getSelectData";
|
||||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||||
|
import { Money } from "./ui/React/Money";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
@@ -611,12 +612,16 @@ class DevMenuComponent extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
viewStockCaps() {
|
viewStockCaps() {
|
||||||
let text = "<table><tbody><tr><th>Stock</th><th>Price cap</th></tr>";
|
let stocks = [];
|
||||||
this.processStocks((stock) => {
|
this.processStocks((stock) => {
|
||||||
text += `<tr><td>${stock.symbol}</td><td style="text-align:right;">${numeralWrapper.format(stock.cap, '$0.000a')}</td></tr>`;
|
stocks.push(<tr key={stock.symbol}>
|
||||||
|
<td>{stock.symbol}</td>
|
||||||
|
<td style={{'textAlign':'right'}}>{Money(stock.cap)}</td>
|
||||||
|
</tr>);
|
||||||
});
|
});
|
||||||
text += "</tbody></table>";
|
dialogBoxCreate(<table><tbody><tr><th>Stock</th><th>Price cap</th></tr>
|
||||||
dialogBoxCreate(text);
|
{stocks}
|
||||||
|
</tbody></table>);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleeveMaxAllShock() {
|
sleeveMaxAllShock() {
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ Source-File minus 1 is extremely weak because it can be fully level up quickly.
|
|||||||
|
|
||||||
export enum Exploit {
|
export enum Exploit {
|
||||||
UndocumentedFunctionCall = 'UndocumentedFunctionCall',
|
UndocumentedFunctionCall = 'UndocumentedFunctionCall',
|
||||||
|
Unclickable = 'Unclickable',
|
||||||
PrototypeTampering = 'PrototypeTampering',
|
PrototypeTampering = 'PrototypeTampering',
|
||||||
// To the players reading this. Yes you're supposed to add EditSaveFile by
|
// To the players reading this. Yes you're supposed to add EditSaveFile by
|
||||||
// editing your save file, yes you could add them all, no we don't care
|
// editing your save file, yes you could add them all, no we don't care
|
||||||
// that's not the point
|
// that's not the point.
|
||||||
EditSaveFile = 'EditSaveFile'
|
EditSaveFile = 'EditSaveFile'
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ const names: {
|
|||||||
'UndocumentedFunctionCall': 'by looking beyond the documentation.',
|
'UndocumentedFunctionCall': 'by looking beyond the documentation.',
|
||||||
'EditSaveFile': 'by editing your save file.',
|
'EditSaveFile': 'by editing your save file.',
|
||||||
'PrototypeTampering': 'by tampering with Numbers prototype.',
|
'PrototypeTampering': 'by tampering with Numbers prototype.',
|
||||||
|
'Unclickable': 'by clicking the unclickable.',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
24
src/Exploits/unclickable.ts
Normal file
24
src/Exploits/unclickable.ts
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import { Player } from "../Player";
|
||||||
|
import { Exploit } from "./Exploit";
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
function clickTheUnclickable(event: MouseEvent) {
|
||||||
|
if(!event.target || !(event.target instanceof Element)) return;
|
||||||
|
const display = window.getComputedStyle(event.target as Element).display;
|
||||||
|
if(display === 'none' && event.isTrusted)
|
||||||
|
Player.giveExploit(Exploit.Unclickable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function targetElement() {
|
||||||
|
const elem = document.getElementById('unclickable');
|
||||||
|
if(elem == null) {
|
||||||
|
console.error('Could not find the unclickable elem for the related exploit.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
elem.addEventListener("click", clickTheUnclickable);
|
||||||
|
document.removeEventListener('DOMContentLoaded', targetElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', targetElement);
|
||||||
|
})();
|
||||||
@@ -25,6 +25,8 @@ import {
|
|||||||
Generic_fromJSON
|
Generic_fromJSON
|
||||||
} from "../../utils/JSONReviver";
|
} from "../../utils/JSONReviver";
|
||||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||||
|
import { numeralWrapper } from "../ui/numeralFormat";
|
||||||
|
import { Money } from "../ui/React/Money";
|
||||||
import {
|
import {
|
||||||
yesNoBoxCreate,
|
yesNoBoxCreate,
|
||||||
yesNoBoxGetYesButton,
|
yesNoBoxGetYesButton,
|
||||||
@@ -108,10 +110,12 @@ export function purchaseAugmentationBoxCreate(aug, fac) {
|
|||||||
yesNoBoxClose();
|
yesNoBoxClose();
|
||||||
});
|
});
|
||||||
|
|
||||||
yesNoBoxCreate("<h2>" + aug.name + "</h2><br>" +
|
yesNoBoxCreate(<>
|
||||||
aug.info + "<br><br>" +
|
<h2>{aug.name}</h2><br />
|
||||||
"<br>Would you like to purchase the " + aug.name + " Augmentation for $" +
|
<div dangerouslySetInnerHTML={{__html: aug.info}}></div><br /><br />
|
||||||
formatNumber(aug.baseCost * factionInfo.augmentationPriceMult, 2) + "?");
|
<br />Would you like to purchase the {aug.name} Augmentation for
|
||||||
|
{Money(aug.baseCost * factionInfo.augmentationPriceMult)}?
|
||||||
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns a boolean indicating whether the player has the prerequisites for the
|
//Returns a boolean indicating whether the player has the prerequisites for the
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import * as React from "react";
|
|||||||
import { PurchaseableAugmentation } from "./PurchaseableAugmentation";
|
import { PurchaseableAugmentation } from "./PurchaseableAugmentation";
|
||||||
|
|
||||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||||
|
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
|
||||||
import { Faction } from "../../Faction/Faction";
|
import { Faction } from "../../Faction/Faction";
|
||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||||
@@ -44,7 +45,7 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
this.rerender = this.rerender.bind(this);
|
this.rerender = this.rerender.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugs() {
|
getAugs(): string[] {
|
||||||
if (this.isPlayersGang) {
|
if (this.isPlayersGang) {
|
||||||
const augs: string[] = [];
|
const augs: string[] = [];
|
||||||
for (const augName in Augmentations) {
|
for (const augName in Augmentations) {
|
||||||
@@ -60,7 +61,7 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSorted() {
|
getAugsSorted(): string[] {
|
||||||
switch (Settings.PurchaseAugmentationsOrder) {
|
switch (Settings.PurchaseAugmentationsOrder) {
|
||||||
case PurchaseAugmentationsOrderSetting.Cost: {
|
case PurchaseAugmentationsOrderSetting.Cost: {
|
||||||
return this.getAugsSortedByCost();
|
return this.getAugsSortedByCost();
|
||||||
@@ -73,7 +74,7 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSortedByCost() {
|
getAugsSortedByCost(): string[] {
|
||||||
const augs = this.getAugs();
|
const augs = this.getAugs();
|
||||||
augs.sort((augName1, augName2)=>{
|
augs.sort((augName1, augName2)=>{
|
||||||
var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2];
|
var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2];
|
||||||
@@ -87,7 +88,7 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
return augs;
|
return augs;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSortedByReputation() {
|
getAugsSortedByReputation(): string[] {
|
||||||
const augs = this.getAugs();
|
const augs = this.getAugs();
|
||||||
augs.sort((augName1, augName2)=>{
|
augs.sort((augName1, augName2)=>{
|
||||||
var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2];
|
var aug1 = Augmentations[augName1], aug2 = Augmentations[augName2];
|
||||||
@@ -100,16 +101,16 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
return augs;
|
return augs;
|
||||||
}
|
}
|
||||||
|
|
||||||
getAugsSortedByDefault() {
|
getAugsSortedByDefault(): string[] {
|
||||||
return this.getAugs();
|
return this.getAugs();
|
||||||
}
|
}
|
||||||
|
|
||||||
switchSortOrder(newOrder: PurchaseAugmentationsOrderSetting) {
|
switchSortOrder(newOrder: PurchaseAugmentationsOrderSetting): void {
|
||||||
Settings.PurchaseAugmentationsOrder = newOrder;
|
Settings.PurchaseAugmentationsOrder = newOrder;
|
||||||
this.rerender();
|
this.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
rerender() {
|
rerender(): void {
|
||||||
this.setState((prevState) => {
|
this.setState((prevState) => {
|
||||||
return {
|
return {
|
||||||
rerenderFlag: !prevState.rerenderFlag,
|
rerenderFlag: !prevState.rerenderFlag,
|
||||||
@@ -119,17 +120,39 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const augs = this.getAugsSorted();
|
const augs = this.getAugsSorted();
|
||||||
const augList = augs.map((aug) => {
|
const purchasable = augs.filter((aug: string) =>
|
||||||
|
aug === AugmentationNames.NeuroFluxGovernor ||
|
||||||
|
(!this.props.p.augmentations.some(a => a.name === aug) &&
|
||||||
|
!this.props.p.queuedAugmentations.some(a => a.name === aug))
|
||||||
|
)
|
||||||
|
|
||||||
|
const parent = this;
|
||||||
|
function purchaseableAugmentation(aug: string) {
|
||||||
return (
|
return (
|
||||||
<PurchaseableAugmentation
|
<PurchaseableAugmentation
|
||||||
augName={aug}
|
augName={aug}
|
||||||
faction={this.props.faction}
|
faction={parent.props.faction}
|
||||||
key={aug}
|
key={aug}
|
||||||
p={this.props.p}
|
p={parent.props.p}
|
||||||
rerender={this.rerender}
|
rerender={parent.rerender}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
});
|
}
|
||||||
|
|
||||||
|
const augListElems = purchasable.map(aug => purchaseableAugmentation(aug));
|
||||||
|
|
||||||
|
let ownedElem = <></>
|
||||||
|
const owned = augs.filter((aug: string) => !purchasable.includes(aug));
|
||||||
|
if (owned.length !== 0) {
|
||||||
|
ownedElem = <>
|
||||||
|
<br />
|
||||||
|
<h2>Purchased Augmentations</h2>
|
||||||
|
<p style={infoStyleMarkup}>
|
||||||
|
This factions also offers these augmentations but you already own them.
|
||||||
|
</p>
|
||||||
|
{owned.map(aug => purchaseableAugmentation(aug))}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -156,7 +179,8 @@ export class AugmentationsPage extends React.Component<IProps, IState> {
|
|||||||
text={"Sort by Default Order"}
|
text={"Sort by Default Order"}
|
||||||
/>
|
/>
|
||||||
<br />
|
<br />
|
||||||
{augList}
|
{augListElems}
|
||||||
|
{ownedElem}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import { Faction } from "../../Faction/Faction";
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
|
||||||
@@ -21,7 +23,7 @@ type IProps = {
|
|||||||
|
|
||||||
type IState = {
|
type IState = {
|
||||||
donateAmt: number;
|
donateAmt: number;
|
||||||
statusTxt: string;
|
status: JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
const inputStyleMarkup = {
|
const inputStyleMarkup = {
|
||||||
@@ -37,7 +39,7 @@ export class DonateOption extends React.Component<IProps, IState> {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
donateAmt: 0,
|
donateAmt: 0,
|
||||||
statusTxt: "",
|
status: <></>,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.calculateRepGain = this.calculateRepGain.bind(this);
|
this.calculateRepGain = this.calculateRepGain.bind(this);
|
||||||
@@ -61,8 +63,9 @@ export class DonateOption extends React.Component<IProps, IState> {
|
|||||||
this.props.p.loseMoney(amt);
|
this.props.p.loseMoney(amt);
|
||||||
const repGain = this.calculateRepGain(amt);
|
const repGain = this.calculateRepGain(amt);
|
||||||
this.props.faction.playerReputation += repGain;
|
this.props.faction.playerReputation += repGain;
|
||||||
dialogBoxCreate(`You just donated ${numeralWrapper.formatMoney(amt)} to ${fac.name} to gain ` +
|
dialogBoxCreate(<>
|
||||||
`${numeralWrapper.format(repGain, "0,0.000")} reputation`);
|
You just donated {Money(amt)} to {fac.name} to gain {Reputation(repGain)} reputation
|
||||||
|
</>);
|
||||||
this.props.rerender();
|
this.props.rerender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -73,13 +76,13 @@ export class DonateOption extends React.Component<IProps, IState> {
|
|||||||
if (isNaN(amt)) {
|
if (isNaN(amt)) {
|
||||||
this.setState({
|
this.setState({
|
||||||
donateAmt: 0,
|
donateAmt: 0,
|
||||||
statusTxt: "Invalid donate amount entered!",
|
status: <>Invalid donate amount entered!</>,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const repGain = this.calculateRepGain(amt);
|
const repGain = this.calculateRepGain(amt);
|
||||||
this.setState({
|
this.setState({
|
||||||
donateAmt: amt,
|
donateAmt: amt,
|
||||||
statusTxt: `This donation will result in ${numeralWrapper.format(repGain, "0,0.000")} reputation gain`,
|
status: <>This donation will result in {Reputation(repGain)} reputation gain</>,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,7 +96,7 @@ export class DonateOption extends React.Component<IProps, IState> {
|
|||||||
onClick={this.donate}
|
onClick={this.donate}
|
||||||
text={"Donate Money"}
|
text={"Donate Money"}
|
||||||
/>
|
/>
|
||||||
<p style={this.blockStyle}>{this.state.statusTxt}</p>
|
<p style={this.blockStyle}>{this.state.status}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
|||||||
|
|
||||||
import { AutoupdatingParagraph } from "../../ui/React/AutoupdatingParagraph";
|
import { AutoupdatingParagraph } from "../../ui/React/AutoupdatingParagraph";
|
||||||
import { ParagraphWithTooltip } from "../../ui/React/ParagraphWithTooltip";
|
import { ParagraphWithTooltip } from "../../ui/React/ParagraphWithTooltip";
|
||||||
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
|
import { Favor } from "../../ui/React/Favor";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
faction: Faction;
|
faction: Faction;
|
||||||
@@ -33,18 +35,17 @@ export class Info extends React.Component<IProps, any> {
|
|||||||
constructor(props: IProps) {
|
constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.getFavorGainText = this.getFavorGainText.bind(this);
|
this.getFavorGainContent = this.getFavorGainContent.bind(this);
|
||||||
this.getReputationText = this.getReputationText.bind(this);
|
this.getReputationContent = this.getReputationContent.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFavorGainText(): string {
|
getFavorGainContent(): JSX.Element {
|
||||||
const favorGain = this.props.faction.getFavorGain()[0];
|
const favorGain = this.props.faction.getFavorGain()[0];
|
||||||
return `You will earn ${numeralWrapper.format(favorGain, "0,0")} faction favor upon resetting after installing an Augmentation`
|
return <>You will earn {Favor(favorGain)} faction favor upon resetting after installing an Augmentation</>
|
||||||
}
|
}
|
||||||
|
|
||||||
getReputationText(): string {
|
getReputationContent(): JSX.Element {
|
||||||
const formattedRep = numeralWrapper.format(this.props.faction.playerReputation, "0.000a");
|
return <>Reputation: {Reputation(this.props.faction.playerReputation)}</>
|
||||||
return `Reputation: ${formattedRep}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -65,12 +66,12 @@ export class Info extends React.Component<IProps, any> {
|
|||||||
<p style={blockStyleMarkup}>-------------------------</p>
|
<p style={blockStyleMarkup}>-------------------------</p>
|
||||||
<AutoupdatingParagraph
|
<AutoupdatingParagraph
|
||||||
intervalTime={5e3}
|
intervalTime={5e3}
|
||||||
getText={this.getReputationText}
|
getContent={this.getReputationContent}
|
||||||
getTooltip={this.getFavorGainText}
|
getTooltip={this.getFavorGainContent}
|
||||||
/>
|
/>
|
||||||
<p style={blockStyleMarkup}>-------------------------</p>
|
<p style={blockStyleMarkup}>-------------------------</p>
|
||||||
<ParagraphWithTooltip
|
<ParagraphWithTooltip
|
||||||
text={`Faction Favor: ${numeralWrapper.format(this.props.faction.favor, "0,0")}`}
|
content={<>Faction Favor: {Favor(this.props.faction.favor)}</>}
|
||||||
tooltip={favorTooltip}
|
tooltip={favorTooltip}
|
||||||
/>
|
/>
|
||||||
<p style={blockStyleMarkup}>-------------------------</p>
|
<p style={blockStyleMarkup}>-------------------------</p>
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ import { Faction } from "../../Faction/Faction";
|
|||||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
import { Settings } from "../../Settings/Settings";
|
import { Settings } from "../../Settings/Settings";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
import { IMap } from "../../types";
|
import { IMap } from "../../types";
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
augName: string;
|
augName: string;
|
||||||
@@ -106,20 +109,19 @@ export class PurchaseableAugmentation extends React.Component<IProps, any> {
|
|||||||
|
|
||||||
// Determine UI properties
|
// Determine UI properties
|
||||||
let disabled: boolean = false;
|
let disabled: boolean = false;
|
||||||
let statusTxt: string = "";
|
let status: JSX.Element = <></>;
|
||||||
let color: string = "";
|
let color: string = "";
|
||||||
if (!this.hasPrereqs()) {
|
if (!this.hasPrereqs()) {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
statusTxt = `LOCKED (Requires ${this.aug.prereqs.join(",")} as prerequisite(s))`;
|
status = <>LOCKED (Requires {this.aug.prereqs.map(aug => AugFormat(aug))} as prerequisite)</>;
|
||||||
color = "red";
|
color = "red";
|
||||||
} else if (this.aug.name !== AugmentationNames.NeuroFluxGovernor && (this.aug.owned || this.owned())) {
|
} else if (this.aug.name !== AugmentationNames.NeuroFluxGovernor && (this.aug.owned || this.owned())) {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
statusTxt = "ALREADY OWNED";
|
|
||||||
} else if (this.hasReputation()) {
|
} else if (this.hasReputation()) {
|
||||||
statusTxt = `UNLOCKED - ${numeralWrapper.formatMoney(moneyCost)}`;
|
status = <>UNLOCKED - {Money(moneyCost)}</>;
|
||||||
} else {
|
} else {
|
||||||
disabled = true;
|
disabled = true;
|
||||||
statusTxt = `LOCKED (Requires ${numeralWrapper.format(repCost, "0,0.0")} faction reputation - ${numeralWrapper.formatMoney(moneyCost)})`;
|
status = <>LOCKED (Requires {Reputation(repCost)} faction reputation - {Money(moneyCost)})</>;
|
||||||
color = "red";
|
color = "red";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +146,7 @@ export class PurchaseableAugmentation extends React.Component<IProps, any> {
|
|||||||
text={btnTxt}
|
text={btnTxt}
|
||||||
tooltip={this.aug.info}
|
tooltip={this.aug.info}
|
||||||
/>
|
/>
|
||||||
<p style={txtStyle}>{statusTxt}</p>
|
<p style={txtStyle}>{status}</p>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ import { removeElement } from "../utils/uiHelpers/removeElement";
|
|||||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||||
|
|
||||||
|
import { StatsTable } from "./ui/React/StatsTable";
|
||||||
|
import { Money } from "./ui/React/Money";
|
||||||
|
import { MoneyRate } from "./ui/React/MoneyRate";
|
||||||
|
import { Reputation } from "./ui/React/Reputation";
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
import ReactDOM from "react-dom";
|
||||||
|
import { renderToStaticMarkup } from "react-dom/server"
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const GangRespectToReputationRatio = 5; // Respect is divided by this to get rep gain
|
const GangRespectToReputationRatio = 5; // Respect is divided by this to get rep gain
|
||||||
@@ -492,15 +500,15 @@ Gang.prototype.ascendMember = function(memberObj, workerScript) {
|
|||||||
if (workerScript == null) {
|
if (workerScript == null) {
|
||||||
dialogBoxCreate([`You ascended ${memberObj.name}!`,
|
dialogBoxCreate([`You ascended ${memberObj.name}!`,
|
||||||
"",
|
"",
|
||||||
`Your gang lost ${numeralWrapper.format(res.respect, "0.000a")} respect`,
|
`Your gang lost ${numeralWrapper.formatRespect(res.respect)} respect`,
|
||||||
"",
|
"",
|
||||||
`${memberObj.name} gained the following stat multipliers for ascending:`,
|
`${memberObj.name} gained the following stat multipliers for ascending:`,
|
||||||
`Hacking: ${numeralWrapper.format(res.hack, "0.000%")}`,
|
`Hacking: ${numeralWrapper.formatPercentage(res.hack, 3)}`,
|
||||||
`Strength: ${numeralWrapper.format(res.str, "0.000%")}`,
|
`Strength: ${numeralWrapper.formatPercentage(res.str, 3)}`,
|
||||||
`Defense: ${numeralWrapper.format(res.def, "0.000%")}`,
|
`Defense: ${numeralWrapper.formatPercentage(res.def, 3)}`,
|
||||||
`Dexterity: ${numeralWrapper.format(res.dex, "0.000%")}`,
|
`Dexterity: ${numeralWrapper.formatPercentage(res.dex, 3)}`,
|
||||||
`Agility: ${numeralWrapper.format(res.agi, "0.000%")}`,
|
`Agility: ${numeralWrapper.formatPercentage(res.agi, 3)}`,
|
||||||
`Charisma: ${numeralWrapper.format(res.cha, "0.000%")}`].join("<br>"));
|
`Charisma: ${numeralWrapper.formatPercentage(res.cha, 3)}`].join("<br>"));
|
||||||
} else {
|
} else {
|
||||||
workerScript.log(`Ascended Gang member ${memberObj.name}`);
|
workerScript.log(`Ascended Gang member ${memberObj.name}`);
|
||||||
}
|
}
|
||||||
@@ -1044,14 +1052,14 @@ Gang.prototype.createGangMemberUpgradeBox = function(player, initialFilter="") {
|
|||||||
type:"text", placeholder:"Filter gang members",
|
type:"text", placeholder:"Filter gang members",
|
||||||
class: "text-input",
|
class: "text-input",
|
||||||
value:initialFilter,
|
value:initialFilter,
|
||||||
onkeyup:()=>{
|
onkeyup:() => {
|
||||||
var filterValue = UIElems.gangMemberUpgradeBoxFilter.value.toString();
|
var filterValue = UIElems.gangMemberUpgradeBoxFilter.value.toString();
|
||||||
this.createGangMemberUpgradeBox(player, filterValue);
|
this.createGangMemberUpgradeBox(player, filterValue);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
UIElems.gangMemberUpgradeBoxDiscount = createElement("p", {
|
UIElems.gangMemberUpgradeBoxDiscount = createElement("p", {
|
||||||
innerText: "Discount: -" + numeralWrapper.format(1 - 1 / this.getDiscount(), "0.00%"),
|
innerText: "Discount: -" + numeralWrapper.formatPercentage(1 - 1 / this.getDiscount()),
|
||||||
marginLeft: "6px",
|
marginLeft: "6px",
|
||||||
tooltip: "You get a discount on equipment and upgrades based on your gang's " +
|
tooltip: "You get a discount on equipment and upgrades based on your gang's " +
|
||||||
"respect and power. More respect and power leads to more discounts."
|
"respect and power. More respect and power leads to more discounts."
|
||||||
@@ -1178,10 +1186,10 @@ GangMember.prototype.createGangMemberUpgradePanel = function(gangObj, player) {
|
|||||||
let upg = upgradeArray[j];
|
let upg = upgradeArray[j];
|
||||||
(function (upg, div, memberObj, i, gang) {
|
(function (upg, div, memberObj, i, gang) {
|
||||||
let createElementParams = {
|
let createElementParams = {
|
||||||
innerText: upg.name + " - " + numeralWrapper.format(upg.getCost(gang), "$0.000a"),
|
innerHTML: `${upg.name} - ${renderToStaticMarkup(Money(upg.getCost(gang)))}`,
|
||||||
class: "a-link-button", margin:"2px", padding:"2px", display:"block",
|
class: "a-link-button", margin:"2px", padding:"2px", display:"block",
|
||||||
fontSize:"11px",
|
fontSize:"11px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
memberObj.buyUpgrade(upg, player, gangObj);
|
memberObj.buyUpgrade(upg, player, gangObj);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1266,7 +1274,7 @@ Gang.prototype.displayGangContent = function(player) {
|
|||||||
// Back button
|
// Back button
|
||||||
UIElems.gangContainer.appendChild(createElement("a", {
|
UIElems.gangContainer.appendChild(createElement("a", {
|
||||||
class:"a-link-button", display:"inline-block", innerText:"Back",
|
class:"a-link-button", display:"inline-block", innerText:"Back",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
Engine.loadFactionContent();
|
Engine.loadFactionContent();
|
||||||
displayFactionContent(facName);
|
displayFactionContent(facName);
|
||||||
return false;
|
return false;
|
||||||
@@ -1277,7 +1285,7 @@ Gang.prototype.displayGangContent = function(player) {
|
|||||||
UIElems.managementButton = createElement("a", {
|
UIElems.managementButton = createElement("a", {
|
||||||
id:"gang-management-subpage-button", class:"a-link-button-inactive",
|
id:"gang-management-subpage-button", class:"a-link-button-inactive",
|
||||||
display:"inline-block", innerHTML: "Gang Management (Alt+1)",
|
display:"inline-block", innerHTML: "Gang Management (Alt+1)",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
UIElems.gangManagementSubpage.style.display = "block";
|
UIElems.gangManagementSubpage.style.display = "block";
|
||||||
UIElems.gangTerritorySubpage.style.display = "none";
|
UIElems.gangTerritorySubpage.style.display = "none";
|
||||||
UIElems.managementButton.classList.toggle("a-link-button-inactive");
|
UIElems.managementButton.classList.toggle("a-link-button-inactive");
|
||||||
@@ -1340,7 +1348,7 @@ Gang.prototype.displayGangContent = function(player) {
|
|||||||
UIElems.gangRecruitMemberButton = createElement("a", {
|
UIElems.gangRecruitMemberButton = createElement("a", {
|
||||||
id: "gang-management-recruit-member-btn", class:"a-link-button-inactive",
|
id: "gang-management-recruit-member-btn", class:"a-link-button-inactive",
|
||||||
innerHTML:"Recruit Gang Member", display:"inline-block", margin:"10px",
|
innerHTML:"Recruit Gang Member", display:"inline-block", margin:"10px",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
const popupId = "recruit-gang-member-popup";
|
const popupId = "recruit-gang-member-popup";
|
||||||
|
|
||||||
let yesBtn;
|
let yesBtn;
|
||||||
@@ -1408,7 +1416,7 @@ Gang.prototype.displayGangContent = function(player) {
|
|||||||
UIElems.gangExpandAllButton = createElement("a", {
|
UIElems.gangExpandAllButton = createElement("a", {
|
||||||
class:"a-link-button", display:"inline-block",
|
class:"a-link-button", display:"inline-block",
|
||||||
innerHTML:"Expand All",
|
innerHTML:"Expand All",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var allHeaders = UIElems.gangManagementSubpage.getElementsByClassName("accordion-header");
|
var allHeaders = UIElems.gangManagementSubpage.getElementsByClassName("accordion-header");
|
||||||
for (var i = 0; i < allHeaders.length; ++i) {
|
for (var i = 0; i < allHeaders.length; ++i) {
|
||||||
var hdr = allHeaders[i];
|
var hdr = allHeaders[i];
|
||||||
@@ -1422,7 +1430,7 @@ Gang.prototype.displayGangContent = function(player) {
|
|||||||
UIElems.gangCollapseAllButton = createElement("a", {
|
UIElems.gangCollapseAllButton = createElement("a", {
|
||||||
class:"a-link-button", display:"inline-block",
|
class:"a-link-button", display:"inline-block",
|
||||||
innerHTML:"Collapse All",
|
innerHTML:"Collapse All",
|
||||||
clickListener:()=>{
|
clickListener:() => {
|
||||||
var allHeaders = UIElems.gangManagementSubpage.getElementsByClassName("accordion-header");
|
var allHeaders = UIElems.gangManagementSubpage.getElementsByClassName("accordion-header");
|
||||||
for (var i = 0; i < allHeaders.length; ++i) {
|
for (var i = 0; i < allHeaders.length; ++i) {
|
||||||
var hdr = allHeaders[i];
|
var hdr = allHeaders[i];
|
||||||
@@ -1436,7 +1444,7 @@ Gang.prototype.displayGangContent = function(player) {
|
|||||||
UIElems.gangMemberFilter = createElement("input", {
|
UIElems.gangMemberFilter = createElement("input", {
|
||||||
type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px",
|
type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px",
|
||||||
class:"text-input",
|
class:"text-input",
|
||||||
onkeyup:()=>{
|
onkeyup:() => {
|
||||||
this.displayGangMemberList();
|
this.displayGangMemberList();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -1584,13 +1592,13 @@ Gang.prototype.updateGangContent = function() {
|
|||||||
|
|
||||||
if (UIElems.gangMemberUpgradeBoxOpened) {
|
if (UIElems.gangMemberUpgradeBoxOpened) {
|
||||||
UIElems.gangMemberUpgradeBoxDiscount.childNodes[0].nodeValue =
|
UIElems.gangMemberUpgradeBoxDiscount.childNodes[0].nodeValue =
|
||||||
"Discount: -" + numeralWrapper.format(1 - 1 / this.getDiscount(), "0.00%");
|
"Discount: -" + numeralWrapper.formatPercentage(1 - 1 / this.getDiscount());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UIElems.gangTerritorySubpage.style.display === "block") {
|
if (UIElems.gangTerritorySubpage.style.display === "block") {
|
||||||
// Territory Warfare Clash Chance
|
// Territory Warfare Clash Chance
|
||||||
UIElems.gangTerritoryWarfareClashChance.innerText =
|
UIElems.gangTerritoryWarfareClashChance.innerText =
|
||||||
`Territory Clash Chance: ${numeralWrapper.format(this.territoryClashChance, '0.000%')}`;
|
`Territory Clash Chance: ${numeralWrapper.formatPercentage(this.territoryClashChance, 3)}`;
|
||||||
|
|
||||||
// Engaged in Territory Warfare checkbox
|
// Engaged in Territory Warfare checkbox
|
||||||
UIElems.gangTerritoryWarfareCheckbox.checked = this.territoryWarfareEngaged;
|
UIElems.gangTerritoryWarfareCheckbox.checked = this.territoryWarfareEngaged;
|
||||||
@@ -1623,7 +1631,7 @@ Gang.prototype.updateGangContent = function() {
|
|||||||
const clashVictoryChance = playerPower / (gangTerritoryInfo.power + playerPower);
|
const clashVictoryChance = playerPower / (gangTerritoryInfo.power + playerPower);
|
||||||
let newHTML = `<u>${gangname}</u><br>Power: ${formatNumber(gangTerritoryInfo.power, 6)}<br>`;
|
let newHTML = `<u>${gangname}</u><br>Power: ${formatNumber(gangTerritoryInfo.power, 6)}<br>`;
|
||||||
newHTML += `Territory: ${displayNumber}%<br>`;
|
newHTML += `Territory: ${displayNumber}%<br>`;
|
||||||
newHTML += `Chance to win clash with this gang: ${numeralWrapper.format(clashVictoryChance, "0.000%")}<br><br>`;
|
newHTML += `Chance to win clash with this gang: ${numeralWrapper.formatPercentage(clashVictoryChance, 3)}<br><br>`;
|
||||||
UIElems.gangTerritoryInfoText.innerHTML += newHTML;
|
UIElems.gangTerritoryInfoText.innerHTML += newHTML;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1641,8 +1649,8 @@ Gang.prototype.updateGangContent = function() {
|
|||||||
removeChildrenFromElement(UIElems.gangInfo);
|
removeChildrenFromElement(UIElems.gangInfo);
|
||||||
UIElems.gangInfo.appendChild(createElement("p", { // Respect
|
UIElems.gangInfo.appendChild(createElement("p", { // Respect
|
||||||
display: "inline-block",
|
display: "inline-block",
|
||||||
innerText: "Respect: " + numeralWrapper.format(this.respect, '0.00000a') +
|
innerText: "Respect: " + numeralWrapper.formatRespect(this.respect) +
|
||||||
" (" + numeralWrapper.format(5*this.respectGainRate, '0.00000a') + " / sec)",
|
" (" + numeralWrapper.formatRespect(5*this.respectGainRate) + " / sec)",
|
||||||
tooltip: "Represents the amount of respect your gang has from other gangs and criminal " +
|
tooltip: "Represents the amount of respect your gang has from other gangs and criminal " +
|
||||||
"organizations. Your respect affects the amount of money " +
|
"organizations. Your respect affects the amount of money " +
|
||||||
"your gang members will earn, and also determines how much " +
|
"your gang members will earn, and also determines how much " +
|
||||||
@@ -1652,8 +1660,8 @@ Gang.prototype.updateGangContent = function() {
|
|||||||
|
|
||||||
UIElems.gangInfo.appendChild(createElement("p", { // Wanted level
|
UIElems.gangInfo.appendChild(createElement("p", { // Wanted level
|
||||||
display: "inline-block",
|
display: "inline-block",
|
||||||
innerText: "Wanted Level: " + numeralWrapper.format(this.wanted, '0.00000a') +
|
innerText: "Wanted Level: " + numeralWrapper.formatWanted(this.wanted) +
|
||||||
" (" + numeralWrapper.format(5*this.wantedGainRate, '0.00000a') + " / sec)",
|
" (" + numeralWrapper.formatWanted(5*this.wantedGainRate) + " / sec)",
|
||||||
tooltip: "Represents how much the gang is wanted by law enforcement. The higher " +
|
tooltip: "Represents how much the gang is wanted by law enforcement. The higher " +
|
||||||
"your gang's wanted level, the harder it will be for your gang members " +
|
"your gang's wanted level, the harder it will be for your gang members " +
|
||||||
"to make money and earn respect. Note that the minimum wanted level is 1."
|
"to make money and earn respect. Note that the minimum wanted level is 1."
|
||||||
@@ -1669,10 +1677,9 @@ Gang.prototype.updateGangContent = function() {
|
|||||||
}));
|
}));
|
||||||
UIElems.gangInfo.appendChild(createElement("br"));
|
UIElems.gangInfo.appendChild(createElement("br"));
|
||||||
|
|
||||||
UIElems.gangInfo.appendChild(createElement("p", { // Money gain rate
|
const d0 = createElement("div");
|
||||||
display: "inline-block",
|
ReactDOM.render(<p style={{'display': 'inline-block'}}>Money gain rate: {MoneyRate(5 * this.moneyGainRate)}</p>, d0);
|
||||||
innerText: `Money gain rate: ${numeralWrapper.format(5 * this.moneyGainRate, "$0.000a")} / sec`,
|
UIElems.gangInfo.appendChild(d0);
|
||||||
}));
|
|
||||||
UIElems.gangInfo.appendChild(createElement("br"));
|
UIElems.gangInfo.appendChild(createElement("br"));
|
||||||
|
|
||||||
// Fix some rounding issues graphically
|
// Fix some rounding issues graphically
|
||||||
@@ -1692,10 +1699,9 @@ Gang.prototype.updateGangContent = function() {
|
|||||||
}));
|
}));
|
||||||
UIElems.gangInfo.appendChild(createElement("br"));
|
UIElems.gangInfo.appendChild(createElement("br"));
|
||||||
|
|
||||||
UIElems.gangInfo.appendChild(createElement("p", { // Faction reputation
|
const d1 = createElement("div");
|
||||||
display:"inline-block",
|
ReactDOM.render(<p style={{'display': 'inline-block'}}>Faction reputation: {Reputation(rep)}</p>, d1);
|
||||||
innerText:"Faction reputation: " + numeralWrapper.format(rep, '0.000a')
|
UIElems.gangInfo.appendChild(d1);
|
||||||
}));
|
|
||||||
UIElems.gangInfo.appendChild(createElement("br"));
|
UIElems.gangInfo.appendChild(createElement("br"));
|
||||||
|
|
||||||
const CyclesPerSecond = 1000 / Engine._idleSpeed;
|
const CyclesPerSecond = 1000 / Engine._idleSpeed;
|
||||||
@@ -1761,12 +1767,12 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
|
|||||||
const statsDiv = createElement("div", {
|
const statsDiv = createElement("div", {
|
||||||
class: "gang-member-info-div",
|
class: "gang-member-info-div",
|
||||||
id: name + "gang-member-stats",
|
id: name + "gang-member-stats",
|
||||||
tooltipsmall: [`Hk: x${numeralWrapper.format(memberObj.hack_mult * memberObj.hack_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.hack_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.hack_asc_mult, "0,0.00")} Asc)`,
|
tooltipsmall: [`Hk: x${numeralWrapper.formatMultiplier(memberObj.hack_mult * memberObj.hack_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.hack_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.hack_asc_mult)} Asc)`,
|
||||||
`St: x${numeralWrapper.format(memberObj.str_mult * memberObj.str_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.str_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.str_asc_mult, "0,0.00")} Asc)`,
|
`St: x${numeralWrapper.formatMultiplier(memberObj.str_mult * memberObj.str_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.str_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.str_asc_mult)} Asc)`,
|
||||||
`Df: x${numeralWrapper.format(memberObj.def_mult * memberObj.def_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.def_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.def_asc_mult, "0,0.00")} Asc)`,
|
`Df: x${numeralWrapper.formatMultiplier(memberObj.def_mult * memberObj.def_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.def_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.def_asc_mult)} Asc)`,
|
||||||
`Dx: x${numeralWrapper.format(memberObj.dex_mult * memberObj.dex_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.dex_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.dex_asc_mult, "0,0.00")} Asc)`,
|
`Dx: x${numeralWrapper.formatMultiplier(memberObj.dex_mult * memberObj.dex_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.dex_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.dex_asc_mult)} Asc)`,
|
||||||
`Ag: x${numeralWrapper.format(memberObj.agi_mult * memberObj.agi_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.agi_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.agi_asc_mult, "0,0.00")} Asc)`,
|
`Ag: x${numeralWrapper.formatMultiplier(memberObj.agi_mult * memberObj.agi_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.agi_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.agi_asc_mult)} Asc)`,
|
||||||
`Ch: x${numeralWrapper.format(memberObj.cha_mult * memberObj.cha_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.cha_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.cha_asc_mult, "0,0.00")} Asc)`].join("<br>"),
|
`Ch: x${numeralWrapper.formatMultiplier(memberObj.cha_mult * memberObj.cha_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.cha_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.cha_asc_mult)} Asc)`].join("<br>"),
|
||||||
});
|
});
|
||||||
UIElems.gangMemberPanels[name]["statsDiv"] = statsDiv;
|
UIElems.gangMemberPanels[name]["statsDiv"] = statsDiv;
|
||||||
const statsP = createElement("pre", {
|
const statsP = createElement("pre", {
|
||||||
@@ -1784,15 +1790,15 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
|
|||||||
innerText: ["Are you sure you want to ascend this member? They will lose all of",
|
innerText: ["Are you sure you want to ascend this member? They will lose all of",
|
||||||
"their non-Augmentation upgrades and their stats will reset back to 1.",
|
"their non-Augmentation upgrades and their stats will reset back to 1.",
|
||||||
"",
|
"",
|
||||||
`Furthermore, your gang will lose ${numeralWrapper.format(memberObj.earnedRespect, "0.000a")} respect`,
|
`Furthermore, your gang will lose ${numeralWrapper.formatRespect(memberObj.earnedRespect)} respect`,
|
||||||
"",
|
"",
|
||||||
"In return, they will gain the following permanent boost to stat multipliers:\n",
|
"In return, they will gain the following permanent boost to stat multipliers:\n",
|
||||||
`Hacking: +${numeralWrapper.format(ascendBenefits.hack, "0.00%")}`,
|
`Hacking: +${numeralWrapper.formatPercentage(ascendBenefits.hack)}`,
|
||||||
`Strength: +${numeralWrapper.format(ascendBenefits.str, "0.00%")}`,
|
`Strength: +${numeralWrapper.formatPercentage(ascendBenefits.str)}`,
|
||||||
`Defense: +${numeralWrapper.format(ascendBenefits.def, "0.00%")}`,
|
`Defense: +${numeralWrapper.formatPercentage(ascendBenefits.def)}`,
|
||||||
`Dexterity: +${numeralWrapper.format(ascendBenefits.dex, "0.00%")}`,
|
`Dexterity: +${numeralWrapper.formatPercentage(ascendBenefits.dex)}`,
|
||||||
`Agility: +${numeralWrapper.format(ascendBenefits.agi, "0.00%")}`,
|
`Agility: +${numeralWrapper.formatPercentage(ascendBenefits.agi)}`,
|
||||||
`Charisma: +${numeralWrapper.format(ascendBenefits.cha, "0.00%")}`].join("\n"),
|
`Charisma: +${numeralWrapper.formatPercentage(ascendBenefits.cha)}`].join("\n"),
|
||||||
});
|
});
|
||||||
const confirmBtn = createElement("button", {
|
const confirmBtn = createElement("button", {
|
||||||
class: "std-button",
|
class: "std-button",
|
||||||
@@ -1874,7 +1880,7 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
|
|||||||
taskSelector.selectedIndex = taskIndex;
|
taskSelector.selectedIndex = taskIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
var gainInfo = createElement("p", {id:name + "gang-member-gain-info"});
|
var gainInfo = createElement("div", {id:name + "gang-member-gain-info"});
|
||||||
taskDiv.appendChild(taskSelector);
|
taskDiv.appendChild(taskSelector);
|
||||||
taskDiv.appendChild(gainInfo);
|
taskDiv.appendChild(gainInfo);
|
||||||
|
|
||||||
@@ -1907,12 +1913,12 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
|
|||||||
var stats = document.getElementById(name + "gang-member-stats-text");
|
var stats = document.getElementById(name + "gang-member-stats-text");
|
||||||
if (stats) {
|
if (stats) {
|
||||||
stats.innerText =
|
stats.innerText =
|
||||||
[`Hacking: ${formatNumber(memberObj.hack, 0)} (${numeralWrapper.format(memberObj.hack_exp, '(0.00a)')} exp)`,
|
[`Hacking: ${formatNumber(memberObj.hack, 0)} (${numeralWrapper.formatExp(memberObj.hack_exp)} exp)`,
|
||||||
`Strength: ${formatNumber(memberObj.str, 0)} (${numeralWrapper.format(memberObj.str_exp, '(0.00a)')} exp)`,
|
`Strength: ${formatNumber(memberObj.str, 0)} (${numeralWrapper.formatExp(memberObj.str_exp)} exp)`,
|
||||||
`Defense: ${formatNumber(memberObj.def, 0)} (${numeralWrapper.format(memberObj.def_exp, '(0.00a)')} exp)`,
|
`Defense: ${formatNumber(memberObj.def, 0)} (${numeralWrapper.formatExp(memberObj.def_exp)} exp)`,
|
||||||
`Dexterity: ${formatNumber(memberObj.dex, 0)} (${numeralWrapper.format(memberObj.dex_exp, '(0.00a)')} exp)`,
|
`Dexterity: ${formatNumber(memberObj.dex, 0)} (${numeralWrapper.formatExp(memberObj.dex_exp)} exp)`,
|
||||||
`Agility: ${formatNumber(memberObj.agi, 0)} (${numeralWrapper.format(memberObj.agi_exp, '(0.00a)')} exp)`,
|
`Agility: ${formatNumber(memberObj.agi, 0)} (${numeralWrapper.formatExp(memberObj.agi_exp)} exp)`,
|
||||||
`Charisma: ${formatNumber(memberObj.cha, 0)} (${numeralWrapper.format(memberObj.cha_exp, '(0.00a)')} exp)`].join("\n");
|
`Charisma: ${formatNumber(memberObj.cha, 0)} (${numeralWrapper.formatExp(memberObj.cha_exp)} exp)`].join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update tooltip for stat multipliers
|
// Update tooltip for stat multipliers
|
||||||
@@ -1921,23 +1927,25 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
|
|||||||
const statsDiv = panel["statsDiv"];
|
const statsDiv = panel["statsDiv"];
|
||||||
if (statsDiv) {
|
if (statsDiv) {
|
||||||
statsDiv.firstChild.innerHTML =
|
statsDiv.firstChild.innerHTML =
|
||||||
[`Hk: x${numeralWrapper.format(memberObj.hack_mult * memberObj.hack_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.hack_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.hack_asc_mult, "0,0.00")} Asc)`,
|
[`Hk: x${numeralWrapper.formatMultiplier(memberObj.hack_mult * memberObj.hack_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.hack_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.hack_asc_mult)} Asc)`,
|
||||||
`St: x${numeralWrapper.format(memberObj.str_mult * memberObj.str_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.str_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.str_asc_mult, "0,0.00")} Asc)`,
|
`St: x${numeralWrapper.formatMultiplier(memberObj.str_mult * memberObj.str_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.str_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.str_asc_mult)} Asc)`,
|
||||||
`Df: x${numeralWrapper.format(memberObj.def_mult * memberObj.def_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.def_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.def_asc_mult, "0,0.00")} Asc)`,
|
`Df: x${numeralWrapper.formatMultiplier(memberObj.def_mult * memberObj.def_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.def_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.def_asc_mult)} Asc)`,
|
||||||
`Dx: x${numeralWrapper.format(memberObj.dex_mult * memberObj.dex_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.dex_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.dex_asc_mult, "0,0.00")} Asc)`,
|
`Dx: x${numeralWrapper.formatMultiplier(memberObj.dex_mult * memberObj.dex_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.dex_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.dex_asc_mult)} Asc)`,
|
||||||
`Ag: x${numeralWrapper.format(memberObj.agi_mult * memberObj.agi_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.agi_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.agi_asc_mult, "0,0.00")} Asc)`,
|
`Ag: x${numeralWrapper.formatMultiplier(memberObj.agi_mult * memberObj.agi_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.agi_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.agi_asc_mult)} Asc)`,
|
||||||
`Ch: x${numeralWrapper.format(memberObj.cha_mult * memberObj.cha_asc_mult, "0,0.00")}(x${numeralWrapper.format(memberObj.cha_mult, "0,0.00")} Eq, x${numeralWrapper.format(memberObj.cha_asc_mult, "0,0.00")} Asc)`].join("<br>");
|
`Ch: x${numeralWrapper.formatMultiplier(memberObj.cha_mult * memberObj.cha_asc_mult)}(x${numeralWrapper.formatMultiplier(memberObj.cha_mult)} Eq, x${numeralWrapper.formatMultiplier(memberObj.cha_asc_mult)} Asc)`].join("<br>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update info about gang member's earnings/gains
|
// Update info about gang member's earnings/gains
|
||||||
var gainInfo = document.getElementById(name + "gang-member-gain-info");
|
var gainInfo = document.getElementById(name + "gang-member-gain-info");
|
||||||
if (gainInfo) {
|
if (gainInfo) {
|
||||||
gainInfo.innerHTML =
|
const data = [
|
||||||
[`Money: ${numeralWrapper.format(5*memberObj.calculateMoneyGain(this), '$0.000a')} / sec`,
|
[`Money:`, MoneyRate(5*memberObj.calculateMoneyGain(this))],
|
||||||
`Respect: ${numeralWrapper.format(5*memberObj.calculateRespectGain(this), '0.00000a')} / sec`,
|
[`Respect:`, `${numeralWrapper.formatRespect(5*memberObj.calculateRespectGain(this))} / sec`],
|
||||||
`Wanted Level: ${numeralWrapper.format(5*memberObj.calculateWantedLevelGain(this), '0.00000a')} / sec`,
|
[`Wanted Level:`, `${numeralWrapper.formatWanted(5*memberObj.calculateWantedLevelGain(this))} / sec`],
|
||||||
`Total Respect Earned: ${numeralWrapper.format(memberObj.earnedRespect, '0.00000a')}`].join("<br>");
|
[`Total Respect:`, `${numeralWrapper.formatRespect(memberObj.earnedRespect)}`],
|
||||||
|
];
|
||||||
|
ReactDOM.render(StatsTable(data), gainInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update selector to have the correct task
|
// Update selector to have the correct task
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers";
|
||||||
import { Player } from "./Player";
|
import { Player } from "./Player";
|
||||||
|
import { IPlayer } from "./PersonObjects/IPlayer";
|
||||||
|
import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence";
|
||||||
import { Server } from "./Server/Server";
|
import { Server } from "./Server/Server";
|
||||||
|
import { HacknetServer } from "./Hacknet/HacknetServer";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the chance the player has to successfully hack a server
|
* Returns the chance the player has to successfully hack a server
|
||||||
*/
|
*/
|
||||||
export function calculateHackingChance(server) {
|
export function calculateHackingChance(server: Server, player: IPlayer): number {
|
||||||
const hackFactor = 1.75;
|
const hackFactor = 1.75;
|
||||||
const intFactor = 0.2;
|
|
||||||
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||||
const skillMult = (hackFactor * Player.hacking_skill) + (intFactor * Player.intelligence);
|
const skillMult = hackFactor * player.hacking_skill;
|
||||||
const skillChance = (skillMult - server.requiredHackingSkill) / skillMult;
|
const skillChance = (skillMult - server.requiredHackingSkill) / skillMult;
|
||||||
const chance = skillChance * difficultyMult * Player.hacking_chance_mult;
|
const chance = skillChance * difficultyMult * player.hacking_chance_mult * calculateIntelligenceBonus(player.intelligence, 1);
|
||||||
if (chance > 1) { return 1; }
|
if (chance > 1) { return 1; }
|
||||||
if (chance < 0) { return 0; }
|
if (chance < 0) { return 0; }
|
||||||
|
|
||||||
@@ -22,14 +24,14 @@ export function calculateHackingChance(server) {
|
|||||||
* Returns the amount of hacking experience the player will gain upon
|
* Returns the amount of hacking experience the player will gain upon
|
||||||
* successfully hacking a server
|
* successfully hacking a server
|
||||||
*/
|
*/
|
||||||
export function calculateHackingExpGain(server) {
|
export function calculateHackingExpGain(server: Server, player: IPlayer): number {
|
||||||
const baseExpGain = 3;
|
const baseExpGain = 3;
|
||||||
const diffFactor = 0.3;
|
const diffFactor = 0.3;
|
||||||
if (server.baseDifficulty == null) {
|
if (server.baseDifficulty == null) {
|
||||||
server.baseDifficulty = server.hackDifficulty;
|
server.baseDifficulty = server.hackDifficulty;
|
||||||
}
|
}
|
||||||
var expGain = baseExpGain;
|
let expGain = baseExpGain;
|
||||||
expGain += (server.baseDifficulty * Player.hacking_exp_mult * diffFactor);
|
expGain += (server.baseDifficulty * player.hacking_exp_mult * diffFactor);
|
||||||
|
|
||||||
return expGain * BitNodeMultipliers.HackExpGain;
|
return expGain * BitNodeMultipliers.HackExpGain;
|
||||||
}
|
}
|
||||||
@@ -38,13 +40,13 @@ export function calculateHackingExpGain(server) {
|
|||||||
* Returns the percentage of money that will be stolen from a server if
|
* Returns the percentage of money that will be stolen from a server if
|
||||||
* it is successfully hacked (returns the decimal form, not the actual percent value)
|
* it is successfully hacked (returns the decimal form, not the actual percent value)
|
||||||
*/
|
*/
|
||||||
export function calculatePercentMoneyHacked(server) {
|
export function calculatePercentMoneyHacked(server: Server, player: IPlayer): number {
|
||||||
// Adjust if needed for balancing. This is the divisor for the final calculation
|
// Adjust if needed for balancing. This is the divisor for the final calculation
|
||||||
const balanceFactor = 240;
|
const balanceFactor = 240;
|
||||||
|
|
||||||
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||||
const skillMult = (Player.hacking_skill - (server.requiredHackingSkill - 1)) / Player.hacking_skill;
|
const skillMult = (player.hacking_skill - (server.requiredHackingSkill - 1)) / player.hacking_skill;
|
||||||
const percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / balanceFactor;
|
const percentMoneyHacked = difficultyMult * skillMult * player.hacking_money_mult / balanceFactor;
|
||||||
if (percentMoneyHacked < 0) { return 0; }
|
if (percentMoneyHacked < 0) { return 0; }
|
||||||
if (percentMoneyHacked > 1) { return 1; }
|
if (percentMoneyHacked > 1) { return 1; }
|
||||||
|
|
||||||
@@ -54,21 +56,18 @@ export function calculatePercentMoneyHacked(server) {
|
|||||||
/**
|
/**
|
||||||
* Returns time it takes to complete a hack on a server, in seconds
|
* Returns time it takes to complete a hack on a server, in seconds
|
||||||
*/
|
*/
|
||||||
export function calculateHackingTime(server, hack, int) {
|
export function calculateHackingTime(server: Server, player: IPlayer): number {
|
||||||
const difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
const difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
||||||
|
|
||||||
const baseDiff = 500;
|
const baseDiff = 500;
|
||||||
const baseSkill = 50;
|
const baseSkill = 50;
|
||||||
const diffFactor = 2.5;
|
const diffFactor = 2.5;
|
||||||
const intFactor = 0.1;
|
let skillFactor = (diffFactor * difficultyMult + baseDiff);
|
||||||
if (hack == null) {hack = Player.hacking_skill;}
|
|
||||||
if (int == null) {int = Player.intelligence;}
|
|
||||||
var skillFactor = (diffFactor * difficultyMult + baseDiff);
|
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
skillFactor /= (hack + baseSkill + (intFactor * int));
|
skillFactor /= (player.hacking_skill + baseSkill);
|
||||||
|
|
||||||
const hackTimeMultiplier = 5;
|
const hackTimeMultiplier = 5;
|
||||||
const hackingTime = hackTimeMultiplier * skillFactor / Player.hacking_speed_mult;
|
const hackingTime = hackTimeMultiplier * skillFactor / (player.hacking_speed_mult * calculateIntelligenceBonus(player.intelligence, 1));
|
||||||
|
|
||||||
return hackingTime;
|
return hackingTime;
|
||||||
}
|
}
|
||||||
@@ -76,17 +75,17 @@ export function calculateHackingTime(server, hack, int) {
|
|||||||
/**
|
/**
|
||||||
* Returns time it takes to complete a grow operation on a server, in seconds
|
* Returns time it takes to complete a grow operation on a server, in seconds
|
||||||
*/
|
*/
|
||||||
export function calculateGrowTime(server, hack, int) {
|
export function calculateGrowTime(server: Server, player: IPlayer): number {
|
||||||
const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2
|
const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2
|
||||||
|
|
||||||
return growTimeMultiplier * calculateHackingTime(server, hack, int);
|
return growTimeMultiplier * calculateHackingTime(server, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns time it takes to complete a weaken operation on a server, in seconds
|
* Returns time it takes to complete a weaken operation on a server, in seconds
|
||||||
*/
|
*/
|
||||||
export function calculateWeakenTime(server, hack, int) {
|
export function calculateWeakenTime(server: Server, player: IPlayer): number {
|
||||||
const weakenTimeMultiplier = 4; // Relative to hacking time
|
const weakenTimeMultiplier = 4; // Relative to hacking time
|
||||||
|
|
||||||
return weakenTimeMultiplier * calculateHackingTime(server, hack, int);
|
return weakenTimeMultiplier * calculateHackingTime(server, player);
|
||||||
}
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* Utility functions for calculating the maximum number of Hacknet upgrades the player
|
|
||||||
* can purchase for a Node with his/her current money
|
|
||||||
*/
|
|
||||||
@@ -8,24 +8,11 @@
|
|||||||
*
|
*
|
||||||
* TODO Should probably split the different types of functions into their own modules
|
* TODO Should probably split the different types of functions into their own modules
|
||||||
*/
|
*/
|
||||||
import {
|
import { HacknetNode } from "./HacknetNode";
|
||||||
HacknetNode,
|
import { calculateNodeCost } from "./formulas/HacknetNodes";
|
||||||
BaseCostForHacknetNode,
|
import { calculateServerCost } from "./formulas/HacknetServers";
|
||||||
HacknetNodePurchaseNextMult,
|
import { HacknetNodeConstants, HacknetServerConstants } from "./data/Constants";
|
||||||
HacknetNodeMaxLevel,
|
import { HacknetServer } from "./HacknetServer";
|
||||||
HacknetNodeMaxRam,
|
|
||||||
HacknetNodeMaxCores
|
|
||||||
} from "./HacknetNode";
|
|
||||||
import {
|
|
||||||
HacknetServer,
|
|
||||||
BaseCostForHacknetServer,
|
|
||||||
HacknetServerPurchaseMult,
|
|
||||||
HacknetServerMaxLevel,
|
|
||||||
HacknetServerMaxRam,
|
|
||||||
HacknetServerMaxCores,
|
|
||||||
HacknetServerMaxCache,
|
|
||||||
MaxNumberHacknetServers
|
|
||||||
} from "./HacknetServer";
|
|
||||||
import { HashManager } from "./HashManager";
|
import { HashManager } from "./HashManager";
|
||||||
import { HashUpgrades } from "./HashUpgrades";
|
import { HashUpgrades } from "./HashUpgrades";
|
||||||
|
|
||||||
@@ -105,24 +92,15 @@ export function purchaseHacknet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function hasMaxNumberHacknetServers() {
|
export function hasMaxNumberHacknetServers() {
|
||||||
return hasHacknetServers() && Player.hacknetNodes.length >= MaxNumberHacknetServers;
|
return hasHacknetServers() && Player.hacknetNodes.length >= HacknetServerConstants.MaxServers;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCostOfNextHacknetNode() {
|
export function getCostOfNextHacknetNode() {
|
||||||
// Cost increases exponentially based on how many you own
|
return calculateNodeCost(Player.hacknetNodes.length+1, Player.hacknet_node_purchase_cost_mult);
|
||||||
const numOwned = Player.hacknetNodes.length;
|
|
||||||
const mult = HacknetNodePurchaseNextMult;
|
|
||||||
|
|
||||||
return BaseCostForHacknetNode * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCostOfNextHacknetServer() {
|
export function getCostOfNextHacknetServer() {
|
||||||
const numOwned = Player.hacknetNodes.length;
|
return calculateServerCost(Player.hacknetNodes.length+1, Player.hacknet_node_purchase_cost_mult);
|
||||||
const mult = HacknetServerPurchaseMult;
|
|
||||||
|
|
||||||
if (numOwned >= MaxNumberHacknetServers) { return Infinity; }
|
|
||||||
|
|
||||||
return BaseCostForHacknetServer * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's level
|
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's level
|
||||||
@@ -270,14 +248,14 @@ export function purchaseLevelUpgrade(node, levels=1) {
|
|||||||
const isServer = (node instanceof HacknetServer);
|
const isServer = (node instanceof HacknetServer);
|
||||||
|
|
||||||
// If we're at max level, return false
|
// If we're at max level, return false
|
||||||
if (node.level >= (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
|
if (node.level >= (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the number of specified upgrades would exceed the max level, calculate
|
// If the number of specified upgrades would exceed the max level, calculate
|
||||||
// the maximum number of upgrades and use that
|
// the maximum number of upgrades and use that
|
||||||
if (node.level + sanitizedLevels > (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
|
if (node.level + sanitizedLevels > (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel)) {
|
||||||
const diff = Math.max(0, (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel) - node.level);
|
const diff = Math.max(0, (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel) - node.level);
|
||||||
return purchaseLevelUpgrade(node, diff);
|
return purchaseLevelUpgrade(node, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,20 +279,20 @@ export function purchaseRamUpgrade(node, levels=1) {
|
|||||||
const isServer = (node instanceof HacknetServer);
|
const isServer = (node instanceof HacknetServer);
|
||||||
|
|
||||||
// Fail if we're already at max
|
// Fail if we're already at max
|
||||||
if (node.ram >= (isServer ? HacknetServerMaxRam : HacknetNodeMaxRam)) {
|
if (node.ram >= (isServer ? HacknetServerConstants.MaxRam : HacknetNodeConstants.MaxRam)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the number of specified upgrades would exceed the max RAM, calculate the
|
// If the number of specified upgrades would exceed the max RAM, calculate the
|
||||||
// max possible number of upgrades and use that
|
// max possible number of upgrades and use that
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
if (node.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerMaxRam) {
|
if (node.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerConstants.MaxRam) {
|
||||||
const diff = Math.max(0, Math.log2(Math.round(HacknetServerMaxRam / node.maxRam)));
|
const diff = Math.max(0, Math.log2(Math.round(HacknetServerConstants.MaxRam / node.maxRam)));
|
||||||
return purchaseRamUpgrade(node, diff);
|
return purchaseRamUpgrade(node, diff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (node.ram * Math.pow(2, sanitizedLevels) > HacknetNodeMaxRam) {
|
if (node.ram * Math.pow(2, sanitizedLevels) > HacknetNodeConstants.MaxRam) {
|
||||||
const diff = Math.max(0, Math.log2(Math.round(HacknetNodeMaxRam / node.ram)));
|
const diff = Math.max(0, Math.log2(Math.round(HacknetNodeConstants.MaxRam / node.ram)));
|
||||||
return purchaseRamUpgrade(node, diff);
|
return purchaseRamUpgrade(node, diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -340,14 +318,14 @@ export function purchaseCoreUpgrade(node, levels=1) {
|
|||||||
const isServer = (node instanceof HacknetServer);
|
const isServer = (node instanceof HacknetServer);
|
||||||
|
|
||||||
// Fail if we're already at max
|
// Fail if we're already at max
|
||||||
if (node.cores >= (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
|
if (node.cores >= (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the specified number of upgrades would exceed the max Cores, calculate
|
// If the specified number of upgrades would exceed the max Cores, calculate
|
||||||
// the max possible number of upgrades and use that
|
// the max possible number of upgrades and use that
|
||||||
if (node.cores + sanitizedLevels > (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
|
if (node.cores + sanitizedLevels > (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores)) {
|
||||||
const diff = Math.max(0, (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores) - node.cores);
|
const diff = Math.max(0, (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores) - node.cores);
|
||||||
return purchaseCoreUpgrade(node, diff);
|
return purchaseCoreUpgrade(node, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,8 +352,8 @@ export function purchaseCacheUpgrade(node, levels=1) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fail if we're already at max
|
// Fail if we're already at max
|
||||||
if (node.cache + sanitizedLevels > HacknetServerMaxCache) {
|
if (node.cache + sanitizedLevels > HacknetServerConstants.MaxCache) {
|
||||||
const diff = Math.max(0, HacknetServerMaxCache - node.cache);
|
const diff = Math.max(0, HacknetServerConstants.MaxCache - node.cache);
|
||||||
return purchaseCacheUpgrade(node, diff);
|
return purchaseCacheUpgrade(node, diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,29 +9,19 @@ import { IHacknetNode } from "./IHacknetNode";
|
|||||||
import { CONSTANTS } from "../Constants";
|
import { CONSTANTS } from "../Constants";
|
||||||
|
|
||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
|
import {
|
||||||
|
calculateMoneyGainRate,
|
||||||
|
calculateLevelUpgradeCost,
|
||||||
|
calculateCoreUpgradeCost,
|
||||||
|
calculateRamUpgradeCost,
|
||||||
|
} from "./formulas/HacknetNodes";
|
||||||
|
import { HacknetNodeConstants } from "./data/Constants";
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
import { Generic_fromJSON,
|
import { Generic_fromJSON,
|
||||||
Generic_toJSON,
|
Generic_toJSON,
|
||||||
Reviver } from "../../utils/JSONReviver";
|
Reviver } from "../../utils/JSONReviver";
|
||||||
|
|
||||||
// Constants for Hacknet Node production
|
|
||||||
export const HacknetNodeMoneyGainPerLevel: number = 1.6; // Base production per level
|
|
||||||
|
|
||||||
// Constants for Hacknet Node purchase/upgrade costs
|
|
||||||
export const BaseCostForHacknetNode: number = 1000;
|
|
||||||
export const BaseCostFor1GBOfRamHacknetNode: number = 30e3;
|
|
||||||
export const BaseCostForHacknetNodeCore: number = 500e3;
|
|
||||||
export const HacknetNodePurchaseNextMult: number = 1.85; // Multiplier when purchasing an additional hacknet node
|
|
||||||
export const HacknetNodeUpgradeLevelMult: number = 1.04; // Multiplier for cost when upgrading level
|
|
||||||
export const HacknetNodeUpgradeRamMult: number = 1.28; // Multiplier for cost when upgrading RAM
|
|
||||||
export const HacknetNodeUpgradeCoreMult: number = 1.48; // Multiplier for cost when buying another core
|
|
||||||
|
|
||||||
// Constants for max upgrade levels for Hacknet Nodes
|
|
||||||
export const HacknetNodeMaxLevel: number = 200;
|
|
||||||
export const HacknetNodeMaxRam: number = 64;
|
|
||||||
export const HacknetNodeMaxCores: number = 16;
|
|
||||||
|
|
||||||
export class HacknetNode implements IHacknetNode {
|
export class HacknetNode implements IHacknetNode {
|
||||||
/**
|
/**
|
||||||
* Initiatizes a HacknetNode object from a JSON save state.
|
* Initiatizes a HacknetNode object from a JSON save state.
|
||||||
@@ -69,79 +59,17 @@ export class HacknetNode implements IHacknetNode {
|
|||||||
|
|
||||||
// Get the cost to upgrade this Node's number of cores
|
// Get the cost to upgrade this Node's number of cores
|
||||||
calculateCoreUpgradeCost(levels: number=1, costMult: number): number {
|
calculateCoreUpgradeCost(levels: number=1, costMult: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateCoreUpgradeCost(this.cores, levels, costMult);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.cores >= HacknetNodeMaxCores) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
const coreBaseCost = BaseCostForHacknetNodeCore;
|
|
||||||
const mult = HacknetNodeUpgradeCoreMult;
|
|
||||||
let totalCost = 0;
|
|
||||||
let currentCores = this.cores;
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
totalCost += (coreBaseCost * Math.pow(mult, currentCores-1));
|
|
||||||
++currentCores;
|
|
||||||
}
|
|
||||||
|
|
||||||
totalCost *= costMult;
|
|
||||||
|
|
||||||
return totalCost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the cost to upgrade this Node's level
|
// Get the cost to upgrade this Node's level
|
||||||
calculateLevelUpgradeCost(levels: number=1, costMult: number): number {
|
calculateLevelUpgradeCost(levels: number=1, costMult: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateLevelUpgradeCost(this.level, levels, costMult);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.level >= HacknetNodeMaxLevel) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mult = HacknetNodeUpgradeLevelMult;
|
|
||||||
let totalMultiplier = 0;
|
|
||||||
let currLevel = this.level;
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
totalMultiplier += Math.pow(mult, currLevel);
|
|
||||||
++currLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BaseCostForHacknetNode / 2 * totalMultiplier * costMult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the cost to upgrade this Node's RAM
|
// Get the cost to upgrade this Node's RAM
|
||||||
calculateRamUpgradeCost(levels: number=1, costMult: number): number {
|
calculateRamUpgradeCost(levels: number=1, costMult: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateRamUpgradeCost(this.ram, levels, costMult);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.ram >= HacknetNodeMaxRam) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
let totalCost = 0;
|
|
||||||
let numUpgrades = Math.round(Math.log2(this.ram));
|
|
||||||
let currentRam = this.ram;
|
|
||||||
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
let baseCost = currentRam * BaseCostFor1GBOfRamHacknetNode;
|
|
||||||
let mult = Math.pow(HacknetNodeUpgradeRamMult, numUpgrades);
|
|
||||||
|
|
||||||
totalCost += (baseCost * mult);
|
|
||||||
|
|
||||||
currentRam *= 2;
|
|
||||||
++numUpgrades;
|
|
||||||
}
|
|
||||||
|
|
||||||
totalCost *= costMult;
|
|
||||||
|
|
||||||
return totalCost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process this Hacknet Node in the game loop.
|
// Process this Hacknet Node in the game loop.
|
||||||
@@ -163,14 +91,14 @@ export class HacknetNode implements IHacknetNode {
|
|||||||
// Upgrade this Node's number of cores, if possible
|
// Upgrade this Node's number of cores, if possible
|
||||||
// Returns a boolean indicating whether new cores were successfully bought
|
// Returns a boolean indicating whether new cores were successfully bought
|
||||||
upgradeCore(levels: number=1, prodMult: number): void {
|
upgradeCore(levels: number=1, prodMult: number): void {
|
||||||
this.cores = Math.min(HacknetNodeMaxCores, Math.round(this.cores + levels));
|
this.cores = Math.min(HacknetNodeConstants.MaxCores, Math.round(this.cores + levels));
|
||||||
this.updateMoneyGainRate(prodMult);
|
this.updateMoneyGainRate(prodMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade this Node's level, if possible
|
// Upgrade this Node's level, if possible
|
||||||
// Returns a boolean indicating whether the level was successfully updated
|
// Returns a boolean indicating whether the level was successfully updated
|
||||||
upgradeLevel(levels: number=1, prodMult: number): void {
|
upgradeLevel(levels: number=1, prodMult: number): void {
|
||||||
this.level = Math.min(HacknetNodeMaxLevel, Math.round(this.level + levels));
|
this.level = Math.min(HacknetNodeConstants.MaxLevel, Math.round(this.level + levels));
|
||||||
this.updateMoneyGainRate(prodMult);
|
this.updateMoneyGainRate(prodMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,14 +114,7 @@ export class HacknetNode implements IHacknetNode {
|
|||||||
|
|
||||||
// Re-calculate this Node's production and update the moneyGainRatePerSecond prop
|
// Re-calculate this Node's production and update the moneyGainRatePerSecond prop
|
||||||
updateMoneyGainRate(prodMult: number): void {
|
updateMoneyGainRate(prodMult: number): void {
|
||||||
//How much extra $/s is gained per level
|
this.moneyGainRatePerSecond = calculateMoneyGainRate(this.level, this.ram, this.cores, prodMult);
|
||||||
var gainPerLevel = HacknetNodeMoneyGainPerLevel;
|
|
||||||
|
|
||||||
this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
|
|
||||||
Math.pow(1.035, this.ram - 1) *
|
|
||||||
((this.cores + 5) / 6) *
|
|
||||||
prodMult *
|
|
||||||
BitNodeMultipliers.HacknetNodeMoney;
|
|
||||||
if (isNaN(this.moneyGainRatePerSecond)) {
|
if (isNaN(this.moneyGainRatePerSecond)) {
|
||||||
this.moneyGainRatePerSecond = 0;
|
this.moneyGainRatePerSecond = 0;
|
||||||
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer", false);
|
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer", false);
|
||||||
|
|||||||
@@ -8,6 +8,14 @@ import { IHacknetNode } from "./IHacknetNode";
|
|||||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||||
import { BaseServer } from "../Server/BaseServer";
|
import { BaseServer } from "../Server/BaseServer";
|
||||||
import { RunningScript } from "../Script/RunningScript";
|
import { RunningScript } from "../Script/RunningScript";
|
||||||
|
import { HacknetServerConstants } from "./data/Constants";
|
||||||
|
import {
|
||||||
|
calculateHashGainRate,
|
||||||
|
calculateLevelUpgradeCost,
|
||||||
|
calculateRamUpgradeCost,
|
||||||
|
calculateCoreUpgradeCost,
|
||||||
|
calculateCacheUpgradeCost,
|
||||||
|
} from "./formulas/HacknetServers";
|
||||||
|
|
||||||
import { createRandomIp } from "../../utils/IPAddress";
|
import { createRandomIp } from "../../utils/IPAddress";
|
||||||
|
|
||||||
@@ -17,29 +25,6 @@ import {
|
|||||||
Reviver
|
Reviver
|
||||||
} from "../../utils/JSONReviver";
|
} from "../../utils/JSONReviver";
|
||||||
|
|
||||||
// Constants for Hacknet Server stats/production
|
|
||||||
export const HacknetServerHashesPerLevel: number = 0.001;
|
|
||||||
|
|
||||||
// Constants for Hacknet Server purchase/upgrade costs
|
|
||||||
export const BaseCostForHacknetServer: number = 50e3;
|
|
||||||
export const BaseCostFor1GBHacknetServerRam: number = 200e3;
|
|
||||||
export const BaseCostForHacknetServerCore: number = 1e6;
|
|
||||||
export const BaseCostForHacknetServerCache: number = 10e6;
|
|
||||||
|
|
||||||
export const HacknetServerPurchaseMult: number = 3.2; // Multiplier for puchasing an additional Hacknet Server
|
|
||||||
export const HacknetServerUpgradeLevelMult: number = 1.1; // Multiplier for cost when upgrading level
|
|
||||||
export const HacknetServerUpgradeRamMult: number = 1.4; // Multiplier for cost when upgrading RAM
|
|
||||||
export const HacknetServerUpgradeCoreMult: number = 1.55; // Multiplier for cost when buying another core
|
|
||||||
export const HacknetServerUpgradeCacheMult: number = 1.85; // Multiplier for cost when upgrading cache
|
|
||||||
|
|
||||||
export const MaxNumberHacknetServers: number = 20; // Max number of Hacknet Servers you can own
|
|
||||||
|
|
||||||
// Constants for max upgrade levels for Hacknet Server
|
|
||||||
export const HacknetServerMaxLevel: number = 300;
|
|
||||||
export const HacknetServerMaxRam: number = 8192;
|
|
||||||
export const HacknetServerMaxCores: number = 128;
|
|
||||||
export const HacknetServerMaxCache: number = 15;
|
|
||||||
|
|
||||||
interface IConstructorParams {
|
interface IConstructorParams {
|
||||||
adminRights?: boolean;
|
adminRights?: boolean;
|
||||||
hostname: string;
|
hostname: string;
|
||||||
@@ -73,7 +58,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
|||||||
// How long this HacknetServer has existed, in seconds
|
// How long this HacknetServer has existed, in seconds
|
||||||
onlineTimeSeconds: number = 0;
|
onlineTimeSeconds: number = 0;
|
||||||
|
|
||||||
// Total number of hashes earned by this
|
// Total number of hashes earned by this server
|
||||||
totalHashesGenerated: number = 0;
|
totalHashesGenerated: number = 0;
|
||||||
|
|
||||||
constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) {
|
constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) {
|
||||||
@@ -84,96 +69,19 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
calculateCacheUpgradeCost(levels: number): number {
|
calculateCacheUpgradeCost(levels: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateCacheUpgradeCost(this.cache, levels);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.cache >= HacknetServerMaxCache) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mult = HacknetServerUpgradeCacheMult;
|
|
||||||
let totalCost = 0;
|
|
||||||
let currentCache = this.cache;
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
totalCost += Math.pow(mult, currentCache - 1);
|
|
||||||
++currentCache;
|
|
||||||
}
|
|
||||||
totalCost *= BaseCostForHacknetServerCache;
|
|
||||||
|
|
||||||
return totalCost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateCoreUpgradeCost(levels: number, costMult: number): number {
|
calculateCoreUpgradeCost(levels: number, costMult: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateCoreUpgradeCost(this.cores, levels, costMult);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.cores >= HacknetServerMaxCores) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mult = HacknetServerUpgradeCoreMult;
|
|
||||||
let totalCost = 0;
|
|
||||||
let currentCores = this.cores;
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
totalCost += Math.pow(mult, currentCores-1);
|
|
||||||
++currentCores;
|
|
||||||
}
|
|
||||||
totalCost *= BaseCostForHacknetServerCore;
|
|
||||||
totalCost *= costMult;
|
|
||||||
|
|
||||||
return totalCost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateLevelUpgradeCost(levels: number, costMult: number): number {
|
calculateLevelUpgradeCost(levels: number, costMult: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateLevelUpgradeCost(this.level, levels, costMult);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.level >= HacknetServerMaxLevel) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mult = HacknetServerUpgradeLevelMult;
|
|
||||||
let totalMultiplier = 0;
|
|
||||||
let currLevel = this.level;
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
totalMultiplier += Math.pow(mult, currLevel);
|
|
||||||
++currLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 10 * BaseCostForHacknetServer * totalMultiplier * costMult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateRamUpgradeCost(levels: number, costMult: number): number {
|
calculateRamUpgradeCost(levels: number, costMult: number): number {
|
||||||
const sanitizedLevels = Math.round(levels);
|
return calculateRamUpgradeCost(this.maxRam, levels, costMult);
|
||||||
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.maxRam >= HacknetServerMaxRam) {
|
|
||||||
return Infinity;
|
|
||||||
}
|
|
||||||
|
|
||||||
let totalCost = 0;
|
|
||||||
let numUpgrades = Math.round(Math.log2(this.maxRam));
|
|
||||||
let currentRam = this.maxRam;
|
|
||||||
for (let i = 0; i < sanitizedLevels; ++i) {
|
|
||||||
let baseCost = currentRam * BaseCostFor1GBHacknetServerRam;
|
|
||||||
let mult = Math.pow(HacknetServerUpgradeRamMult, numUpgrades);
|
|
||||||
|
|
||||||
totalCost += (baseCost * mult);
|
|
||||||
|
|
||||||
currentRam *= 2;
|
|
||||||
++numUpgrades;
|
|
||||||
}
|
|
||||||
totalCost *= costMult;
|
|
||||||
|
|
||||||
return totalCost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process this Hacknet Server in the game loop. Returns the number of hashes generated
|
// Process this Hacknet Server in the game loop. Returns the number of hashes generated
|
||||||
@@ -184,17 +92,17 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
upgradeCache(levels: number): void {
|
upgradeCache(levels: number): void {
|
||||||
this.cache = Math.min(HacknetServerMaxCache, Math.round(this.cache + levels));
|
this.cache = Math.min(HacknetServerConstants.MaxCache, Math.round(this.cache + levels));
|
||||||
this.updateHashCapacity();
|
this.updateHashCapacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeCore(levels: number, prodMult: number): void {
|
upgradeCore(levels: number, prodMult: number): void {
|
||||||
this.cores = Math.min(HacknetServerMaxCores, Math.round(this.cores + levels));
|
this.cores = Math.min(HacknetServerConstants.MaxCores, Math.round(this.cores + levels));
|
||||||
this.updateHashRate(prodMult);
|
this.updateHashRate(prodMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeLevel(levels: number, prodMult: number): void {
|
upgradeLevel(levels: number, prodMult: number): void {
|
||||||
this.level = Math.min(HacknetServerMaxLevel, Math.round(this.level + levels));
|
this.level = Math.min(HacknetServerConstants.MaxLevel, Math.round(this.level + levels));
|
||||||
this.updateHashRate(prodMult);
|
this.updateHashRate(prodMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +110,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
|||||||
for (let i = 0; i < levels; ++i) {
|
for (let i = 0; i < levels; ++i) {
|
||||||
this.maxRam *= 2;
|
this.maxRam *= 2;
|
||||||
}
|
}
|
||||||
this.maxRam = Math.min(HacknetServerMaxRam, Math.round(this.maxRam));
|
this.maxRam = Math.min(HacknetServerConstants.MaxRam, Math.round(this.maxRam));
|
||||||
this.updateHashRate(prodMult);
|
this.updateHashRate(prodMult);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -221,14 +129,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateHashRate(prodMult: number): void {
|
updateHashRate(prodMult: number): void {
|
||||||
const baseGain = HacknetServerHashesPerLevel * this.level;
|
this.hashRate = calculateHashGainRate(this.level, this.ramUsed, this.maxRam, this.cores, prodMult)
|
||||||
const ramMultiplier = Math.pow(1.07, Math.log2(this.maxRam));
|
|
||||||
const coreMultiplier = 1 + (this.cores - 1) / 5;
|
|
||||||
const ramRatio = (1 - this.ramUsed / this.maxRam);
|
|
||||||
|
|
||||||
const hashRate = baseGain * ramMultiplier * coreMultiplier * ramRatio;
|
|
||||||
|
|
||||||
this.hashRate = hashRate * prodMult * BitNodeMultipliers.HacknetNodeMoney;
|
|
||||||
|
|
||||||
if (isNaN(this.hashRate)) {
|
if (isNaN(this.hashRate)) {
|
||||||
this.hashRate = 0;
|
this.hashRate = 0;
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
* those upgrades
|
* those upgrades
|
||||||
*/
|
*/
|
||||||
import { HashUpgrades } from "./HashUpgrades";
|
import { HashUpgrades } from "./HashUpgrades";
|
||||||
|
import { HashUpgrade } from "./HashUpgrade";
|
||||||
|
|
||||||
import { IMap } from "../types";
|
import { IMap } from "../types";
|
||||||
import { Generic_fromJSON,
|
import { Generic_fromJSON,
|
||||||
@@ -67,11 +68,20 @@ export class HashManager {
|
|||||||
return this.getMult(upgName);
|
return this.getMult(upgName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUpgrade(upgName: string): HashUpgrade | null {
|
||||||
|
const upg = HashUpgrades[upgName];
|
||||||
|
if (!upg) {
|
||||||
|
console.error(`Invalid Upgrade Name given to HashManager.getUpgrade(): ${upgName}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return upg;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the cost (in hashes) of an upgrade
|
* Get the cost (in hashes) of an upgrade
|
||||||
*/
|
*/
|
||||||
getUpgradeCost(upgName: string): number {
|
getUpgradeCost(upgName: string): number {
|
||||||
const upg = HashUpgrades[upgName];
|
const upg = this.getUpgrade(upgName);
|
||||||
const currLevel = this.upgrades[upgName];
|
const currLevel = this.upgrades[upgName];
|
||||||
if (upg == null || currLevel == null) {
|
if (upg == null || currLevel == null) {
|
||||||
console.error(`Invalid Upgrade Name given to HashManager.getUpgradeCost(): ${upgName}`);
|
console.error(`Invalid Upgrade Name given to HashManager.getUpgradeCost(): ${upgName}`);
|
||||||
|
|||||||
80
src/Hacknet/data/Constants.ts
Normal file
80
src/Hacknet/data/Constants.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
export const HacknetNodeConstants: {
|
||||||
|
// Constants for Hacknet Node production
|
||||||
|
MoneyGainPerLevel: number;
|
||||||
|
|
||||||
|
// Constants for Hacknet Node purchase/upgrade costs
|
||||||
|
BaseCost: number;
|
||||||
|
LevelBaseCost: number;
|
||||||
|
RamBaseCost: number;
|
||||||
|
CoreBaseCost: number;
|
||||||
|
|
||||||
|
PurchaseNextMult: number;
|
||||||
|
UpgradeLevelMult: number;
|
||||||
|
UpgradeRamMult: number;
|
||||||
|
UpgradeCoreMult: number;
|
||||||
|
|
||||||
|
// Constants for max upgrade levels for Hacknet Nodes
|
||||||
|
MaxLevel: number;
|
||||||
|
MaxRam: number;
|
||||||
|
MaxCores: number;
|
||||||
|
} = {
|
||||||
|
MoneyGainPerLevel: 1.6,
|
||||||
|
|
||||||
|
BaseCost: 1000,
|
||||||
|
LevelBaseCost: 1,
|
||||||
|
RamBaseCost: 30e3,
|
||||||
|
CoreBaseCost: 500e3,
|
||||||
|
|
||||||
|
PurchaseNextMult: 1.85,
|
||||||
|
UpgradeLevelMult: 1.04,
|
||||||
|
UpgradeRamMult: 1.28,
|
||||||
|
UpgradeCoreMult: 1.48,
|
||||||
|
|
||||||
|
MaxLevel: 200,
|
||||||
|
MaxRam: 64,
|
||||||
|
MaxCores: 16,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const HacknetServerConstants: {
|
||||||
|
// Constants for Hacknet Server stats/production
|
||||||
|
HashesPerLevel: number;
|
||||||
|
|
||||||
|
// Constants for Hacknet Server purchase/upgrade costs
|
||||||
|
BaseCost: number;
|
||||||
|
RamBaseCost: number;
|
||||||
|
CoreBaseCost: number;
|
||||||
|
CacheBaseCost: number;
|
||||||
|
|
||||||
|
PurchaseMult: number; // Multiplier for puchasing an additional Hacknet Server
|
||||||
|
UpgradeLevelMult: number; // Multiplier for cost when upgrading level
|
||||||
|
UpgradeRamMult: number; // Multiplier for cost when upgrading RAM
|
||||||
|
UpgradeCoreMult: number; // Multiplier for cost when buying another core
|
||||||
|
UpgradeCacheMult: number; // Multiplier for cost when upgrading cache
|
||||||
|
MaxServers: number; // Max number of Hacknet Servers you can own
|
||||||
|
|
||||||
|
// Constants for max upgrade levels for Hacknet Server
|
||||||
|
MaxLevel: number;
|
||||||
|
MaxRam: number;
|
||||||
|
MaxCores: number;
|
||||||
|
MaxCache: number;
|
||||||
|
} = {
|
||||||
|
HashesPerLevel: 0.001,
|
||||||
|
|
||||||
|
BaseCost: 50e3,
|
||||||
|
RamBaseCost: 200e3,
|
||||||
|
CoreBaseCost: 1e6,
|
||||||
|
CacheBaseCost: 10e6,
|
||||||
|
|
||||||
|
PurchaseMult: 3.20,
|
||||||
|
UpgradeLevelMult: 1.10,
|
||||||
|
UpgradeRamMult: 1.40,
|
||||||
|
UpgradeCoreMult: 1.55,
|
||||||
|
UpgradeCacheMult: 1.85,
|
||||||
|
|
||||||
|
MaxServers: 20,
|
||||||
|
|
||||||
|
MaxLevel: 300,
|
||||||
|
MaxRam: 8192,
|
||||||
|
MaxCores: 128,
|
||||||
|
MaxCache: 15,
|
||||||
|
}
|
||||||
96
src/Hacknet/formulas/HacknetNodes.ts
Normal file
96
src/Hacknet/formulas/HacknetNodes.ts
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||||
|
import { HacknetNodeConstants } from "../data/Constants";
|
||||||
|
|
||||||
|
export function calculateMoneyGainRate(level: number, ram: number, cores: number, mult: number): number {
|
||||||
|
const gainPerLevel = HacknetNodeConstants.MoneyGainPerLevel;
|
||||||
|
|
||||||
|
const levelMult = (level * gainPerLevel);
|
||||||
|
const ramMult = Math.pow(1.035, ram - 1);
|
||||||
|
const coresMult = ((cores + 5) / 6);
|
||||||
|
return levelMult *
|
||||||
|
ramMult *
|
||||||
|
coresMult *
|
||||||
|
mult *
|
||||||
|
BitNodeMultipliers.HacknetNodeMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: number=1, costMult: number=1): number {
|
||||||
|
const sanitizedLevels = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingLevel >= HacknetNodeConstants.MaxLevel) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mult = HacknetNodeConstants.UpgradeLevelMult;
|
||||||
|
let totalMultiplier = 0;
|
||||||
|
let currLevel = startingLevel;
|
||||||
|
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||||
|
totalMultiplier += (HacknetNodeConstants.LevelBaseCost * Math.pow(mult, currLevel));
|
||||||
|
++currLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return HacknetNodeConstants.BaseCost / 2 * totalMultiplier * costMult;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateRamUpgradeCost(startingRam: number, extraLevels: number=1, costMult: number=1): number {
|
||||||
|
const sanitizedLevels = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingRam >= HacknetNodeConstants.MaxRam) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalCost = 0;
|
||||||
|
let numUpgrades = Math.round(Math.log2(startingRam));
|
||||||
|
let currentRam = startingRam;
|
||||||
|
|
||||||
|
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||||
|
const baseCost = currentRam * HacknetNodeConstants.RamBaseCost;
|
||||||
|
const mult = Math.pow(HacknetNodeConstants.UpgradeRamMult, numUpgrades);
|
||||||
|
|
||||||
|
totalCost += (baseCost * mult);
|
||||||
|
|
||||||
|
currentRam *= 2;
|
||||||
|
++numUpgrades;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCost *= costMult;
|
||||||
|
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateCoreUpgradeCost(startingCore: number, extraLevels: number=1, costMult: number=1): number {
|
||||||
|
const sanitizedCores = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedCores) || sanitizedCores < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingCore >= HacknetNodeConstants.MaxCores) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const coreBaseCost = HacknetNodeConstants.CoreBaseCost;
|
||||||
|
const mult = HacknetNodeConstants.UpgradeCoreMult;
|
||||||
|
let totalCost = 0;
|
||||||
|
let currentCores = startingCore;
|
||||||
|
for (let i = 0; i < sanitizedCores; ++i) {
|
||||||
|
totalCost += (coreBaseCost * Math.pow(mult, currentCores-1));
|
||||||
|
++currentCores;
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCost *= costMult;
|
||||||
|
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateNodeCost(n: number, mult: number=1): number {
|
||||||
|
if(n <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return HacknetNodeConstants.BaseCost * Math.pow(HacknetNodeConstants.PurchaseNextMult, n-1) * mult;
|
||||||
|
}
|
||||||
115
src/Hacknet/formulas/HacknetServers.ts
Normal file
115
src/Hacknet/formulas/HacknetServers.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||||
|
import { HacknetServerConstants } from "../data/Constants";
|
||||||
|
|
||||||
|
export function calculateHashGainRate(level: number, ramUsed: number, maxRam: number, cores: number, mult: number): number {
|
||||||
|
const baseGain = HacknetServerConstants.HashesPerLevel * level;
|
||||||
|
const ramMultiplier = Math.pow(1.07, Math.log2(maxRam));
|
||||||
|
const coreMultiplier = 1 + (cores - 1) / 5;
|
||||||
|
const ramRatio = (1 - ramUsed / maxRam);
|
||||||
|
|
||||||
|
return baseGain *
|
||||||
|
ramMultiplier *
|
||||||
|
coreMultiplier *
|
||||||
|
ramRatio *
|
||||||
|
mult *
|
||||||
|
BitNodeMultipliers.HacknetNodeMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateLevelUpgradeCost(startingLevel: number, extraLevels: number=1, costMult: number=1): number {
|
||||||
|
const sanitizedLevels = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingLevel >= HacknetServerConstants.MaxLevel) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mult = HacknetServerConstants.UpgradeLevelMult;
|
||||||
|
let totalMultiplier = 0;
|
||||||
|
let currLevel = startingLevel;
|
||||||
|
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||||
|
totalMultiplier += Math.pow(mult, currLevel);
|
||||||
|
++currLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 10 * HacknetServerConstants.BaseCost * totalMultiplier * costMult;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateRamUpgradeCost(startingRam: number, extraLevels: number=1, costMult: number=1): number {
|
||||||
|
const sanitizedLevels = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingRam >= HacknetServerConstants.MaxRam) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
let totalCost = 0;
|
||||||
|
let numUpgrades = Math.round(Math.log2(startingRam));
|
||||||
|
let currentRam = startingRam;
|
||||||
|
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||||
|
let baseCost = currentRam * HacknetServerConstants.RamBaseCost;
|
||||||
|
let mult = Math.pow(HacknetServerConstants.UpgradeRamMult, numUpgrades);
|
||||||
|
|
||||||
|
totalCost += (baseCost * mult);
|
||||||
|
|
||||||
|
currentRam *= 2;
|
||||||
|
++numUpgrades;
|
||||||
|
}
|
||||||
|
totalCost *= costMult;
|
||||||
|
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateCoreUpgradeCost(startingCores: number, extraLevels: number=1, costMult: number=1): number {
|
||||||
|
const sanitizedLevels = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingCores >= HacknetServerConstants.MaxCores) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mult = HacknetServerConstants.UpgradeCoreMult;
|
||||||
|
let totalCost = 0;
|
||||||
|
let currentCores = startingCores;
|
||||||
|
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||||
|
totalCost += Math.pow(mult, currentCores-1);
|
||||||
|
++currentCores;
|
||||||
|
}
|
||||||
|
totalCost *= HacknetServerConstants.CoreBaseCost;
|
||||||
|
totalCost *= costMult;
|
||||||
|
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateCacheUpgradeCost(startingCache: number, extraLevels: number=1): number {
|
||||||
|
const sanitizedLevels = Math.round(extraLevels);
|
||||||
|
if (isNaN(sanitizedLevels) || sanitizedLevels < 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (startingCache >= HacknetServerConstants.MaxCache) {
|
||||||
|
return Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mult = HacknetServerConstants.UpgradeCacheMult;
|
||||||
|
let totalCost = 0;
|
||||||
|
let currentCache = startingCache;
|
||||||
|
for (let i = 0; i < sanitizedLevels; ++i) {
|
||||||
|
totalCost += Math.pow(mult, currentCache - 1);
|
||||||
|
++currentCache;
|
||||||
|
}
|
||||||
|
totalCost *= HacknetServerConstants.CacheBaseCost;
|
||||||
|
|
||||||
|
return totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateServerCost(n: number, mult: number=1): number {
|
||||||
|
if (n-1 >= HacknetServerConstants.MaxServers) { return Infinity; }
|
||||||
|
|
||||||
|
return HacknetServerConstants.BaseCost * Math.pow(HacknetServerConstants.PurchaseMult, n-1) * mult;
|
||||||
|
}
|
||||||
@@ -42,11 +42,9 @@ export class GeneralInfo extends React.Component {
|
|||||||
hackers all around the world to anonymously share computing power and
|
hackers all around the world to anonymously share computing power and
|
||||||
perform distributed cyberattacks without the fear of being traced.
|
perform distributed cyberattacks without the fear of being traced.
|
||||||
</p>
|
</p>
|
||||||
<br />
|
|
||||||
<p className={"hacknet-general-info"}>
|
<p className={"hacknet-general-info"}>
|
||||||
{this.getSecondParagraph()}
|
{this.getSecondParagraph()}
|
||||||
</p>
|
</p>
|
||||||
<br />
|
|
||||||
<p className={"hacknet-general-info"}>
|
<p className={"hacknet-general-info"}>
|
||||||
{this.getThirdParagraph()}
|
{this.getThirdParagraph()}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -4,11 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import {
|
import { HacknetNodeConstants } from "../data/Constants";
|
||||||
HacknetNodeMaxLevel,
|
|
||||||
HacknetNodeMaxRam,
|
|
||||||
HacknetNodeMaxCores
|
|
||||||
} from "../HacknetNode";
|
|
||||||
import {
|
import {
|
||||||
getMaxNumberLevelUpgrades,
|
getMaxNumberLevelUpgrades,
|
||||||
getMaxNumberRamUpgrades,
|
getMaxNumberRamUpgrades,
|
||||||
@@ -21,6 +17,8 @@ import {
|
|||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||||
|
|
||||||
export class HacknetNode extends React.Component {
|
export class HacknetNode extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
@@ -29,21 +27,21 @@ export class HacknetNode extends React.Component {
|
|||||||
const recalculate = this.props.recalculate;
|
const recalculate = this.props.recalculate;
|
||||||
|
|
||||||
// Upgrade Level Button
|
// Upgrade Level Button
|
||||||
let upgradeLevelText, upgradeLevelClass;
|
let upgradeLevelContent, upgradeLevelClass;
|
||||||
if (node.level >= HacknetNodeMaxLevel) {
|
if (node.level >= HacknetNodeConstants.MaxLevel) {
|
||||||
upgradeLevelText = "MAX LEVEL";
|
upgradeLevelContent = <>MAX LEVEL</>;
|
||||||
upgradeLevelClass = "std-button-disabled";
|
upgradeLevelClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel);
|
multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeConstants.MaxLevel);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetNodeMaxLevel - node.level;
|
const levelsToMax = HacknetNodeConstants.MaxLevel - node.level;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.hacknet_node_level_cost_mult);
|
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.hacknet_node_level_cost_mult);
|
||||||
upgradeLevelText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeLevelCost)}`;
|
upgradeLevelContent = <>Upgrade x{multiplier} - {Money(upgradeLevelCost)}</>;
|
||||||
if (Player.money.lt(upgradeLevelCost)) {
|
if (Player.money.lt(upgradeLevelCost)) {
|
||||||
upgradeLevelClass = "std-button-disabled";
|
upgradeLevelClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -53,28 +51,28 @@ export class HacknetNode extends React.Component {
|
|||||||
const upgradeLevelOnClick = () => {
|
const upgradeLevelOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel);
|
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeConstants.MaxLevel);
|
||||||
}
|
}
|
||||||
purchaseLevelUpgrade(node, numUpgrades);
|
purchaseLevelUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let upgradeRamText, upgradeRamClass;
|
let upgradeRamContent, upgradeRamClass;
|
||||||
if (node.ram >= HacknetNodeMaxRam) {
|
if (node.ram >= HacknetNodeConstants.MaxRam) {
|
||||||
upgradeRamText = "MAX RAM";
|
upgradeRamContent = <>MAX RAM</>;
|
||||||
upgradeRamClass = "std-button-disabled";
|
upgradeRamClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam);
|
multiplier = getMaxNumberRamUpgrades(node, HacknetNodeConstants.MaxRam);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = Math.round(Math.log2(HacknetNodeMaxRam / node.ram));
|
const levelsToMax = Math.round(Math.log2(HacknetNodeConstants.MaxRam / node.ram));
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player.hacknet_node_ram_cost_mult);
|
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player.hacknet_node_ram_cost_mult);
|
||||||
upgradeRamText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeRamCost)}`;
|
upgradeRamContent = <>Upgrade x{multiplier} - {Money(upgradeRamCost)}</>;
|
||||||
if (Player.money.lt(upgradeRamCost)) {
|
if (Player.money.lt(upgradeRamCost)) {
|
||||||
upgradeRamClass = "std-button-disabled";
|
upgradeRamClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -84,28 +82,28 @@ export class HacknetNode extends React.Component {
|
|||||||
const upgradeRamOnClick = () => {
|
const upgradeRamOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam);
|
numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeConstants.MaxRam);
|
||||||
}
|
}
|
||||||
purchaseRamUpgrade(node, numUpgrades);
|
purchaseRamUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let upgradeCoresText, upgradeCoresClass;
|
let upgradeCoresContent, upgradeCoresClass;
|
||||||
if (node.cores >= HacknetNodeMaxCores) {
|
if (node.cores >= HacknetNodeConstants.MaxCores) {
|
||||||
upgradeCoresText = "MAX CORES";
|
upgradeCoresContent = <>MAX CORES</>;
|
||||||
upgradeCoresClass = "std-button-disabled";
|
upgradeCoresClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores);
|
multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeConstants.MaxCores);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetNodeMaxCores - node.cores;
|
const levelsToMax = HacknetNodeConstants.MaxCores - node.cores;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player.hacknet_node_core_cost_mult);
|
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player.hacknet_node_core_cost_mult);
|
||||||
upgradeCoresText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCoreCost)}`;
|
upgradeCoresContent = <>Upgrade x{multiplier} - {Money(upgradeCoreCost)}</>;
|
||||||
if (Player.money.lt(upgradeCoreCost)) {
|
if (Player.money.lt(upgradeCoreCost)) {
|
||||||
upgradeCoresClass = "std-button-disabled";
|
upgradeCoresClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -115,7 +113,7 @@ export class HacknetNode extends React.Component {
|
|||||||
const upgradeCoresOnClick = () => {
|
const upgradeCoresOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores);
|
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeConstants.MaxCores);
|
||||||
}
|
}
|
||||||
purchaseCoreUpgrade(node, numUpgrades);
|
purchaseCoreUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
@@ -132,25 +130,28 @@ export class HacknetNode extends React.Component {
|
|||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Production:</p>
|
<p>Production:</p>
|
||||||
<span className={"text money-gold"}>
|
<span className={"text money-gold"}>
|
||||||
{numeralWrapper.formatMoney(node.totalMoneyGenerated)} ({numeralWrapper.formatMoney(node.moneyGainRatePerSecond)} / sec)
|
{Money(node.totalMoneyGenerated)} ({MoneyRate(node.moneyGainRatePerSecond)})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
<p>Level:</p>
|
||||||
|
<span className={"text upgradable-info"}>{node.level}</span>
|
||||||
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
||||||
{upgradeLevelText}
|
{upgradeLevelContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>RAM:</p><span className={"text upgradable-info"}>{node.ram}GB</span>
|
<p>RAM:</p>
|
||||||
|
<span className={"text upgradable-info"}>{node.ram}GB</span>
|
||||||
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
||||||
{upgradeRamText}
|
{upgradeRamContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
<p>Cores:</p>
|
||||||
|
<span className={"text upgradable-info"}>{node.cores}</span>
|
||||||
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
||||||
{upgradeCoresText}
|
{upgradeCoresContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,12 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
import {
|
import { HacknetServerConstants } from "../data/Constants";
|
||||||
HacknetServerMaxLevel,
|
|
||||||
HacknetServerMaxRam,
|
|
||||||
HacknetServerMaxCores,
|
|
||||||
HacknetServerMaxCache
|
|
||||||
} from "../HacknetServer";
|
|
||||||
import {
|
import {
|
||||||
getMaxNumberLevelUpgrades,
|
getMaxNumberLevelUpgrades,
|
||||||
getMaxNumberRamUpgrades,
|
getMaxNumberRamUpgrades,
|
||||||
@@ -25,6 +20,9 @@ import {
|
|||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { Hashes } from "../../ui/React/Hashes";
|
||||||
|
import { HashRate } from "../../ui/React/HashRate";
|
||||||
|
|
||||||
export class HacknetServer extends React.Component {
|
export class HacknetServer extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
@@ -33,21 +31,21 @@ export class HacknetServer extends React.Component {
|
|||||||
const recalculate = this.props.recalculate;
|
const recalculate = this.props.recalculate;
|
||||||
|
|
||||||
// Upgrade Level Button
|
// Upgrade Level Button
|
||||||
let upgradeLevelText, upgradeLevelClass;
|
let upgradeLevelContent, upgradeLevelClass;
|
||||||
if (node.level >= HacknetServerMaxLevel) {
|
if (node.level >= HacknetServerConstants.MaxLevel) {
|
||||||
upgradeLevelText = "MAX LEVEL";
|
upgradeLevelContent = <>MAX LEVEL</>;
|
||||||
upgradeLevelClass = "std-button-disabled";
|
upgradeLevelClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel);
|
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetServerMaxLevel - node.level;
|
const levelsToMax = HacknetServerConstants.MaxLevel - node.level;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.hacknet_node_level_cost_mult);
|
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, Player.hacknet_node_level_cost_mult);
|
||||||
upgradeLevelText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeLevelCost)}`;
|
upgradeLevelContent = <>Upgrade x{multiplier} - {Money(upgradeLevelCost)}</>;
|
||||||
if (Player.money.lt(upgradeLevelCost)) {
|
if (Player.money.lt(upgradeLevelCost)) {
|
||||||
upgradeLevelClass = "std-button-disabled";
|
upgradeLevelClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -57,7 +55,7 @@ export class HacknetServer extends React.Component {
|
|||||||
const upgradeLevelOnClick = () => {
|
const upgradeLevelOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel);
|
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||||
}
|
}
|
||||||
purchaseLevelUpgrade(node, numUpgrades);
|
purchaseLevelUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
@@ -65,21 +63,21 @@ export class HacknetServer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade RAM Button
|
// Upgrade RAM Button
|
||||||
let upgradeRamText, upgradeRamClass;
|
let upgradeRamContent, upgradeRamClass;
|
||||||
if (node.maxRam >= HacknetServerMaxRam) {
|
if (node.maxRam >= HacknetServerConstants.MaxRam) {
|
||||||
upgradeRamText = "MAX RAM";
|
upgradeRamContent = <>MAX RAM</>;
|
||||||
upgradeRamClass = "std-button-disabled";
|
upgradeRamClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberRamUpgrades(node, HacknetServerMaxRam);
|
multiplier = getMaxNumberRamUpgrades(node, HacknetServerConstants.MaxRam);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = Math.round(Math.log2(HacknetServerMaxRam / node.maxRam));
|
const levelsToMax = Math.round(Math.log2(HacknetServerConstants.MaxRam / node.maxRam));
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player.hacknet_node_ram_cost_mult);
|
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, Player.hacknet_node_ram_cost_mult);
|
||||||
upgradeRamText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeRamCost)}`;
|
upgradeRamContent = <>Upgrade x{multiplier} - {Money(upgradeRamCost)}</>;
|
||||||
if (Player.money.lt(upgradeRamCost)) {
|
if (Player.money.lt(upgradeRamCost)) {
|
||||||
upgradeRamClass = "std-button-disabled";
|
upgradeRamClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -89,7 +87,7 @@ export class HacknetServer extends React.Component {
|
|||||||
const upgradeRamOnClick = () => {
|
const upgradeRamOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerMaxRam);
|
numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerConstants.MaxRam);
|
||||||
}
|
}
|
||||||
purchaseRamUpgrade(node, numUpgrades);
|
purchaseRamUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
@@ -97,21 +95,21 @@ export class HacknetServer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade Cores Button
|
// Upgrade Cores Button
|
||||||
let upgradeCoresText, upgradeCoresClass;
|
let upgradeCoresContent, upgradeCoresClass;
|
||||||
if (node.cores >= HacknetServerMaxCores) {
|
if (node.cores >= HacknetServerConstants.MaxCores) {
|
||||||
upgradeCoresText = "MAX CORES";
|
upgradeCoresContent = <>MAX CORES</>;
|
||||||
upgradeCoresClass = "std-button-disabled";
|
upgradeCoresClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores);
|
multiplier = getMaxNumberCoreUpgrades(node, HacknetServerConstants.MaxCores);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetServerMaxCores - node.cores;
|
const levelsToMax = HacknetServerConstants.MaxCores - node.cores;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player.hacknet_node_core_cost_mult);
|
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, Player.hacknet_node_core_cost_mult);
|
||||||
upgradeCoresText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCoreCost)}`;
|
upgradeCoresContent = <>Upgrade x{multiplier} - {Money(upgradeCoreCost)}</>;
|
||||||
if (Player.money.lt(upgradeCoreCost)) {
|
if (Player.money.lt(upgradeCoreCost)) {
|
||||||
upgradeCoresClass = "std-button-disabled";
|
upgradeCoresClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -121,7 +119,7 @@ export class HacknetServer extends React.Component {
|
|||||||
const upgradeCoresOnClick = () => {
|
const upgradeCoresOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores);
|
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerConstants.MaxCores);
|
||||||
}
|
}
|
||||||
purchaseCoreUpgrade(node, numUpgrades);
|
purchaseCoreUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
@@ -129,21 +127,21 @@ export class HacknetServer extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Upgrade Cache button
|
// Upgrade Cache button
|
||||||
let upgradeCacheText, upgradeCacheClass;
|
let upgradeCacheContent, upgradeCacheClass;
|
||||||
if (node.cache >= HacknetServerMaxCache) {
|
if (node.cache >= HacknetServerConstants.MaxCache) {
|
||||||
upgradeCacheText = "MAX CACHE";
|
upgradeCacheContent = <>MAX CACHE</>;
|
||||||
upgradeCacheClass = "std-button-disabled";
|
upgradeCacheClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
let multiplier = 0;
|
let multiplier = 0;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
multiplier = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache);
|
multiplier = getMaxNumberCacheUpgrades(node, HacknetServerConstants.MaxCache);
|
||||||
} else {
|
} else {
|
||||||
const levelsToMax = HacknetServerMaxCache - node.cache;
|
const levelsToMax = HacknetServerConstants.MaxCache - node.cache;
|
||||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||||
}
|
}
|
||||||
|
|
||||||
const upgradeCacheCost = node.calculateCacheUpgradeCost(multiplier);
|
const upgradeCacheCost = node.calculateCacheUpgradeCost(multiplier);
|
||||||
upgradeCacheText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCacheCost)}`;
|
upgradeCacheContent = <>Upgrade x{multiplier} - {Money(upgradeCacheCost)}</>;
|
||||||
if (Player.money.lt(upgradeCacheCost)) {
|
if (Player.money.lt(upgradeCacheCost)) {
|
||||||
upgradeCacheClass = "std-button-disabled";
|
upgradeCacheClass = "std-button-disabled";
|
||||||
} else {
|
} else {
|
||||||
@@ -153,7 +151,7 @@ export class HacknetServer extends React.Component {
|
|||||||
const upgradeCacheOnClick = () => {
|
const upgradeCacheOnClick = () => {
|
||||||
let numUpgrades = purchaseMult;
|
let numUpgrades = purchaseMult;
|
||||||
if (purchaseMult === "MAX") {
|
if (purchaseMult === "MAX") {
|
||||||
numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache);
|
numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerConstants.MaxCache);
|
||||||
}
|
}
|
||||||
purchaseCacheUpgrade(node, numUpgrades);
|
purchaseCacheUpgrade(node, numUpgrades);
|
||||||
recalculate();
|
recalculate();
|
||||||
@@ -171,7 +169,7 @@ export class HacknetServer extends React.Component {
|
|||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Production:</p>
|
<p>Production:</p>
|
||||||
<span className={"text money-gold"}>
|
<span className={"text money-gold"}>
|
||||||
{numeralWrapper.formatBigNumber(node.totalHashesGenerated)} ({numeralWrapper.formatBigNumber(node.hashRate)} / sec)
|
{Hashes(node.totalHashesGenerated)} ({HashRate(node.hashRate)})
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
@@ -181,25 +179,25 @@ export class HacknetServer extends React.Component {
|
|||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
||||||
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
||||||
{upgradeLevelText}
|
{upgradeLevelContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>RAM:</p><span className={"text upgradable-info"}>{node.maxRam}GB</span>
|
<p>RAM:</p><span className={"text upgradable-info"}>{node.maxRam}GB</span>
|
||||||
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
||||||
{upgradeRamText}
|
{upgradeRamContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
||||||
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
||||||
{upgradeCoresText}
|
{upgradeCoresContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Cache Level:</p><span className={"text upgradable-info"}>{node.cache}</span>
|
<p>Cache Level:</p><span className={"text upgradable-info"}>{node.cache}</span>
|
||||||
<button className={upgradeCacheClass} onClick={upgradeCacheOnClick}>
|
<button className={upgradeCacheClass} onClick={upgradeCacheOnClick}>
|
||||||
{upgradeCacheText}
|
{upgradeCacheContent}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ import { ServerDropdown,
|
|||||||
ServerType } from "../../ui/React/ServerDropdown"
|
ServerType } from "../../ui/React/ServerDropdown"
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
import { CopyableText } from "../../ui/React/CopyableText";
|
||||||
|
import { Hashes } from "../../ui/React/Hashes";
|
||||||
|
|
||||||
class HashUpgrade extends React.Component {
|
class HashUpgrade extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -63,8 +65,8 @@ class HashUpgrade extends React.Component {
|
|||||||
// We'll reuse a Bladeburner css class
|
// We'll reuse a Bladeburner css class
|
||||||
return (
|
return (
|
||||||
<div className={"bladeburner-action"}>
|
<div className={"bladeburner-action"}>
|
||||||
<h2>{upg.name}</h2>
|
<CopyableText value={upg.name} />
|
||||||
<p>Cost: {numeralWrapper.format(cost, "0.000a")}</p>
|
<p>Cost: {Hashes(cost)}</p>
|
||||||
<p>{upg.desc}</p>
|
<p>{upg.desc}</p>
|
||||||
<button className={btnClass} onClick={this.purchase}>
|
<button className={btnClass} onClick={this.purchase}>
|
||||||
Purchase
|
Purchase
|
||||||
@@ -122,7 +124,7 @@ export class HashUpgradePopup extends React.Component {
|
|||||||
<div>
|
<div>
|
||||||
<PopupCloseButton popup={this.props.popupId} text={"Close"} />
|
<PopupCloseButton popup={this.props.popupId} text={"Close"} />
|
||||||
<p>Spend your hashes on a variety of different upgrades</p>
|
<p>Spend your hashes on a variety of different upgrades</p>
|
||||||
<p>Hashes: {numeralWrapper.formatBigNumber(this.state.totalHashes)}</p>
|
<p>Hashes: {numeralWrapper.formatHashes(this.state.totalHashes)}</p>
|
||||||
{upgradeElems}
|
{upgradeElems}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,43 +9,33 @@ import React from "react";
|
|||||||
import { hasHacknetServers } from "../HacknetHelpers";
|
import { hasHacknetServers } from "../HacknetHelpers";
|
||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||||
|
import { HashRate } from "../../ui/React/HashRate";
|
||||||
|
import { Hashes } from "../../ui/React/Hashes";
|
||||||
|
|
||||||
export function PlayerInfo(props) {
|
export function PlayerInfo(props) {
|
||||||
const hasServers = hasHacknetServers();
|
const hasServers = hasHacknetServers();
|
||||||
|
|
||||||
let prod;
|
let prod;
|
||||||
if (hasServers) {
|
if (hasServers) {
|
||||||
prod = numeralWrapper.format(props.totalProduction, "0.000a") + " hashes / sec";
|
prod = HashRate(props.totalProduction);
|
||||||
} else {
|
} else {
|
||||||
prod = numeralWrapper.formatMoney(props.totalProduction) + " / sec";
|
prod = MoneyRate(props.totalProduction);
|
||||||
}
|
|
||||||
|
|
||||||
let hashInfo;
|
|
||||||
if (hasServers) {
|
|
||||||
hashInfo = numeralWrapper.format(Player.hashManager.hashes, "0.000a") + " / " +
|
|
||||||
numeralWrapper.format(Player.hashManager.capacity, "0.000a");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<p id={"hacknet-nodes-money"}>
|
<p id={"hacknet-nodes-money"}>
|
||||||
<span>Money:</span>
|
<span>Money: </span>
|
||||||
<span className={"money-gold"}>{numeralWrapper.formatMoney(Player.money.toNumber())}</span><br />
|
{Money(Player.money.toNumber())}<br />
|
||||||
|
|
||||||
{
|
{
|
||||||
hasServers &&
|
hasServers &&
|
||||||
<span>Hashes:</span>
|
<><span>Hashes: {Hashes(Player.hashManager.hashes)} / {Hashes(Player.hashManager.capacity)}</span><br /></>
|
||||||
}
|
|
||||||
{
|
|
||||||
hasServers &&
|
|
||||||
<span className={"money-gold"}>{hashInfo}</span>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
hasServers &&
|
|
||||||
<br />
|
|
||||||
}
|
}
|
||||||
|
|
||||||
<span>Total Hacknet Node Production:</span>
|
<span>Total Hacknet Node Production: </span>
|
||||||
<span className={"money-gold"}>{prod}</span>
|
{prod}
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { hasHacknetServers,
|
|||||||
hasMaxNumberHacknetServers } from "../HacknetHelpers";
|
hasMaxNumberHacknetServers } from "../HacknetHelpers";
|
||||||
import { Player } from "../../Player";
|
import { Player } from "../../Player";
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
|
||||||
export function PurchaseButton(props) {
|
export function PurchaseButton(props) {
|
||||||
if (props.multiplier == null || props.onClick == null) {
|
if (props.multiplier == null || props.onClick == null) {
|
||||||
@@ -20,13 +21,13 @@ export function PurchaseButton(props) {
|
|||||||
if (hasHacknetServers()) {
|
if (hasHacknetServers()) {
|
||||||
if (hasMaxNumberHacknetServers()) {
|
if (hasMaxNumberHacknetServers()) {
|
||||||
className = "std-button-disabled";
|
className = "std-button-disabled";
|
||||||
text = "Hacknet Server limit reached";
|
text = <>Hacknet Server limit reached</>;
|
||||||
style = {color: "red"};
|
style = {color: "red"};
|
||||||
} else {
|
} else {
|
||||||
text = `Purchase Hacknet Server - ${numeralWrapper.formatMoney(cost)}`;
|
text = <>Purchase Hacknet Server - {Money(cost)}</>;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
text = `Purchase Hacknet Node - ${numeralWrapper.formatMoney(cost)}`;
|
text = <>Purchase Hacknet Node - {Money(cost)}</>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
26
src/Hospital/Hospital.ts
Normal file
26
src/Hospital/Hospital.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { CONSTANTS } from "../Constants";
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer"
|
||||||
|
|
||||||
|
export function getHospitalizationCost(p: IPlayer): number {
|
||||||
|
let money;
|
||||||
|
if (typeof p.money === 'number') {
|
||||||
|
money = p.money;
|
||||||
|
} else {
|
||||||
|
money = p.money.toNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (money < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.min(money*0.1, (p.max_hp - p.hp) * CONSTANTS.HospitalCostPerHp);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function calculateHospitalizationCost(p: IPlayer, damage: number): number {
|
||||||
|
const oldhp = p.hp;
|
||||||
|
p.hp -= damage
|
||||||
|
if (p.hp < 0) p.hp = 0;
|
||||||
|
const cost = getHospitalizationCost(p);
|
||||||
|
p.hp = oldhp;
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import { Player } from "./Player";
|
|||||||
import { Settings } from "./Settings/Settings";
|
import { Settings } from "./Settings/Settings";
|
||||||
|
|
||||||
import { initializeMainMenuLinks } from "./ui/MainMenu/Links";
|
import { initializeMainMenuLinks } from "./ui/MainMenu/Links";
|
||||||
|
import { LiteratureNames } from "./Literature/data/LiteratureNames";
|
||||||
|
|
||||||
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
import { exceptionAlert } from "../utils/helpers/exceptionAlert";
|
||||||
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
|
import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
|
||||||
@@ -499,7 +500,7 @@ function iTutorialEnd() {
|
|||||||
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html' target='_blank'>Getting Started Guide</a>" +
|
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html' target='_blank'>Getting Started Guide</a>" +
|
||||||
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/' target='_blank'>Documentation</a><br><br>" +
|
"<a class='a-link-button' href='https://bitburner.readthedocs.io/en/latest/' target='_blank'>Documentation</a><br><br>" +
|
||||||
"The Beginner's Guide to Hacking was added to your home computer! It contains some tips/pointers for starting out with the game. " +
|
"The Beginner's Guide to Hacking was added to your home computer! It contains some tips/pointers for starting out with the game. " +
|
||||||
"To read it, go to Terminal and enter<br><br>cat hackers-starting-handbook.lit"
|
"To read it, go to Terminal and enter<br><br>cat " + LiteratureNames.HackersStartingHandbook
|
||||||
});
|
});
|
||||||
var gotitBtn = createElement("a", {
|
var gotitBtn = createElement("a", {
|
||||||
class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
|
class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
|
||||||
@@ -509,7 +510,7 @@ function iTutorialEnd() {
|
|||||||
});
|
});
|
||||||
createPopup(popupId, [txt, gotitBtn]);
|
createPopup(popupId, [txt, gotitBtn]);
|
||||||
|
|
||||||
Player.getHomeComputer().messages.push("hackers-starting-handbook.lit");
|
Player.getHomeComputer().messages.push(LiteratureNames.HackersStartingHandbook);
|
||||||
}
|
}
|
||||||
|
|
||||||
function iTutorialSetText(txt) {
|
function iTutorialSetText(txt) {
|
||||||
|
|||||||
15
src/Literature/Literature.ts
Normal file
15
src/Literature/Literature.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/**
|
||||||
|
* Lore / world building literature files that can be found on servers.
|
||||||
|
* These files can be read by the player
|
||||||
|
*/
|
||||||
|
export class Literature {
|
||||||
|
title: string;
|
||||||
|
fn: string;
|
||||||
|
txt: string;
|
||||||
|
|
||||||
|
constructor(title: string, filename: string, txt: string) {
|
||||||
|
this.title = title;
|
||||||
|
this.fn = filename;
|
||||||
|
this.txt = txt;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
src/Literature/LiteratureHelpers.ts
Normal file
9
src/Literature/LiteratureHelpers.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import { Literatures } from "./Literatures";
|
||||||
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
|
|
||||||
|
export function showLiterature(fn: string): void {
|
||||||
|
const litObj = Literatures[fn];
|
||||||
|
if (litObj == null) { return; }
|
||||||
|
const txt = `<i>${litObj.title}</i><br><br>${litObj.txt}`;
|
||||||
|
dialogBoxCreate(txt);
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user