mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-17 14:59:16 +02:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e5ebcfe6f | ||
|
|
80b703639e | ||
|
|
0afdba8f38 | ||
|
|
925e96345d | ||
|
|
db2bf79e3b | ||
|
|
6f330efc44 | ||
|
|
708c73fa0f | ||
|
|
c7febd5551 | ||
|
|
ddbdf66d00 | ||
|
|
e572c6dad8 | ||
|
|
ff097db1e2 | ||
|
|
ad12f0e551 | ||
|
|
93f8785ec6 | ||
|
|
8e79658e67 | ||
|
|
9840e1f4eb | ||
|
|
d170693da4 | ||
|
|
8f30e60d08 | ||
|
|
101834fcaf | ||
|
|
63da8d709a |
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([380,0]),o()}({323:function(n,t,o){},325:function(n,t,o){},327:function(n,t,o){},329:function(n,t,o){},331:function(n,t,o){},333:function(n,t,o){},335:function(n,t,o){},337:function(n,t,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){},380:function(n,t,o){"use strict";o.r(t);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),o(337),o(335),o(333),o(331),o(329),o(327),o(325),o(323)}});
|
!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([400,0]),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){},395:function(n,t,o){},397:function(n,t,o){},400:function(n,t,o){"use strict";o.r(t);o(399),o(397),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)}});
|
||||||
//# 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,6 +3,135 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
v0.51.3 - 2021-04-16 Y'all broke it on the first day (hydroflame)
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
**Passive faction reputation**
|
||||||
|
|
||||||
|
* Reworked, from 1 rep / 2 minute. Now is a complicated percentage of the
|
||||||
|
reputation you'd gain working for them. It's not op but it feels a bit
|
||||||
|
more useful.
|
||||||
|
|
||||||
|
**Netscript**
|
||||||
|
|
||||||
|
* print/tprint now take any number of arguments.
|
||||||
|
* print/tprint will now print object as json.
|
||||||
|
* print/tprint now handle passing in an undefined argument properly.
|
||||||
|
|
||||||
|
**Casino**
|
||||||
|
|
||||||
|
* Cannot bet negative money anymore.
|
||||||
|
* Roulette max bet is a bit higher.
|
||||||
|
* Coin Flip has a small cooldown.
|
||||||
|
* All buttons reject unstrusted mouse events.
|
||||||
|
|
||||||
|
**Documentation**
|
||||||
|
|
||||||
|
* Changed a message that said nsjs only works on Chrome.
|
||||||
|
|
||||||
|
**Bugfix**
|
||||||
|
|
||||||
|
* hacknet.maxNumNodes now works for both nodes and servers.
|
||||||
|
* Fixed a bug where the popup boxes would contain data from previous popup boxes.
|
||||||
|
* .js files will also have the 'export async function' boilerplate.
|
||||||
|
|
||||||
|
**Misc.**
|
||||||
|
|
||||||
|
* turned off web form autocomplete for the terminal text input.
|
||||||
|
* Fixed an issue on Windows+Firefox where pressing up on the terminal would
|
||||||
|
bring the cursor to the begining of the line. (Issue #836)
|
||||||
|
* Hacknet node names is easier to handle for screen readers.
|
||||||
|
* Money spent on classes is now tracked independently of work money.
|
||||||
|
* running coding contract from the terminal will display its name.
|
||||||
|
|
||||||
|
v0.51.2 - 2021-04-09 Vegas, Baby! (hydroflame)
|
||||||
|
----------------------------------------------
|
||||||
|
|
||||||
|
**New location: The Iker Molina Casino**
|
||||||
|
|
||||||
|
* A casino opened in Aevum. However the house is rumored to cheat. If only
|
||||||
|
we could give them a taste of their own medicine.
|
||||||
|
|
||||||
|
**Misc.**
|
||||||
|
|
||||||
|
* Link to discord added under options
|
||||||
|
* 'getMemberInformation' doc updated, oops
|
||||||
|
* tech vendor now handle max ram and cores.
|
||||||
|
|
||||||
|
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)
|
v0.50.1 - 2021-03-22 (hydroflame)
|
||||||
---------------------------------
|
---------------------------------
|
||||||
**Netscript**
|
**Netscript**
|
||||||
|
|||||||
@@ -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.50'
|
version = '0.51'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.50.2'
|
release = '0.51.3'
|
||||||
|
|
||||||
# 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.
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
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
|
||||||
|
}
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
print() Netscript Function
|
print() Netscript Function
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
.. js:function:: print(x)
|
.. js:function:: print(args...)
|
||||||
|
|
||||||
:RAM cost: 0 GB
|
:RAM cost: 0 GB
|
||||||
:param x: Value to be printed.
|
:param args: Values to be printed.
|
||||||
|
|
||||||
Prints a value or a variable to the script's logs.
|
Prints any number of values to the script's logs.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
print("Hello world!"); // Prints "Hello world!" in the logs.
|
print("Hello world!"); // Prints "Hello world!" in the logs.
|
||||||
|
print({a:5}); // Prints '{"a":5}' in the logs.
|
||||||
@@ -1,15 +1,16 @@
|
|||||||
tprint() Netscript Function
|
tprint() Netscript Function
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
.. js:function:: tprint(x)
|
.. js:function:: tprint(args...)
|
||||||
|
|
||||||
:RAM cost: 0 GB
|
:RAM cost: 0 GB
|
||||||
:param x: Value to be printed
|
:param args: Values to be printed
|
||||||
|
|
||||||
Prints a value or a variable to the Terminal.
|
Prints any number of values to the Terminal.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
.. code-block:: javascript
|
.. code-block:: javascript
|
||||||
|
|
||||||
tprint("Hello world!"); // Prints "Hello world!" to the terminal.
|
tprint("Hello world!"); // Prints "Hello world!" to the terminal.
|
||||||
|
tprint({a:5}); // Prints '{"a":5}' to the terminal.
|
||||||
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 (not exp multiplier).
|
||||||
|
: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 (not exp multiplier).
|
||||||
|
: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
|
||||||
@@ -10,27 +10,35 @@ getMemberInformation() Netscript Function
|
|||||||
The object has the following structure::
|
The object has the following structure::
|
||||||
|
|
||||||
{
|
{
|
||||||
agility: Agility stat
|
name: Name of this member.
|
||||||
agilityEquipMult: Agility multiplier from equipment. Decimal form
|
task: Name of currently assigned task.
|
||||||
agilityAscensionMult: Agility multiplier from ascension. Decimal form
|
earnedRespect: Total amount of respect earned by this member.
|
||||||
augmentations: Array of names of all owned Augmentations
|
hack: Hacking stat
|
||||||
charisma: Charisma stat
|
str: Strength stat
|
||||||
charismaEquipMult: Charisma multiplier from equipment. Decimal form
|
def: Defense stat
|
||||||
charismaAscensionMult: Charisma multiplier from ascension. Decimal form
|
dex: Dexterity stat
|
||||||
defense: Defense stat
|
agi: Agility stat
|
||||||
defenseEquipMult: Defense multiplier from equipment. Decimal form
|
cha: Charisma stat
|
||||||
defenseAscensionMult: Defense multiplier from ascension. Decimal form
|
hack_exp: Hacking experience
|
||||||
dexterity: Dexterity stat
|
str_exp: Strength experience
|
||||||
dexterityEquipMult: Dexterity multiplier from equipment. Decimal form
|
def_exp: Defense experience
|
||||||
dexterityAscensionMult: Dexterity multiplier from ascension. Decimal form
|
dex_exp: Dexterity experience
|
||||||
equipment: Array of names of all owned Non-Augmentation Equipment
|
agi_exp: Agility experience
|
||||||
hacking: Hacking stat
|
cha_exp: Charisma experience
|
||||||
hackingEquipMult: Hacking multiplier from equipment. Decimal form
|
hack_mult: Hacking multiplier from equipment. Decimal form
|
||||||
hackingAscensionMult: Hacking multiplier from ascension. Decimal form
|
str_mult: Strength multiplier from equipment. Decimal form
|
||||||
strength: Strength stat
|
def_mult: Defense multiplier from equipment. Decimal form
|
||||||
strengthEquipMult: Strength multiplier from equipment. Decimal form
|
dex_mult: Dexterity multiplier from equipment. Decimal form
|
||||||
strengthAscensionMult: Strength multiplier from ascension. Decimal form
|
agi_mult: Agility multiplier from equipment. Decimal form
|
||||||
task: Name of currently assigned task
|
cha_mult: Charisma multiplier from equipment. Decimal form
|
||||||
|
hack_asc_mult: Hacking multiplier from ascension. Decimal form
|
||||||
|
str_asc_mult: Strength multiplier from ascension. Decimal form
|
||||||
|
def_asc_mult: Defense multiplier from ascension. Decimal form
|
||||||
|
dex_asc_mult: Dexterity multiplier from ascension. Decimal form
|
||||||
|
agi_asc_mult: Agility multiplier from ascension. Decimal form
|
||||||
|
cha_asc_mult: Charisma multiplier from ascension. Decimal form
|
||||||
|
upgrades: Array of names of all owned Non-Augmentation Equipment
|
||||||
|
augmentations: Array of names of all owned Augmentations
|
||||||
}
|
}
|
||||||
|
|
||||||
Get stat and equipment-related information about a Gang Member
|
Get stat and equipment-related information about a Gang Member
|
||||||
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,3 +9,4 @@ they contain spoilers for the game.
|
|||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
||||||
getBitNodeMultipliers() <advancedfunctions/getBitNodeMultipliers>
|
getBitNodeMultipliers() <advancedfunctions/getBitNodeMultipliers>
|
||||||
|
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>
|
||||||
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,6 @@ Here is a short summary of the differences between Netscript 1.0 and Netscript 2
|
|||||||
|
|
||||||
* Supports (almost) all features of modern JavaScript
|
* Supports (almost) all features of modern JavaScript
|
||||||
* Extremely fast - code is executed as an Async Function
|
* Extremely fast - code is executed as an Async Function
|
||||||
* Currently only works with Google Chrome browser
|
* Works on most modern browsers.
|
||||||
* Each script becomes a module and therefore all instances of that script can easily
|
* Each script becomes a module and therefore all instances of that script can easily
|
||||||
share data between each other (essentially global/static variables)
|
share data between each other (essentially global/static variables)
|
||||||
|
|||||||
@@ -24,10 +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>
|
||||||
|
getCurrentServer() <singularityfunctions/getCurrentServer>
|
||||||
connect() <singularityfunctions/connect>
|
connect() <singularityfunctions/connect>
|
||||||
manualHack() <singularityfunctions/manualHack>
|
manualHack() <singularityfunctions/manualHack>
|
||||||
getStats() <singularityfunctions/getStats>
|
getPlayer() <singularityfunctions/getPlayer>
|
||||||
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
hospitalize() <singularityfunctions/hospitalize>
|
||||||
isBusy() <singularityfunctions/isBusy>
|
isBusy() <singularityfunctions/isBusy>
|
||||||
stopAction() <singularityfunctions/stopAction>
|
stopAction() <singularityfunctions/stopAction>
|
||||||
upgradeHomeRam() <singularityfunctions/upgradeHomeRam>
|
upgradeHomeRam() <singularityfunctions/upgradeHomeRam>
|
||||||
@@ -57,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>
|
||||||
@@ -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.
|
||||||
37
index.html
37
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>
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
<table id="terminal">
|
<table id="terminal">
|
||||||
<tr id="terminal-input">
|
<tr id="terminal-input">
|
||||||
<td id="terminal-input-td" tabindex="2">$
|
<td id="terminal-input-td" tabindex="2">$
|
||||||
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;"/>
|
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;" autocomplete="off"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -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:
|
||||||
@@ -549,6 +559,7 @@
|
|||||||
<div id="game-options-right-panel">
|
<div id="game-options-right-panel">
|
||||||
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank"> Changelog </a>
|
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank"> Changelog </a>
|
||||||
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank">Documentation</a>
|
<a class="a-link-button" href="https://bitburner.readthedocs.io/en/latest/index.html" target="_blank">Documentation</a>
|
||||||
|
<a class="a-link-button" href="https://discord.gg/TFc3hKD" target="_blank">Discord</a>
|
||||||
<a class="a-link-button" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
|
<a class="a-link-button" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
|
||||||
<button id="save-game-link" class="a-link-button"> Save Game </button>
|
<button id="save-game-link" class="a-link-button"> Save Game </button>
|
||||||
<button id="delete-game-link" class="a-link-button"> Delete Game </button>
|
<button id="delete-game-link" class="a-link-button"> Delete Game </button>
|
||||||
|
|||||||
@@ -121,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.50.1"
|
"version": "0.51.3"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1395,6 +1395,23 @@ function initAugmentations() {
|
|||||||
}
|
}
|
||||||
AddToAugmentations(Xanipher);
|
AddToAugmentations(Xanipher);
|
||||||
|
|
||||||
|
const HydroflameLeftArm = new Augmentation({
|
||||||
|
name:AugmentationNames.HydroflameLeftArm, repCost:500e3, moneyCost:500e9,
|
||||||
|
info:"The left arm of a legendary BitRunner who ascended beyond this world. " +
|
||||||
|
"It projects a light blue energy shield that protects the exposed inner parts. " +
|
||||||
|
"Even though it contains no weapons, the advance tungsten titanium " +
|
||||||
|
"alloy increases the users strength to unbelievable levels.<br><br>" +
|
||||||
|
"This augmentation increases the player's strength by 300%.",
|
||||||
|
strength_mult: 3,
|
||||||
|
});
|
||||||
|
HydroflameLeftArm.addToFactions(["NWO"]);
|
||||||
|
if (augmentationExists(AugmentationNames.HydroflameLeftArm)) {
|
||||||
|
delete Augmentations[AugmentationNames.HydroflameLeftArm];
|
||||||
|
}
|
||||||
|
AddToAugmentations(HydroflameLeftArm);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ClarkeIncorporated
|
// ClarkeIncorporated
|
||||||
const nextSENS = new Augmentation({
|
const nextSENS = new Augmentation({
|
||||||
name:AugmentationNames.nextSENS, repCost:175e3, moneyCost:385e6,
|
name:AugmentationNames.nextSENS, repCost:175e3, moneyCost:385e6,
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ export let AugmentationNames: IMap<string> = {
|
|||||||
BrachiBlades: "BrachiBlades",
|
BrachiBlades: "BrachiBlades",
|
||||||
BionicArms: "Bionic Arms",
|
BionicArms: "Bionic Arms",
|
||||||
SNA: "Social Negotiation Assistant (S.N.A)",
|
SNA: "Social Negotiation Assistant (S.N.A)",
|
||||||
|
HydroflameLeftArm: "Hydroflame left arm",
|
||||||
EsperEyewear: "EsperTech Bladeburner Eyewear",
|
EsperEyewear: "EsperTech Bladeburner Eyewear",
|
||||||
EMS4Recombination: "EMS-4 Recombination",
|
EMS4Recombination: "EMS-4 Recombination",
|
||||||
OrionShoulder: "ORION-MKIV Shoulder",
|
OrionShoulder: "ORION-MKIV Shoulder",
|
||||||
|
|||||||
@@ -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";
|
||||||
@@ -51,6 +52,9 @@ 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 { 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";
|
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> `
|
||||||
@@ -709,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);
|
||||||
@@ -725,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 = "";
|
||||||
@@ -797,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);
|
||||||
@@ -902,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;
|
||||||
}
|
}
|
||||||
@@ -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, " +
|
||||||
@@ -1421,12 +1427,12 @@ Bladeburner.prototype.createOverviewContent = function() {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -1445,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();
|
||||||
@@ -1468,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);
|
||||||
@@ -1512,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;
|
||||||
@@ -1764,15 +1770,16 @@ 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);
|
||||||
@@ -1898,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);
|
||||||
@@ -1939,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);
|
||||||
@@ -1963,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);
|
||||||
@@ -1975,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);
|
||||||
@@ -1989,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,
|
||||||
@@ -2038,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);
|
||||||
@@ -2049,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 " +
|
||||||
@@ -2063,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)")
|
||||||
@@ -2077,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;
|
||||||
}
|
}
|
||||||
@@ -2101,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);
|
||||||
@@ -2113,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);
|
||||||
@@ -2129,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,
|
||||||
@@ -2190,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);
|
||||||
@@ -2201,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 " +
|
||||||
@@ -2215,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)")
|
||||||
@@ -2229,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;
|
||||||
}
|
}
|
||||||
@@ -2252,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),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2265,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;
|
||||||
@@ -2275,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);
|
||||||
@@ -2284,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",
|
||||||
@@ -2311,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);
|
||||||
98
src/Casino/CoinFlip.tsx
Normal file
98
src/Casino/CoinFlip.tsx
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/**
|
||||||
|
* React Subcomponent for displaying a location's UI, when that location is a gym
|
||||||
|
*
|
||||||
|
* This subcomponent renders all of the buttons for training at the gym
|
||||||
|
*/
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { StdButton } from "../ui/React/StdButton";
|
||||||
|
import { BadRNG } from "./RNG";
|
||||||
|
import { Game } from "./Game";
|
||||||
|
import { trusted } from "./utils";
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
p: IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
type IState = {
|
||||||
|
investment: number;
|
||||||
|
result: any;
|
||||||
|
status: string;
|
||||||
|
playLock: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const minPlay = 0;
|
||||||
|
const maxPlay = 10e3;
|
||||||
|
|
||||||
|
export class CoinFlip extends Game<IProps, IState> {
|
||||||
|
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
investment: 1000,
|
||||||
|
result: <span> </span>,
|
||||||
|
status: '',
|
||||||
|
playLock: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.play = this.play.bind(this);
|
||||||
|
this.updateInvestment = this.updateInvestment.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInvestment(e: React.FormEvent<HTMLInputElement>) {
|
||||||
|
let investment: number = parseInt(e.currentTarget.value);
|
||||||
|
if (isNaN(investment)) {
|
||||||
|
investment = minPlay;
|
||||||
|
}
|
||||||
|
if (investment > maxPlay) {
|
||||||
|
investment = maxPlay;
|
||||||
|
}
|
||||||
|
if (investment < minPlay) {
|
||||||
|
investment = minPlay;
|
||||||
|
}
|
||||||
|
this.setState({investment: investment});
|
||||||
|
}
|
||||||
|
|
||||||
|
play(guess: string) {
|
||||||
|
if(this.reachedLimit(this.props.p)) return;
|
||||||
|
const v = BadRNG.random();
|
||||||
|
let letter: string;
|
||||||
|
if (v < 0.5) {
|
||||||
|
letter = 'H';
|
||||||
|
} else {
|
||||||
|
letter = 'T';
|
||||||
|
}
|
||||||
|
const correct: boolean = guess===letter;
|
||||||
|
this.setState({
|
||||||
|
result: <span className={correct ? "text" : "failure"}>{letter}</span>,
|
||||||
|
status: correct ? " win!" : "lose!",
|
||||||
|
playLock: true,
|
||||||
|
});
|
||||||
|
setTimeout(()=>this.setState({playLock: false}), 250);
|
||||||
|
if (correct) {
|
||||||
|
this.win(this.props.p, this.state.investment);
|
||||||
|
} else {
|
||||||
|
this.win(this.props.p, -this.state.investment);
|
||||||
|
}
|
||||||
|
if(this.reachedLimit(this.props.p)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <>
|
||||||
|
<pre>
|
||||||
|
+———————+<br />
|
||||||
|
| | | |<br />
|
||||||
|
| | {this.state.result} | |<br />
|
||||||
|
| | | |<br />
|
||||||
|
+———————+<br />
|
||||||
|
</pre>
|
||||||
|
<span className="text">Play for: </span><input type="number" className='text-input' onChange={this.updateInvestment} value={this.state.investment} /><br />
|
||||||
|
<StdButton onClick={trusted(() => this.play('H'))} text={"Head!"} disabled={this.state.playLock} />
|
||||||
|
<StdButton onClick={trusted(() => this.play('T'))} text={"Tail!"} disabled={this.state.playLock} />
|
||||||
|
<h1>{this.state.status}</h1>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/Casino/Game.tsx
Normal file
20
src/Casino/Game.tsx
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
|
|
||||||
|
const gainLimit = 10e9;
|
||||||
|
|
||||||
|
export class Game<T,U> extends React.Component<T, U> {
|
||||||
|
win(p: IPlayer, n: number) {
|
||||||
|
p.gainMoney(n);
|
||||||
|
p.recordMoneySource(n, "casino");
|
||||||
|
}
|
||||||
|
|
||||||
|
reachedLimit(p: IPlayer): boolean {
|
||||||
|
const reached = p.getCasinoWinnings() > gainLimit;
|
||||||
|
if(reached) {
|
||||||
|
dialogBoxCreate(<>Alright cheater get out of here. You're not allowed here anymore.</>);
|
||||||
|
}
|
||||||
|
return reached;
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/Casino/RNG.ts
Normal file
64
src/Casino/RNG.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
|
||||||
|
export interface RNG {
|
||||||
|
random(): number
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* very bad RNG, meant to be used as introduction to RNG manipulation. It has a
|
||||||
|
* period of 1024.
|
||||||
|
*/
|
||||||
|
class RNG0 implements RNG {
|
||||||
|
x: number;
|
||||||
|
m: number = 1024;
|
||||||
|
a: number = 341;
|
||||||
|
c: number = 1;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.x = 0;
|
||||||
|
this.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
step() {
|
||||||
|
this.x = (this.a*this.x+this.c) % this.m;
|
||||||
|
}
|
||||||
|
|
||||||
|
random(): number {
|
||||||
|
this.step();
|
||||||
|
return this.x/this.m;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.x = (new Date()).getTime() % this.m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const BadRNG: RNG0 = new RNG0();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wichmann–Hill PRNG
|
||||||
|
* The period is 6e12.
|
||||||
|
*/
|
||||||
|
export class WHRNG implements RNG {
|
||||||
|
s1: number = 0;
|
||||||
|
s2: number = 0;
|
||||||
|
s3: number = 0;
|
||||||
|
|
||||||
|
constructor(totalPlaytime: number) {
|
||||||
|
// This one is seeded by the players total play time.
|
||||||
|
const v: number = (totalPlaytime/1000)%30000;
|
||||||
|
this.s1 = v;
|
||||||
|
this.s2 = v;
|
||||||
|
this.s3 = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
step() {
|
||||||
|
this.s1 = (171 * this.s1) % 30269;
|
||||||
|
this.s2 = (172 * this.s2) % 30307;
|
||||||
|
this.s3 = (170 * this.s3) % 30323;
|
||||||
|
}
|
||||||
|
|
||||||
|
random(): number {
|
||||||
|
this.step();
|
||||||
|
return (this.s1/30269.0 + this.s2/30307.0 + this.s3/30323.0)%1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
295
src/Casino/Roulette.tsx
Normal file
295
src/Casino/Roulette.tsx
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { StdButton } from "../ui/React/StdButton";
|
||||||
|
import { Money } from "../ui/React/Money";
|
||||||
|
import { Game } from "./Game";
|
||||||
|
import { WHRNG } from "./RNG";
|
||||||
|
import { trusted } from "./utils";
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
p: IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
type IState = {
|
||||||
|
investment: number;
|
||||||
|
canPlay: boolean;
|
||||||
|
status: string | JSX.Element;
|
||||||
|
n: number;
|
||||||
|
lock: boolean;
|
||||||
|
strategy: Strategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
const minPlay = 0;
|
||||||
|
const maxPlay = 1e7;
|
||||||
|
|
||||||
|
function isRed(n: number): boolean {
|
||||||
|
return [1, 3, 5, 7, 9, 12, 14, 16, 18, 19,
|
||||||
|
21, 23, 25, 27, 30, 32, 34, 36].includes(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isBlack(n: number): boolean {
|
||||||
|
return !isRed(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
type Strategy = {
|
||||||
|
match: (n: number) => boolean;
|
||||||
|
payout: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const redNumbers: number[] = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19,
|
||||||
|
21, 23, 25, 27, 30, 32, 34, 36];
|
||||||
|
|
||||||
|
const strategies: {
|
||||||
|
Red: Strategy;
|
||||||
|
Black: Strategy;
|
||||||
|
Odd: Strategy;
|
||||||
|
Even: Strategy;
|
||||||
|
High: Strategy;
|
||||||
|
Low: Strategy;
|
||||||
|
Third1: Strategy;
|
||||||
|
Third2: Strategy;
|
||||||
|
Third3: Strategy;
|
||||||
|
} = {
|
||||||
|
Red: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return redNumbers.includes(n);
|
||||||
|
},
|
||||||
|
payout: 1,
|
||||||
|
},
|
||||||
|
Black: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
return !redNumbers.includes(n);
|
||||||
|
},
|
||||||
|
payout: 1,
|
||||||
|
},
|
||||||
|
Odd: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return n%2 === 1;
|
||||||
|
},
|
||||||
|
payout: 1,
|
||||||
|
},
|
||||||
|
Even: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return n%2 === 0;
|
||||||
|
},
|
||||||
|
payout: 1,
|
||||||
|
},
|
||||||
|
High: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return n>18
|
||||||
|
},
|
||||||
|
payout: 1,
|
||||||
|
},
|
||||||
|
Low: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return n<19;
|
||||||
|
},
|
||||||
|
payout: 1,
|
||||||
|
},
|
||||||
|
Third1: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return n <= 12;
|
||||||
|
},
|
||||||
|
payout: 2,
|
||||||
|
},
|
||||||
|
Third2: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return 13 <= n && n <= 24;
|
||||||
|
},
|
||||||
|
payout: 2,
|
||||||
|
},
|
||||||
|
Third3: {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
if (n === 0) return false;
|
||||||
|
return 25 <= n;
|
||||||
|
},
|
||||||
|
payout: 2,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function Single(s: number): Strategy {
|
||||||
|
return {
|
||||||
|
match: (n: number): boolean => {
|
||||||
|
return s === n;
|
||||||
|
},
|
||||||
|
payout: 36,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Roulette extends Game<IProps, IState> {
|
||||||
|
interval: number = -1;
|
||||||
|
rng: WHRNG;
|
||||||
|
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.rng = new WHRNG((new Date()).getTime());
|
||||||
|
this.state = {
|
||||||
|
investment: 1000,
|
||||||
|
canPlay: true,
|
||||||
|
status: 'waiting',
|
||||||
|
n: 0,
|
||||||
|
lock: true,
|
||||||
|
strategy: {
|
||||||
|
payout: 0,
|
||||||
|
match: (n: number): boolean => { return false },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
this.step = this.step.bind(this);
|
||||||
|
this.currentNumber = this.currentNumber.bind(this);
|
||||||
|
this.updateInvestment = this.updateInvestment.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.interval = setInterval(this.step, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
step() {
|
||||||
|
if (!this.state.lock) {
|
||||||
|
this.setState({n: Math.floor(Math.random()*37)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInvestment(e: React.FormEvent<HTMLInputElement>) {
|
||||||
|
let investment: number = parseInt(e.currentTarget.value);
|
||||||
|
if (isNaN(investment)) {
|
||||||
|
investment = minPlay;
|
||||||
|
}
|
||||||
|
if (investment > maxPlay) {
|
||||||
|
investment = maxPlay;
|
||||||
|
}
|
||||||
|
if (investment < minPlay) {
|
||||||
|
investment = minPlay;
|
||||||
|
}
|
||||||
|
this.setState({investment: investment});
|
||||||
|
}
|
||||||
|
|
||||||
|
currentNumber() {
|
||||||
|
if (this.state.n === 0) return '0';
|
||||||
|
const color = isRed(this.state.n) ? 'R' : 'B';
|
||||||
|
return `${this.state.n}${color}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
play(s: Strategy) {
|
||||||
|
if(this.reachedLimit(this.props.p)) return;
|
||||||
|
this.setState({
|
||||||
|
canPlay: false,
|
||||||
|
lock: false,
|
||||||
|
status: 'playing',
|
||||||
|
strategy: s,
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
let n = Math.floor(this.rng.random()*37);
|
||||||
|
let status = <></>;
|
||||||
|
let gain = 0;
|
||||||
|
let playerWin = this.state.strategy.match(n)
|
||||||
|
// oh yeah, the house straight up cheats. Try finding the seed now!
|
||||||
|
if(playerWin && Math.random() > 0.9) {
|
||||||
|
playerWin = false;
|
||||||
|
while(this.state.strategy.match(n)) {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(playerWin) {
|
||||||
|
gain = this.state.investment*this.state.strategy.payout;
|
||||||
|
status = <>won {Money(gain)}</>;
|
||||||
|
} else {
|
||||||
|
gain = -this.state.investment;
|
||||||
|
status = <>lost {Money(-gain)}</>;
|
||||||
|
}
|
||||||
|
this.win(this.props.p, gain);
|
||||||
|
this.setState({
|
||||||
|
canPlay: true,
|
||||||
|
lock: true,
|
||||||
|
status: status,
|
||||||
|
n: n,
|
||||||
|
});
|
||||||
|
this.reachedLimit(this.props.p);
|
||||||
|
}, 1600);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <>
|
||||||
|
<h1>{this.currentNumber()}</h1>
|
||||||
|
<input type="number" className='text-input' onChange={this.updateInvestment} placeholder={"Amount to play"} value={this.state.investment} disabled={!this.state.canPlay} />
|
||||||
|
<h1>{this.state.status}</h1>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td><StdButton text={"3"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(3)))} /></td>
|
||||||
|
<td><StdButton text={"6"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(6)))} /></td>
|
||||||
|
<td><StdButton text={"9"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(9)))} /></td>
|
||||||
|
<td><StdButton text={"12"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(12)))} /></td>
|
||||||
|
<td><StdButton text={"15"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(15)))} /></td>
|
||||||
|
<td><StdButton text={"18"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(18)))} /></td>
|
||||||
|
<td><StdButton text={"21"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(21)))} /></td>
|
||||||
|
<td><StdButton text={"24"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(24)))} /></td>
|
||||||
|
<td><StdButton text={"27"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(27)))} /></td>
|
||||||
|
<td><StdButton text={"30"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(30)))} /></td>
|
||||||
|
<td><StdButton text={"33"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(33)))} /></td>
|
||||||
|
<td><StdButton text={"36"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(36)))} /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><StdButton text={"2"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(2)))} /></td>
|
||||||
|
<td><StdButton text={"5"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(5)))} /></td>
|
||||||
|
<td><StdButton text={"8"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(8)))} /></td>
|
||||||
|
<td><StdButton text={"11"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(11)))} /></td>
|
||||||
|
<td><StdButton text={"14"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(14)))} /></td>
|
||||||
|
<td><StdButton text={"17"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(17)))} /></td>
|
||||||
|
<td><StdButton text={"20"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(20)))} /></td>
|
||||||
|
<td><StdButton text={"23"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(23)))} /></td>
|
||||||
|
<td><StdButton text={"26"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(26)))} /></td>
|
||||||
|
<td><StdButton text={"29"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(29)))} /></td>
|
||||||
|
<td><StdButton text={"32"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(32)))} /></td>
|
||||||
|
<td><StdButton text={"35"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(35)))} /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><StdButton text={"1"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(1)))} /></td>
|
||||||
|
<td><StdButton text={"4"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(4)))} /></td>
|
||||||
|
<td><StdButton text={"7"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(7)))} /></td>
|
||||||
|
<td><StdButton text={"10"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(10)))} /></td>
|
||||||
|
<td><StdButton text={"13"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(13)))} /></td>
|
||||||
|
<td><StdButton text={"16"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(16)))} /></td>
|
||||||
|
<td><StdButton text={"19"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(19)))} /></td>
|
||||||
|
<td><StdButton text={"22"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(22)))} /></td>
|
||||||
|
<td><StdButton text={"25"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(25)))} /></td>
|
||||||
|
<td><StdButton text={"28"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(28)))} /></td>
|
||||||
|
<td><StdButton text={"31"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(31)))} /></td>
|
||||||
|
<td><StdButton text={"34"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(34)))} /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={4}><StdButton text={"1 to 12"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Third1))} /></td>
|
||||||
|
<td colSpan={4}><StdButton text={"13 to 24"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Third2))} /></td>
|
||||||
|
<td colSpan={4}><StdButton text={"25 to 36"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Third3))} /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td colSpan={2}><StdButton text={"Red"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Red))} /></td>
|
||||||
|
<td colSpan={2}><StdButton text={"Black"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Black))} /></td>
|
||||||
|
<td colSpan={2}><StdButton text={"Odd"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Odd))} /></td>
|
||||||
|
<td colSpan={2}><StdButton text={"Even"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Even))} /></td>
|
||||||
|
<td colSpan={2}><StdButton text={"High"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.High))} /></td>
|
||||||
|
<td colSpan={2}><StdButton text={"Low"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(strategies.Low))} /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><StdButton text={"0"} disabled={!this.state.canPlay} onClick={trusted(()=>this.play(Single(0)))} /></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
239
src/Casino/SlotMachine.tsx
Normal file
239
src/Casino/SlotMachine.tsx
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
||||||
|
import { StdButton } from "../ui/React/StdButton";
|
||||||
|
import { Money } from "../ui/React/Money";
|
||||||
|
import { WHRNG } from "./RNG";
|
||||||
|
import { Game } from "./Game";
|
||||||
|
import { trusted } from "./utils";
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
p: IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
type IState = {
|
||||||
|
index: number[];
|
||||||
|
locks: number[];
|
||||||
|
investment: number;
|
||||||
|
canPlay: boolean;
|
||||||
|
status: string | JSX.Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
// statically shuffled array of symbols.
|
||||||
|
let symbols = ["D", "C", "$", "?", "♥", "A", "C", "B", "C", "E", "B", "E", "C",
|
||||||
|
"*", "D", "♥", "B", "A", "A", "A", "C", "A", "D", "B", "E", "?", "D", "*",
|
||||||
|
"@", "♥", "B", "E", "?"];
|
||||||
|
|
||||||
|
function getPayout(s: string, n: number): number {
|
||||||
|
switch (s) {
|
||||||
|
case "$":
|
||||||
|
return [20, 200, 1000][n];
|
||||||
|
case "@":
|
||||||
|
return [8, 80, 400][n];
|
||||||
|
case "♥":
|
||||||
|
case "?":
|
||||||
|
return [6, 20, 150][n];
|
||||||
|
case "D":
|
||||||
|
case "E":
|
||||||
|
return [1, 8, 30][n];
|
||||||
|
default:
|
||||||
|
return [1, 5, 20][n];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const payLines = [
|
||||||
|
// lines
|
||||||
|
[[0, 0], [0, 1], [0, 2], [0, 3], [0, 4]],
|
||||||
|
[[1, 0], [1, 1], [1, 2], [1, 3], [1, 4]],
|
||||||
|
[[2, 0], [2, 1], [2, 2], [2, 3], [2, 4]],
|
||||||
|
|
||||||
|
// Vs
|
||||||
|
[[2, 0], [1, 1], [0, 2], [1, 3], [2, 4]],
|
||||||
|
[[0, 0], [1, 1], [2, 2], [1, 3], [0, 4]],
|
||||||
|
|
||||||
|
// rest
|
||||||
|
[[0, 0], [1, 1], [1, 2], [1, 3], [0, 4]],
|
||||||
|
[[2, 0], [1, 1], [1, 2], [1, 3], [2, 4]],
|
||||||
|
[[1, 0], [0, 1], [0, 2], [0, 3], [1, 4]],
|
||||||
|
[[1, 0], [2, 1], [2, 2], [2, 3], [1, 4]],
|
||||||
|
];
|
||||||
|
|
||||||
|
const minPlay = 0;
|
||||||
|
const maxPlay = 1e6;
|
||||||
|
|
||||||
|
export class SlotMachine extends Game<IProps, IState> {
|
||||||
|
rng: WHRNG;
|
||||||
|
interval: number = -1;
|
||||||
|
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
this.rng = new WHRNG(this.props.p.totalPlaytime);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
index: [0, 0, 0, 0, 0],
|
||||||
|
investment: 1000,
|
||||||
|
locks: [0, 0, 0, 0, 0],
|
||||||
|
canPlay: true,
|
||||||
|
status: 'waiting',
|
||||||
|
};
|
||||||
|
|
||||||
|
this.play = this.play.bind(this);
|
||||||
|
this.lock = this.lock.bind(this);
|
||||||
|
this.unlock = this.unlock.bind(this);
|
||||||
|
this.step = this.step.bind(this);
|
||||||
|
this.checkWinnings = this.checkWinnings.bind(this);
|
||||||
|
this.getTable = this.getTable.bind(this);
|
||||||
|
this.updateInvestment = this.updateInvestment.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.interval = setInterval(this.step, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
step() {
|
||||||
|
let stoppedOne = false;
|
||||||
|
const index = this.state.index.slice();
|
||||||
|
for(const i in index) {
|
||||||
|
if (index[i] === this.state.locks[i] && !stoppedOne) continue;
|
||||||
|
index[i] = (index[i] + 1) % symbols.length;
|
||||||
|
stoppedOne = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({index: index});
|
||||||
|
|
||||||
|
if(stoppedOne && index.every((e, i) => e === this.state.locks[i])) {
|
||||||
|
this.checkWinnings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
clearInterval(this.interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
getTable(): string[][] {
|
||||||
|
return [
|
||||||
|
[symbols[(this.state.index[0]+symbols.length-1)%symbols.length], symbols[(this.state.index[1]+symbols.length-1)%symbols.length], symbols[(this.state.index[2]+symbols.length-1)%symbols.length], symbols[(this.state.index[3]+symbols.length-1)%symbols.length], symbols[(this.state.index[4]+symbols.length-1)%symbols.length]],
|
||||||
|
[symbols[this.state.index[0]], symbols[this.state.index[1]], symbols[this.state.index[2]], symbols[this.state.index[3]], symbols[this.state.index[4]]],
|
||||||
|
[symbols[(this.state.index[0]+1)%symbols.length], symbols[(this.state.index[1]+1)%symbols.length], symbols[(this.state.index[2]+1)%symbols.length], symbols[(this.state.index[3]+1)%symbols.length], symbols[(this.state.index[4]+1)%symbols.length]],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
play() {
|
||||||
|
if(this.reachedLimit(this.props.p)) return;
|
||||||
|
this.setState({status: 'playing'});
|
||||||
|
this.win(this.props.p, -this.state.investment);
|
||||||
|
if(!this.state.canPlay) return;
|
||||||
|
this.unlock();
|
||||||
|
setTimeout(this.lock, this.rng.random()*2000+1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
lock() {
|
||||||
|
this.setState({
|
||||||
|
locks: [
|
||||||
|
Math.floor(this.rng.random()*symbols.length),
|
||||||
|
Math.floor(this.rng.random()*symbols.length),
|
||||||
|
Math.floor(this.rng.random()*symbols.length),
|
||||||
|
Math.floor(this.rng.random()*symbols.length),
|
||||||
|
Math.floor(this.rng.random()*symbols.length),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
checkWinnings() {
|
||||||
|
const t = this.getTable();
|
||||||
|
const getPaylineData = function(payline: number[][]): string[] {
|
||||||
|
let data = [];
|
||||||
|
for(const point of payline) {
|
||||||
|
data.push(t[point[0]][point[1]]);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const countSequence = function(data: string[]): number {
|
||||||
|
let count = 1;
|
||||||
|
for(let i = 1; i < data.length; i++) {
|
||||||
|
if (data[i]!==data[i-1]) break;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
let gains = -this.state.investment;
|
||||||
|
for (const payline of payLines) {
|
||||||
|
const data = getPaylineData(payline);
|
||||||
|
const count = countSequence(data);
|
||||||
|
if (count < 3) continue;
|
||||||
|
const payout = getPayout(data[0], count-3);
|
||||||
|
gains += this.state.investment*payout;
|
||||||
|
this.win(this.props.p, this.state.investment*payout);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
status: <>{gains>0?"gained":"lost"} {Money(Math.abs(gains))}</>,
|
||||||
|
canPlay: true,
|
||||||
|
})
|
||||||
|
if(this.reachedLimit(this.props.p)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unlock() {
|
||||||
|
this.setState({
|
||||||
|
locks: [-1, -1, -1, -1, -1],
|
||||||
|
canPlay: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInvestment(e: React.FormEvent<HTMLInputElement>) {
|
||||||
|
let investment: number = parseInt(e.currentTarget.value);
|
||||||
|
if (isNaN(investment)) {
|
||||||
|
investment = minPlay;
|
||||||
|
}
|
||||||
|
if (investment > maxPlay) {
|
||||||
|
investment = maxPlay;
|
||||||
|
}
|
||||||
|
if (investment < minPlay) {
|
||||||
|
investment = minPlay;
|
||||||
|
}
|
||||||
|
this.setState({investment: investment});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const t = this.getTable();
|
||||||
|
return <>
|
||||||
|
<pre>
|
||||||
|
+———————————————————————+<br />
|
||||||
|
| | {t[0][0]} | {t[0][1]} | {t[0][2]} | {t[0][3]} | {t[0][4]} | |<br />
|
||||||
|
| | | | | | | |<br />
|
||||||
|
| | {symbols[this.state.index[0]]} | {symbols[this.state.index[1]]} | {symbols[this.state.index[2]]} | {symbols[this.state.index[3]]} | {symbols[this.state.index[4]]} | |<br />
|
||||||
|
| | | | | | | |<br />
|
||||||
|
| | {symbols[(this.state.index[0]+1)%symbols.length]} | {symbols[(this.state.index[1]+1)%symbols.length]} | {symbols[(this.state.index[2]+1)%symbols.length]} | {symbols[(this.state.index[3]+1)%symbols.length]} | {symbols[(this.state.index[4]+1)%symbols.length]} | |<br />
|
||||||
|
+———————————————————————+<br />
|
||||||
|
</pre>
|
||||||
|
<input type="number" className='text-input' onChange={this.updateInvestment} placeholder={"Amount to play"} value={this.state.investment} disabled={!this.state.canPlay} />
|
||||||
|
<StdButton onClick={trusted(this.play)} text={"Spin!"} disabled={!this.state.canPlay} />
|
||||||
|
<h1>{this.state.status}</h1>
|
||||||
|
<h2>Pay lines</h2>
|
||||||
|
<pre>
|
||||||
|
----- ····· ····· <br />
|
||||||
|
····· ----- ····· <br />
|
||||||
|
····· ····· ----- <br />
|
||||||
|
</pre>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
··^·· \···/ \···/<br />
|
||||||
|
·/·\· ·\·/· ·---·<br />
|
||||||
|
/···\ ··v·· ·····<br />
|
||||||
|
</pre>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
····· ·---· ·····<br />
|
||||||
|
·---· /···\ \···/<br />
|
||||||
|
/···\ ····· ·---·<br />
|
||||||
|
</pre>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://felgo.com/doc/how-to-make-a-slot-game-tutorial/
|
||||||
8
src/Casino/utils.ts
Normal file
8
src/Casino/utils.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
export function trusted(f: () => void): (event: React.MouseEvent<HTMLElement, MouseEvent>) => any {
|
||||||
|
return function(event: React.MouseEvent<HTMLElement, MouseEvent>): any {
|
||||||
|
if(!event.isTrusted) return;
|
||||||
|
f();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -181,6 +181,9 @@ export class CodingContract {
|
|||||||
return new Promise<CodingContractResult>((resolve: Function, reject: Function) => {
|
return new Promise<CodingContractResult>((resolve: Function, reject: Function) => {
|
||||||
const contractType: CodingContractType = CodingContractTypes[this.type];
|
const contractType: CodingContractType = CodingContractTypes[this.type];
|
||||||
const popupId: string = `coding-contract-prompt-popup-${this.fn}`;
|
const popupId: string = `coding-contract-prompt-popup-${this.fn}`;
|
||||||
|
const title: HTMLElement = createElement("h1", {
|
||||||
|
innerHTML: this.type,
|
||||||
|
});
|
||||||
const txt: HTMLElement = createElement("p", {
|
const txt: HTMLElement = createElement("p", {
|
||||||
innerHTML: ["You are attempting to solve a Coding Contract. You have",
|
innerHTML: ["You are attempting to solve a Coding Contract. You have",
|
||||||
`${this.getMaxNumTries() - this.tries} tries remaining,`,
|
`${this.getMaxNumTries() - this.tries} tries remaining,`,
|
||||||
@@ -225,7 +228,7 @@ export class CodingContract {
|
|||||||
innerText: "Cancel",
|
innerText: "Cancel",
|
||||||
});
|
});
|
||||||
const lineBreak: HTMLElement = createElement("br");
|
const lineBreak: HTMLElement = createElement("br");
|
||||||
createPopup(popupId, [txt, lineBreak, lineBreak, answerInput, solveBtn, cancelBtn]);
|
createPopup(popupId, [title, lineBreak, txt, lineBreak, lineBreak, answerInput, solveBtn, cancelBtn]);
|
||||||
answerInput.focus();
|
answerInput.focus();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
import { IMap } from "./types";
|
import { IMap } from "./types";
|
||||||
|
|
||||||
export let CONSTANTS: IMap<any> = {
|
export let CONSTANTS: IMap<any> = {
|
||||||
Version: "0.50.2",
|
Version: "0.51.3",
|
||||||
|
|
||||||
/** 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
|
||||||
* the player will have this level assuming no multipliers. Multipliers can cause skills to go above this.
|
* the player will have this level assuming no multipliers. Multipliers can cause skills to go above this.
|
||||||
*/
|
*/
|
||||||
MaxSkillLevel: 975,
|
MaxSkillLevel: 975,
|
||||||
|
|
||||||
// Milliseconds per game cycle
|
// Milliseconds per game cycle
|
||||||
MilliPerCycle: 200,
|
MilliPerCycle: 200,
|
||||||
@@ -218,7 +218,7 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
CrimeHeist: "pull off the ultimate heist",
|
CrimeHeist: "pull off the ultimate heist",
|
||||||
|
|
||||||
// Coding Contract
|
// Coding Contract
|
||||||
// TODO Move this into Coding contract impelmentation?
|
// TODO: Move this into Coding contract implementation?
|
||||||
CodingContractBaseFactionRepGain: 2500,
|
CodingContractBaseFactionRepGain: 2500,
|
||||||
CodingContractBaseCompanyRepGain: 4000,
|
CodingContractBaseCompanyRepGain: 4000,
|
||||||
CodingContractBaseMoneyGain: 75e6,
|
CodingContractBaseMoneyGain: 75e6,
|
||||||
@@ -228,18 +228,39 @@ export let CONSTANTS: IMap<any> = {
|
|||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
`
|
`
|
||||||
v0.50.2 - 2021-03-25 Everyone asked for this one. (hydroflame)
|
v0.51.3 - 2021-04-16 Y'all broke it on the first day (hydroflame)
|
||||||
-------
|
-------
|
||||||
BitNodeMultipliers
|
|
||||||
* 'GangKarmaRequirements': a new multipler that influences how much karma is required to make a gang different bitnodes.
|
Passive faction reputation
|
||||||
|
* Reworked, from 1 rep / 2 minute. Now is a complicated percentage of the
|
||||||
|
reputation you'd gain working for them. It's not op but it feels a bit
|
||||||
|
more useful.
|
||||||
|
|
||||||
Netscript
|
Netscript
|
||||||
* 'connect': a new singularity function that connects you to a server. (like the terminal command)
|
* print/tprint now take any number of arguments.
|
||||||
* 'manualHack': a new singularity function that performs a manual hack on the players current server.
|
* print/tprint will now print object as json.
|
||||||
* ns2 stack trace works on Firefox now.
|
* print/tprint now handle passing in an undefined argument properly.
|
||||||
|
|
||||||
|
Casino
|
||||||
|
* Cannot bet negative money anymore.
|
||||||
|
* Roulette max bet is a bit higher.
|
||||||
|
* Coin Flip has a small cooldown.
|
||||||
|
* All buttons reject unstrusted mouse events.
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
* Changed a message that said nsjs only works on Chrome.
|
||||||
|
|
||||||
|
Bugfix
|
||||||
|
* hacknet.maxNumNodes now works for both nodes and servers.
|
||||||
|
* Fixed a bug where the popup boxes would contain data from previous popup boxes.
|
||||||
|
* .js files will also have the export async function boilerplate.
|
||||||
|
|
||||||
Misc.
|
Misc.
|
||||||
* New shortcut, Alt + b, brings you to bladeburner
|
* turned off autocomplete for the terminal text input.
|
||||||
* New shortcut, Alt + g, brings you to gang
|
* Fixed an issue on Windows+Firefox where pressing up on the terminal would
|
||||||
|
bring the cursor to the begining of the line. (Issue #836)
|
||||||
|
* Hacknet node names is easier to handle for screen readers.
|
||||||
|
* Money spent on classes is now tracked independently of work money.
|
||||||
|
* running coding contract from the terminal will display its name.
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
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,11 +1,14 @@
|
|||||||
|
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(): void {
|
export function checkIfConnectedToDarkweb(): void {
|
||||||
@@ -49,7 +52,7 @@ export function executeDarkwebTerminalCommand(commandArray: string[]): void {
|
|||||||
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}</>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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() {
|
||||||
@@ -703,8 +708,11 @@ class DevMenuComponent extends Component {
|
|||||||
<h2>Generic</h2>
|
<h2>Generic</h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
<button className="std-button" onClick={this.addMoney(1e6)}>Add $1m</button>
|
||||||
|
<button className="std-button" onClick={this.addMoney(1e9)}>Add $1b</button>
|
||||||
<button className="std-button" onClick={this.addMoney(1e12)}>Add $1t</button>
|
<button className="std-button" onClick={this.addMoney(1e12)}>Add $1t</button>
|
||||||
<button className="std-button" onClick={this.addMoney(1e15)}>Add $1000t</button>
|
<button className="std-button" onClick={this.addMoney(1e15)}>Add $1000t</button>
|
||||||
|
<button className="std-button" onClick={this.addMoney(1e27)}>Add $1e27</button>
|
||||||
<button className="std-button" onClick={this.upgradeRam}>Upgrade Home Computer's RAM</button>
|
<button className="std-button" onClick={this.upgradeRam}>Upgrade Home Computer's RAM</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ import { Factions } from "./Factions";
|
|||||||
import { HackingMission, setInMission } from "../Missions";
|
import { HackingMission, setInMission } from "../Missions";
|
||||||
import { Player } from "../Player";
|
import { Player } from "../Player";
|
||||||
import { Settings } from "../Settings/Settings";
|
import { Settings } from "../Settings/Settings";
|
||||||
|
import {
|
||||||
|
getHackingWorkRepGain,
|
||||||
|
getFactionSecurityWorkRepGain,
|
||||||
|
getFactionFieldWorkRepGain,
|
||||||
|
} from "../PersonObjects/formulas/reputation";
|
||||||
|
|
||||||
import { Page, routing } from "../ui/navigationTracking";
|
import { Page, routing } from "../ui/navigationTracking";
|
||||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
@@ -25,6 +30,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 +115,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
|
||||||
@@ -231,15 +240,24 @@ export function getNextNeurofluxLevel() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function processPassiveFactionRepGain(numCycles) {
|
export function processPassiveFactionRepGain(numCycles) {
|
||||||
var numTimesGain = (numCycles / 600) * Player.faction_rep_mult;
|
for (const name in Factions) {
|
||||||
for (var name in Factions) {
|
if (name === Player.currentWorkFactionName) continue;
|
||||||
if (Factions.hasOwnProperty(name)) {
|
if (!Factions.hasOwnProperty(name)) continue;
|
||||||
var faction = Factions[name];
|
const faction = Factions[name];
|
||||||
|
if (!faction.isMember) continue;
|
||||||
|
// 0 favor = 1%/s
|
||||||
|
// 50 favor = 6%/s
|
||||||
|
// 100 favor = 11%/s
|
||||||
|
const favorMult = Math.min(0.1, (faction.favor / 1000) + 0.01);
|
||||||
|
// Find the best of all possible favor gain, minimum 1 rep / 2 minute.
|
||||||
|
const hRep = getHackingWorkRepGain(Player, faction);
|
||||||
|
const sRep = getFactionSecurityWorkRepGain(Player, faction);
|
||||||
|
const fRep = getFactionFieldWorkRepGain(Player, faction);
|
||||||
|
const rate = Math.max(hRep * favorMult, sRep * favorMult, fRep * favorMult, 1/120);
|
||||||
|
|
||||||
//TODO Get hard value of 1 rep per "rep gain cycle"" for now..
|
faction.playerReputation += rate *
|
||||||
//maybe later make this based on
|
(numCycles) *
|
||||||
//a player's 'status' like how powerful they are and how much money they have
|
Player.faction_rep_mult *
|
||||||
if (faction.isMember) {faction.playerReputation += (numTimesGain * BitNodeMultipliers.FactionPassiveRepGain);}
|
BitNodeMultipliers.FactionPassiveRepGain;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,19 +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;
|
||||||
} 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.000a")} faction reputation - ${numeralWrapper.formatMoney(moneyCost)})`;
|
status = <>LOCKED (Requires {Reputation(repCost)} faction reputation - {Money(moneyCost)})</>;
|
||||||
color = "red";
|
color = "red";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,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";
|
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: Server): number {
|
export function calculateHackingChance(server: Server, player: IPlayer): number {
|
||||||
const hackFactor = 1.75;
|
const hackFactor = 1.75;
|
||||||
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||||
const skillMult = hackFactor * Player.hacking_skill;
|
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 * Player.getIntelligenceBonus(1);
|
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: Server): number {
|
|||||||
* 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: Server): number {
|
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;
|
||||||
}
|
}
|
||||||
let 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: Server): number {
|
|||||||
* 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: Server): number {
|
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,19 +56,18 @@ export function calculatePercentMoneyHacked(server: Server): number {
|
|||||||
/**
|
/**
|
||||||
* 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: Server, hack: number): number {
|
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;
|
||||||
if (hack == null) {hack = Player.hacking_skill;}
|
|
||||||
let skillFactor = (diffFactor * difficultyMult + baseDiff);
|
let skillFactor = (diffFactor * difficultyMult + baseDiff);
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
skillFactor /= (hack + baseSkill);
|
skillFactor /= (player.hacking_skill + baseSkill);
|
||||||
|
|
||||||
const hackTimeMultiplier = 5;
|
const hackTimeMultiplier = 5;
|
||||||
const hackingTime = hackTimeMultiplier * skillFactor / (Player.hacking_speed_mult * Player.getIntelligenceBonus(1));
|
const hackingTime = hackTimeMultiplier * skillFactor / (player.hacking_speed_mult * calculateIntelligenceBonus(player.intelligence, 1));
|
||||||
|
|
||||||
return hackingTime;
|
return hackingTime;
|
||||||
}
|
}
|
||||||
@@ -74,17 +75,17 @@ export function calculateHackingTime(server: Server, hack: number): number {
|
|||||||
/**
|
/**
|
||||||
* 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: Server, hack: number): number {
|
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);
|
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: Server, hack: number): number {
|
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);
|
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();
|
||||||
@@ -126,31 +124,33 @@ export class HacknetNode extends React.Component {
|
|||||||
<li className={"hacknet-node"}>
|
<li className={"hacknet-node"}>
|
||||||
<div className={"hacknet-node-container"}>
|
<div className={"hacknet-node-container"}>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Node name:</p>
|
<h1 style={{"fontSize":"1em"}}>{node.name}</h1>
|
||||||
<span className={"text"}>{node.name}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<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();
|
||||||
@@ -165,13 +163,12 @@ export class HacknetServer extends React.Component {
|
|||||||
<li className={"hacknet-node"}>
|
<li className={"hacknet-node"}>
|
||||||
<div className={"hacknet-node-container"}>
|
<div className={"hacknet-node-container"}>
|
||||||
<div className={"row"}>
|
<div className={"row"}>
|
||||||
<p>Node name:</p>
|
<h1 style={{"fontSize":"1em"}}>{node.hostname}</h1>
|
||||||
<span className={"text"}>{node.hostname}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<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 +178,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;
|
||||||
|
}
|
||||||
@@ -11,4 +11,5 @@ export enum LocationType {
|
|||||||
TechVendor,
|
TechVendor,
|
||||||
TravelAgency,
|
TravelAgency,
|
||||||
University,
|
University,
|
||||||
|
Casino,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,14 +47,14 @@ Cities[CityName.Aevum].asciiArt = `
|
|||||||
\\ 56 B
|
\\ 56 B
|
||||||
x \\ [summit university]
|
x \\ [summit university]
|
||||||
\\ \\ 28
|
\\ \\ 28
|
||||||
\\ [snap fitness gym] x o--L------------
|
\\ [snap fitness gym] x o--L-----------N
|
||||||
K \\ /
|
K \\ /
|
||||||
\\ \\ P
|
\\ \\ Q [casino]
|
||||||
x 58 \\ / [travel agency]
|
x 58 \\ / [travel agency]
|
||||||
\\ 94 95 o
|
\\ 94 95 o
|
||||||
90 x 59 o------o |
|
90 x 59 o------o |
|
||||||
\\ / \\ | 98 102 103
|
\\ / \\ | 98 102 103
|
||||||
o--------N------x----o 93 96 o-----+------------o o----o
|
o--------O------x----o 93 96 o-----+------------o o----o
|
||||||
\\ | \\ /
|
\\ | \\ /
|
||||||
[hospital] \\ 61 [ecorp] x 31 99 o-F-o 101
|
[hospital] \\ 61 [ecorp] x 31 99 o-F-o 101
|
||||||
o |
|
o |
|
||||||
@@ -69,13 +69,13 @@ Cities[CityName.Aevum].asciiArt = `
|
|||||||
| 34 x \\
|
| 34 x \\
|
||||||
[clarke inc.] C | \\ [world stock exchange]
|
[clarke inc.] C | \\ [world stock exchange]
|
||||||
| | \\
|
| | \\
|
||||||
| | o-M-------Q--------o
|
| | o-M-------R--------o
|
||||||
[galactic cybersystems] G 35 x
|
[galactic cybersystems] G 35 x
|
||||||
| [watchdog security]
|
| [watchdog security]
|
||||||
|
|
|
|
||||||
67 o
|
67 o
|
||||||
|
|
||||||
[the slums] O `
|
[the slums] P `
|
||||||
Cities[CityName.Chongqing].asciiArt = `
|
Cities[CityName.Chongqing].asciiArt = `
|
||||||
|
|
|
|
||||||
75 o
|
75 o
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { SpecialServerIps } from "../Server/SpecialServerIps";
|
|||||||
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 { dialogBoxCreate } from "../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||||
import {
|
import {
|
||||||
@@ -38,6 +39,7 @@ import { createElement } from "../../utils/uiHelpers/createElement";
|
|||||||
import { createPopup } from "../../utils/uiHelpers/createPopup";
|
import { createPopup } from "../../utils/uiHelpers/createPopup";
|
||||||
import { createPopupCloseButton } from "../../utils/uiHelpers/createPopupCloseButton";
|
import { createPopupCloseButton } from "../../utils/uiHelpers/createPopupCloseButton";
|
||||||
import { removeElementById } from "../../utils/uiHelpers/removeElementById";
|
import { removeElementById } from "../../utils/uiHelpers/removeElementById";
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a pop-up box that lets the player confirm traveling to a different city.
|
* Create a pop-up box that lets the player confirm traveling to a different city.
|
||||||
@@ -49,7 +51,7 @@ import { removeElementById } from "../../utils/uiHelpers/removeElementById";
|
|||||||
*/
|
*/
|
||||||
type TravelFunction = (to: CityName) => void;
|
type TravelFunction = (to: CityName) => void;
|
||||||
export function createTravelPopup(destination: CityName, travelFn: TravelFunction): void {
|
export function createTravelPopup(destination: CityName, travelFn: TravelFunction): void {
|
||||||
const cost = CONSTANTS.TravelCost;
|
const cost: number = CONSTANTS.TravelCost;
|
||||||
|
|
||||||
if (Settings.SuppressTravelConfirmation) {
|
if (Settings.SuppressTravelConfirmation) {
|
||||||
travelFn(destination);
|
travelFn(destination);
|
||||||
@@ -76,8 +78,8 @@ export function createTravelPopup(destination: CityName, travelFn: TravelFunctio
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
yesNoBoxCreate(`Would you like to travel to ${destination}? The trip will ` +
|
yesNoBoxCreate(<span>Would you like to travel to ${destination}? The trip will
|
||||||
`cost ${numeralWrapper.formatMoney(cost)}`);
|
cost {Money(cost)}.</span>);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,10 +107,9 @@ export function createPurchaseServerPopup(ram: number, p: IPlayer): void {
|
|||||||
yesNoTxtInpBoxClose();
|
yesNoTxtInpBoxClose();
|
||||||
});
|
});
|
||||||
|
|
||||||
yesNoTxtInpBoxCreate(
|
yesNoTxtInpBoxCreate(<>Would you like to purchase a new server with {numeralWrapper.formatRAM(ram)} of RAM for {Money(cost)}?
|
||||||
`Would you like to purchase a new server with ${ram} GB of RAM for ` +
|
<br /><br />Please enter the server hostname below:<br />
|
||||||
`${numeralWrapper.formatMoney(cost)}?<br><br>Please enter the server hostname below:<br>`
|
</>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,7 +198,12 @@ export function createStartCorporationPopup(p: IPlayer) {
|
|||||||
*/
|
*/
|
||||||
export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
||||||
const currentCores = p.getHomeComputer().cpuCores;
|
const currentCores = p.getHomeComputer().cpuCores;
|
||||||
if (currentCores >= 8) { return; } // Max of 8 cores
|
if (currentCores >= 8) {
|
||||||
|
dialogBoxCreate(<>
|
||||||
|
You've have the maximum amount of CPU cores on your home computer.
|
||||||
|
</>);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Cost of purchasing another cost is found by indexing this array with number of current cores
|
// Cost of purchasing another cost is found by indexing this array with number of current cores
|
||||||
const allCosts = [
|
const allCosts = [
|
||||||
@@ -236,12 +242,10 @@ export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
|||||||
yesNoBoxClose();
|
yesNoBoxClose();
|
||||||
});
|
});
|
||||||
|
|
||||||
yesNoBoxCreate(
|
yesNoBoxCreate(<>Would you like to purchase an additional CPU Core for your home computer? Each CPU Core
|
||||||
"Would you like to purchase an additional CPU Core for your home computer? Each CPU Core " +
|
lets you start with an additional Core Node in Hacking Missions.<br /><br />
|
||||||
"lets you start with an additional Core Node in Hacking Missions.<br><br>" +
|
Purchasing an additional core (for a total of {p.getHomeComputer().cpuCores + 1}) will
|
||||||
"Purchasing an additional core (for a total of " + (p.getHomeComputer().cpuCores + 1) + ") will " +
|
cost {Money(cost)}</>);
|
||||||
"cost " + numeralWrapper.formatMoney(cost)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -256,6 +260,14 @@ export function createUpgradeHomeRamPopup(p: IPlayer) {
|
|||||||
const noBtn = yesNoBoxGetNoButton();
|
const noBtn = yesNoBoxGetNoButton();
|
||||||
if (yesBtn == null || noBtn == null) { return; }
|
if (yesBtn == null || noBtn == null) { return; }
|
||||||
|
|
||||||
|
const homeComputer = p.getHomeComputer();
|
||||||
|
if (homeComputer.maxRam >= CONSTANTS.HomeComputerMaxRam) {
|
||||||
|
dialogBoxCreate(<>
|
||||||
|
You've have the maximum amount of RAM on your home computer.
|
||||||
|
</>);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
yesBtn.innerText = "Purchase";
|
yesBtn.innerText = "Purchase";
|
||||||
yesBtn.addEventListener("click", ()=>{
|
yesBtn.addEventListener("click", ()=>{
|
||||||
purchaseRamForHomeComputer(cost, p);
|
purchaseRamForHomeComputer(cost, p);
|
||||||
@@ -267,11 +279,11 @@ export function createUpgradeHomeRamPopup(p: IPlayer) {
|
|||||||
yesNoBoxClose();
|
yesNoBoxClose();
|
||||||
});
|
});
|
||||||
|
|
||||||
yesNoBoxCreate(
|
yesNoBoxCreate(<>
|
||||||
"Would you like to purchase additional RAM for your home computer? <br><br>" +
|
Would you like to purchase additional RAM for your home computer? <br /><br />
|
||||||
"This will upgrade your RAM from " + ram + "GB to " + ram*2 + "GB. <br><br>" +
|
This will upgrade your RAM from {numeralWrapper.formatRAM(ram)} to {numeralWrapper.formatRAM(ram*2)}. <br /><br />
|
||||||
"This will cost " + numeralWrapper.format(cost, '$0.000a')
|
This will cost {Money(cost)}
|
||||||
);
|
</>);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@ export enum LocationName {
|
|||||||
AevumSnapFitnessGym = "Snap Fitness Gym",
|
AevumSnapFitnessGym = "Snap Fitness Gym",
|
||||||
AevumSummitUniversity = "Summit University",
|
AevumSummitUniversity = "Summit University",
|
||||||
AevumWatchdogSecurity = "Watchdog Security",
|
AevumWatchdogSecurity = "Watchdog Security",
|
||||||
|
AevumCasino = "Iker Molina Casino",
|
||||||
|
|
||||||
// Chongqing locations
|
// Chongqing locations
|
||||||
ChongqingKuaiGongInternational = "KuaiGong International",
|
ChongqingKuaiGongInternational = "KuaiGong International",
|
||||||
|
|||||||
@@ -145,6 +145,11 @@ export const LocationsMetadata: IConstructorParams[] = [
|
|||||||
name: LocationName.AevumWatchdogSecurity,
|
name: LocationName.AevumWatchdogSecurity,
|
||||||
types: [LocationType.Company],
|
types: [LocationType.Company],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
city: CityName.Aevum,
|
||||||
|
name: LocationName.AevumCasino,
|
||||||
|
types: [LocationType.Casino],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
city: CityName.Chongqing,
|
city: CityName.Chongqing,
|
||||||
infiltrationData: {
|
infiltrationData: {
|
||||||
|
|||||||
89
src/Locations/ui/CasinoLocation.tsx
Normal file
89
src/Locations/ui/CasinoLocation.tsx
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/**
|
||||||
|
* React Subcomponent for displaying a location's UI, when that location is a gym
|
||||||
|
*
|
||||||
|
* This subcomponent renders all of the buttons for training at the gym
|
||||||
|
*/
|
||||||
|
import * as React from "react";
|
||||||
|
|
||||||
|
import { Location } from "../Location";
|
||||||
|
|
||||||
|
import { CONSTANTS } from "../../Constants";
|
||||||
|
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||||
|
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
import { SlotMachine } from "../../Casino/SlotMachine";
|
||||||
|
import { CoinFlip } from "../../Casino/CoinFlip";
|
||||||
|
import { Roulette } from "../../Casino/Roulette";
|
||||||
|
|
||||||
|
type IProps = {
|
||||||
|
p: IPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
type IState = {
|
||||||
|
game: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CasinoLocation extends React.Component<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
game: '',
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateGame = this.updateGame.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGame(game: string) {
|
||||||
|
this.setState({
|
||||||
|
game: game,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderGames() {
|
||||||
|
return (<>
|
||||||
|
<StdButton
|
||||||
|
onClick={() => this.updateGame('coin')}
|
||||||
|
text={"Play coin flip"}
|
||||||
|
/><br />
|
||||||
|
<StdButton
|
||||||
|
onClick={() => this.updateGame('slots')}
|
||||||
|
text={"Play slots"}
|
||||||
|
/><br />
|
||||||
|
<StdButton
|
||||||
|
onClick={() => this.updateGame('roulette')}
|
||||||
|
text={"Play roulette"}
|
||||||
|
/>
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderGame() {
|
||||||
|
let elem;
|
||||||
|
switch(this.state.game) {
|
||||||
|
case 'coin':
|
||||||
|
elem = <CoinFlip p={this.props.p} />
|
||||||
|
break;
|
||||||
|
case 'slots':
|
||||||
|
elem = <SlotMachine p={this.props.p} />
|
||||||
|
break;
|
||||||
|
case 'roulette':
|
||||||
|
elem = <Roulette p={this.props.p} />
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<StdButton onClick={() => this.updateGame('')} text={"Stop playing"} />
|
||||||
|
{elem}
|
||||||
|
</>)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if(!this.state.game) {
|
||||||
|
return this.renderGames();
|
||||||
|
} else {
|
||||||
|
return this.renderGame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import * as React from "react";
|
|||||||
|
|
||||||
import { City } from "../City";
|
import { City } from "../City";
|
||||||
import { LocationName } from "../data/LocationNames";
|
import { LocationName } from "../data/LocationNames";
|
||||||
|
import { Settings } from "../../Settings/Settings";
|
||||||
|
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
|
||||||
@@ -16,7 +17,7 @@ type IProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class LocationCity extends React.Component<IProps, any> {
|
export class LocationCity extends React.Component<IProps, any> {
|
||||||
render() {
|
asciiCity() {
|
||||||
const thiscity = this;
|
const thiscity = this;
|
||||||
const topprop = this.props
|
const topprop = this.props
|
||||||
|
|
||||||
@@ -66,9 +67,29 @@ export class LocationCity extends React.Component<IProps, any> {
|
|||||||
elems.push(<pre key={i}>{lineElems(lines[i])}</pre>)
|
elems.push(<pre key={i}>{lineElems(lines[i])}</pre>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return elems;
|
||||||
|
}
|
||||||
|
|
||||||
|
listCity() {
|
||||||
|
const locationButtons = this.props.city.locations.map((locName) => {
|
||||||
|
return (
|
||||||
|
<li key={locName}>
|
||||||
|
<StdButton onClick={this.props.enterLocation.bind(this, locName)} text={locName} />
|
||||||
|
</li>
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ul>
|
||||||
|
{locationButtons}
|
||||||
|
</ul>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{elems}
|
{Settings.DisableASCIIArt ? this.listCity() : this.asciiCity()}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
|||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
import { Reputation } from "../../ui/React/Reputation";
|
||||||
|
import { Favor } from "../../ui/React/Favor";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
engine: IEngine;
|
engine: IEngine;
|
||||||
@@ -34,6 +36,10 @@ type IState = {
|
|||||||
employedHere: boolean;
|
employedHere: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const blockStyleMarkup = {
|
||||||
|
display: "block",
|
||||||
|
}
|
||||||
|
|
||||||
export class CompanyLocation extends React.Component<IProps, IState> {
|
export class CompanyLocation extends React.Component<IProps, IState> {
|
||||||
/**
|
/**
|
||||||
* We'll keep a reference to the Company that this component is being rendered for,
|
* We'll keep a reference to the Company that this component is being rendered for,
|
||||||
@@ -211,23 +217,24 @@ export class CompanyLocation extends React.Component<IProps, IState> {
|
|||||||
isEmployedHere &&
|
isEmployedHere &&
|
||||||
<div>
|
<div>
|
||||||
<p>Job Title: {this.jobTitle}</p>
|
<p>Job Title: {this.jobTitle}</p>
|
||||||
<p>--------------------</p>
|
<br /><p style={blockStyleMarkup}>-------------------------</p><br />
|
||||||
<p className={"tooltip"}>
|
<p className={"tooltip"}>
|
||||||
Company reputation: {numeralWrapper.format(this.company.playerReputation, "0,0.000")}
|
Company reputation: {Reputation(this.company.playerReputation)}
|
||||||
<span className={"tooltiptext"}>
|
<span className={"tooltiptext"}>
|
||||||
You will earn {numeralWrapper.format(favorGain[0], "0,0")} company
|
You will earn {Favor(favorGain[0])} company
|
||||||
favor upon resetting after installing Augmentations
|
favor upon resetting after installing Augmentations
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p><br />
|
||||||
<p>--------------------</p>
|
<br /><p style={blockStyleMarkup}>-------------------------</p><br />
|
||||||
<p className={"tooltip"}>
|
<p className={"tooltip"}>
|
||||||
Company Favor: {numeralWrapper.format(this.company.favor, "0,0")}
|
Company Favor: {Favor(this.company.favor)}
|
||||||
<span className={"tooltiptext"}>
|
<span className={"tooltiptext"}>
|
||||||
Company favor increases the rate at which you earn reputation for this company by
|
Company favor increases the rate at which you earn reputation for this company by
|
||||||
1% per favor. Company favor is gained whenever you reset after installing Augmentations. The amount
|
1% per favor. Company favor is gained whenever you reset after installing Augmentations. The amount
|
||||||
of favor you gain depends on how much reputation you have with the comapny.
|
of favor you gain depends on how much reputation you have with the comapny.
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p><br />
|
||||||
|
<br /><p style={blockStyleMarkup}>-------------------------</p><br />
|
||||||
<StdButton
|
<StdButton
|
||||||
id={"foo-work-button-id"}
|
id={"foo-work-button-id"}
|
||||||
onClick={this.work}
|
onClick={this.work}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { SpecialLocation } from "./SpecialLocation";
|
|||||||
import { TechVendorLocation } from "./TechVendorLocation";
|
import { TechVendorLocation } from "./TechVendorLocation";
|
||||||
import { TravelAgencyLocation } from "./TravelAgencyLocation";
|
import { TravelAgencyLocation } from "./TravelAgencyLocation";
|
||||||
import { UniversityLocation } from "./UniversityLocation";
|
import { UniversityLocation } from "./UniversityLocation";
|
||||||
|
import { CasinoLocation } from "./CasinoLocation";
|
||||||
|
|
||||||
import { Location } from "../Location";
|
import { Location } from "../Location";
|
||||||
import { LocationType } from "../LocationTypeEnum";
|
import { LocationType } from "../LocationTypeEnum";
|
||||||
@@ -131,6 +132,15 @@ export class GenericLocation extends React.Component<IProps, any> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.loc.types.includes(LocationType.Casino)) {
|
||||||
|
content.push(
|
||||||
|
<CasinoLocation
|
||||||
|
key={"casinoLocation"}
|
||||||
|
p={this.props.p}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
|||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { StdButton } from "../../ui/React/StdButton";
|
import { StdButton } from "../../ui/React/StdButton";
|
||||||
|
import { Money } from "../../ui/React/Money";
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {
|
||||||
loc: Location;
|
loc: Location;
|
||||||
@@ -66,22 +67,22 @@ export class GymLocation extends React.Component<IProps, any> {
|
|||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.trainStrength}
|
onClick={this.trainStrength}
|
||||||
style={this.btnStyle}
|
style={this.btnStyle}
|
||||||
text={`Train Strength (${numeralWrapper.formatMoney(cost)} / sec)`}
|
text={<>Train Strength ({Money(cost)} / sec)</>}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.trainDefense}
|
onClick={this.trainDefense}
|
||||||
style={this.btnStyle}
|
style={this.btnStyle}
|
||||||
text={`Train Defense (${numeralWrapper.formatMoney(cost)} / sec)`}
|
text={<>Train Defense ({Money(cost)} / sec)</>}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.trainDexterity}
|
onClick={this.trainDexterity}
|
||||||
style={this.btnStyle}
|
style={this.btnStyle}
|
||||||
text={`Train Dexterity (${numeralWrapper.formatMoney(cost)} / sec)`}
|
text={<>Train Dexterity ({Money(cost)} / sec)</>}
|
||||||
/>
|
/>
|
||||||
<StdButton
|
<StdButton
|
||||||
onClick={this.trainAgility}
|
onClick={this.trainAgility}
|
||||||
style={this.btnStyle}
|
style={this.btnStyle}
|
||||||
text={`Train Agility (${numeralWrapper.formatMoney(cost)} / sec)`}
|
text={<>Train Agility ({Money(cost)} / sec)</>}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user