mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-09 09:13:52 +01:00
v0.51.0 (#826)
* Hash upgrades and Bladeburner skills can now be clicked to copy to clipboard * Aug purchase confirmation popup displays money in 0.000a format * Character now displays hacknet server info properly * Character,Info now displays hacknet server info correctly. * Formulas (#825) Formulas API v0.1 * Make all money the same color, same for reputation, format all numbers consistently. * rename a lot of the formulas function to no longer contain calculate * added hacking related formulas * removed unused variable * v0.51.0
This commit is contained in:
parent
ff097db1e2
commit
e572c6dad8
@ -356,10 +356,27 @@ a:visited {
|
||||
color: $my-stat-cha-color;
|
||||
}
|
||||
|
||||
.reputation {
|
||||
color: $light-yellow;
|
||||
}
|
||||
|
||||
.smallfont {
|
||||
font-size: $defaultFontSize * 0.8125;
|
||||
}
|
||||
|
||||
.samefont {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.noscrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
.noscrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10);
|
||||
}
|
||||
@ -395,4 +412,12 @@ input[type=checkbox] {
|
||||
height: 10px;
|
||||
background: var(--my-font-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.noselect {
|
||||
-moz-user-select: -moz-none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
@ -85,3 +85,45 @@
|
||||
.tooltip:hover .tooltiptextlow {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.copy_tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.copy_tooltip_copied {
|
||||
color: #fff;
|
||||
transition: color 0.3s;
|
||||
}
|
||||
|
||||
.copy_tooltip .copy_tooltip_text {
|
||||
visibility: hidden;
|
||||
font-size: 15px;
|
||||
padding: 5px;
|
||||
background-color: var(--my-background-color);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 120%;
|
||||
left: 5%;
|
||||
opacity: 0;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
}
|
||||
|
||||
.copy_tooltip .copy_tooltip_text::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
border-width: 8px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent white transparent;
|
||||
}
|
||||
|
||||
.copy_tooltip .copy_tooltip_text_visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s;
|
||||
}
|
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([395,0]),o()}({338:function(n,t,o){},340:function(n,t,o){},342:function(n,t,o){},344:function(n,t,o){},346:function(n,t,o){},348:function(n,t,o){},350:function(n,t,o){},352:function(n,t,o){},354:function(n,t,o){},356:function(n,t,o){},358:function(n,t,o){},360:function(n,t,o){},362:function(n,t,o){},364:function(n,t,o){},366:function(n,t,o){},368:function(n,t,o){},370:function(n,t,o){},372:function(n,t,o){},374:function(n,t,o){},376:function(n,t,o){},378:function(n,t,o){},380:function(n,t,o){},382:function(n,t,o){},384:function(n,t,o){},386:function(n,t,o){},388:function(n,t,o){},390:function(n,t,o){},392:function(n,t,o){},395:function(n,t,o){"use strict";o.r(t);o(394),o(392),o(390),o(388),o(386),o(384),o(382),o(380),o(378),o(376),o(374),o(372),o(370),o(368),o(366),o(364),o(362),o(360),o(358),o(356),o(354),o(352),o(350),o(348),o(346),o(344),o(342),o(340),o(338)}});
|
||||
//# sourceMappingURL=engineStyle.bundle.js.map
|
59
dist/engineStyle.css
vendored
59
dist/engineStyle.css
vendored
@ -353,9 +353,24 @@ a:visited {
|
||||
.charisma-purple {
|
||||
color: #a671d1; }
|
||||
|
||||
.reputation {
|
||||
color: #faffdf; }
|
||||
|
||||
.smallfont {
|
||||
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] {
|
||||
filter: invert(1) sepia(1) hue-rotate(41deg) brightness(100%) saturate(10); }
|
||||
|
||||
@ -387,6 +402,13 @@ input[type=checkbox] {
|
||||
background: var(--my-font-color);
|
||||
cursor: pointer; }
|
||||
|
||||
.noselect {
|
||||
-moz-user-select: -moz-none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
/* Styling for tooltip-style elements */
|
||||
@ -460,6 +482,43 @@ input[type=checkbox] {
|
||||
.tooltip:hover .tooltiptextlow {
|
||||
visibility: visible; }
|
||||
|
||||
.copy_tooltip {
|
||||
position: relative;
|
||||
display: inline-block; }
|
||||
|
||||
.copy_tooltip_copied {
|
||||
color: #fff;
|
||||
transition: color 0.3s; }
|
||||
|
||||
.copy_tooltip .copy_tooltip_text {
|
||||
visibility: hidden;
|
||||
font-size: 15px;
|
||||
padding: 5px;
|
||||
background-color: var(--my-background-color);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 120%;
|
||||
left: 5%;
|
||||
opacity: 0;
|
||||
border: 2px solid var(--my-highlight-color); }
|
||||
|
||||
.copy_tooltip .copy_tooltip_text::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
border-width: 8px;
|
||||
border-style: solid;
|
||||
border-color: transparent transparent white transparent; }
|
||||
|
||||
.copy_tooltip .copy_tooltip_text_visible {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity 0.3s; }
|
||||
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
/**
|
||||
|
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,31 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
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)
|
||||
--------------------------------------------------------------
|
||||
|
||||
|
@ -64,9 +64,9 @@ documentation_title = '{0} Documentation'.format(project)
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.50'
|
||||
version = '0.51'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.50.2'
|
||||
release = '0.51.0'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -30,4 +30,5 @@ to reach out to the developer!
|
||||
Gang API <netscript/netscriptgangapi>
|
||||
Coding Contract API <netscript/netscriptcodingcontractapi>
|
||||
Sleeve API <netscript/netscriptsleeveapi>
|
||||
Formulas API <netscript/netscriptformulasapi>
|
||||
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
|
||||
}
|
22
doc/source/netscript/formulasapi/basic/calculateExp.rst
Normal file
22
doc/source/netscript/formulasapi/basic/calculateExp.rst
Normal file
@ -0,0 +1,22 @@
|
||||
calculateExp() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: calculateExp(skillLevel[, mult])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number skillLevel: ``skillLevel`` to convert to exp.
|
||||
:param number mult: Assume a specific skill multipler.
|
||||
:returns: number of exp required to reach given ``skillLevel`` with that multiplier.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the amount of experience needed to reach level the given ``skillLevel``.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
nextHacking = getStats().hacking+1;
|
||||
nextExp = formulas.basic.calculateExp(nextHacking);
|
||||
missingExp = nextExp - getCharacterInformation().hackingExp;
|
||||
tprint("Missing " + missingExp + " to reach next hacking level");
|
20
doc/source/netscript/formulasapi/basic/calculateSkill.rst
Normal file
20
doc/source/netscript/formulasapi/basic/calculateSkill.rst
Normal file
@ -0,0 +1,20 @@
|
||||
calculateSkill() Netscript Function
|
||||
===================================
|
||||
|
||||
.. js:function:: calculateSkill(exp[, mult])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number exp: ``exp`` to convert to skillLevel.
|
||||
:param number mult: Assume a specific skill multipler.
|
||||
:returns: skillLevel that ``exp`` would reach with that multiplier.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the skillLevel that the given amount of ``exp`` would reach.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
skillLevel = formulas.basic.calculateSkill(1000);
|
||||
tprint("1000 exp would reach level " + skillLevel);
|
23
doc/source/netscript/formulasapi/basic/growPercent.rst
Normal file
23
doc/source/netscript/formulasapi/basic/growPercent.rst
Normal file
@ -0,0 +1,23 @@
|
||||
growPercent() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: growPercent(server, threads, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server that receives the growth.
|
||||
:param number threads: The number of thread that would be used.
|
||||
:param player player: The player.
|
||||
:returns: The percentage growth this server would receive with these parameters.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates percentage of growth a server would receive with these parameters.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
tprint(growPercent(getServer(), 50, getPlayer()))
|
24
doc/source/netscript/formulasapi/basic/growTime.rst
Normal file
24
doc/source/netscript/formulasapi/basic/growTime.rst
Normal file
@ -0,0 +1,24 @@
|
||||
growTime() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: growTime(server, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server to grow.
|
||||
:param player player: The player.
|
||||
:returns: The time it takes to grow this server. In seconds.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates the amount of time it takes to grow a server.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = getServer();
|
||||
server.hackDifficulty = server.minDifficulty;
|
||||
tprint(growTime(server, getPlayer()));
|
24
doc/source/netscript/formulasapi/basic/hackChance.rst
Normal file
24
doc/source/netscript/formulasapi/basic/hackChance.rst
Normal file
@ -0,0 +1,24 @@
|
||||
hackChance() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: hackChance(server, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server to hack.
|
||||
:param player player: The player.
|
||||
:returns: The change to hack that server. between 0 and 1.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates percentage chance to hack a server.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = getServer();
|
||||
server.hackDifficulty = server.minDifficulty;
|
||||
tprint(hackChance(server, getPlayer()));
|
24
doc/source/netscript/formulasapi/basic/hackExp.rst
Normal file
24
doc/source/netscript/formulasapi/basic/hackExp.rst
Normal file
@ -0,0 +1,24 @@
|
||||
hackExp() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: hackExp(server, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server to hack.
|
||||
:param player player: The player.
|
||||
:returns: The amount of exp that would be acquired if this server were to be hacked.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates the amount of exp obtained by hacking a server.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = getServer();
|
||||
server.hackDifficulty = 99.9;
|
||||
tprint(hackExp(server, getPlayer()));
|
25
doc/source/netscript/formulasapi/basic/hackPercent.rst
Normal file
25
doc/source/netscript/formulasapi/basic/hackPercent.rst
Normal file
@ -0,0 +1,25 @@
|
||||
hackPercent() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: hackPercent(server, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server to hack.
|
||||
:param player player: The player.
|
||||
:returns: The percentage of money hacked from a servers maximum money.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates the percentage of maximum money hacked from a server.
|
||||
Multiply this by thread count to know calculate the percentage for more than 1 thread.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = getServer();
|
||||
server.hackDifficulty = server.minDifficulty;
|
||||
tprint(hackPercent(server, getPlayer()));
|
24
doc/source/netscript/formulasapi/basic/hackTime.rst
Normal file
24
doc/source/netscript/formulasapi/basic/hackTime.rst
Normal file
@ -0,0 +1,24 @@
|
||||
hackTime() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: hackTime(server, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server to hack.
|
||||
:param player player: The player.
|
||||
:returns: The time it takes to hack this server. In seconds.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates the amount of time it takes to hack a server.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = getServer();
|
||||
server.hackDifficulty = server.minDifficulty;
|
||||
tprint(hackTime(server, getPlayer()));
|
24
doc/source/netscript/formulasapi/basic/weakenTime.rst
Normal file
24
doc/source/netscript/formulasapi/basic/weakenTime.rst
Normal file
@ -0,0 +1,24 @@
|
||||
weakenTime() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: weakenTime(server, player)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param server server: The server to weaken.
|
||||
:param player player: The player.
|
||||
:returns: The time it takes to weaken this server. In seconds.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
Server can be acquired with the :doc:`getServer<../../advancedfunctions/getServer>` function.
|
||||
Player can be acquired with the :doc:`getPlayer<../../singularityfunctions/getPlayer>` function.
|
||||
|
||||
This function calculates the amount of time it takes to weaken a server.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = getServer();
|
||||
server.hackDifficulty = server.minDifficulty;
|
||||
tprint(weakenTime(server, getPlayer()));
|
26
doc/source/netscript/formulasapi/hacknetNodes/constants.rst
Normal file
26
doc/source/netscript/formulasapi/hacknetNodes/constants.rst
Normal file
@ -0,0 +1,26 @@
|
||||
constants() Netscript Function
|
||||
==============================
|
||||
|
||||
.. js:function:: constants()
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:returns: A structure with various constants related to hacknet nodes.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
MoneyGainPerLevel
|
||||
BaseCost
|
||||
LevelBaseCost
|
||||
RamBaseCost
|
||||
CoreBaseCost
|
||||
PurchaseNextMult
|
||||
UpgradeLevelMult
|
||||
UpgradeRamMult
|
||||
UpgradeCoreMult
|
||||
MaxLevel
|
||||
MaxRam
|
||||
MaxCores
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
coreUpgradeCost() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: coreUpgradeCost(startingCores[, extraCores[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingCores: Number of core at the start the calculation.
|
||||
:param number extraCores: Extra number of cores you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingCores`` to ``startingCores+extraCores``.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading cores from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetNodes.coreUpgradeCost(1, 5); // returns: 6355000
|
@ -0,0 +1,19 @@
|
||||
hacknetNodeCost() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: hacknetNodeCost(nodeN[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number nodeN: Number of the new node.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to buy your ``nodeN`` th node.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the cost purchasing a hacknet node.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetNodes.hacknetNodeCost(2); // returns: 1800
|
@ -0,0 +1,20 @@
|
||||
levelUpgradeCost() Netscript Function
|
||||
==============================================
|
||||
|
||||
.. js:function:: levelUpgradeCost(startingLevel[, extraLevels[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingLevel: Number of level at the start the calculation.
|
||||
:param number extraLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingLevel`` to ``startingLevel+extraLevels``.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading levels from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetNodes.levelUpgradeCost(1, 5); // returns: 2816
|
@ -0,0 +1,24 @@
|
||||
moneyGainRate() Netscript Function
|
||||
===========================================
|
||||
|
||||
.. js:function:: moneyGainRate(level, ram, core[, mult])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number level: level of the node.
|
||||
:param number ram: ram of the node.
|
||||
:param number core: cores of the node.
|
||||
:returns: Money per second that a node with those stats would gain per second.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the money rate of a node with the given stats.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
node = hacknet.getNodeStats(1);
|
||||
currentRate = formulas.hacknetNodes.moneyGainRate(node.level, node.ram, node.cores);
|
||||
levelRate = formulas.hacknetNodes.moneyGainRate(node.level+1, node.ram, node.cores);
|
||||
ramRate = formulas.hacknetNodes.moneyGainRate(node.level, node.ram*2, node.cores);
|
||||
coresRate = formulas.hacknetNodes.moneyGainRate(node.level, node.ram, node.cores+1);
|
@ -0,0 +1,22 @@
|
||||
ramUpgradeCost() Netscript Function
|
||||
============================================
|
||||
|
||||
.. js:function:: ramUpgradeCost(startingRam[, extraRamLevels[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingRam: Amount of RAM at the start the calculation.
|
||||
:param number extraRamLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingRam`` to ``startingRam+extraRamLevels``.
|
||||
|
||||
..note:: ``startingRam`` is the actual amount of ram, not the amount of levels of ram.
|
||||
|
||||
You must have Source-File 5-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading levels from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetNodes.ramUpgradeCost(1, 5); // returns: 2095000
|
@ -0,0 +1,20 @@
|
||||
cacheUpgradeCost() Netscript Function
|
||||
==============================================
|
||||
|
||||
.. js:function:: cacheUpgradeCost(startingCache[, extraCacheLevels[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingCache: Cache level at the start the calculation.
|
||||
:param number extraCacheLevels: Extra number of cache level you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingLevel`` to ``startingLevel+extraLevels``.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading cache from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetServers.cacheUpgradeCost(1, 5); // returns: 243170000
|
@ -0,0 +1,29 @@
|
||||
constants() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: constants()
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:returns: A structure with various constants related to hacknet servers.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
{
|
||||
HashesPerLevel
|
||||
BaseCost
|
||||
RamBaseCost
|
||||
CoreBaseCost
|
||||
CacheBaseCost
|
||||
PurchaseMult
|
||||
UpgradeLevelMult
|
||||
UpgradeRamMult
|
||||
UpgradeCoreMult
|
||||
UpgradeCacheMult
|
||||
MaxServers
|
||||
MaxLevel
|
||||
MaxRam
|
||||
MaxCores
|
||||
MaxCache
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
coreUpgradeCost() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: coreUpgradeCost(startingCores[, extraCores[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingCores: Number of core at the start the calculation.
|
||||
:param number extraCores: Extra number of cores you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingCores`` to ``startingCores+extraCores``.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading cores from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetServers.coreUpgradeCost(1, 5); // returns: 12015000
|
@ -0,0 +1,19 @@
|
||||
hacknetServerCost() Netscript Function
|
||||
===============================================
|
||||
|
||||
.. js:function:: hacknetServerCost(serverN[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number serverN: Number of the new node.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to buy your ``serverN`` th node.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates the cost purchasing a hacknet node.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetNodes.hacknetServerCost(2); // returns: 1800000
|
@ -0,0 +1,24 @@
|
||||
hashGainRate() Netscript Function
|
||||
==========================================
|
||||
|
||||
.. js:function:: hashGainRate(level, ram, core[, mult])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number level: level of the server.
|
||||
:param number ram: ram of the server.
|
||||
:param number core: cores of the server.
|
||||
:returns: Money per second that a server with those stats would gain per second.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates the hash rate of a server with the given stats.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
server = hacknet.getNodeStats(1);
|
||||
currentRate = formulas.hacknetNodes.hashGainRate(server.level, server.ram, server.cores);
|
||||
levelRate = formulas.hacknetNodes.hashGainRate(server.level+1, server.ram, server.cores);
|
||||
ramRate = formulas.hacknetNodes.hashGainRate(server.level, server.ram*2, server.cores);
|
||||
coresRate = formulas.hacknetNodes.hashGainRate(server.level, server.ram, server.cores+1);
|
@ -0,0 +1,19 @@
|
||||
hashUpgradeCost() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: hashUpgradeCost(upgName, level)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param string upgName: Name of the Hash upgrade.
|
||||
:param number level: Level of the upgrade.
|
||||
:returns: Amount of Hash.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates amount of Hash require to buy level ``level`` of upgrade ``upgName``.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetServers.hashUpgradeCost("Increase Maximum Money", 5); // returns: 250
|
@ -0,0 +1,20 @@
|
||||
levelUpgradeCost() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: levelUpgradeCost(startingLevel[, extraLevels[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingLevel: Number of level at the start the calculation.
|
||||
:param number extraLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingLevel`` to ``startingLevel+extraLevels``.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading levels from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetServers.levelUpgradeCost(1, 5); // returns: 2792000
|
@ -0,0 +1,22 @@
|
||||
ramUpgradeCost() Netscript Function
|
||||
=============================================
|
||||
|
||||
.. js:function:: ramUpgradeCost(startingRam[, extraRamLevels[, costMult]])
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param number startingRam: Amount of RAM at the start the calculation.
|
||||
:param number extraRamLevels: Extra number of levels you want to buy. Default to ``1``.
|
||||
:param number costMult: Aug multiplier that reduces cost. Defaults to ``1``.
|
||||
:returns: Money required to go from ``startingRam`` to ``startingRam+extraRamLevels``.
|
||||
|
||||
..note:: ``startingRam`` is the actual amount of ram, not the amount of levels of ram.
|
||||
|
||||
You must have Source-File 5-1 and Source-File 9-1 in order to use this function.
|
||||
|
||||
This function calculates the cost of upgrading levels from any level to any level.
|
||||
|
||||
Examples:
|
||||
|
||||
.. code-block:: javascript
|
||||
|
||||
formulas.hacknetServers.ramUpgradeCost(1, 5); // returns: 15810000
|
18
doc/source/netscript/hacknetnodeapi/getHashUpgradeLevel.rst
Normal file
18
doc/source/netscript/hacknetnodeapi/getHashUpgradeLevel.rst
Normal file
@ -0,0 +1,18 @@
|
||||
getHashUpgradeLevel() Netscript Function
|
||||
========================================
|
||||
|
||||
.. js:function:: getHashUpgradeLevel(upgName)
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:param string upgName: Name of upgrade to spend hashes on. Must be an exact match.
|
||||
:returns: level of the upgrade.
|
||||
|
||||
.. note:: This function is only applicable for Hacknet Servers (the upgraded version
|
||||
of a Hacknet Node).
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
hacknet.getHashUpgradeLevel("Sell for Money"); // returns: 5
|
||||
// "Sell for Money" was bought 5 times.
|
13
doc/source/netscript/hacknetnodeapi/getStudyMult.rst
Normal file
13
doc/source/netscript/hacknetnodeapi/getStudyMult.rst
Normal file
@ -0,0 +1,13 @@
|
||||
getStudyMult() Netscript Function
|
||||
=================================
|
||||
|
||||
.. js:function:: getStudyMult()
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:returns: The multiplier to studying that hash upgrades provide to the player.
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
hacknet.getStudyMult(); // return: 1.4
|
13
doc/source/netscript/hacknetnodeapi/getTrainingMult.rst
Normal file
13
doc/source/netscript/hacknetnodeapi/getTrainingMult.rst
Normal file
@ -0,0 +1,13 @@
|
||||
getTrainingMul() Netscript Function
|
||||
===================================
|
||||
|
||||
.. js:function:: getTrainingMul()
|
||||
|
||||
:RAM cost: 0 GB
|
||||
:returns: The multiplier to training that hash upgrades provide to the player.
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: javascript
|
||||
|
||||
hacknet.getTrainingMult(); // return: 1.4
|
@ -9,3 +9,4 @@ they contain spoilers for the game.
|
||||
.. toctree::
|
||||
|
||||
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;
|
||||
|
||||
.. toctree::
|
||||
:caption: API Functions:
|
||||
:caption: Hacknet Nodes API Functions:
|
||||
|
||||
numNodes() <hacknetnodeapi/numNodes>
|
||||
maxNumNodes() <hacknetnodeapi/maxNumNodes>
|
||||
@ -36,14 +36,21 @@ In :ref:`netscriptjs`::
|
||||
upgradeLevel() <hacknetnodeapi/upgradeLevel>
|
||||
upgradeRam() <hacknetnodeapi/upgradeRam>
|
||||
upgradeCore() <hacknetnodeapi/upgradeCore>
|
||||
upgradeCache() <hacknetnodeapi/upgradeCache>
|
||||
getLevelUpgradeCost() <hacknetnodeapi/getLevelUpgradeCost>
|
||||
getRamUpgradeCost() <hacknetnodeapi/getRamUpgradeCost>
|
||||
getCoreUpgradeCost() <hacknetnodeapi/getCoreUpgradeCost>
|
||||
|
||||
.. toctree::
|
||||
:caption: Hacknet Servers API Functions:
|
||||
|
||||
upgradeCache() <hacknetnodeapi/upgradeCache>
|
||||
getCacheUpgradeCost() <hacknetnodeapi/getCacheUpgradeCost>
|
||||
numHashes() <hacknetnodeapi/numHashes>
|
||||
hashCost() <hacknetnodeapi/hashCost>
|
||||
spendHashes() <hacknetnodeapi/spendHashes>
|
||||
getHashUpgradeLevel() <hacknetnodeapi/getHashUpgradeLevel>
|
||||
getTrainingMult() <hacknetnodeapi/getTrainingMult>
|
||||
getStudyMult() <hacknetnodeapi/getStudyMult>
|
||||
|
||||
.. _netscript_hacknetnodeapi_referencingahacknetnode:
|
||||
|
||||
|
@ -24,10 +24,10 @@ level 3, then you will be able to access all of the Singularity Functions.
|
||||
travelToCity() <singularityfunctions/travelToCity>
|
||||
purchaseTor() <singularityfunctions/purchaseTor>
|
||||
purchaseProgram() <singularityfunctions/purchaseProgram>
|
||||
getCurrentServer() <singularityfunctions/getCurrentServer>
|
||||
connect() <singularityfunctions/connect>
|
||||
manualHack() <singularityfunctions/manualHack>
|
||||
getStats() <singularityfunctions/getStats>
|
||||
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
||||
getPlayer() <singularityfunctions/getPlayer>
|
||||
isBusy() <singularityfunctions/isBusy>
|
||||
stopAction() <singularityfunctions/stopAction>
|
||||
upgradeHomeRam() <singularityfunctions/upgradeHomeRam>
|
||||
@ -57,3 +57,10 @@ level 3, then you will be able to access all of the Singularity Functions.
|
||||
purchaseAugmentation() <singularityfunctions/purchaseAugmentation>
|
||||
installAugmentations() <singularityfunctions/installAugmentations>
|
||||
softReset() <singularityfunctions/softReset>
|
||||
|
||||
|
||||
.. toctree::
|
||||
:caption: Deprecated:
|
||||
|
||||
getStats() <singularityfunctions/getStats>
|
||||
getCharacterInformation() <singularityfunctions/getCharacterInformation>
|
@ -3,6 +3,8 @@ getCharacterInformation() Netscript Function
|
||||
|
||||
.. js:function:: getCharacterInformation()
|
||||
|
||||
.. warning:: This function is deprecated.
|
||||
|
||||
: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.
|
||||
|
@ -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.
|
||||
|
101
doc/source/netscript/singularityfunctions/getPlayer.rst
Normal file
101
doc/source/netscript/singularityfunctions/getPlayer.rst
Normal file
@ -0,0 +1,101 @@
|
||||
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
|
||||
}
|
||||
|
||||
Example::
|
||||
|
||||
player = getPlayer();
|
||||
print('My charisma level is: ' + player.charisma);
|
@ -3,6 +3,8 @@ getStats() Netscript Function
|
||||
|
||||
.. js:function:: getStats()
|
||||
|
||||
.. warning:: This function is deprecated.
|
||||
|
||||
: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.
|
||||
|
@ -30,7 +30,7 @@
|
||||
<div id="entire-game-container" style="visibility:hidden;">
|
||||
<div id="mainmenu-container">
|
||||
<!-- Main menu -->
|
||||
<ul id="mainmenu" class="mainmenu">
|
||||
<ul id="mainmenu" class="mainmenu noscrollbar">
|
||||
<!-- Hacking dropdown -->
|
||||
<li id="hacking-menu-header-li">
|
||||
<button id="hacking-menu-header" class="mainmenu-accordion-header"> Hacking </button>
|
||||
|
@ -51,6 +51,9 @@ import { removeElement } from "../utils/uiHelpers/removeElement";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
|
||||
import { StatsTable } from "./ui/React/StatsTable";
|
||||
import { CopyableText } from "./ui/React/CopyableText";
|
||||
import { Money } from "./ui/React/Money";
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
const stealthIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 166 132" style="fill:#adff2f;"><g><path d="M132.658-0.18l-24.321,24.321c-7.915-2.71-16.342-4.392-25.087-4.392c-45.84,0-83,46-83,46 s14.1,17.44,35.635,30.844L12.32,120.158l12.021,12.021L144.68,11.841L132.658-0.18z M52.033,80.445 c-2.104-4.458-3.283-9.438-3.283-14.695c0-19.054,15.446-34.5,34.5-34.5c5.258,0,10.237,1.179,14.695,3.284L52.033,80.445z"/><path d="M134.865,37.656l-18.482,18.482c0.884,3.052,1.367,6.275,1.367,9.612c0,19.055-15.446,34.5-34.5,34.5 c-3.337,0-6.56-0.483-9.611-1.367l-10.124,10.124c6.326,1.725,12.934,2.743,19.735,2.743c45.84,0,83-46,83-46 S153.987,50.575,134.865,37.656z"/></g></svg> `
|
||||
@ -709,7 +712,7 @@ Bladeburner.prototype.completeAction = function() {
|
||||
if (isOperation && this.logging.ops) {
|
||||
this.log(action.name + " successfully completed! Gained " + formatNumber(gain, 3) + " rank");
|
||||
} 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);
|
||||
@ -902,7 +905,7 @@ Bladeburner.prototype.completeAction = function() {
|
||||
this.stamina = Math.min(this.maxStamina, this.stamina + staminaGain);
|
||||
this.startAction(this.action);
|
||||
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;
|
||||
}
|
||||
@ -1256,7 +1259,7 @@ Bladeburner.prototype.createContent = function() {
|
||||
// Console
|
||||
DomElems.consoleDiv = createElement("div", {
|
||||
class:"bladeburner-console-div",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
if (DomElems.consoleInput instanceof Element) {
|
||||
DomElems.consoleInput.focus();
|
||||
}
|
||||
@ -1264,12 +1267,12 @@ Bladeburner.prototype.createContent = function() {
|
||||
}
|
||||
});
|
||||
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.consoleInputHeader = createElement("pre", {innerText:"> "});
|
||||
DomElems.consoleInput = createElement("input", {
|
||||
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);
|
||||
@ -1330,7 +1333,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
DomElems.overviewStaminaHelpTip = createElement("div", {
|
||||
class:"help-tip",
|
||||
innerText:"?",
|
||||
clickListener: ()=> {
|
||||
clickListener: () => {
|
||||
dialogBoxCreate("Performing actions will use up your stamina.<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 " +
|
||||
@ -1358,7 +1361,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
|
||||
DomElems.overviewEstPopHelpTip = createElement("div", {
|
||||
innerText:"?", class:"help-tip",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
dialogBoxCreate("The success rate of your contracts/operations depends on " +
|
||||
"the population of Synthoids in your current city. " +
|
||||
"The success rate that is shown to you is only an estimate, " +
|
||||
@ -1421,12 +1424,12 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
appendLineBreaks(DomElems.overviewDiv, 1);
|
||||
DomElems.overviewDiv.appendChild(createElement("a", {
|
||||
innerHTML:"Travel", class:"a-link-button", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var popupId = "bladeburner-travel-popup-cancel-btn";
|
||||
var popupArguments = [];
|
||||
popupArguments.push(createElement("a", { // Cancel Button
|
||||
innerText:"Cancel", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
removeElementById(popupId); return false;
|
||||
}
|
||||
}))
|
||||
@ -1445,7 +1448,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
*/
|
||||
class:"cmpy-mgmt-find-employee-option",
|
||||
innerText:BladeburnerConstants.CityNames[i],
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
inst.city = BladeburnerConstants.CityNames[i];
|
||||
removeElementById(popupId);
|
||||
inst.updateOverviewContent();
|
||||
@ -1468,7 +1471,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
DomElems.overviewDiv.appendChild(createElement("a", {
|
||||
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",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
if (bladeburnerFac.isMember) {
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(bladeburnersFactionName);
|
||||
@ -1512,7 +1515,7 @@ Bladeburner.prototype.createActionAndSkillsContent = function() {
|
||||
DomElems.actionAndSkillsDiv.appendChild(createElement("a", {
|
||||
innerText:buttons[i],
|
||||
class:currTab === buttons[i].toLowerCase() ? "bladeburner-nav-button-inactive" : "bladeburner-nav-button",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
DomElems.currentTab = buttons[i].toLowerCase();
|
||||
inst.createActionAndSkillsContent();
|
||||
return false;
|
||||
@ -1764,15 +1767,16 @@ Bladeburner.prototype.updateOverviewContent = function() {
|
||||
if (!routing.isOn(Page.Bladeburner)) {return;}
|
||||
DomElems.overviewRank.childNodes[0].nodeValue = "Rank: " + formatNumber(this.rank, 2);
|
||||
DomElems.overviewStamina.innerText = "Stamina: " + formatNumber(this.stamina, 3) + " / " + formatNumber(this.maxStamina, 3);
|
||||
DomElems.overviewGen1.innerHTML =
|
||||
"Stamina Penalty: " + formatNumber((1-this.calculateStaminaPenalty())*100, 1) + "%<br><br>" +
|
||||
"Team Size: " + formatNumber(this.teamSize, 0) + "<br>" +
|
||||
"Team Members Lost: " + formatNumber(this.teamLost, 0) + "<br><br>" +
|
||||
"Num Times Hospitalized: " + this.numHosp + "<br>" +
|
||||
"Money Lost From Hospitalizations: " + numeralWrapper.format(this.moneyLost, "$0.000a") + "<br><br>" +
|
||||
"Current City: " + this.city + "<br>";
|
||||
ReactDOM.render(<>
|
||||
Stamina Penalty: {formatNumber((1-this.calculateStaminaPenalty())*100, 1)}%<br /><br />
|
||||
Team Size: {formatNumber(this.teamSize, 0)}<br />
|
||||
Team Members Lost: {formatNumber(this.teamLost, 0)}<br /><br />
|
||||
Num Times Hospitalized: this.numHosp<br />
|
||||
Money Lost From Hospitalizations: {Money(this.moneyLost)}<br /><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.overviewChaos.childNodes[0].nodeValue = "City Chaos: " + formatNumber(this.getCurrentCity().chaos);
|
||||
DomElems.overviewSkillPoints.innerText = "Skill Points: " + formatNumber(this.skillPoints, 0);
|
||||
@ -1898,7 +1902,7 @@ Bladeburner.prototype.updateGeneralActionsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("a", {
|
||||
innerText:"Start", class: "a-link-button",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
this.action.type = ActionTypes[action.name];
|
||||
this.action.name = action.name;
|
||||
this.startAction(this.action);
|
||||
@ -1939,7 +1943,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("a", {
|
||||
innerText:"Start", class: "a-link-button",
|
||||
padding:"3px", margin:"3px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
this.action.type = ActionTypes.Contract;
|
||||
this.action.name = action.name;
|
||||
this.startAction(this.action);
|
||||
@ -1963,7 +1967,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
||||
padding:"2px", margin:"2px",
|
||||
tooltip: isActive ? "WARNING: changing the level will restart the contract" : "",
|
||||
display:"inline",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
++action.level;
|
||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||
this.updateContractsUIElement(el, action);
|
||||
@ -1975,7 +1979,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
||||
padding:"2px", margin:"2px",
|
||||
tooltip: isActive ? "WARNING: changing the level will restart the contract" : "",
|
||||
display:"inline",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
--action.level;
|
||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||
this.updateContractsUIElement(el, action);
|
||||
@ -1989,8 +1993,7 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
||||
display:"inline-block",
|
||||
innerHTML:action.desc + "\n\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" +
|
||||
"Contracts remaining: " + Math.floor(action.count) + "\n" +
|
||||
"Successes: " + action.successes + "\n" +
|
||||
"Failures: " + action.failures,
|
||||
@ -2038,7 +2041,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("a", {
|
||||
innerText:"Start", class: "a-link-button",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
this.action.type = ActionTypes.Operation;
|
||||
this.action.name = action.name;
|
||||
this.startAction(this.action);
|
||||
@ -2049,7 +2052,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("a", {
|
||||
innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var popupId = "bladeburner-operation-set-team-size-popup";
|
||||
var txt = createElement("p", {
|
||||
innerText:"Enter the amount of team members you would like to take on these " +
|
||||
@ -2063,7 +2066,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
});
|
||||
var setBtn = createElement("a", {
|
||||
innerText:"Confirm", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var num = Math.round(parseFloat(input.value));
|
||||
if (isNaN(num)) {
|
||||
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric)")
|
||||
@ -2077,7 +2080,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
});
|
||||
var cancelBtn = createElement("a", {
|
||||
innerText:"Cancel", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
}
|
||||
@ -2101,7 +2104,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
padding:"2px", margin:"2px",
|
||||
tooltip: isActive ? "WARNING: changing the level will restart the Operation" : "",
|
||||
display:"inline",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
++action.level;
|
||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||
this.updateOperationsUIElement(el, action);
|
||||
@ -2113,7 +2116,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
padding:"2px", margin:"2px",
|
||||
tooltip: isActive ? "WARNING: changing the level will restart the Operation" : "",
|
||||
display:"inline",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
--action.level;
|
||||
if (isActive) {this.startAction(this.action);} // Restart Action
|
||||
this.updateOperationsUIElement(el, action);
|
||||
@ -2129,7 +2132,7 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
display:"inline-block",
|
||||
innerHTML:action.desc + "\n\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" +
|
||||
"Successes: " + action.successes + "\n" +
|
||||
"Failures: " + action.failures,
|
||||
@ -2190,7 +2193,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("a", { // Start button
|
||||
innerText:"Start", margin:"3px", padding:"3px",
|
||||
class:hasReqdRank ? "a-link-button" : "a-link-button-inactive",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
this.action.type = ActionTypes.BlackOperation;
|
||||
this.action.name = action.name;
|
||||
this.startAction(this.action);
|
||||
@ -2201,7 +2204,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("a", { // Set Team Size Button
|
||||
innerText:"Set Team Size (Curr Size: " + formatNumber(action.teamCount, 0) + ")", class:"a-link-button",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var popupId = "bladeburner-operation-set-team-size-popup";
|
||||
var txt = createElement("p", {
|
||||
innerText:"Enter the amount of team members you would like to take on this " +
|
||||
@ -2215,7 +2218,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
||||
});
|
||||
var setBtn = createElement("a", {
|
||||
innerText:"Confirm", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var num = Math.round(parseFloat(input.value));
|
||||
if (isNaN(num)) {
|
||||
dialogBoxCreate("Invalid value entered for number of Team Members (must be numeric)")
|
||||
@ -2229,7 +2232,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
||||
});
|
||||
var cancelBtn = createElement("a", {
|
||||
innerText:"Cancel", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
}
|
||||
@ -2252,7 +2255,7 @@ Bladeburner.prototype.updateBlackOpsUIElement = function(el, action) {
|
||||
el.appendChild(createElement("p", {
|
||||
display:"inline-block",
|
||||
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 +2268,15 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
||||
}
|
||||
var pointCost = skill.calculateCost(currentLevel);
|
||||
|
||||
el.appendChild(createElement("h2", { // Header
|
||||
innerText:skill.name + " (Lvl " + currentLevel + ")", display:"inline-block"
|
||||
}));
|
||||
const nameDiv = createElement("div");
|
||||
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 maxLvl = skill.maxLvl ? currentLevel >= skill.maxLvl : false;
|
||||
@ -2275,7 +2284,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
||||
innerText:"Level", display:"inline-block",
|
||||
class: canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
if (this.skillPoints < pointCost) {return;}
|
||||
this.skillPoints -= pointCost;
|
||||
this.upgradeSkill(skill);
|
||||
@ -2284,6 +2293,10 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
||||
}
|
||||
}));
|
||||
appendLineBreaks(el, 2);
|
||||
el.appendChild(createElement("p", {
|
||||
display:"block",
|
||||
innerText:`Level: ${currentLevel}`,
|
||||
}));
|
||||
if (maxLvl) {
|
||||
el.appendChild(createElement("p", {
|
||||
color:"red", display:"block",
|
||||
@ -2311,7 +2324,7 @@ Bladeburner.prototype.postToConsole = function(input, saveToLogs=true) {
|
||||
}
|
||||
|
||||
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) {
|
||||
DomElems.consoleTable.removeChild(DomElems.consoleTable.firstChild);
|
@ -6,7 +6,7 @@
|
||||
import { IMap } from "./types";
|
||||
|
||||
export let CONSTANTS: IMap<any> = {
|
||||
Version: "0.50.2",
|
||||
Version: "0.51.0",
|
||||
|
||||
/** 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
|
||||
@ -228,18 +228,25 @@ export let CONSTANTS: IMap<any> = {
|
||||
|
||||
LatestUpdate:
|
||||
`
|
||||
v0.50.2 - 2021-03-25 Everyone asked for this one. (hydroflame)
|
||||
v0.51.0 - 2021-03-31 Formulas (hydroflame)
|
||||
-------
|
||||
BitNodeMultipliers
|
||||
* 'GangKarmaRequirements': a new multipler that influences how much karma is required to make a gang different bitnodes.
|
||||
|
||||
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
|
||||
* '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.
|
||||
* '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.
|
||||
|
||||
Misc.
|
||||
* New shortcut, Alt + b, brings you to bladeburner
|
||||
* New shortcut, Alt + g, brings you to gang
|
||||
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'
|
||||
`
|
||||
}
|
||||
|
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 { Player } from "../Player";
|
||||
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 { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
|
||||
//Posts a "help" message if connected to DarkWeb
|
||||
export function checkIfConnectedToDarkweb(): void {
|
||||
@ -49,7 +52,7 @@ export function executeDarkwebTerminalCommand(commandArray: string[]): void {
|
||||
function listAllDarkwebItems() {
|
||||
for(const key in DarkWebItems) {
|
||||
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 {
|
||||
program: string;
|
||||
@ -10,9 +10,4 @@ export class DarkWebItem {
|
||||
this.price = price;
|
||||
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 { getSelectText } from "../utils/uiHelpers/getSelectData";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
import { Money } from "./ui/React/Money";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
@ -611,12 +612,16 @@ class DevMenuComponent extends Component {
|
||||
}
|
||||
|
||||
viewStockCaps() {
|
||||
let text = "<table><tbody><tr><th>Stock</th><th>Price cap</th></tr>";
|
||||
let stocks = [];
|
||||
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(text);
|
||||
dialogBoxCreate(<table><tbody><tr><th>Stock</th><th>Price cap</th></tr>
|
||||
{stocks}
|
||||
</tbody></table>);
|
||||
}
|
||||
|
||||
sleeveMaxAllShock() {
|
||||
|
@ -25,6 +25,8 @@ import {
|
||||
Generic_fromJSON
|
||||
} from "../../utils/JSONReviver";
|
||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import {
|
||||
yesNoBoxCreate,
|
||||
yesNoBoxGetYesButton,
|
||||
@ -108,10 +110,12 @@ export function purchaseAugmentationBoxCreate(aug, fac) {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
yesNoBoxCreate("<h2>" + aug.name + "</h2><br>" +
|
||||
aug.info + "<br><br>" +
|
||||
"<br>Would you like to purchase the " + aug.name + " Augmentation for $" +
|
||||
formatNumber(aug.baseCost * factionInfo.augmentationPriceMult, 2) + "?");
|
||||
yesNoBoxCreate(<>
|
||||
<h2>{aug.name}</h2><br />
|
||||
<div dangerouslySetInnerHTML={{__html: aug.info}}></div><br /><br />
|
||||
<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
|
||||
|
@ -8,6 +8,8 @@ import { Faction } from "../../Faction/Faction";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
|
||||
@ -21,7 +23,7 @@ type IProps = {
|
||||
|
||||
type IState = {
|
||||
donateAmt: number;
|
||||
statusTxt: string;
|
||||
status: JSX.Element;
|
||||
}
|
||||
|
||||
const inputStyleMarkup = {
|
||||
@ -37,7 +39,7 @@ export class DonateOption extends React.Component<IProps, IState> {
|
||||
|
||||
this.state = {
|
||||
donateAmt: 0,
|
||||
statusTxt: "",
|
||||
status: <></>,
|
||||
}
|
||||
|
||||
this.calculateRepGain = this.calculateRepGain.bind(this);
|
||||
@ -61,8 +63,9 @@ export class DonateOption extends React.Component<IProps, IState> {
|
||||
this.props.p.loseMoney(amt);
|
||||
const repGain = this.calculateRepGain(amt);
|
||||
this.props.faction.playerReputation += repGain;
|
||||
dialogBoxCreate(`You just donated ${numeralWrapper.formatMoney(amt)} to ${fac.name} to gain ` +
|
||||
`${numeralWrapper.format(repGain, "0,0.000")} reputation`);
|
||||
dialogBoxCreate(<>
|
||||
You just donated {Money(amt)} to {fac.name} to gain {Reputation(repGain)} reputation
|
||||
</>);
|
||||
this.props.rerender();
|
||||
}
|
||||
}
|
||||
@ -73,13 +76,13 @@ export class DonateOption extends React.Component<IProps, IState> {
|
||||
if (isNaN(amt)) {
|
||||
this.setState({
|
||||
donateAmt: 0,
|
||||
statusTxt: "Invalid donate amount entered!",
|
||||
status: <>Invalid donate amount entered!</>,
|
||||
});
|
||||
} else {
|
||||
const repGain = this.calculateRepGain(amt);
|
||||
this.setState({
|
||||
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}
|
||||
text={"Donate Money"}
|
||||
/>
|
||||
<p style={this.blockStyle}>{this.state.statusTxt}</p>
|
||||
<p style={this.blockStyle}>{this.state.status}</p>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
@ -10,6 +10,8 @@ import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
|
||||
import { AutoupdatingParagraph } from "../../ui/React/AutoupdatingParagraph";
|
||||
import { ParagraphWithTooltip } from "../../ui/React/ParagraphWithTooltip";
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { Favor } from "../../ui/React/Favor";
|
||||
|
||||
type IProps = {
|
||||
faction: Faction;
|
||||
@ -33,18 +35,17 @@ export class Info extends React.Component<IProps, any> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this.getFavorGainText = this.getFavorGainText.bind(this);
|
||||
this.getReputationText = this.getReputationText.bind(this);
|
||||
this.getFavorGainContent = this.getFavorGainContent.bind(this);
|
||||
this.getReputationContent = this.getReputationContent.bind(this);
|
||||
}
|
||||
|
||||
getFavorGainText(): string {
|
||||
getFavorGainContent(): JSX.Element {
|
||||
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 {
|
||||
const formattedRep = numeralWrapper.format(this.props.faction.playerReputation, "0.000a");
|
||||
return `Reputation: ${formattedRep}`
|
||||
getReputationContent(): JSX.Element {
|
||||
return <>Reputation: {Reputation(this.props.faction.playerReputation)}</>
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -65,12 +66,12 @@ export class Info extends React.Component<IProps, any> {
|
||||
<p style={blockStyleMarkup}>-------------------------</p>
|
||||
<AutoupdatingParagraph
|
||||
intervalTime={5e3}
|
||||
getText={this.getReputationText}
|
||||
getTooltip={this.getFavorGainText}
|
||||
getContent={this.getReputationContent}
|
||||
getTooltip={this.getFavorGainContent}
|
||||
/>
|
||||
<p style={blockStyleMarkup}>-------------------------</p>
|
||||
<ParagraphWithTooltip
|
||||
text={`Faction Favor: ${numeralWrapper.format(this.props.faction.favor, "0,0")}`}
|
||||
content={<>Faction Favor: {Favor(this.props.faction.favor)}</>}
|
||||
tooltip={favorTooltip}
|
||||
/>
|
||||
<p style={blockStyleMarkup}>-------------------------</p>
|
||||
|
@ -18,9 +18,12 @@ import { Faction } from "../../Faction/Faction";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { IMap } from "../../types";
|
||||
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { Augmentation as AugFormat } from "../../ui/React/Augmentation";
|
||||
|
||||
type IProps = {
|
||||
augName: string;
|
||||
@ -106,19 +109,19 @@ export class PurchaseableAugmentation extends React.Component<IProps, any> {
|
||||
|
||||
// Determine UI properties
|
||||
let disabled: boolean = false;
|
||||
let statusTxt: string = "";
|
||||
let status: JSX.Element = <></>;
|
||||
let color: string = "";
|
||||
if (!this.hasPrereqs()) {
|
||||
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";
|
||||
} else if (this.aug.name !== AugmentationNames.NeuroFluxGovernor && (this.aug.owned || this.owned())) {
|
||||
disabled = true;
|
||||
} else if (this.hasReputation()) {
|
||||
statusTxt = `UNLOCKED - ${numeralWrapper.formatMoney(moneyCost)}`;
|
||||
status = <>UNLOCKED - {Money(moneyCost)}</>;
|
||||
} else {
|
||||
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";
|
||||
}
|
||||
|
||||
@ -143,7 +146,7 @@ export class PurchaseableAugmentation extends React.Component<IProps, any> {
|
||||
text={btnTxt}
|
||||
tooltip={this.aug.info}
|
||||
/>
|
||||
<p style={txtStyle}>{statusTxt}</p>
|
||||
<p style={txtStyle}>{status}</p>
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
|
@ -35,6 +35,14 @@ import { removeElement } from "../utils/uiHelpers/removeElement";
|
||||
import { removeElementById } from "../utils/uiHelpers/removeElementById";
|
||||
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
|
||||
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) {
|
||||
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:`,
|
||||
`Hacking: ${numeralWrapper.format(res.hack, "0.000%")}`,
|
||||
`Strength: ${numeralWrapper.format(res.str, "0.000%")}`,
|
||||
`Defense: ${numeralWrapper.format(res.def, "0.000%")}`,
|
||||
`Dexterity: ${numeralWrapper.format(res.dex, "0.000%")}`,
|
||||
`Agility: ${numeralWrapper.format(res.agi, "0.000%")}`,
|
||||
`Charisma: ${numeralWrapper.format(res.cha, "0.000%")}`].join("<br>"));
|
||||
`Hacking: ${numeralWrapper.formatPercentage(res.hack, 3)}`,
|
||||
`Strength: ${numeralWrapper.formatPercentage(res.str, 3)}`,
|
||||
`Defense: ${numeralWrapper.formatPercentage(res.def, 3)}`,
|
||||
`Dexterity: ${numeralWrapper.formatPercentage(res.dex, 3)}`,
|
||||
`Agility: ${numeralWrapper.formatPercentage(res.agi, 3)}`,
|
||||
`Charisma: ${numeralWrapper.formatPercentage(res.cha, 3)}`].join("<br>"));
|
||||
} else {
|
||||
workerScript.log(`Ascended Gang member ${memberObj.name}`);
|
||||
}
|
||||
@ -1044,14 +1052,14 @@ Gang.prototype.createGangMemberUpgradeBox = function(player, initialFilter="") {
|
||||
type:"text", placeholder:"Filter gang members",
|
||||
class: "text-input",
|
||||
value:initialFilter,
|
||||
onkeyup:()=>{
|
||||
onkeyup:() => {
|
||||
var filterValue = UIElems.gangMemberUpgradeBoxFilter.value.toString();
|
||||
this.createGangMemberUpgradeBox(player, filterValue);
|
||||
}
|
||||
});
|
||||
|
||||
UIElems.gangMemberUpgradeBoxDiscount = createElement("p", {
|
||||
innerText: "Discount: -" + numeralWrapper.format(1 - 1 / this.getDiscount(), "0.00%"),
|
||||
innerText: "Discount: -" + numeralWrapper.formatPercentage(1 - 1 / this.getDiscount()),
|
||||
marginLeft: "6px",
|
||||
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."
|
||||
@ -1178,10 +1186,10 @@ GangMember.prototype.createGangMemberUpgradePanel = function(gangObj, player) {
|
||||
let upg = upgradeArray[j];
|
||||
(function (upg, div, memberObj, i, gang) {
|
||||
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",
|
||||
fontSize:"11px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
memberObj.buyUpgrade(upg, player, gangObj);
|
||||
return false;
|
||||
}
|
||||
@ -1266,7 +1274,7 @@ Gang.prototype.displayGangContent = function(player) {
|
||||
// Back button
|
||||
UIElems.gangContainer.appendChild(createElement("a", {
|
||||
class:"a-link-button", display:"inline-block", innerText:"Back",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(facName);
|
||||
return false;
|
||||
@ -1277,7 +1285,7 @@ Gang.prototype.displayGangContent = function(player) {
|
||||
UIElems.managementButton = createElement("a", {
|
||||
id:"gang-management-subpage-button", class:"a-link-button-inactive",
|
||||
display:"inline-block", innerHTML: "Gang Management (Alt+1)",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
UIElems.gangManagementSubpage.style.display = "block";
|
||||
UIElems.gangTerritorySubpage.style.display = "none";
|
||||
UIElems.managementButton.classList.toggle("a-link-button-inactive");
|
||||
@ -1340,7 +1348,7 @@ Gang.prototype.displayGangContent = function(player) {
|
||||
UIElems.gangRecruitMemberButton = createElement("a", {
|
||||
id: "gang-management-recruit-member-btn", class:"a-link-button-inactive",
|
||||
innerHTML:"Recruit Gang Member", display:"inline-block", margin:"10px",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
const popupId = "recruit-gang-member-popup";
|
||||
|
||||
let yesBtn;
|
||||
@ -1408,7 +1416,7 @@ Gang.prototype.displayGangContent = function(player) {
|
||||
UIElems.gangExpandAllButton = createElement("a", {
|
||||
class:"a-link-button", display:"inline-block",
|
||||
innerHTML:"Expand All",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var allHeaders = UIElems.gangManagementSubpage.getElementsByClassName("accordion-header");
|
||||
for (var i = 0; i < allHeaders.length; ++i) {
|
||||
var hdr = allHeaders[i];
|
||||
@ -1422,7 +1430,7 @@ Gang.prototype.displayGangContent = function(player) {
|
||||
UIElems.gangCollapseAllButton = createElement("a", {
|
||||
class:"a-link-button", display:"inline-block",
|
||||
innerHTML:"Collapse All",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
var allHeaders = UIElems.gangManagementSubpage.getElementsByClassName("accordion-header");
|
||||
for (var i = 0; i < allHeaders.length; ++i) {
|
||||
var hdr = allHeaders[i];
|
||||
@ -1436,7 +1444,7 @@ Gang.prototype.displayGangContent = function(player) {
|
||||
UIElems.gangMemberFilter = createElement("input", {
|
||||
type:"text", placeholder:"Filter gang members", margin:"5px", padding:"5px",
|
||||
class:"text-input",
|
||||
onkeyup:()=>{
|
||||
onkeyup:() => {
|
||||
this.displayGangMemberList();
|
||||
}
|
||||
});
|
||||
@ -1584,13 +1592,13 @@ Gang.prototype.updateGangContent = function() {
|
||||
|
||||
if (UIElems.gangMemberUpgradeBoxOpened) {
|
||||
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") {
|
||||
// Territory Warfare Clash Chance
|
||||
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
|
||||
UIElems.gangTerritoryWarfareCheckbox.checked = this.territoryWarfareEngaged;
|
||||
@ -1623,7 +1631,7 @@ Gang.prototype.updateGangContent = function() {
|
||||
const clashVictoryChance = playerPower / (gangTerritoryInfo.power + playerPower);
|
||||
let newHTML = `<u>${gangname}</u><br>Power: ${formatNumber(gangTerritoryInfo.power, 6)}<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;
|
||||
}
|
||||
}
|
||||
@ -1641,8 +1649,8 @@ Gang.prototype.updateGangContent = function() {
|
||||
removeChildrenFromElement(UIElems.gangInfo);
|
||||
UIElems.gangInfo.appendChild(createElement("p", { // Respect
|
||||
display: "inline-block",
|
||||
innerText: "Respect: " + numeralWrapper.format(this.respect, '0.00000a') +
|
||||
" (" + numeralWrapper.format(5*this.respectGainRate, '0.00000a') + " / sec)",
|
||||
innerText: "Respect: " + numeralWrapper.formatRespect(this.respect) +
|
||||
" (" + numeralWrapper.formatRespect(5*this.respectGainRate) + " / sec)",
|
||||
tooltip: "Represents the amount of respect your gang has from other gangs and criminal " +
|
||||
"organizations. Your respect affects the amount of money " +
|
||||
"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
|
||||
display: "inline-block",
|
||||
innerText: "Wanted Level: " + numeralWrapper.format(this.wanted, '0.00000a') +
|
||||
" (" + numeralWrapper.format(5*this.wantedGainRate, '0.00000a') + " / sec)",
|
||||
innerText: "Wanted Level: " + numeralWrapper.formatWanted(this.wanted) +
|
||||
" (" + numeralWrapper.formatWanted(5*this.wantedGainRate) + " / sec)",
|
||||
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 " +
|
||||
"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("p", { // Money gain rate
|
||||
display: "inline-block",
|
||||
innerText: `Money gain rate: ${numeralWrapper.format(5 * this.moneyGainRate, "$0.000a")} / sec`,
|
||||
}));
|
||||
const d0 = createElement("div");
|
||||
ReactDOM.render(<p style={{'display': 'inline-block'}}>Money gain rate: {MoneyRate(5 * this.moneyGainRate)}</p>, d0);
|
||||
UIElems.gangInfo.appendChild(d0);
|
||||
UIElems.gangInfo.appendChild(createElement("br"));
|
||||
|
||||
// Fix some rounding issues graphically
|
||||
@ -1692,10 +1699,9 @@ Gang.prototype.updateGangContent = function() {
|
||||
}));
|
||||
UIElems.gangInfo.appendChild(createElement("br"));
|
||||
|
||||
UIElems.gangInfo.appendChild(createElement("p", { // Faction reputation
|
||||
display:"inline-block",
|
||||
innerText:"Faction reputation: " + numeralWrapper.format(rep, '0.000a')
|
||||
}));
|
||||
const d1 = createElement("div");
|
||||
ReactDOM.render(<p style={{'display': 'inline-block'}}>Faction reputation: {Reputation(rep)}</p>, d1);
|
||||
UIElems.gangInfo.appendChild(d1);
|
||||
UIElems.gangInfo.appendChild(createElement("br"));
|
||||
|
||||
const CyclesPerSecond = 1000 / Engine._idleSpeed;
|
||||
@ -1761,12 +1767,12 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
|
||||
const statsDiv = createElement("div", {
|
||||
class: "gang-member-info-div",
|
||||
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)`,
|
||||
`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)`,
|
||||
`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)`,
|
||||
`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)`,
|
||||
`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)`,
|
||||
`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>"),
|
||||
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.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.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.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.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.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;
|
||||
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",
|
||||
"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",
|
||||
`Hacking: +${numeralWrapper.format(ascendBenefits.hack, "0.00%")}`,
|
||||
`Strength: +${numeralWrapper.format(ascendBenefits.str, "0.00%")}`,
|
||||
`Defense: +${numeralWrapper.format(ascendBenefits.def, "0.00%")}`,
|
||||
`Dexterity: +${numeralWrapper.format(ascendBenefits.dex, "0.00%")}`,
|
||||
`Agility: +${numeralWrapper.format(ascendBenefits.agi, "0.00%")}`,
|
||||
`Charisma: +${numeralWrapper.format(ascendBenefits.cha, "0.00%")}`].join("\n"),
|
||||
`Hacking: +${numeralWrapper.formatPercentage(ascendBenefits.hack)}`,
|
||||
`Strength: +${numeralWrapper.formatPercentage(ascendBenefits.str)}`,
|
||||
`Defense: +${numeralWrapper.formatPercentage(ascendBenefits.def)}`,
|
||||
`Dexterity: +${numeralWrapper.formatPercentage(ascendBenefits.dex)}`,
|
||||
`Agility: +${numeralWrapper.formatPercentage(ascendBenefits.agi)}`,
|
||||
`Charisma: +${numeralWrapper.formatPercentage(ascendBenefits.cha)}`].join("\n"),
|
||||
});
|
||||
const confirmBtn = createElement("button", {
|
||||
class: "std-button",
|
||||
@ -1874,7 +1880,7 @@ Gang.prototype.createGangMemberDisplayElement = function(memberObj) {
|
||||
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(gainInfo);
|
||||
|
||||
@ -1907,12 +1913,12 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
|
||||
var stats = document.getElementById(name + "gang-member-stats-text");
|
||||
if (stats) {
|
||||
stats.innerText =
|
||||
[`Hacking: ${formatNumber(memberObj.hack, 0)} (${numeralWrapper.format(memberObj.hack_exp, '(0.00a)')} exp)`,
|
||||
`Strength: ${formatNumber(memberObj.str, 0)} (${numeralWrapper.format(memberObj.str_exp, '(0.00a)')} exp)`,
|
||||
`Defense: ${formatNumber(memberObj.def, 0)} (${numeralWrapper.format(memberObj.def_exp, '(0.00a)')} exp)`,
|
||||
`Dexterity: ${formatNumber(memberObj.dex, 0)} (${numeralWrapper.format(memberObj.dex_exp, '(0.00a)')} exp)`,
|
||||
`Agility: ${formatNumber(memberObj.agi, 0)} (${numeralWrapper.format(memberObj.agi_exp, '(0.00a)')} exp)`,
|
||||
`Charisma: ${formatNumber(memberObj.cha, 0)} (${numeralWrapper.format(memberObj.cha_exp, '(0.00a)')} exp)`].join("\n");
|
||||
[`Hacking: ${formatNumber(memberObj.hack, 0)} (${numeralWrapper.formatExp(memberObj.hack_exp)} exp)`,
|
||||
`Strength: ${formatNumber(memberObj.str, 0)} (${numeralWrapper.formatExp(memberObj.str_exp)} exp)`,
|
||||
`Defense: ${formatNumber(memberObj.def, 0)} (${numeralWrapper.formatExp(memberObj.def_exp)} exp)`,
|
||||
`Dexterity: ${formatNumber(memberObj.dex, 0)} (${numeralWrapper.formatExp(memberObj.dex_exp)} exp)`,
|
||||
`Agility: ${formatNumber(memberObj.agi, 0)} (${numeralWrapper.formatExp(memberObj.agi_exp)} exp)`,
|
||||
`Charisma: ${formatNumber(memberObj.cha, 0)} (${numeralWrapper.formatExp(memberObj.cha_exp)} exp)`].join("\n");
|
||||
}
|
||||
|
||||
// Update tooltip for stat multipliers
|
||||
@ -1921,23 +1927,25 @@ Gang.prototype.updateGangMemberDisplayElement = function(memberObj) {
|
||||
const statsDiv = panel["statsDiv"];
|
||||
if (statsDiv) {
|
||||
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)`,
|
||||
`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)`,
|
||||
`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)`,
|
||||
`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)`,
|
||||
`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)`,
|
||||
`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>");
|
||||
[`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.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.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.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.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.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
|
||||
var gainInfo = document.getElementById(name + "gang-member-gain-info");
|
||||
if (gainInfo) {
|
||||
gainInfo.innerHTML =
|
||||
[`Money: ${numeralWrapper.format(5*memberObj.calculateMoneyGain(this), '$0.000a')} / sec`,
|
||||
`Respect: ${numeralWrapper.format(5*memberObj.calculateRespectGain(this), '0.00000a')} / sec`,
|
||||
`Wanted Level: ${numeralWrapper.format(5*memberObj.calculateWantedLevelGain(this), '0.00000a')} / sec`,
|
||||
`Total Respect Earned: ${numeralWrapper.format(memberObj.earnedRespect, '0.00000a')}`].join("<br>");
|
||||
const data = [
|
||||
[`Money:`, MoneyRate(5*memberObj.calculateMoneyGain(this))],
|
||||
[`Respect:`, `${numeralWrapper.formatRespect(5*memberObj.calculateRespectGain(this))} / sec`],
|
||||
[`Wanted Level:`, `${numeralWrapper.formatWanted(5*memberObj.calculateWantedLevelGain(this))} / sec`],
|
||||
[`Total Respect:`, `${numeralWrapper.formatRespect(memberObj.earnedRespect)}`],
|
||||
];
|
||||
ReactDOM.render(StatsTable(data), gainInfo);
|
||||
}
|
||||
|
||||
// Update selector to have the correct task
|
@ -1,17 +1,19 @@
|
||||
import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers";
|
||||
import { Player } from "./Player";
|
||||
import { IPlayer } from "./PersonObjects/IPlayer";
|
||||
import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence";
|
||||
import { Server } from "./Server/Server";
|
||||
import { HacknetServer } from "./Hacknet/HacknetServer";
|
||||
|
||||
/**
|
||||
* 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 difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||
const skillMult = hackFactor * Player.hacking_skill;
|
||||
const skillMult = hackFactor * player.hacking_skill;
|
||||
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 < 0) { return 0; }
|
||||
|
||||
@ -22,14 +24,14 @@ export function calculateHackingChance(server: Server): number {
|
||||
* Returns the amount of hacking experience the player will gain upon
|
||||
* successfully hacking a server
|
||||
*/
|
||||
export function calculateHackingExpGain(server: Server): number {
|
||||
export function calculateHackingExpGain(server: Server, player: IPlayer): number {
|
||||
const baseExpGain = 3;
|
||||
const diffFactor = 0.3;
|
||||
if (server.baseDifficulty == null) {
|
||||
server.baseDifficulty = server.hackDifficulty;
|
||||
}
|
||||
let expGain = baseExpGain;
|
||||
expGain += (server.baseDifficulty * Player.hacking_exp_mult * diffFactor);
|
||||
expGain += (server.baseDifficulty * player.hacking_exp_mult * diffFactor);
|
||||
|
||||
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
|
||||
* 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
|
||||
const balanceFactor = 240;
|
||||
|
||||
const difficultyMult = (100 - server.hackDifficulty) / 100;
|
||||
const skillMult = (Player.hacking_skill - (server.requiredHackingSkill - 1)) / Player.hacking_skill;
|
||||
const percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / balanceFactor;
|
||||
const skillMult = (player.hacking_skill - (server.requiredHackingSkill - 1)) / player.hacking_skill;
|
||||
const percentMoneyHacked = difficultyMult * skillMult * player.hacking_money_mult / balanceFactor;
|
||||
if (percentMoneyHacked < 0) { return 0; }
|
||||
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
|
||||
*/
|
||||
export function calculateHackingTime(server: Server, hack: number): number {
|
||||
export function calculateHackingTime(server: Server, player: IPlayer): number {
|
||||
const difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
|
||||
|
||||
const baseDiff = 500;
|
||||
const baseSkill = 50;
|
||||
const diffFactor = 2.5;
|
||||
if (hack == null) {hack = Player.hacking_skill;}
|
||||
let skillFactor = (diffFactor * difficultyMult + baseDiff);
|
||||
// tslint:disable-next-line
|
||||
skillFactor /= (hack + baseSkill);
|
||||
skillFactor /= (player.hacking_skill + baseSkill);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -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
|
||||
*/
|
||||
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
|
||||
|
||||
return growTimeMultiplier * calculateHackingTime(server, hack);
|
||||
return growTimeMultiplier * calculateHackingTime(server, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
||||
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
|
||||
*/
|
||||
import {
|
||||
HacknetNode,
|
||||
BaseCostForHacknetNode,
|
||||
HacknetNodePurchaseNextMult,
|
||||
HacknetNodeMaxLevel,
|
||||
HacknetNodeMaxRam,
|
||||
HacknetNodeMaxCores
|
||||
} from "./HacknetNode";
|
||||
import {
|
||||
HacknetServer,
|
||||
BaseCostForHacknetServer,
|
||||
HacknetServerPurchaseMult,
|
||||
HacknetServerMaxLevel,
|
||||
HacknetServerMaxRam,
|
||||
HacknetServerMaxCores,
|
||||
HacknetServerMaxCache,
|
||||
MaxNumberHacknetServers
|
||||
} from "./HacknetServer";
|
||||
import { HacknetNode } from "./HacknetNode";
|
||||
import { calculateNodeCost } from "./formulas/HacknetNodes";
|
||||
import { calculateServerCost } from "./formulas/HacknetServers";
|
||||
import { HacknetNodeConstants, HacknetServerConstants } from "./data/Constants";
|
||||
import { HacknetServer } from "./HacknetServer";
|
||||
import { HashManager } from "./HashManager";
|
||||
import { HashUpgrades } from "./HashUpgrades";
|
||||
|
||||
@ -105,24 +92,15 @@ export function purchaseHacknet() {
|
||||
}
|
||||
|
||||
export function hasMaxNumberHacknetServers() {
|
||||
return hasHacknetServers() && Player.hacknetNodes.length >= MaxNumberHacknetServers;
|
||||
return hasHacknetServers() && Player.hacknetNodes.length >= HacknetServerConstants.MaxServers;
|
||||
}
|
||||
|
||||
export function getCostOfNextHacknetNode() {
|
||||
// Cost increases exponentially based on how many you own
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const mult = HacknetNodePurchaseNextMult;
|
||||
|
||||
return BaseCostForHacknetNode * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
||||
return calculateNodeCost(Player.hacknetNodes.length+1, Player.hacknet_node_purchase_cost_mult);
|
||||
}
|
||||
|
||||
export function getCostOfNextHacknetServer() {
|
||||
const numOwned = Player.hacknetNodes.length;
|
||||
const mult = HacknetServerPurchaseMult;
|
||||
|
||||
if (numOwned >= MaxNumberHacknetServers) { return Infinity; }
|
||||
|
||||
return BaseCostForHacknetServer * Math.pow(mult, numOwned) * Player.hacknet_node_purchase_cost_mult;
|
||||
return calculateServerCost(Player.hacknetNodes.length+1, Player.hacknet_node_purchase_cost_mult);
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// If we're at max level, return false
|
||||
if (node.level >= (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
|
||||
if (node.level >= (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the number of specified upgrades would exceed the max level, calculate
|
||||
// the maximum number of upgrades and use that
|
||||
if (node.level + sanitizedLevels > (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel)) {
|
||||
const diff = Math.max(0, (isServer ? HacknetServerMaxLevel : HacknetNodeMaxLevel) - node.level);
|
||||
if (node.level + sanitizedLevels > (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel)) {
|
||||
const diff = Math.max(0, (isServer ? HacknetServerConstants.MaxLevel : HacknetNodeConstants.MaxLevel) - node.level);
|
||||
return purchaseLevelUpgrade(node, diff);
|
||||
}
|
||||
|
||||
@ -301,20 +279,20 @@ export function purchaseRamUpgrade(node, levels=1) {
|
||||
const isServer = (node instanceof HacknetServer);
|
||||
|
||||
// Fail if we're already at max
|
||||
if (node.ram >= (isServer ? HacknetServerMaxRam : HacknetNodeMaxRam)) {
|
||||
if (node.ram >= (isServer ? HacknetServerConstants.MaxRam : HacknetNodeConstants.MaxRam)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the number of specified upgrades would exceed the max RAM, calculate the
|
||||
// max possible number of upgrades and use that
|
||||
if (isServer) {
|
||||
if (node.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerMaxRam) {
|
||||
const diff = Math.max(0, Math.log2(Math.round(HacknetServerMaxRam / node.maxRam)));
|
||||
if (node.maxRam * Math.pow(2, sanitizedLevels) > HacknetServerConstants.MaxRam) {
|
||||
const diff = Math.max(0, Math.log2(Math.round(HacknetServerConstants.MaxRam / node.maxRam)));
|
||||
return purchaseRamUpgrade(node, diff);
|
||||
}
|
||||
} else {
|
||||
if (node.ram * Math.pow(2, sanitizedLevels) > HacknetNodeMaxRam) {
|
||||
const diff = Math.max(0, Math.log2(Math.round(HacknetNodeMaxRam / node.ram)));
|
||||
if (node.ram * Math.pow(2, sanitizedLevels) > HacknetNodeConstants.MaxRam) {
|
||||
const diff = Math.max(0, Math.log2(Math.round(HacknetNodeConstants.MaxRam / node.ram)));
|
||||
return purchaseRamUpgrade(node, diff);
|
||||
}
|
||||
}
|
||||
@ -340,14 +318,14 @@ export function purchaseCoreUpgrade(node, levels=1) {
|
||||
const isServer = (node instanceof HacknetServer);
|
||||
|
||||
// Fail if we're already at max
|
||||
if (node.cores >= (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
|
||||
if (node.cores >= (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the specified number of upgrades would exceed the max Cores, calculate
|
||||
// the max possible number of upgrades and use that
|
||||
if (node.cores + sanitizedLevels > (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores)) {
|
||||
const diff = Math.max(0, (isServer ? HacknetServerMaxCores : HacknetNodeMaxCores) - node.cores);
|
||||
if (node.cores + sanitizedLevels > (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores)) {
|
||||
const diff = Math.max(0, (isServer ? HacknetServerConstants.MaxCores : HacknetNodeConstants.MaxCores) - node.cores);
|
||||
return purchaseCoreUpgrade(node, diff);
|
||||
}
|
||||
|
||||
@ -374,8 +352,8 @@ export function purchaseCacheUpgrade(node, levels=1) {
|
||||
}
|
||||
|
||||
// Fail if we're already at max
|
||||
if (node.cache + sanitizedLevels > HacknetServerMaxCache) {
|
||||
const diff = Math.max(0, HacknetServerMaxCache - node.cache);
|
||||
if (node.cache + sanitizedLevels > HacknetServerConstants.MaxCache) {
|
||||
const diff = Math.max(0, HacknetServerConstants.MaxCache - node.cache);
|
||||
return purchaseCacheUpgrade(node, diff);
|
||||
}
|
||||
|
||||
|
@ -9,29 +9,19 @@ import { IHacknetNode } from "./IHacknetNode";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import {
|
||||
calculateMoneyGainRate,
|
||||
calculateLevelUpgradeCost,
|
||||
calculateCoreUpgradeCost,
|
||||
calculateRamUpgradeCost,
|
||||
} from "./formulas/HacknetNodes";
|
||||
import { HacknetNodeConstants } from "./data/Constants";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
import { Generic_fromJSON,
|
||||
Generic_toJSON,
|
||||
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 {
|
||||
/**
|
||||
* 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
|
||||
calculateCoreUpgradeCost(levels: number=1, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
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;
|
||||
return calculateCoreUpgradeCost(this.cores, levels, costMult);
|
||||
}
|
||||
|
||||
// Get the cost to upgrade this Node's level
|
||||
calculateLevelUpgradeCost(levels: number=1, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
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;
|
||||
return calculateLevelUpgradeCost(this.level, levels, costMult);
|
||||
}
|
||||
|
||||
// Get the cost to upgrade this Node's RAM
|
||||
calculateRamUpgradeCost(levels: number=1, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
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;
|
||||
return calculateRamUpgradeCost(this.ram, levels, costMult);
|
||||
}
|
||||
|
||||
// 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
|
||||
// Returns a boolean indicating whether new cores were successfully bought
|
||||
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);
|
||||
}
|
||||
|
||||
// Upgrade this Node's level, if possible
|
||||
// Returns a boolean indicating whether the level was successfully updated
|
||||
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);
|
||||
}
|
||||
|
||||
@ -186,14 +114,7 @@ export class HacknetNode implements IHacknetNode {
|
||||
|
||||
// Re-calculate this Node's production and update the moneyGainRatePerSecond prop
|
||||
updateMoneyGainRate(prodMult: number): void {
|
||||
//How much extra $/s is gained per level
|
||||
var gainPerLevel = HacknetNodeMoneyGainPerLevel;
|
||||
|
||||
this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
|
||||
Math.pow(1.035, this.ram - 1) *
|
||||
((this.cores + 5) / 6) *
|
||||
prodMult *
|
||||
BitNodeMultipliers.HacknetNodeMoney;
|
||||
this.moneyGainRatePerSecond = calculateMoneyGainRate(this.level, this.ram, this.cores, prodMult);
|
||||
if (isNaN(this.moneyGainRatePerSecond)) {
|
||||
this.moneyGainRatePerSecond = 0;
|
||||
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 { BaseServer } from "../Server/BaseServer";
|
||||
import { RunningScript } from "../Script/RunningScript";
|
||||
import { HacknetServerConstants } from "./data/Constants";
|
||||
import {
|
||||
calculateHashGainRate,
|
||||
calculateLevelUpgradeCost,
|
||||
calculateRamUpgradeCost,
|
||||
calculateCoreUpgradeCost,
|
||||
calculateCacheUpgradeCost,
|
||||
} from "./formulas/HacknetServers";
|
||||
|
||||
import { createRandomIp } from "../../utils/IPAddress";
|
||||
|
||||
@ -17,29 +25,6 @@ import {
|
||||
Reviver
|
||||
} 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 {
|
||||
adminRights?: boolean;
|
||||
hostname: string;
|
||||
@ -73,7 +58,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
// How long this HacknetServer has existed, in seconds
|
||||
onlineTimeSeconds: number = 0;
|
||||
|
||||
// Total number of hashes earned by this
|
||||
// Total number of hashes earned by this server
|
||||
totalHashesGenerated: number = 0;
|
||||
|
||||
constructor(params: IConstructorParams={ hostname: "", ip: createRandomIp() }) {
|
||||
@ -84,96 +69,19 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
}
|
||||
|
||||
calculateCacheUpgradeCost(levels: number): number {
|
||||
const sanitizedLevels = Math.round(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;
|
||||
return calculateCacheUpgradeCost(this.cache, levels);
|
||||
}
|
||||
|
||||
calculateCoreUpgradeCost(levels: number, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
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;
|
||||
return calculateCoreUpgradeCost(this.cores, levels, costMult);
|
||||
}
|
||||
|
||||
calculateLevelUpgradeCost(levels: number, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
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;
|
||||
return calculateLevelUpgradeCost(this.level, levels, costMult);
|
||||
}
|
||||
|
||||
calculateRamUpgradeCost(levels: number, costMult: number): number {
|
||||
const sanitizedLevels = Math.round(levels);
|
||||
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;
|
||||
return calculateRamUpgradeCost(this.maxRam, levels, costMult);
|
||||
}
|
||||
|
||||
// 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 {
|
||||
this.cache = Math.min(HacknetServerMaxCache, Math.round(this.cache + levels));
|
||||
this.cache = Math.min(HacknetServerConstants.MaxCache, Math.round(this.cache + levels));
|
||||
this.updateHashCapacity();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -202,7 +110,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
for (let i = 0; i < levels; ++i) {
|
||||
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);
|
||||
|
||||
return true;
|
||||
@ -221,14 +129,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
|
||||
}
|
||||
|
||||
updateHashRate(prodMult: number): void {
|
||||
const baseGain = HacknetServerHashesPerLevel * this.level;
|
||||
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;
|
||||
this.hashRate = calculateHashGainRate(this.level, this.ramUsed, this.maxRam, this.cores, prodMult)
|
||||
|
||||
if (isNaN(this.hashRate)) {
|
||||
this.hashRate = 0;
|
||||
|
@ -7,6 +7,7 @@
|
||||
* those upgrades
|
||||
*/
|
||||
import { HashUpgrades } from "./HashUpgrades";
|
||||
import { HashUpgrade } from "./HashUpgrade";
|
||||
|
||||
import { IMap } from "../types";
|
||||
import { Generic_fromJSON,
|
||||
@ -67,11 +68,20 @@ export class HashManager {
|
||||
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
|
||||
*/
|
||||
getUpgradeCost(upgName: string): number {
|
||||
const upg = HashUpgrades[upgName];
|
||||
const upg = this.getUpgrade(upgName);
|
||||
const currLevel = this.upgrades[upgName];
|
||||
if (upg == null || currLevel == null) {
|
||||
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;
|
||||
}
|
@ -4,11 +4,7 @@
|
||||
*/
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
HacknetNodeMaxLevel,
|
||||
HacknetNodeMaxRam,
|
||||
HacknetNodeMaxCores
|
||||
} from "../HacknetNode";
|
||||
import { HacknetNodeConstants } from "../data/Constants";
|
||||
import {
|
||||
getMaxNumberLevelUpgrades,
|
||||
getMaxNumberRamUpgrades,
|
||||
@ -21,6 +17,8 @@ import {
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
|
||||
export class HacknetNode extends React.Component {
|
||||
render() {
|
||||
@ -29,21 +27,21 @@ export class HacknetNode extends React.Component {
|
||||
const recalculate = this.props.recalculate;
|
||||
|
||||
// Upgrade Level Button
|
||||
let upgradeLevelText, upgradeLevelClass;
|
||||
if (node.level >= HacknetNodeMaxLevel) {
|
||||
upgradeLevelText = "MAX LEVEL";
|
||||
let upgradeLevelContent, upgradeLevelClass;
|
||||
if (node.level >= HacknetNodeConstants.MaxLevel) {
|
||||
upgradeLevelContent = <>MAX LEVEL</>;
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel);
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetNodeConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetNodeMaxLevel - node.level;
|
||||
const levelsToMax = HacknetNodeConstants.MaxLevel - node.level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
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)) {
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -53,28 +51,28 @@ export class HacknetNode extends React.Component {
|
||||
const upgradeLevelOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeMaxLevel);
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetNodeConstants.MaxLevel);
|
||||
}
|
||||
purchaseLevelUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
return false;
|
||||
}
|
||||
|
||||
let upgradeRamText, upgradeRamClass;
|
||||
if (node.ram >= HacknetNodeMaxRam) {
|
||||
upgradeRamText = "MAX RAM";
|
||||
let upgradeRamContent, upgradeRamClass;
|
||||
if (node.ram >= HacknetNodeConstants.MaxRam) {
|
||||
upgradeRamContent = <>MAX RAM</>;
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam);
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetNodeConstants.MaxRam);
|
||||
} 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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -84,28 +82,28 @@ export class HacknetNode extends React.Component {
|
||||
const upgradeRamOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeMaxRam);
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetNodeConstants.MaxRam);
|
||||
}
|
||||
purchaseRamUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
return false;
|
||||
}
|
||||
|
||||
let upgradeCoresText, upgradeCoresClass;
|
||||
if (node.cores >= HacknetNodeMaxCores) {
|
||||
upgradeCoresText = "MAX CORES";
|
||||
let upgradeCoresContent, upgradeCoresClass;
|
||||
if (node.cores >= HacknetNodeConstants.MaxCores) {
|
||||
upgradeCoresContent = <>MAX CORES</>;
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores);
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetNodeConstants.MaxCores);
|
||||
} else {
|
||||
const levelsToMax = HacknetNodeMaxCores - node.cores;
|
||||
const levelsToMax = HacknetNodeConstants.MaxCores - node.cores;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
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)) {
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -115,7 +113,7 @@ export class HacknetNode extends React.Component {
|
||||
const upgradeCoresOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeMaxCores);
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetNodeConstants.MaxCores);
|
||||
}
|
||||
purchaseCoreUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@ -132,25 +130,25 @@ export class HacknetNode extends React.Component {
|
||||
<div className={"row"}>
|
||||
<p>Production:</p>
|
||||
<span className={"text money-gold"}>
|
||||
{numeralWrapper.formatMoney(node.totalMoneyGenerated)} ({numeralWrapper.formatMoney(node.moneyGainRatePerSecond)} / sec)
|
||||
{Money(node.totalMoneyGenerated)} ({MoneyRate(node.moneyGainRatePerSecond)})
|
||||
</span>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
||||
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
||||
{upgradeLevelText}
|
||||
{upgradeLevelContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>RAM:</p><span className={"text upgradable-info"}>{node.ram}GB</span>
|
||||
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
||||
{upgradeRamText}
|
||||
{upgradeRamContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
||||
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
||||
{upgradeCoresText}
|
||||
{upgradeCoresContent}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,12 +4,7 @@
|
||||
*/
|
||||
import React from "react";
|
||||
|
||||
import {
|
||||
HacknetServerMaxLevel,
|
||||
HacknetServerMaxRam,
|
||||
HacknetServerMaxCores,
|
||||
HacknetServerMaxCache
|
||||
} from "../HacknetServer";
|
||||
import { HacknetServerConstants } from "../data/Constants";
|
||||
import {
|
||||
getMaxNumberLevelUpgrades,
|
||||
getMaxNumberRamUpgrades,
|
||||
@ -25,6 +20,9 @@ import {
|
||||
import { Player } from "../../Player";
|
||||
|
||||
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 {
|
||||
render() {
|
||||
@ -33,21 +31,21 @@ export class HacknetServer extends React.Component {
|
||||
const recalculate = this.props.recalculate;
|
||||
|
||||
// Upgrade Level Button
|
||||
let upgradeLevelText, upgradeLevelClass;
|
||||
if (node.level >= HacknetServerMaxLevel) {
|
||||
upgradeLevelText = "MAX LEVEL";
|
||||
let upgradeLevelContent, upgradeLevelClass;
|
||||
if (node.level >= HacknetServerConstants.MaxLevel) {
|
||||
upgradeLevelContent = <>MAX LEVEL</>;
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel);
|
||||
multiplier = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerMaxLevel - node.level;
|
||||
const levelsToMax = HacknetServerConstants.MaxLevel - node.level;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
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)) {
|
||||
upgradeLevelClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -57,7 +55,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeLevelOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerMaxLevel);
|
||||
numUpgrades = getMaxNumberLevelUpgrades(node, HacknetServerConstants.MaxLevel);
|
||||
}
|
||||
purchaseLevelUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@ -65,21 +63,21 @@ export class HacknetServer extends React.Component {
|
||||
}
|
||||
|
||||
// Upgrade RAM Button
|
||||
let upgradeRamText, upgradeRamClass;
|
||||
if (node.maxRam >= HacknetServerMaxRam) {
|
||||
upgradeRamText = "MAX RAM";
|
||||
let upgradeRamContent, upgradeRamClass;
|
||||
if (node.maxRam >= HacknetServerConstants.MaxRam) {
|
||||
upgradeRamContent = <>MAX RAM</>;
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetServerMaxRam);
|
||||
multiplier = getMaxNumberRamUpgrades(node, HacknetServerConstants.MaxRam);
|
||||
} 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);
|
||||
}
|
||||
|
||||
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)) {
|
||||
upgradeRamClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -89,7 +87,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeRamOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerMaxRam);
|
||||
numUpgrades = getMaxNumberRamUpgrades(node, HacknetServerConstants.MaxRam);
|
||||
}
|
||||
purchaseRamUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@ -97,21 +95,21 @@ export class HacknetServer extends React.Component {
|
||||
}
|
||||
|
||||
// Upgrade Cores Button
|
||||
let upgradeCoresText, upgradeCoresClass;
|
||||
if (node.cores >= HacknetServerMaxCores) {
|
||||
upgradeCoresText = "MAX CORES";
|
||||
let upgradeCoresContent, upgradeCoresClass;
|
||||
if (node.cores >= HacknetServerConstants.MaxCores) {
|
||||
upgradeCoresContent = <>MAX CORES</>;
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores);
|
||||
multiplier = getMaxNumberCoreUpgrades(node, HacknetServerConstants.MaxCores);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerMaxCores - node.cores;
|
||||
const levelsToMax = HacknetServerConstants.MaxCores - node.cores;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
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)) {
|
||||
upgradeCoresClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -121,7 +119,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeCoresOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerMaxCores);
|
||||
numUpgrades = getMaxNumberCoreUpgrades(node, HacknetServerConstants.MaxCores);
|
||||
}
|
||||
purchaseCoreUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@ -129,21 +127,21 @@ export class HacknetServer extends React.Component {
|
||||
}
|
||||
|
||||
// Upgrade Cache button
|
||||
let upgradeCacheText, upgradeCacheClass;
|
||||
if (node.cache >= HacknetServerMaxCache) {
|
||||
upgradeCacheText = "MAX CACHE";
|
||||
let upgradeCacheContent, upgradeCacheClass;
|
||||
if (node.cache >= HacknetServerConstants.MaxCache) {
|
||||
upgradeCacheContent = <>MAX CACHE</>;
|
||||
upgradeCacheClass = "std-button-disabled";
|
||||
} else {
|
||||
let multiplier = 0;
|
||||
if (purchaseMult === "MAX") {
|
||||
multiplier = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache);
|
||||
multiplier = getMaxNumberCacheUpgrades(node, HacknetServerConstants.MaxCache);
|
||||
} else {
|
||||
const levelsToMax = HacknetServerMaxCache - node.cache;
|
||||
const levelsToMax = HacknetServerConstants.MaxCache - node.cache;
|
||||
multiplier = Math.min(levelsToMax, purchaseMult);
|
||||
}
|
||||
|
||||
const upgradeCacheCost = node.calculateCacheUpgradeCost(multiplier);
|
||||
upgradeCacheText = `Upgrade x${multiplier} - ${numeralWrapper.formatMoney(upgradeCacheCost)}`;
|
||||
upgradeCacheContent = <>Upgrade x{multiplier} - {Money(upgradeCacheCost)}</>;
|
||||
if (Player.money.lt(upgradeCacheCost)) {
|
||||
upgradeCacheClass = "std-button-disabled";
|
||||
} else {
|
||||
@ -153,7 +151,7 @@ export class HacknetServer extends React.Component {
|
||||
const upgradeCacheOnClick = () => {
|
||||
let numUpgrades = purchaseMult;
|
||||
if (purchaseMult === "MAX") {
|
||||
numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerMaxCache);
|
||||
numUpgrades = getMaxNumberCacheUpgrades(node, HacknetServerConstants.MaxCache);
|
||||
}
|
||||
purchaseCacheUpgrade(node, numUpgrades);
|
||||
recalculate();
|
||||
@ -171,7 +169,7 @@ export class HacknetServer extends React.Component {
|
||||
<div className={"row"}>
|
||||
<p>Production:</p>
|
||||
<span className={"text money-gold"}>
|
||||
{numeralWrapper.formatBigNumber(node.totalHashesGenerated)} ({numeralWrapper.formatBigNumber(node.hashRate)} / sec)
|
||||
{Hashes(node.totalHashesGenerated)} ({HashRate(node.hashRate)})
|
||||
</span>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
@ -181,25 +179,25 @@ export class HacknetServer extends React.Component {
|
||||
<div className={"row"}>
|
||||
<p>Level:</p><span className={"text upgradable-info"}>{node.level}</span>
|
||||
<button className={upgradeLevelClass} onClick={upgradeLevelOnClick}>
|
||||
{upgradeLevelText}
|
||||
{upgradeLevelContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>RAM:</p><span className={"text upgradable-info"}>{node.maxRam}GB</span>
|
||||
<button className={upgradeRamClass} onClick={upgradeRamOnClick}>
|
||||
{upgradeRamText}
|
||||
{upgradeRamContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Cores:</p><span className={"text upgradable-info"}>{node.cores}</span>
|
||||
<button className={upgradeCoresClass} onClick={upgradeCoresOnClick}>
|
||||
{upgradeCoresText}
|
||||
{upgradeCoresContent}
|
||||
</button>
|
||||
</div>
|
||||
<div className={"row"}>
|
||||
<p>Cache Level:</p><span className={"text upgradable-info"}>{node.cache}</span>
|
||||
<button className={upgradeCacheClass} onClick={upgradeCacheOnClick}>
|
||||
{upgradeCacheText}
|
||||
{upgradeCacheContent}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,6 +19,8 @@ import { ServerDropdown,
|
||||
ServerType } from "../../ui/React/ServerDropdown"
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import { CopyableText } from "../../ui/React/CopyableText";
|
||||
import { Hashes } from "../../ui/React/Hashes";
|
||||
|
||||
class HashUpgrade extends React.Component {
|
||||
constructor(props) {
|
||||
@ -63,8 +65,8 @@ class HashUpgrade extends React.Component {
|
||||
// We'll reuse a Bladeburner css class
|
||||
return (
|
||||
<div className={"bladeburner-action"}>
|
||||
<h2>{upg.name}</h2>
|
||||
<p>Cost: {numeralWrapper.format(cost, "0.000a")}</p>
|
||||
<CopyableText value={upg.name} />
|
||||
<p>Cost: {Hashes(cost)}</p>
|
||||
<p>{upg.desc}</p>
|
||||
<button className={btnClass} onClick={this.purchase}>
|
||||
Purchase
|
||||
@ -122,7 +124,7 @@ export class HashUpgradePopup extends React.Component {
|
||||
<div>
|
||||
<PopupCloseButton popup={this.props.popupId} text={"Close"} />
|
||||
<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}
|
||||
</div>
|
||||
)
|
||||
|
@ -9,43 +9,33 @@ import React from "react";
|
||||
import { hasHacknetServers } from "../HacknetHelpers";
|
||||
import { Player } from "../../Player";
|
||||
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) {
|
||||
const hasServers = hasHacknetServers();
|
||||
|
||||
let prod;
|
||||
if (hasServers) {
|
||||
prod = numeralWrapper.format(props.totalProduction, "0.000a") + " hashes / sec";
|
||||
prod = HashRate(props.totalProduction);
|
||||
} else {
|
||||
prod = numeralWrapper.formatMoney(props.totalProduction) + " / sec";
|
||||
}
|
||||
|
||||
let hashInfo;
|
||||
if (hasServers) {
|
||||
hashInfo = numeralWrapper.format(Player.hashManager.hashes, "0.000a") + " / " +
|
||||
numeralWrapper.format(Player.hashManager.capacity, "0.000a");
|
||||
prod = MoneyRate(props.totalProduction);
|
||||
}
|
||||
|
||||
return (
|
||||
<p id={"hacknet-nodes-money"}>
|
||||
<span>Money:</span>
|
||||
<span className={"money-gold"}>{numeralWrapper.formatMoney(Player.money.toNumber())}</span><br />
|
||||
<span>Money: </span>
|
||||
{Money(Player.money.toNumber())}<br />
|
||||
|
||||
{
|
||||
hasServers &&
|
||||
<span>Hashes:</span>
|
||||
}
|
||||
{
|
||||
hasServers &&
|
||||
<span className={"money-gold"}>{hashInfo}</span>
|
||||
}
|
||||
{
|
||||
hasServers &&
|
||||
<br />
|
||||
<><span>Hashes: {Hashes(Player.hashManager.hashes)} / {Hashes(Player.hashManager.capacity)}</span><br /></>
|
||||
}
|
||||
|
||||
<span>Total Hacknet Node Production:</span>
|
||||
<span className={"money-gold"}>{prod}</span>
|
||||
<span>Total Hacknet Node Production: </span>
|
||||
{prod}
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import { hasHacknetServers,
|
||||
hasMaxNumberHacknetServers } from "../HacknetHelpers";
|
||||
import { Player } from "../../Player";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
export function PurchaseButton(props) {
|
||||
if (props.multiplier == null || props.onClick == null) {
|
||||
@ -20,13 +21,13 @@ export function PurchaseButton(props) {
|
||||
if (hasHacknetServers()) {
|
||||
if (hasMaxNumberHacknetServers()) {
|
||||
className = "std-button-disabled";
|
||||
text = "Hacknet Server limit reached";
|
||||
text = <>Hacknet Server limit reached</>;
|
||||
style = {color: "red"};
|
||||
} else {
|
||||
text = `Purchase Hacknet Server - ${numeralWrapper.formatMoney(cost)}`;
|
||||
text = <>Purchase Hacknet Server - {Money(cost)}</>;
|
||||
}
|
||||
} else {
|
||||
text = `Purchase Hacknet Node - ${numeralWrapper.formatMoney(cost)}`;
|
||||
text = <>Purchase Hacknet Node - {Money(cost)}</>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -21,6 +21,7 @@ import { SpecialServerIps } from "../Server/SpecialServerIps";
|
||||
import { Settings } from "../Settings/Settings";
|
||||
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import { Money } from "../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
import {
|
||||
@ -38,6 +39,7 @@ import { createElement } from "../../utils/uiHelpers/createElement";
|
||||
import { createPopup } from "../../utils/uiHelpers/createPopup";
|
||||
import { createPopupCloseButton } from "../../utils/uiHelpers/createPopupCloseButton";
|
||||
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.
|
||||
@ -49,7 +51,7 @@ import { removeElementById } from "../../utils/uiHelpers/removeElementById";
|
||||
*/
|
||||
type TravelFunction = (to: CityName) => void;
|
||||
export function createTravelPopup(destination: CityName, travelFn: TravelFunction): void {
|
||||
const cost = CONSTANTS.TravelCost;
|
||||
const cost: number = CONSTANTS.TravelCost;
|
||||
|
||||
if (Settings.SuppressTravelConfirmation) {
|
||||
travelFn(destination);
|
||||
@ -76,8 +78,8 @@ export function createTravelPopup(destination: CityName, travelFn: TravelFunctio
|
||||
return false;
|
||||
});
|
||||
|
||||
yesNoBoxCreate(`Would you like to travel to ${destination}? The trip will ` +
|
||||
`cost ${numeralWrapper.formatMoney(cost)}`);
|
||||
yesNoBoxCreate(<span>Would you like to travel to ${destination}? The trip will
|
||||
cost {Money(cost)}.</span>);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,10 +107,9 @@ export function createPurchaseServerPopup(ram: number, p: IPlayer): void {
|
||||
yesNoTxtInpBoxClose();
|
||||
});
|
||||
|
||||
yesNoTxtInpBoxCreate(
|
||||
`Would you like to purchase a new server with ${ram} GB of RAM for ` +
|
||||
`${numeralWrapper.formatMoney(cost)}?<br><br>Please enter the server hostname below:<br>`
|
||||
);
|
||||
yesNoTxtInpBoxCreate(<>Would you like to purchase a new server with {numeralWrapper.formatRAM(ram)} of RAM for {Money(cost)}?
|
||||
<br /><br />Please enter the server hostname below:<br />
|
||||
</>);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,12 +237,10 @@ export function createUpgradeHomeCoresPopup(p: IPlayer) {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
yesNoBoxCreate(
|
||||
"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>" +
|
||||
"Purchasing an additional core (for a total of " + (p.getHomeComputer().cpuCores + 1) + ") will " +
|
||||
"cost " + numeralWrapper.formatMoney(cost)
|
||||
);
|
||||
yesNoBoxCreate(<>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 />
|
||||
Purchasing an additional core (for a total of {p.getHomeComputer().cpuCores + 1}) will
|
||||
cost {Money(cost)}</>);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -267,11 +266,11 @@ export function createUpgradeHomeRamPopup(p: IPlayer) {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
|
||||
yesNoBoxCreate(
|
||||
"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 cost " + numeralWrapper.format(cost, '$0.000a')
|
||||
);
|
||||
yesNoBoxCreate(<>
|
||||
Would you like to purchase additional RAM for your home computer? <br /><br />
|
||||
This will upgrade your RAM from {numeralWrapper.formatRAM(ram)} to {numeralWrapper.formatRAM(ram*2)}. <br /><br />
|
||||
This will cost {Money(cost)}
|
||||
</>);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,8 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { Favor } from "../../ui/React/Favor";
|
||||
|
||||
type IProps = {
|
||||
engine: IEngine;
|
||||
@ -34,6 +36,10 @@ type IState = {
|
||||
employedHere: boolean;
|
||||
}
|
||||
|
||||
const blockStyleMarkup = {
|
||||
display: "block",
|
||||
}
|
||||
|
||||
export class CompanyLocation extends React.Component<IProps, IState> {
|
||||
/**
|
||||
* 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 &&
|
||||
<div>
|
||||
<p>Job Title: {this.jobTitle}</p>
|
||||
<p>--------------------</p>
|
||||
<br /><p style={blockStyleMarkup}>-------------------------</p><br />
|
||||
<p className={"tooltip"}>
|
||||
Company reputation: {numeralWrapper.format(this.company.playerReputation, "0,0.000")}
|
||||
Company reputation: {Reputation(this.company.playerReputation)}
|
||||
<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
|
||||
</span>
|
||||
</p>
|
||||
<p>--------------------</p>
|
||||
</p><br />
|
||||
<br /><p style={blockStyleMarkup}>-------------------------</p><br />
|
||||
<p className={"tooltip"}>
|
||||
Company Favor: {numeralWrapper.format(this.company.favor, "0,0")}
|
||||
Company Favor: {Favor(this.company.favor)}
|
||||
<span className={"tooltiptext"}>
|
||||
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
|
||||
of favor you gain depends on how much reputation you have with the comapny.
|
||||
</span>
|
||||
</p>
|
||||
</p><br />
|
||||
<br /><p style={blockStyleMarkup}>-------------------------</p><br />
|
||||
<StdButton
|
||||
id={"foo-work-button-id"}
|
||||
onClick={this.work}
|
||||
|
@ -12,6 +12,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
@ -66,22 +67,22 @@ export class GymLocation extends React.Component<IProps, any> {
|
||||
<StdButton
|
||||
onClick={this.trainStrength}
|
||||
style={this.btnStyle}
|
||||
text={`Train Strength (${numeralWrapper.formatMoney(cost)} / sec)`}
|
||||
text={<>Train Strength ({Money(cost)} / sec)</>}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.trainDefense}
|
||||
style={this.btnStyle}
|
||||
text={`Train Defense (${numeralWrapper.formatMoney(cost)} / sec)`}
|
||||
text={<>Train Defense ({Money(cost)} / sec)</>}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.trainDexterity}
|
||||
style={this.btnStyle}
|
||||
text={`Train Dexterity (${numeralWrapper.formatMoney(cost)} / sec)`}
|
||||
text={<>Train Dexterity ({Money(cost)} / sec)</>}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.trainAgility}
|
||||
style={this.btnStyle}
|
||||
text={`Train Agility (${numeralWrapper.formatMoney(cost)} / sec)`}
|
||||
text={<>Train Agility ({Money(cost)} / sec)</>}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
@ -10,6 +10,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { AutoupdatingStdButton } from "../../ui/React/AutoupdatingStdButton";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
@ -59,7 +60,7 @@ export class HospitalLocation extends React.Component<IProps, IState> {
|
||||
currHp: this.props.p.hp,
|
||||
});
|
||||
|
||||
dialogBoxCreate(`You were healed to full health! The hospital billed you for ${numeralWrapper.formatMoney(cost)}`);
|
||||
dialogBoxCreate(<>You were healed to full health! The hospital billed you for {Money(cost)}</>);
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -69,7 +70,7 @@ export class HospitalLocation extends React.Component<IProps, IState> {
|
||||
<AutoupdatingStdButton
|
||||
onClick={this.getHealed}
|
||||
style={this.btnStyle}
|
||||
text={`Get treatment for wounds - ${numeralWrapper.formatMoney(cost)}`}
|
||||
text={<>Get treatment for wounds - {Money(cost)}</>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import { getPurchaseServerCost } from "../../Server/ServerPurchases";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StdButtonPurchased } from "../../ui/React/StdButtonPurchased";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
@ -70,7 +71,7 @@ export class TechVendorLocation extends React.Component<IProps, any> {
|
||||
key={i}
|
||||
onClick={() => createPurchaseServerPopup(i, this.props.p)}
|
||||
style={this.btnStyle}
|
||||
text={`Purchase ${i}GB Server - ${numeralWrapper.formatMoney(cost)}`}
|
||||
text={<>Purchase {i}GB Server - {Money(cost)}</>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -88,7 +89,7 @@ export class TechVendorLocation extends React.Component<IProps, any> {
|
||||
<StdButton
|
||||
onClick={this.purchaseTorRouter}
|
||||
style={this.btnStyle}
|
||||
text={`Purchase TOR Router - ${numeralWrapper.formatMoney(CONSTANTS.TorRouterCost)}`}
|
||||
text={<>Purchase TOR Router - {Money(CONSTANTS.TorRouterCost)}</>}
|
||||
/>
|
||||
)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/**
|
||||
* React Subcomponent for displaying a location's UI, when that location is a Travel Agency
|
||||
*
|
||||
* This subcomponent renders all of the buttons for traveling to different cities
|
||||
* TThis subcomponent renders all of the buttons for traveling to different cities
|
||||
*/
|
||||
import * as React from "react";
|
||||
|
||||
@ -13,6 +13,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
type IProps = {
|
||||
p: IPlayer;
|
||||
@ -48,7 +49,7 @@ export class TravelAgencyLocation extends React.Component<IProps, any> {
|
||||
<div>
|
||||
<p>
|
||||
From here, you can travel to any other city! A ticket
|
||||
costs {numeralWrapper.formatMoney(CONSTANTS.TravelCost)}
|
||||
costs {Money(CONSTANTS.TravelCost)}.
|
||||
</p>
|
||||
<pre> ,_ . ._. _. .</pre>
|
||||
<pre> , _-\','|~\~ ~/ ;-'_ _-' ,;_;_, ~~-</pre>
|
||||
|
@ -12,6 +12,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
@ -90,31 +91,31 @@ export class UniversityLocation extends React.Component<IProps, any> {
|
||||
<StdButton
|
||||
onClick={this.dataStructures}
|
||||
style={this.btnStyle}
|
||||
text={`Take Data Structures course (${numeralWrapper.formatMoney(dataStructuresCost)} / sec)`}
|
||||
text={<>Take Data Structures course ({Money(dataStructuresCost)} / sec)</>}
|
||||
tooltip={earnHackingExpTooltip}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.networks}
|
||||
style={this.btnStyle}
|
||||
text={`Take Networks course (${numeralWrapper.formatMoney(networksCost)} / sec)`}
|
||||
text={<>Take Networks course ({Money(networksCost)} / sec)</>}
|
||||
tooltip={earnHackingExpTooltip}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.algorithms}
|
||||
style={this.btnStyle}
|
||||
text={`Take Algorithms course (${numeralWrapper.formatMoney(algorithmsCost)} / sec)`}
|
||||
text={<>Take Algorithms course ({Money(algorithmsCost)} / sec)</>}
|
||||
tooltip={earnHackingExpTooltip}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.management}
|
||||
style={this.btnStyle}
|
||||
text={`Take Management course (${numeralWrapper.formatMoney(managementCost)} / sec)`}
|
||||
text={<>Take Management course ({Money(managementCost)} / sec)</>}
|
||||
tooltip={earnCharismaExpTooltip}
|
||||
/>
|
||||
<StdButton
|
||||
onClick={this.leadership}
|
||||
style={this.btnStyle}
|
||||
text={`Take Leadership course (${numeralWrapper.formatMoney(leadershipCost)} / sec)`}
|
||||
text={<>Take Leadership course ({Money(leadershipCost)} / sec)</>}
|
||||
tooltip={earnCharismaExpTooltip}
|
||||
/>
|
||||
</div>
|
||||
|
@ -6,6 +6,7 @@ import { Player } from "./Player";
|
||||
import { dialogBoxCreate } from "../utils/DialogBox";
|
||||
import { formatNumber } from "../utils/StringHelperFunctions";
|
||||
import { numeralWrapper } from "./ui/numeralFormat";
|
||||
import { Reputation } from "./ui/React/Reputation";
|
||||
|
||||
import { addOffset } from "../utils/helpers/addOffset";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
@ -15,6 +16,9 @@ import { clearEventListeners } from "../utils/uiHelpers/clearEventListeners";
|
||||
|
||||
import jsplumb from "jsplumb";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
|
||||
let inMission = false; // Flag to denote whether a mission is running
|
||||
let currMission = null;
|
||||
@ -286,9 +290,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
var favorMult = 1 + (this.faction.favor / 100);
|
||||
var gain = this.reward * Player.faction_rep_mult * favorMult;
|
||||
var headerText = document.createElement("p");
|
||||
headerText.innerHTML = "You are about to start a hacking mission! You will gain " +
|
||||
numeralWrapper.format(gain, '0.000a') + " faction reputation with " + this.faction.name +
|
||||
" if you win. Click the 'Start' button to begin.";
|
||||
ReactDOM.render(<>You are about to start a hacking mission! You will gain {Reputation(gain)} faction reputation with {this.faction.name} if you win. Click the 'Start' button to begin.</>, headerText);
|
||||
headerText.style.display = "block";
|
||||
headerText.classList.add("hack-mission-header-element");
|
||||
headerText.style.width = "80%";
|
||||
@ -310,7 +312,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
startBtn.classList.add("a-link-button");
|
||||
startBtn.classList.add("hack-mission-header-element");
|
||||
startBtn.style.display = "inline-block";
|
||||
startBtn.addEventListener("click", ()=>{
|
||||
startBtn.addEventListener("click", () => {
|
||||
this.start();
|
||||
return false;
|
||||
});
|
||||
@ -320,7 +322,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
forfeitMission.classList.add("a-link-button");
|
||||
forfeitMission.classList.add("hack-mission-header-element");
|
||||
forfeitMission.style.display = "inline-block";
|
||||
forfeitMission.addEventListener("click", ()=> {
|
||||
forfeitMission.addEventListener("click", () => {
|
||||
this.finishMission(false);
|
||||
return false;
|
||||
});
|
||||
@ -394,7 +396,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
actionsContainer.appendChild(enemyStats);
|
||||
|
||||
// Set Action Button event listeners
|
||||
this.actionButtons[0].addEventListener("click", ()=>{
|
||||
this.actionButtons[0].addEventListener("click", () => {
|
||||
if (!(this.selectedNode.length > 0)) {
|
||||
console.error("Pressing Action button without selected node");
|
||||
return;
|
||||
@ -407,7 +409,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
});
|
||||
});
|
||||
|
||||
this.actionButtons[1].addEventListener("click", ()=>{
|
||||
this.actionButtons[1].addEventListener("click", () => {
|
||||
if (!(this.selectedNode.length > 0)) {
|
||||
console.error("Pressing Action button without selected node");
|
||||
return;
|
||||
@ -421,7 +423,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
});
|
||||
});
|
||||
|
||||
this.actionButtons[2].addEventListener("click", ()=>{
|
||||
this.actionButtons[2].addEventListener("click", () => {
|
||||
if (!(this.selectedNode.length > 0)) {
|
||||
console.error("Pressing Action button without selected node");
|
||||
return;
|
||||
@ -435,7 +437,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
});
|
||||
});
|
||||
|
||||
this.actionButtons[3].addEventListener("click", ()=>{
|
||||
this.actionButtons[3].addEventListener("click", () => {
|
||||
if (!(this.selectedNode.length > 0)) {
|
||||
console.error("Pressing Action button without selected node");
|
||||
return;
|
||||
@ -447,7 +449,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
});
|
||||
});
|
||||
|
||||
this.actionButtons[4].addEventListener("click", ()=>{
|
||||
this.actionButtons[4].addEventListener("click", () => {
|
||||
if (!(this.selectedNode.length > 0)) {
|
||||
console.error("Pressing Action button without selected node");
|
||||
return;
|
||||
@ -461,7 +463,7 @@ HackingMission.prototype.createPageDom = function() {
|
||||
});
|
||||
});
|
||||
|
||||
this.actionButtons[5].addEventListener("click", ()=>{
|
||||
this.actionButtons[5].addEventListener("click", () => {
|
||||
if (!(this.selectedNode.length > 0)) {
|
||||
console.error("Pressing Action button without selected node");
|
||||
return;
|
||||
@ -1049,7 +1051,7 @@ HackingMission.prototype.initJsPlumb = function() {
|
||||
});
|
||||
|
||||
// Detach Connection events
|
||||
instance.bind("connectionDetached", (info, originalEvent)=>{
|
||||
instance.bind("connectionDetached", (info, originalEvent) => {
|
||||
var sourceNode = this.getNodeFromElement(info.source);
|
||||
sourceNode.conn = null;
|
||||
var targetNode = this.getNodeFromElement(info.target);
|
||||
@ -1087,11 +1089,11 @@ HackingMission.prototype.process = function(numCycles=1) {
|
||||
|
||||
var res = false;
|
||||
// Process actions of all player nodes
|
||||
this.playerCores.forEach((node)=>{
|
||||
this.playerCores.forEach((node) => {
|
||||
res |= this.processNode(node, storedCycles);
|
||||
});
|
||||
|
||||
this.playerNodes.forEach((node)=>{
|
||||
this.playerNodes.forEach((node) => {
|
||||
if (node.type === NodeTypes.Transfer ||
|
||||
node.type === NodeTypes.Shield ||
|
||||
node.type === NodeTypes.Firewall) {
|
||||
@ -1100,12 +1102,12 @@ HackingMission.prototype.process = function(numCycles=1) {
|
||||
});
|
||||
|
||||
// Process actions of all enemy nodes
|
||||
this.enemyCores.forEach((node)=>{
|
||||
this.enemyCores.forEach((node) => {
|
||||
this.enemyAISelectAction(node);
|
||||
res |= this.processNode(node, storedCycles);
|
||||
});
|
||||
|
||||
this.enemyNodes.forEach((node)=>{
|
||||
this.enemyNodes.forEach((node) => {
|
||||
if (node.type === NodeTypes.Transfer ||
|
||||
node.type === NodeTypes.Shield ||
|
||||
node.type === NodeTypes.Firewall) {
|
||||
@ -1115,7 +1117,7 @@ HackingMission.prototype.process = function(numCycles=1) {
|
||||
});
|
||||
|
||||
// The hp of enemy databases increases slowly
|
||||
this.enemyDatabases.forEach((node)=>{
|
||||
this.enemyDatabases.forEach((node) => {
|
||||
node.maxhp += (0.1 * storedCycles);
|
||||
node.hp += (0.1 * storedCycles);
|
||||
});
|
||||
@ -1138,7 +1140,7 @@ HackingMission.prototype.process = function(numCycles=1) {
|
||||
}
|
||||
|
||||
// Defense/hp of misc nodes increases slowly over time
|
||||
this.miscNodes.forEach((node)=>{
|
||||
this.miscNodes.forEach((node) => {
|
||||
node.def += (0.1 * storedCycles);
|
||||
node.maxhp += (0.05 * storedCycles);
|
||||
node.hp += (0.1 * storedCycles);
|
||||
@ -1353,7 +1355,7 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
||||
|
||||
// If a misc node was conquered, the defense for all misc nodes increases by some fixed amount
|
||||
if (isMiscNode) { //&& conqueredByPlayer) {
|
||||
this.miscNodes.forEach((node)=>{
|
||||
this.miscNodes.forEach((node) => {
|
||||
if (node.targetedCount === 0) {
|
||||
node.def *= CONSTANTS.HackingMissionMiscDefenseIncrease;
|
||||
}
|
||||
@ -1514,8 +1516,7 @@ HackingMission.prototype.finishMission = function(win) {
|
||||
if (win) {
|
||||
var favorMult = 1 + (this.faction.favor / 100);
|
||||
var gain = this.reward * Player.faction_rep_mult * favorMult;
|
||||
dialogBoxCreate("Mission won! You earned " +
|
||||
numeralWrapper.format(gain, '0.000a') + " reputation with " + this.faction.name);
|
||||
dialogBoxCreate(<>Mission won! You earned {Reputation(gain)} reputation with {this.faction.name}</>);
|
||||
Player.gainIntelligenceExp(this.difficulty * CONSTANTS.IntelligenceHackingMissionBaseExpGain);
|
||||
this.faction.playerReputation += gain;
|
||||
} else {
|
@ -111,6 +111,7 @@ export const RamCosts: IMap<any> = {
|
||||
getHackingMultipliers: () => RamCostConstants.ScriptGetMultipliersRamCost,
|
||||
getHacknetMultipliers: () => RamCostConstants.ScriptGetMultipliersRamCost,
|
||||
getBitNodeMultipliers: () => RamCostConstants.ScriptGetMultipliersRamCost,
|
||||
getServer: () => RamCostConstants.ScriptGetMultipliersRamCost / 2,
|
||||
getServerMoneyAvailable: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
getServerSecurityLevel: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
getServerBaseSecurityLevel: () => RamCostConstants.ScriptGetServerRamCost,
|
||||
@ -176,10 +177,12 @@ export const RamCosts: IMap<any> = {
|
||||
travelToCity: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||
purchaseTor: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||
purchaseProgram: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||
getCurrentServer: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||
connect: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||
manualHack: () => RamCostConstants.ScriptSingularityFn1RamCost,
|
||||
getStats: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||
getCharacterInformation: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||
getPlayer: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||
isBusy: () => RamCostConstants.ScriptSingularityFn1RamCost / 4,
|
||||
stopAction: () => RamCostConstants.ScriptSingularityFn1RamCost / 2,
|
||||
upgradeHomeRam: () => RamCostConstants.ScriptSingularityFn2RamCost,
|
||||
|
@ -29,6 +29,7 @@ import {
|
||||
calculateGrowTime,
|
||||
calculateWeakenTime
|
||||
} from "./Hacking";
|
||||
import { calculateServerGrowth } from "./Server/formulas/grow";
|
||||
import {
|
||||
AllGangs,
|
||||
GangMemberUpgrades,
|
||||
@ -56,10 +57,30 @@ import {
|
||||
purchaseHashUpgrade,
|
||||
updateHashManagerCapacity,
|
||||
} from "./Hacknet/HacknetHelpers";
|
||||
import {
|
||||
calculateMoneyGainRate,
|
||||
calculateLevelUpgradeCost,
|
||||
calculateRamUpgradeCost,
|
||||
calculateCoreUpgradeCost,
|
||||
calculateNodeCost,
|
||||
} from "./Hacknet/formulas/HacknetNodes";
|
||||
import {
|
||||
calculateHashGainRate as HScalculateHashGainRate,
|
||||
calculateLevelUpgradeCost as HScalculateLevelUpgradeCost,
|
||||
calculateRamUpgradeCost as HScalculateRamUpgradeCost,
|
||||
calculateCoreUpgradeCost as HScalculateCoreUpgradeCost,
|
||||
calculateCacheUpgradeCost as HScalculateCacheUpgradeCost,
|
||||
calculateServerCost as HScalculateServerCost,
|
||||
} from "./Hacknet/formulas/HacknetServers";
|
||||
import { HacknetNodeConstants, HacknetServerConstants } from "./Hacknet/data/Constants";
|
||||
import { HacknetServer, MaxNumberHacknetServers } from "./Hacknet/HacknetServer";
|
||||
import { CityName } from "./Locations/data/CityNames";
|
||||
import { LocationName } from "./Locations/data/LocationNames";
|
||||
import { Terminal } from "./Terminal";
|
||||
import {
|
||||
calculateSkill,
|
||||
calculateExp,
|
||||
} from "./PersonObjects/formulas/skill";
|
||||
|
||||
import { Message } from "./Message/Message";
|
||||
import { Messages } from "./Message/MessageHelpers";
|
||||
@ -449,6 +470,16 @@ function NetscriptFunctions(workerScript) {
|
||||
return makeRuntimeRejectMsg(workerScript, rejectMsg);
|
||||
}
|
||||
|
||||
const checkFormulasAccess = function(func, n) {
|
||||
if (SourceFileFlags[5] < 1 || SourceFileFlags[n] < 1) {
|
||||
let extra = '';
|
||||
if (n !== 5) {
|
||||
extra = ` and Source-File ${n}-1`;
|
||||
}
|
||||
throw makeRuntimeErrorMsg(`formulas.${func}`, `Requires Source-File 5-1${extra} to run.`);
|
||||
}
|
||||
}
|
||||
|
||||
const checkSingularityAccess = function(func, n) {
|
||||
if (Player.bitNodeN !== 4) {
|
||||
if (SourceFileFlags[4] < n) {
|
||||
@ -592,7 +623,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
// Calculate the hacking time
|
||||
var hackingTime = calculateHackingTime(server); // This is in seconds
|
||||
var hackingTime = calculateHackingTime(server, Player); // This is in seconds
|
||||
|
||||
// No root access or skill level too low
|
||||
const canHack = netscriptCanHack(server, Player);
|
||||
@ -604,12 +635,12 @@ function NetscriptFunctions(workerScript) {
|
||||
|
||||
return netscriptDelay(hackingTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var hackChance = calculateHackingChance(server);
|
||||
var hackChance = calculateHackingChance(server, Player);
|
||||
var rand = Math.random();
|
||||
var expGainedOnSuccess = calculateHackingExpGain(server) * threads;
|
||||
var expGainedOnSuccess = calculateHackingExpGain(server, Player) * threads;
|
||||
var expGainedOnFailure = (expGainedOnSuccess / 4);
|
||||
if (rand < hackChance) { // Success!
|
||||
const percentHacked = calculatePercentMoneyHacked(server);
|
||||
const percentHacked = calculatePercentMoneyHacked(server, Player);
|
||||
let maxThreadNeeded = Math.ceil(1/percentHacked*(server.moneyAvailable/server.moneyMax));
|
||||
if (isNaN(maxThreadNeeded)) {
|
||||
// Server has a 'max money' of 0 (probably). We'll set this to an arbitrarily large value
|
||||
@ -636,7 +667,7 @@ function NetscriptFunctions(workerScript) {
|
||||
workerScript.scriptRef.recordHack(server.ip, moneyGained, threads);
|
||||
Player.gainHackingExp(expGainedOnSuccess);
|
||||
workerScript.scriptRef.onlineExpGained += expGainedOnSuccess;
|
||||
workerScript.log("hack", `Successfully hacked '${server.hostname}' for ${numeralWrapper.format(moneyGained, '$0.000a')} and ${numeralWrapper.format(expGainedOnSuccess, '0.000a')} exp (t=${threads})`);
|
||||
workerScript.log("hack", `Successfully hacked '${server.hostname}' for ${numeralWrapper.formatMoney(moneyGained)} and ${numeralWrapper.formatExp(expGainedOnSuccess)} exp (t=${threads})`);
|
||||
server.fortify(CONSTANTS.ServerFortifyAmount * Math.min(threads, maxThreadNeeded));
|
||||
if (stock) {
|
||||
influenceStockThroughServerHack(server, moneyGained);
|
||||
@ -649,7 +680,7 @@ function NetscriptFunctions(workerScript) {
|
||||
// Player only gains 25% exp for failure?
|
||||
Player.gainHackingExp(expGainedOnFailure);
|
||||
workerScript.scriptRef.onlineExpGained += expGainedOnFailure;
|
||||
workerScript.log("hack", `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.format(expGainedOnFailure, '0.000a')} exp (t=${threads})`);
|
||||
workerScript.log("hack", `Failed to hack '${server.hostname}'. Gained ${numeralWrapper.formatExp(expGainedOnFailure)} exp (t=${threads})`);
|
||||
return Promise.resolve(0);
|
||||
}
|
||||
});
|
||||
@ -743,7 +774,22 @@ function NetscriptFunctions(workerScript) {
|
||||
spendHashes : function(upgName, upgTarget) {
|
||||
if (!hasHacknetServers()) { return false; }
|
||||
return purchaseHashUpgrade(upgName, upgTarget);
|
||||
}
|
||||
},
|
||||
getHashUpgradeLevel : function(upgName) {
|
||||
const level = Player.hashManager.upgrades[upgName];
|
||||
if(level === undefined) {
|
||||
throw makeRuntimeErrorMsg("hacknet.hashUpgradeLevel", `Invalid Hash Upgrade: ${upgName}`);
|
||||
}
|
||||
return level;
|
||||
},
|
||||
getStudyMult : function() {
|
||||
if (!hasHacknetServers()) { return false; }
|
||||
return Player.hashManager.getStudyMult();
|
||||
},
|
||||
getTrainingMult : function() {
|
||||
if (!hasHacknetServers()) { return false; }
|
||||
return Player.hashManager.getTrainingMult();
|
||||
},
|
||||
},
|
||||
sprintf : sprintf,
|
||||
vsprintf: vsprintf,
|
||||
@ -786,7 +832,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const percentHacked = calculatePercentMoneyHacked(server);
|
||||
const percentHacked = calculatePercentMoneyHacked(server, Player);
|
||||
|
||||
return hackAmount / Math.floor(server.moneyAvailable * percentHacked);
|
||||
},
|
||||
@ -795,14 +841,14 @@ function NetscriptFunctions(workerScript) {
|
||||
|
||||
const server = safeGetServer(ip, 'hackAnalyzePercent');
|
||||
|
||||
return calculatePercentMoneyHacked(server) * 100;
|
||||
return calculatePercentMoneyHacked(server, Player) * 100;
|
||||
},
|
||||
hackChance : function(ip) {
|
||||
updateDynamicRam("hackChance", getRamCost("hackChance"));
|
||||
|
||||
const server = safeGetServer(ip, 'hackChance');
|
||||
|
||||
return calculateHackingChance(server);
|
||||
return calculateHackingChance(server, Player);
|
||||
},
|
||||
sleep : function(time){
|
||||
if (time === undefined) {
|
||||
@ -830,21 +876,21 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeErrorMsg("grow", canHack.msg);
|
||||
}
|
||||
|
||||
var growTime = calculateGrowTime(server);
|
||||
var growTime = calculateGrowTime(server, Player);
|
||||
workerScript.log("grow", `Executing on '${server.hostname}' in ${formatNumber(growTime, 3)} seconds (t=${threads}).`);
|
||||
return netscriptDelay(growTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
const moneyBefore = server.moneyAvailable <= 0 ? 1 : server.moneyAvailable;
|
||||
server.moneyAvailable += (1 * threads); // It can be grown even if it has no money
|
||||
var growthPercentage = processSingleServerGrowth(server, 450 * threads, Player);
|
||||
var growthPercentage = processSingleServerGrowth(server, threads, Player);
|
||||
const moneyAfter = server.moneyAvailable;
|
||||
workerScript.scriptRef.recordGrow(server.ip, threads);
|
||||
var expGain = calculateHackingExpGain(server) * threads;
|
||||
var expGain = calculateHackingExpGain(server, Player) * threads;
|
||||
if (growthPercentage == 1) {
|
||||
expGain = 0;
|
||||
}
|
||||
const logGrowPercent = (moneyAfter/moneyBefore)*100 - 100;
|
||||
workerScript.log("grow", `Available money on '${server.hostname}' grown by ${formatNumber(logGrowPercent, 6)}%. Gained ${numeralWrapper.format(expGain, '0.000a')} hacking exp (t=${threads}).`);
|
||||
workerScript.log("grow", `Available money on '${server.hostname}' grown by ${formatNumber(logGrowPercent, 6)}%. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${threads}).`);
|
||||
workerScript.scriptRef.onlineExpGained += expGain;
|
||||
Player.gainHackingExp(expGain);
|
||||
if (stock) {
|
||||
@ -881,14 +927,14 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeErrorMsg("weaken", canHack.msg);
|
||||
}
|
||||
|
||||
var weakenTime = calculateWeakenTime(server);
|
||||
var weakenTime = calculateWeakenTime(server, Player);
|
||||
workerScript.log("weaken", `Executing on '${server.hostname}' in ${formatNumber(weakenTime, 3)} seconds (t=${threads})`);
|
||||
return netscriptDelay(weakenTime * 1000, workerScript).then(function() {
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
||||
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
||||
var expGain = calculateHackingExpGain(server) * threads;
|
||||
workerScript.log("weaken", `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.format(expGain, '0.000a')} hacking exp (t=${threads})`);
|
||||
var expGain = calculateHackingExpGain(server, Player) * threads;
|
||||
workerScript.log("weaken", `'${server.hostname}' security level weakened to ${server.hackDifficulty}. Gained ${numeralWrapper.formatExp(expGain)} hacking exp (t=${threads})`);
|
||||
workerScript.scriptRef.onlineExpGained += expGain;
|
||||
Player.gainHackingExp(expGain);
|
||||
return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads);
|
||||
@ -1508,16 +1554,33 @@ function NetscriptFunctions(workerScript) {
|
||||
let copy = Object.assign({}, BitNodeMultipliers);
|
||||
return copy;
|
||||
},
|
||||
getServer: function(ip) {
|
||||
updateDynamicRam("getServer", getRamCost("getServer"));
|
||||
if (SourceFileFlags[5] <= 0) {
|
||||
throw makeRuntimeErrorMsg("getServer", "Requires Source-File 5 to run.");
|
||||
}
|
||||
const server = safeGetServer(ip, "getServer");
|
||||
const copy = Object.assign({}, server);
|
||||
// These fields should be hidden.
|
||||
copy.contracts = undefined;
|
||||
copy.messages = undefined;
|
||||
copy.runningScripts = undefined;
|
||||
copy.scripts = undefined;
|
||||
copy.textFiles = undefined;
|
||||
copy.programs = undefined;
|
||||
copy.serversOnNetwork = undefined;
|
||||
return copy;
|
||||
},
|
||||
getServerMoneyAvailable: function(ip) {
|
||||
updateDynamicRam("getServerMoneyAvailable", getRamCost("getServerMoneyAvailable"));
|
||||
const server = safeGetServer(ip, "getServerMoneyAvailable");
|
||||
if (failOnHacknetServer(server, "getServerMoneyAvailable")) { return 0; }
|
||||
if (server.hostname == "home") {
|
||||
// Return player's money
|
||||
workerScript.log("getServerMoneyAvailable", `returned player's money: ${numeralWrapper.format(Player.money.toNumber(), '$0.000a')}`);
|
||||
workerScript.log("getServerMoneyAvailable", `returned player's money: ${numeralWrapper.formatMoney(Player.money.toNumber())}`);
|
||||
return Player.money.toNumber();
|
||||
}
|
||||
workerScript.log("getServerMoneyAvailable", `returned ${numeralWrapper.format(server.moneyAvailable, '$0.000a')} for '${server.hostname}`);
|
||||
workerScript.log("getServerMoneyAvailable", `returned ${numeralWrapper.formatMoney(server.moneyAvailable)} for '${server.hostname}`);
|
||||
return server.moneyAvailable;
|
||||
},
|
||||
getServerSecurityLevel: function(ip) {
|
||||
@ -1552,7 +1615,7 @@ function NetscriptFunctions(workerScript) {
|
||||
updateDynamicRam("getServerMaxMoney", getRamCost("getServerMaxMoney"));
|
||||
const server = safeGetServer(ip, "getServerMaxMoney");
|
||||
if (failOnHacknetServer(server, "getServerMaxMoney")) { return 0; }
|
||||
workerScript.log("getServerMaxMoney", `returned ${numeralWrapper.format(server.moneyMax, '$0.000a')} for '${server.hostname}'`);
|
||||
workerScript.log("getServerMaxMoney", `returned ${numeralWrapper.formatMoney(server.moneyMax)} for '${server.hostname}'`);
|
||||
return server.moneyMax;
|
||||
},
|
||||
getServerGrowth: function(ip) {
|
||||
@ -1959,7 +2022,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
workerScript.log("purchaseServer", `Not enough money to purchase server. Need ${numeralWrapper.format(cost, '$0.000a')}`);
|
||||
workerScript.log("purchaseServer", `Not enough money to purchase server. Need ${numeralWrapper.formatMoney(cost)}`);
|
||||
return "";
|
||||
}
|
||||
var newServ = safetlyCreateUniqueServer({
|
||||
@ -1978,7 +2041,7 @@ function NetscriptFunctions(workerScript) {
|
||||
homeComputer.serversOnNetwork.push(newServ.ip);
|
||||
newServ.serversOnNetwork.push(homeComputer.ip);
|
||||
Player.loseMoney(cost);
|
||||
workerScript.log("purchaseServer", `Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.format(cost, '$0.000a')}`);
|
||||
workerScript.log("purchaseServer", `Purchased new server with hostname '${newServ.hostname}' for ${numeralWrapper.formatMoney(cost)}`);
|
||||
return newServ.hostname;
|
||||
},
|
||||
deleteServer: function(hostname) {
|
||||
@ -2300,21 +2363,21 @@ function NetscriptFunctions(workerScript) {
|
||||
const server = safeGetServer(ip, "getHackTime");
|
||||
if (failOnHacknetServer(server, "getHackTime")) { return Infinity; }
|
||||
|
||||
return calculateHackingTime(server, hack, int); // Returns seconds
|
||||
return calculateHackingTime(server, Player); // Returns seconds
|
||||
},
|
||||
getGrowTime: function(ip, hack, int) {
|
||||
updateDynamicRam("getGrowTime", getRamCost("getGrowTime"));
|
||||
const server = safeGetServer(ip, "getGrowTime");
|
||||
if (failOnHacknetServer(server, "getGrowTime")) { return Infinity; }
|
||||
|
||||
return calculateGrowTime(server, hack, int); // Returns seconds
|
||||
return calculateGrowTime(server, Player); // Returns seconds
|
||||
},
|
||||
getWeakenTime: function(ip, hack, int) {
|
||||
updateDynamicRam("getWeakenTime", getRamCost("getWeakenTime"));
|
||||
const server = safeGetServer(ip, "getWeakenTime");
|
||||
if (failOnHacknetServer(server, "getWeakenTime")) { return Infinity; }
|
||||
|
||||
return calculateWeakenTime(server, hack, int); // Returns seconds
|
||||
return calculateWeakenTime(server, Player); // Returns seconds
|
||||
},
|
||||
getScriptIncome: function(scriptname, ip) {
|
||||
updateDynamicRam("getScriptIncome", getRamCost("getScriptIncome"));
|
||||
@ -2695,7 +2758,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
|
||||
if(Player.money.lt(item.price)) {
|
||||
workerScript.log("purchaseProgram", `Not enough money to purchase '${item.program}'. Need ${numeralWrapper.format(item.price, '$0.000a')}`);
|
||||
workerScript.log("purchaseProgram", `Not enough money to purchase '${item.program}'. Need ${numeralWrapper.formatMoney(item.price)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2710,7 +2773,14 @@ function NetscriptFunctions(workerScript) {
|
||||
workerScript.log("purchaseProgram", `You have purchased the '${item.program}' program. The new program can be found on your home computer.`);
|
||||
return true;
|
||||
},
|
||||
getCurrentServer: function() {
|
||||
updateDynamicRam("getCurrentServer", getRamCost("getCurrentServer"));
|
||||
checkSingularityAccess("getCurrentServer", 1);
|
||||
return Player.getCurrentServer().hostname;
|
||||
},
|
||||
connect: function(hostname) {
|
||||
updateDynamicRam("connect", getRamCost("connect"));
|
||||
checkSingularityAccess("connect", 1);
|
||||
if (!hostname) {
|
||||
throw makeRuntimeErrorMsg("connect", `Invalid hostname: '${hostname}'`);
|
||||
}
|
||||
@ -2754,6 +2824,7 @@ function NetscriptFunctions(workerScript) {
|
||||
getStats: function() {
|
||||
updateDynamicRam("getStats", getRamCost("getStats"));
|
||||
checkSingularityAccess("getStats", 1);
|
||||
workerScript.log("getStats", `getStats is deprecated, please use getPlayer`);
|
||||
|
||||
return {
|
||||
hacking: Player.hacking_skill,
|
||||
@ -2768,6 +2839,7 @@ function NetscriptFunctions(workerScript) {
|
||||
getCharacterInformation: function() {
|
||||
updateDynamicRam("getCharacterInformation", getRamCost("getCharacterInformation"));
|
||||
checkSingularityAccess("getCharacterInformation", 1);
|
||||
workerScript.log("getCharacterInformation", `getCharacterInformation is deprecated, please use getPlayer`);
|
||||
|
||||
return {
|
||||
bitnode: Player.bitNodeN,
|
||||
@ -2812,6 +2884,96 @@ function NetscriptFunctions(workerScript) {
|
||||
charismaExp: Player.charisma_exp,
|
||||
};
|
||||
},
|
||||
getPlayer: function() {
|
||||
updateDynamicRam("getPlayer", getRamCost("getPlayer"));
|
||||
checkSingularityAccess("getPlayer", 1);
|
||||
|
||||
const data = {
|
||||
hacking_skill: Player.hacking_skill,
|
||||
hp: Player.hp,
|
||||
max_hp: Player.max_hp,
|
||||
strength: Player.strength,
|
||||
defense: Player.defense,
|
||||
dexterity: Player.dexterity,
|
||||
agility: Player.agility,
|
||||
charisma: Player.charisma,
|
||||
intelligence: Player.intelligence,
|
||||
hacking_chance_mult: Player.hacking_chance_mult,
|
||||
hacking_speed_mult: Player.hacking_speed_mult,
|
||||
hacking_money_mult: Player.hacking_money_mult,
|
||||
hacking_grow_mult: Player.hacking_grow_mult,
|
||||
hacking_exp: Player.hacking_exp,
|
||||
strength_exp: Player.strength_exp,
|
||||
defense_exp: Player.defense_exp,
|
||||
dexterity_exp: Player.dexterity_exp,
|
||||
agility_exp: Player.agility_exp,
|
||||
charisma_exp: Player.charisma_exp,
|
||||
hacking_mult: Player.hacking_mult,
|
||||
strength_mult: Player.strength_mult,
|
||||
defense_mult: Player.defense_mult,
|
||||
dexterity_mult: Player.dexterity_mult,
|
||||
agility_mult: Player.agility_mult,
|
||||
charisma_mult: Player.charisma_mult,
|
||||
hacking_exp_mult: Player.hacking_exp_mult,
|
||||
strength_exp_mult: Player.strength_exp_mult,
|
||||
defense_exp_mult: Player.defense_exp_mult,
|
||||
dexterity_exp_mult: Player.dexterity_exp_mult,
|
||||
agility_exp_mult: Player.agility_exp_mult,
|
||||
charisma_exp_mult: Player.charisma_exp_mult,
|
||||
company_rep_mult: Player.company_rep_mult,
|
||||
faction_rep_mult: Player.faction_rep_mult,
|
||||
money: Player.money.toNumber(),
|
||||
city: Player.city,
|
||||
location: Player.location,
|
||||
crime_money_mult: Player.crime_money_mult,
|
||||
crime_success_mult: Player.crime_success_mult,
|
||||
isWorking: Player.isWorking,
|
||||
workType: Player.workType,
|
||||
currentWorkFactionName: Player.currentWorkFactionName,
|
||||
currentWorkFactionDescription: Player.currentWorkFactionDescription,
|
||||
workHackExpGainRate: Player.workHackExpGainRate,
|
||||
workStrExpGainRate: Player.workStrExpGainRate,
|
||||
workDefExpGainRate: Player.workDefExpGainRate,
|
||||
workDexExpGainRate: Player.workDexExpGainRate,
|
||||
workAgiExpGainRate: Player.workAgiExpGainRate,
|
||||
workChaExpGainRate: Player.workChaExpGainRate,
|
||||
workRepGainRate: Player.workRepGainRate,
|
||||
workMoneyGainRate: Player.workMoneyGainRate,
|
||||
workMoneyLossRate: Player.workMoneyLossRate,
|
||||
workHackExpGained: Player.workHackExpGained,
|
||||
workStrExpGained: Player.workStrExpGained,
|
||||
workDefExpGained: Player.workDefExpGained,
|
||||
workDexExpGained: Player.workDexExpGained,
|
||||
workAgiExpGained: Player.workAgiExpGained,
|
||||
workChaExpGained: Player.workChaExpGained,
|
||||
workRepGained: Player.workRepGained,
|
||||
workMoneyGained: Player.workMoneyGained,
|
||||
createProgramName: Player.createProgramName,
|
||||
createProgramReqLvl: Player.createProgramReqLvl,
|
||||
className: Player.className,
|
||||
crimeType: Player.crimeType,
|
||||
work_money_mult: Player.work_money_mult,
|
||||
hacknet_node_money_mult: Player.hacknet_node_money_mult,
|
||||
hacknet_node_purchase_cost_mult: Player.hacknet_node_purchase_cost_mult,
|
||||
hacknet_node_ram_cost_mult: Player.hacknet_node_ram_cost_mult,
|
||||
hacknet_node_core_cost_mult: Player.hacknet_node_core_cost_mult,
|
||||
hacknet_node_level_cost_mult: Player.hacknet_node_level_cost_mult,
|
||||
hasWseAccount: Player.hasWseAccount,
|
||||
hasTixApiAccess: Player.hasTixApiAccess,
|
||||
has4SData: Player.has4SData,
|
||||
has4SDataTixApi: Player.has4SDataTixApi,
|
||||
bladeburner_max_stamina_mult: Player.bladeburner_max_stamina_mult,
|
||||
bladeburner_stamina_gain_mult: Player.bladeburner_stamina_gain_mult,
|
||||
bladeburner_success_chance_mult: Player.bladeburner_success_chance_mult,
|
||||
bitNodeN: Player.bitNodeN,
|
||||
totalPlaytime: Player.totalPlaytime,
|
||||
playtimeSinceLastAug: Player.playtimeSinceLastAug,
|
||||
playtimeSinceLastBitnode: Player.playtimeSinceLastBitnode,
|
||||
jobs: {},
|
||||
};
|
||||
Object.assign(data.jobs, Player.jobs);
|
||||
return data;
|
||||
},
|
||||
isBusy: function() {
|
||||
updateDynamicRam("isBusy", getRamCost("isBusy"));
|
||||
checkSingularityAccess("isBusy", 1);
|
||||
@ -2840,7 +3002,7 @@ function NetscriptFunctions(workerScript) {
|
||||
|
||||
const cost = Player.getUpgradeHomeRamCost();
|
||||
if (Player.money.lt(cost)) {
|
||||
workerScript.log("upgradeHomeRam", `You don't have enough money. Need ${numeralWrapper.format(cost, '$0.000a')}`);
|
||||
workerScript.log("upgradeHomeRam", `You don't have enough money. Need ${numeralWrapper.formatMoney(cost)}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2995,7 +3157,7 @@ function NetscriptFunctions(workerScript) {
|
||||
joinFaction: function(name) {
|
||||
updateDynamicRam("joinFaction", getRamCost("joinFaction"));
|
||||
checkSingularityAccess("joinFaction", 2);
|
||||
getFaction("workForFaction", name);
|
||||
getFaction("joinFaction", name);
|
||||
|
||||
if (!Player.factionInvitations.includes(name)) {
|
||||
workerScript.log("joinFaction", `You have not been invited by faction '${name}'`);
|
||||
@ -3127,7 +3289,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return false;
|
||||
}
|
||||
if (Player.money.lt(amt)) {
|
||||
workerScript.log("donateToFaction", `You do not have enough money to donate ${numeralWrapper.format(amt, '$0.000a')} to '${name}'`);
|
||||
workerScript.log("donateToFaction", `You do not have enough money to donate ${numeralWrapper.formatMoney(amt)} to '${name}'`);
|
||||
return false;
|
||||
}
|
||||
const repNeededToDonate = Math.round(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
|
||||
@ -3138,7 +3300,7 @@ function NetscriptFunctions(workerScript) {
|
||||
const repGain = amt / CONSTANTS.DonateMoneyToRepDivisor * Player.faction_rep_mult;
|
||||
faction.playerReputation += repGain;
|
||||
Player.loseMoney(amt);
|
||||
workerScript.log("donateToFaction", `${numeralWrapper.format(amt, '$0.000a')} donated to '${name}' for ${numeralWrapper.format(repGain, '0.000a')} reputation`);
|
||||
workerScript.log("donateToFaction", `${numeralWrapper.formatMoney(amt)} donated to '${name}' for ${numeralWrapper.formatReputation(repGain)} reputation`);
|
||||
return true;
|
||||
},
|
||||
createProgram: function(name) {
|
||||
@ -4088,6 +4250,110 @@ function NetscriptFunctions(workerScript) {
|
||||
return Player.sleeves[sleeveNumber].tryBuyAugmentation(Player, aug);
|
||||
}
|
||||
}, // End sleeve
|
||||
formulas: {
|
||||
basic: {
|
||||
calculateSkill: function(exp, mult = 1) {
|
||||
checkFormulasAccess("basic.calculateSkill", 5);
|
||||
return calculateSkill(exp, mult);
|
||||
},
|
||||
calculateExp: function(skill, mult = 1) {
|
||||
checkFormulasAccess("basic.calculateExp", 5);
|
||||
return calculateExp(skill, mult);
|
||||
},
|
||||
hackChance: function(server, player) {
|
||||
checkFormulasAccess("basic.hackChance", 5);
|
||||
return calculateHackingChance(server, player);
|
||||
},
|
||||
hackExp: function(server, player) {
|
||||
checkFormulasAccess("basic.hackExp", 5);
|
||||
return calculateHackingExpGain(server, player);
|
||||
},
|
||||
hackPercent: function(server, player) {
|
||||
checkFormulasAccess("basic.hackPercent", 5);
|
||||
return calculatePercentMoneyHacked(server, player);
|
||||
},
|
||||
growPercent: function(server, threads, player) {
|
||||
checkFormulasAccess("basic.growPercent", 5);
|
||||
return calculateServerGrowth(server, threads, player);
|
||||
},
|
||||
hackTime: function(server, player) {
|
||||
checkFormulasAccess("basic.hackTime", 5);
|
||||
return calculateHackingTime(server, player);
|
||||
},
|
||||
growTime: function(server, player) {
|
||||
checkFormulasAccess("basic.growTime", 5);
|
||||
return calculateGrowTime(server, player);
|
||||
},
|
||||
weakenTime: function(server, player) {
|
||||
checkFormulasAccess("basic.weakenTime", 5);
|
||||
return calculateWeakenTime(server, player);
|
||||
},
|
||||
},
|
||||
hacknetNodes: {
|
||||
moneyGainRate: function(level, ram, cores, mult=1) {
|
||||
checkFormulasAccess("hacknetNodes.moneyGainRate", 5);
|
||||
return calculateMoneyGainRate(level, ram, cores, mult);
|
||||
},
|
||||
levelUpgradeCost: function(startingLevel, extraLevels=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetNodes.levelUpgradeCost", 5);
|
||||
return calculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||
},
|
||||
ramUpgradeCost: function(startingRam, extraLevels=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetNodes.ramUpgradeCost", 5);
|
||||
return calculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||
},
|
||||
coreUpgradeCost: function(startingCore, extraCores=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetNodes.coreUpgradeCost", 5);
|
||||
return calculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||
},
|
||||
hacknetNodeCost: function(n, mult) {
|
||||
checkFormulasAccess("hacknetNodes.hacknetNodeCost", 5);
|
||||
return calculateNodeCost(n, mult);
|
||||
},
|
||||
constants: function() {
|
||||
checkFormulasAccess("hacknetNodes.constants", 5);
|
||||
return Object.assign({}, HacknetNodeConstants, HacknetServerConstants);
|
||||
}
|
||||
},
|
||||
hacknetServers: {
|
||||
hashGainRate: function(level, ram, cores, mult=1) {
|
||||
checkFormulasAccess("hacknetServers.hashGainRate", 9);
|
||||
return HScalculateHashGainRate(level, ram, cores, mult);
|
||||
},
|
||||
levelUpgradeCost: function(startingLevel, extraLevels=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetServers.levelUpgradeCost", 9);
|
||||
return HScalculateLevelUpgradeCost(startingLevel, extraLevels, costMult);
|
||||
},
|
||||
ramUpgradeCost: function(startingRam, extraLevels=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetServers.ramUpgradeCost", 9);
|
||||
return HScalculateRamUpgradeCost(startingRam, extraLevels, costMult);
|
||||
},
|
||||
coreUpgradeCost: function(startingCore, extraCores=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetServers.coreUpgradeCost", 9);
|
||||
return HScalculateCoreUpgradeCost(startingCore, extraCores, costMult);
|
||||
},
|
||||
cacheUpgradeCost: function(startingCache, extraCache=1, costMult=1) {
|
||||
checkFormulasAccess("hacknetServers.cacheUpgradeCost", 9);
|
||||
return HScalculateCacheUpgradeCost(startingCache, extraCache, costMult);
|
||||
},
|
||||
hashUpgradeCost: function(upgName, level) {
|
||||
checkFormulasAccess("hacknetServers.hashUpgradeCost", 9);
|
||||
const upg = Player.hashManager.getUpgrade(upgName);
|
||||
if(!upg) {
|
||||
throw makeRuntimeErrorMsg("formulas.hacknetServers.calculateHashUpgradeCost", `Invalid Hash Upgrade: ${upgName}`);
|
||||
}
|
||||
return upg.getCost(level);
|
||||
},
|
||||
hacknetServerCost: function(n, mult) {
|
||||
checkFormulasAccess("hacknetServers.hacknetServerCost", 9);
|
||||
return HScalculateServerCost(n, mult);
|
||||
},
|
||||
constants: function() {
|
||||
checkFormulasAccess("hacknetServers.constants", 9);
|
||||
return Object.assign({}, HacknetServerConstants);
|
||||
}
|
||||
},
|
||||
}, // end formulas
|
||||
heart: {
|
||||
// Easter egg function
|
||||
break: function() {
|
||||
|
@ -5,6 +5,8 @@ import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentatio
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import { CityName } from "../Locations/data/CityNames";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { calculateSkill } from "./formulas/skill";
|
||||
import { calculateIntelligenceBonus } from "./formulas/intelligence";
|
||||
|
||||
// Interface that defines a generic object used to track experience/money
|
||||
// earnings for tasks
|
||||
@ -127,7 +129,7 @@ export abstract class Person {
|
||||
* stat level. Stat-agnostic (same formula for every stat)
|
||||
*/
|
||||
calculateStat(exp: number, mult: number=1): number {
|
||||
return Math.max(Math.floor(mult*(32 * Math.log(exp + 534.5) - 200)), 1);
|
||||
return calculateSkill(exp, mult);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,10 +214,6 @@ export abstract class Person {
|
||||
|
||||
|
||||
getIntelligenceBonus(weight: number): number {
|
||||
// 15 => +1.4% when you initially acquire int
|
||||
// 50 => +3.8% mid game
|
||||
// 100 => +6.6% late game
|
||||
// 250 => +13.4% realistic best possible
|
||||
return 1+(weight*Math.pow(this.intelligence, 0.8)/600);
|
||||
return calculateIntelligenceBonus(this.intelligence, weight);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ import { Locations } from "../../Locations/Locations";
|
||||
import { CityName } from "../../Locations/data/CityNames";
|
||||
import { LocationName } from "../../Locations/data/LocationNames";
|
||||
import { Sleeve } from "../../PersonObjects/Sleeve/Sleeve";
|
||||
import { calculateSkill as calculateSkillF } from "../formulas/skill";
|
||||
import { calculateIntelligenceBonus } from "../formulas/intelligence";
|
||||
import {
|
||||
AllServers,
|
||||
AddToAllServers,
|
||||
@ -55,6 +57,14 @@ import {
|
||||
} from "../../../utils/JSONReviver";
|
||||
import {convertTimeMsToTimeElapsedString} from "../../../utils/StringHelperFunctions";
|
||||
|
||||
import { Reputation } from "../../ui/React/Reputation";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { ReputationRate } from "../../ui/React/ReputationRate";
|
||||
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
|
||||
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
|
||||
|
||||
export function init() {
|
||||
@ -293,7 +303,7 @@ export function receiveInvite(factionName) {
|
||||
|
||||
//Calculates skill level based on experience. The same formula will be used for every skill
|
||||
export function calculateSkill(exp, mult=1) {
|
||||
return Math.max(Math.floor(mult*(32 * Math.log(exp + 534.5) - 200)), 1);
|
||||
return calculateSkillF(exp, mult);
|
||||
}
|
||||
|
||||
export function updateSkillLevels() {
|
||||
@ -520,7 +530,7 @@ export function resetWorkStatus() {
|
||||
this.createProgramName = "";
|
||||
this.className = "";
|
||||
|
||||
document.getElementById("work-in-progress-text").innerHTML = "";
|
||||
ReactDOM.unmountComponentAtNode(document.getElementById("work-in-progress-text"));
|
||||
}
|
||||
|
||||
export function processWorkEarnings(numCycles=1) {
|
||||
@ -611,22 +621,22 @@ export function work(numCycles) {
|
||||
|
||||
const position = this.jobs[this.companyName];
|
||||
|
||||
var txt = document.getElementById("work-in-progress-text");
|
||||
txt.innerHTML = "You are currently working as a " + position +
|
||||
" at " + this.companyName + " (Current Company Reputation: " +
|
||||
numeralWrapper.format(companyRep, '0,0') + ")<br><br>" +
|
||||
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||
"You have earned: <br><br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " ($" + numeralWrapper.format(this.workMoneyGainRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " (" + numeralWrapper.format(this.workRepGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) reputation for this company <br><br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br><br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br><br> " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br><br>" +
|
||||
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, " +
|
||||
"but you will only gain half of the reputation you've earned so far."
|
||||
var elem = document.getElementById("work-in-progress-text");
|
||||
ReactDOM.render(<>
|
||||
You are currently working as a {position} at {this.companyName} (Current Company Reputation: {Reputation(companyRep)})<br /><br />
|
||||
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}<br /><br />
|
||||
You have earned: <br /><br />
|
||||
{Money(this.workMoneyGained)} ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br /><br />
|
||||
{Reputation(this.workRepGained)} ({ReputationRate(this.workRepGainRate * CYCLES_PER_SEC)}) reputation for this company <br /><br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} ({`${numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}) hacking exp <br /><br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} ({`${numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}) strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} ({`${numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}) defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} ({`${numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}) dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} ({`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}) agility exp <br /><br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} ({`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}) charisma exp <br /><br />
|
||||
You will automatically finish after working for 8 hours. You can cancel earlier if you wish,
|
||||
but you will only gain half of the reputation you've earned so far.
|
||||
</>, elem);
|
||||
}
|
||||
|
||||
export function finishWork(cancelled, sing=false) {
|
||||
@ -640,23 +650,27 @@ export function finishWork(cancelled, sing=false) {
|
||||
|
||||
this.updateSkillLevels();
|
||||
|
||||
var txt = "You earned a total of: <br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation for the company <br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
|
||||
let content = <>
|
||||
You earned a total of: <br />
|
||||
{Money(this.workMoneyGained)}<br />
|
||||
{Reputation(this.workRepGained)} reputation for the company <br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp<br />
|
||||
</>
|
||||
|
||||
if (cancelled) {
|
||||
txt = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
|
||||
"Since you cancelled your work early, you only gained half of the reputation you earned. <br><br>" + txt;
|
||||
content = <>
|
||||
You worked a short shift of {convertTimeMsToTimeElapsedString(this.timeWorked)} <br /><br />
|
||||
Since you cancelled your work early, you only gained half of the reputation you earned. <br /><br />{content}
|
||||
</>
|
||||
} else {
|
||||
txt = "You worked a full shift of 8 hours! <br><br> " + txt;
|
||||
content = <>You worked a full shift of 8 hours! <br /><br />{content}</>;
|
||||
}
|
||||
if (!sing) {dialogBoxCreate(txt);}
|
||||
if (!sing) {dialogBoxCreate(content);}
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
@ -665,14 +679,14 @@ export function finishWork(cancelled, sing=false) {
|
||||
|
||||
if (sing) {
|
||||
var res = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
|
||||
"earned $" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + ", " +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation, " +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp, " +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp, " +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp, " +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp, and " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp.";
|
||||
"earned $" + numeralWrapper.formatMoney(this.workMoneyGained) + ", " +
|
||||
numeralWrapper.formatReputation(this.workRepGained) + " reputation, " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) + " hacking exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) + " strength exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) + " defense exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) + " dexterity exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) + " agility exp, and " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) + " charisma exp.";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
@ -734,23 +748,21 @@ export function workPartTime(numCycles) {
|
||||
|
||||
const position = this.jobs[this.companyName];
|
||||
|
||||
var txt = document.getElementById("work-in-progress-text");
|
||||
txt.innerHTML = "You are currently working as a " + position +
|
||||
" at " + this.companyName + " (Current Company Reputation: " +
|
||||
numeralWrapper.format(companyRep, '0,0') + ")<br><br>" +
|
||||
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||
"You have earned: <br><br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " ($" + numeralWrapper.format(this.workMoneyGainRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " (" + numeralWrapper.format(this.workRepGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) reputation for this company <br><br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br><br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br><br> " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br><br>" +
|
||||
"You will automatically finish after working for 8 hours. You can cancel earlier if you wish, <br>" +
|
||||
"and there will be no penalty because this is a part-time job.";
|
||||
|
||||
const elem = document.getElementById("work-in-progress-text");
|
||||
ReactDOM.render(<>
|
||||
You are currently working as a {position} at {this.companyName} (Current Company Reputation: {Reputation(companyRep)})<br /><br />
|
||||
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}<br /><br />
|
||||
You have earned: <br /><br />
|
||||
{Money(this.workMoneyGained)} ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br /><br />
|
||||
{Reputation(this.workRepGained)} ({Reputation(`${numeralWrapper.formatExp(this.workRepGainRate * CYCLES_PER_SEC)} / sec`)}) reputation for this company <br /><br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} ({`${numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}) hacking exp <br /><br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} ({`${numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}) strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} ({`${numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}) defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} ({`${numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}) dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} ({`${numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}) agility exp <br /><br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} ({`${numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}) charisma exp <br /><br />
|
||||
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, and there will be no penalty because this is a part-time job.
|
||||
</>, elem);
|
||||
}
|
||||
|
||||
export function finishWorkPartTime(sing=false) {
|
||||
@ -759,17 +771,19 @@ export function finishWorkPartTime(sing=false) {
|
||||
|
||||
this.updateSkillLevels();
|
||||
|
||||
var txt = "You earned a total of: <br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation for the company <br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
|
||||
txt = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br> " + txt;
|
||||
if (!sing) {dialogBoxCreate(txt);}
|
||||
const content = <>
|
||||
You worked for {convertTimeMsToTimeElapsedString(this.timeWorked)}<br /><br />
|
||||
You earned a total of: <br />
|
||||
{Money(this.workMoneyGained)}<br />
|
||||
{Reputation(this.workRepGained)} reputation for the company <br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp<br />
|
||||
</>;
|
||||
if (!sing) {dialogBoxCreate(content);}
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
@ -778,14 +792,14 @@ export function finishWorkPartTime(sing=false) {
|
||||
if (sing) {
|
||||
var res = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
|
||||
"earned a total of " +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + ", " +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation, " +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp, " +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp, " +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp, " +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp, and " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp";
|
||||
"$" + numeralWrapper.formatMoney(this.workMoneyGained) + ", " +
|
||||
numeralWrapper.formatReputation(this.workRepGained) + " reputation, " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) + " hacking exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) + " strength exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) + " defense exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) + " dexterity exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) + " agility exp, and " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) + " charisma exp";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
@ -902,22 +916,22 @@ export function workForFaction(numCycles) {
|
||||
return this.finishFactionWork(false);
|
||||
}
|
||||
|
||||
var txt = document.getElementById("work-in-progress-text");
|
||||
txt.innerHTML = "You are currently " + this.currentWorkFactionDescription + " for your faction " + faction.name +
|
||||
" (Current Faction Reputation: " + numeralWrapper.format(faction.playerReputation, '0,0') + "). <br>" +
|
||||
"You have been doing this for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||
"You have earned: <br><br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " (" + numeralWrapper.format(this.workMoneyGainRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " (" + numeralWrapper.format(this.workRepGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) reputation for this faction <br><br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br><br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br><br> " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br><br>" +
|
||||
const elem = document.getElementById("work-in-progress-text");
|
||||
ReactDOM.render(<>You are currently {this.currentWorkFactionDescription} for your faction {faction.name}<br />
|
||||
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br />
|
||||
You have been doing this for {convertTimeMsToTimeElapsedString(this.timeWorked)}<br /><br />
|
||||
You have earned: <br /><br />
|
||||
{Money(this.workMoneyGained)} ({MoneyRate(this.workMoneyGainRate * CYCLES_PER_SEC)}) <br /><br />
|
||||
{Reputation(this.workRepGained)} ({ReputationRate(this.workRepGainRate * CYCLES_PER_SEC)}) reputation for this faction <br /><br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} ({numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br /><br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} ({numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} ({numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} ({numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} ({numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br /><br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} ({numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br /><br />
|
||||
|
||||
"You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br>" +
|
||||
"There is no penalty for cancelling earlier.";
|
||||
You will automatically finish after working for 20 hours. You can cancel earlier if you wish.<br />
|
||||
There is no penalty for cancelling earlier.</>, elem)
|
||||
}
|
||||
|
||||
export function finishFactionWork(cancelled, sing=false) {
|
||||
@ -926,17 +940,20 @@ export function finishFactionWork(cancelled, sing=false) {
|
||||
|
||||
this.updateSkillLevels();
|
||||
|
||||
var txt = "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " <br><br> " +
|
||||
"You earned a total of: <br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " reputation for the faction <br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
|
||||
if (!sing) {dialogBoxCreate(txt);}
|
||||
if (!sing) {
|
||||
dialogBoxCreate(<>
|
||||
You worked for your faction {faction.name} for a total of {convertTimeMsToTimeElapsedString(this.timeWorked)} <br /><br />
|
||||
You earned a total of: <br />
|
||||
{Money(this.workMoneyGained)}<br />
|
||||
{Reputation(this.workRepGained)} reputation for the faction <br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp<br />
|
||||
</>);
|
||||
}
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
@ -948,13 +965,13 @@ export function finishFactionWork(cancelled, sing=false) {
|
||||
if (sing) {
|
||||
var res="You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
|
||||
"You earned " +
|
||||
numeralWrapper.format(this.workRepGained, '0,0.0000') + " rep, " +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " str exp, " +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " def exp, " +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dex exp, " +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agi exp, and " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " cha exp.";
|
||||
numeralWrapper.formatReputation(this.workRepGained) + " rep, " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) + " hacking exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) + " str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) + " def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) + " dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) + " agi exp, and " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) + " cha exp.";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
@ -1169,11 +1186,13 @@ export function createProgramWork(numCycles) {
|
||||
this.finishCreateProgramWork(false);
|
||||
}
|
||||
|
||||
var txt = document.getElementById("work-in-progress-text");
|
||||
txt.innerHTML = "You are currently working on coding " + programName + ".<br><br> " +
|
||||
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||
"The program is " + (this.timeWorkedCreateProgram / this.timeNeededToCompleteWork * 100).toFixed(2) + "% complete. <br>" +
|
||||
"If you cancel, your work will be saved and you can come back to complete the program later.";
|
||||
const elem = document.getElementById("work-in-progress-text");
|
||||
ReactDOM.render(<>
|
||||
You are currently working on coding {programName}.<br /><br />
|
||||
You have been working for {convertTimeMsToTimeElapsedString(this.timeWorked)}<br /><br />
|
||||
The program is {(this.timeWorkedCreateProgram / this.timeNeededToCompleteWork * 100).toFixed(2)}% complete. <br />
|
||||
If you cancel, your work will be saved and you can come back to complete the program later.
|
||||
</>, elem);
|
||||
}
|
||||
|
||||
export function finishCreateProgramWork(cancelled, sing=false) {
|
||||
@ -1210,9 +1229,7 @@ export function startClass(costMult, expMult, className) {
|
||||
|
||||
this.className = className;
|
||||
|
||||
var gameCPS = 1000 / Engine._idleSpeed;
|
||||
|
||||
const baseGymExp = 1;
|
||||
const gameCPS = 1000 / Engine._idleSpeed;
|
||||
|
||||
//Find cost and exp gain per game cycle
|
||||
var cost = 0;
|
||||
@ -1244,19 +1261,19 @@ export function startClass(costMult, expMult, className) {
|
||||
break;
|
||||
case CONSTANTS.ClassGymStrength:
|
||||
cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS;
|
||||
strExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult();
|
||||
strExp = expMult / gameCPS * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDefense:
|
||||
cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS;
|
||||
defExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult();
|
||||
defExp = expMult / gameCPS * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDexterity:
|
||||
cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS;
|
||||
dexExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult();
|
||||
dexExp = expMult / gameCPS * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymAgility:
|
||||
cost = CONSTANTS.ClassGymBaseCost * costMult / gameCPS;
|
||||
agiExp = baseGymExp * expMult / gameCPS * hashManager.getTrainingMult();
|
||||
agiExp = expMult / gameCPS * hashManager.getTrainingMult();
|
||||
break;
|
||||
default:
|
||||
throw new Error("ERR: Invalid/unrecognized class name");
|
||||
@ -1294,19 +1311,21 @@ export function takeClass(numCycles) {
|
||||
var className = this.className;
|
||||
|
||||
this.processWorkEarnings(numCycles);
|
||||
|
||||
var txt = document.getElementById("work-in-progress-text");
|
||||
txt.innerHTML = "You have been " + className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||
"This has cost you: <br>" +
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + " ($" + numeralWrapper.format(this.workMoneyLossRate * CYCLES_PER_SEC, '0,0.00') + " / sec) <br><br>" +
|
||||
"You have gained: <br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workHackExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) hacking exp <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workStrExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDefExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workDexExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workAgiExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) agility exp <br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " (" + numeralWrapper.format(this.workChaExpGainRate * CYCLES_PER_SEC, '0,0.0000') + " / sec) charisma exp <br>" +
|
||||
"You may cancel at any time";
|
||||
|
||||
const elem = document.getElementById("work-in-progress-text");
|
||||
ReactDOM.render(<>
|
||||
You have been {className} for {convertTimeMsToTimeElapsedString(this.timeWorked)}<br /><br />
|
||||
This has cost you: <br />
|
||||
{Money(-this.workMoneyGained)} ({MoneyRate(this.workMoneyLossRate * CYCLES_PER_SEC)}) <br /><br />
|
||||
You have gained: <br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} ({numeralWrapper.formatExp(this.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} ({numeralWrapper.formatExp(this.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} ({numeralWrapper.formatExp(this.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} ({numeralWrapper.formatExp(this.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} ({numeralWrapper.formatExp(this.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} ({numeralWrapper.formatExp(this.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
|
||||
You may cancel at any time
|
||||
</>, elem);
|
||||
}
|
||||
|
||||
//The 'sing' argument defines whether or not this function was called
|
||||
@ -1319,16 +1338,19 @@ export function finishClass(sing=false) {
|
||||
}
|
||||
|
||||
this.updateSkillLevels();
|
||||
var txt = "After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", <br>" +
|
||||
"you spent a total of $" + numeralWrapper.format(this.workMoneyGained * -1, '0,0.00') + ". <br><br>" +
|
||||
"You earned a total of: <br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp <br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp <br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp <br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp <br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp<br>";
|
||||
if (!sing) {dialogBoxCreate(txt);}
|
||||
if (!sing) {
|
||||
dialogBoxCreate(<>
|
||||
After {this.className} for {convertTimeMsToTimeElapsedString(this.timeWorked)}, <br />
|
||||
you spent a total of {Money(this.workMoneyGained * -1)}. <br /><br />
|
||||
You earned a total of: <br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity exp <br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility exp <br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma exp<br />
|
||||
</>);
|
||||
}
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
@ -1338,14 +1360,14 @@ export function finishClass(sing=false) {
|
||||
Engine.loadLocationContent(false);
|
||||
if (sing) {
|
||||
var res="After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", " +
|
||||
"you spent a total of $" + numeralWrapper.format(this.workMoneyGained * -1, '0,0.00') + ". " +
|
||||
"you spent a total of " + numeralWrapper.formatMoney(this.workMoneyGained * -1) + ". " +
|
||||
"You earned a total of: " +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking exp, " +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength exp, " +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense exp, " +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity exp, " +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility exp, and " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma exp";
|
||||
numeralWrapper.formatExp(this.workHackExpGained) + " hacking exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) + " strength exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) + " defense exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) + " dexterity exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) + " agility exp, and " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) + " charisma exp";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
@ -1438,24 +1460,26 @@ export function finishCrime(cancelled) {
|
||||
if (this.committingCrimeThruSingFn) {
|
||||
if(this.singFnCrimeWorkerScript.disableLogs.ALL == null && this.singFnCrimeWorkerScript.disableLogs.commitCrime == null) {
|
||||
this.singFnCrimeWorkerScript.scriptRef.log("Crime successful! Gained " +
|
||||
numeralWrapper.format(this.workMoneyGained, "$0.000a") + ", " +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hack exp, " +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " str exp, " +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " def exp, " +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dex exp, " +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agi exp, " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " cha exp.");
|
||||
numeralWrapper.formatMoney(this.workMoneyGained) + ", " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) + " hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) + " str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) + " def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) + " dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) + " agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) + " cha exp.");
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate("Crime successful! <br><br>" +
|
||||
"You gained:<br>"+
|
||||
"$" + numeralWrapper.format(this.workMoneyGained, '0,0.00') + "<br>" +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking experience <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength experience<br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense experience<br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity experience<br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility experience<br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma experience");
|
||||
dialogBoxCreate(<>
|
||||
Crime successful!<br /><br />
|
||||
You gained:<br />
|
||||
{Money(this.workMoneyGained)}<br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking experience <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength experience<br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense experience<br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity experience<br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility experience<br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma experience
|
||||
</>);
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -1469,22 +1493,25 @@ export function finishCrime(cancelled) {
|
||||
if (this.committingCrimeThruSingFn) {
|
||||
if(this.singFnCrimeWorkerScript.disableLogs.ALL == null && this.singFnCrimeWorkerScript.disableLogs.commitCrime == null) {
|
||||
this.singFnCrimeWorkerScript.scriptRef.log("Crime failed! Gained " +
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hack exp, " +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " str exp, " +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " def exp, " +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dex exp, " +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agi exp, " +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " cha exp.");
|
||||
numeralWrapper.formatExp(this.workHackExpGained) + " hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) + " str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) + " def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) + " dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) + " agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) + " cha exp.");
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate("Crime failed! <br><br>" +
|
||||
"You gained:<br>"+
|
||||
numeralWrapper.format(this.workHackExpGained, '0,0.0000') + " hacking experience <br>" +
|
||||
numeralWrapper.format(this.workStrExpGained, '0,0.0000') + " strength experience<br>" +
|
||||
numeralWrapper.format(this.workDefExpGained, '0,0.0000') + " defense experience<br>" +
|
||||
numeralWrapper.format(this.workDexExpGained, '0,0.0000') + " dexterity experience<br>" +
|
||||
numeralWrapper.format(this.workAgiExpGained, '0,0.0000') + " agility experience<br>" +
|
||||
numeralWrapper.format(this.workChaExpGained, '0,0.0000') + " charisma experience");
|
||||
dialogBoxCreate(<>
|
||||
Crime failed!<br /><br />
|
||||
You gained:<br />
|
||||
{Money(this.workMoneyGained)}<br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking experience <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength experience<br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense experience<br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity experience<br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility experience<br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma experience
|
||||
</>);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1563,11 +1590,11 @@ export function regenerateHp(amt) {
|
||||
|
||||
export function hospitalize() {
|
||||
if (Settings.SuppressHospitalizationPopup === false) {
|
||||
dialogBoxCreate(
|
||||
"You were in critical condition! You were taken to the hospital where " +
|
||||
"luckily they were able to save your life. You were charged " +
|
||||
numeralWrapper.format(this.max_hp * CONSTANTS.HospitalCostPerHp, '$0.000a')
|
||||
);
|
||||
dialogBoxCreate(<>
|
||||
You were in critical condition! You were taken to the hospital where
|
||||
luckily they were able to save your life. You were charged
|
||||
{Money(this.max_hp * CONSTANTS.HospitalCostPerHp)}
|
||||
</>);
|
||||
}
|
||||
|
||||
const cost = this.max_hp * CONSTANTS.HospitalCostPerHp
|
||||
@ -2271,7 +2298,7 @@ export function gainCodingContractReward(reward, difficulty=1) {
|
||||
var moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers.CodingContractMoney;
|
||||
this.gainMoney(moneyGain);
|
||||
this.recordMoneySource(moneyGain, "codingcontract");
|
||||
return `Gained ${numeralWrapper.format(moneyGain, '$0.000a')}`;
|
||||
return `Gained ${numeralWrapper.formatMoney(moneyGain)}`;
|
||||
break;
|
||||
}
|
||||
/* eslint-enable no-case-declarations */
|
||||
@ -2309,9 +2336,5 @@ export function giveExploit(exploit) {
|
||||
|
||||
|
||||
export function getIntelligenceBonus(weight) {
|
||||
// 15 => +1.4% when you initially acquire int
|
||||
// 50 => +3.8% mid game
|
||||
// 100 => +6.6% late game
|
||||
// 250 => +13.4% realistic best possible
|
||||
return 1+(weight*Math.pow(this.intelligence, 0.8)/600);
|
||||
return calculateIntelligenceBonus(this.intelligence, weight);
|
||||
}
|
@ -11,6 +11,7 @@ import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { Page,
|
||||
routing } from "../../ui/navigationTracking";
|
||||
|
||||
@ -24,6 +25,9 @@ import { getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
||||
import { removeChildrenFromElement } from "../../../utils/uiHelpers/removeChildrenFromElement";
|
||||
import { removeElement } from "../../../utils/uiHelpers/removeElement";
|
||||
|
||||
import * as React from "react";
|
||||
import { renderToStaticMarkup } from "react-dom/server"
|
||||
|
||||
interface IResleeveUIElems {
|
||||
container: HTMLElement | null;
|
||||
statsPanel: HTMLElement | null;
|
||||
@ -74,13 +78,13 @@ export function createResleevesPage(p: IPlayer) {
|
||||
innerHTML: "Re-sleeving is the process of digitizing and transferring your consciousness " +
|
||||
"into a new human body, or 'sleeve'. Here at VitaLife, you can purchase new " +
|
||||
"specially-engineered bodies for the re-sleeve process. Many of these bodies " +
|
||||
"even come with genetic and cybernetic Augmentations!<br><br>" +
|
||||
"even come with genetic and cybernetic Augmentations!<br /><br />" +
|
||||
"Re-sleeving will change your experience for every stat. It will also REMOVE " +
|
||||
"all of your currently-installed Augmentations, and replace " +
|
||||
"them with the ones provided by the purchased sleeve. However, Augmentations that you have " +
|
||||
"purchased but not installed will NOT be removed. If you have purchased an " +
|
||||
"Augmentation and then re-sleeve into a body which already has that Augmentation, " +
|
||||
"it will be removed (since you cannot have duplicate Augmentations).<br><br>" +
|
||||
"it will be removed (since you cannot have duplicate Augmentations).<br /><br />" +
|
||||
"NOTE: The stats and multipliers displayed on this page do NOT include your bonuses from " +
|
||||
"Source-File.",
|
||||
width: "75%",
|
||||
@ -225,7 +229,7 @@ export function clearResleevesPage() {
|
||||
}
|
||||
|
||||
for (const prop in UIElems) {
|
||||
(<any>UIElems)[prop] = null;
|
||||
(UIElems as any)[prop] = null;
|
||||
}
|
||||
|
||||
playerRef = null;
|
||||
@ -256,12 +260,12 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
elems.stats = createElement("p", {
|
||||
class: "resleeve-stats-text",
|
||||
innerHTML:
|
||||
`Hacking: ${numeralWrapper.format(resleeve.hacking_skill, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.hacking_exp)} exp)<br>` +
|
||||
`Strength: ${numeralWrapper.format(resleeve.strength, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.strength_exp)} exp)<br>` +
|
||||
`Defense: ${numeralWrapper.format(resleeve.defense, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.defense_exp)} exp)<br>` +
|
||||
`Dexterity: ${numeralWrapper.format(resleeve.dexterity, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.dexterity_exp)} exp)<br>` +
|
||||
`Agility: ${numeralWrapper.format(resleeve.agility, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.agility_exp)} exp)<br>` +
|
||||
`Charisma: ${numeralWrapper.format(resleeve.charisma, "0,0")} (${numeralWrapper.formatBigNumber(resleeve.charisma_exp)} exp)<br>` +
|
||||
`Hacking: ${numeralWrapper.formatSkill(resleeve.hacking_skill)} (${numeralWrapper.formatExp(resleeve.hacking_exp)} exp)<br />` +
|
||||
`Strength: ${numeralWrapper.formatSkill(resleeve.strength)} (${numeralWrapper.formatExp(resleeve.strength_exp)} exp)<br />` +
|
||||
`Defense: ${numeralWrapper.formatSkill(resleeve.defense)} (${numeralWrapper.formatExp(resleeve.defense_exp)} exp)<br />` +
|
||||
`Dexterity: ${numeralWrapper.formatSkill(resleeve.dexterity)} (${numeralWrapper.formatExp(resleeve.dexterity_exp)} exp)<br />` +
|
||||
`Agility: ${numeralWrapper.formatSkill(resleeve.agility)} (${numeralWrapper.formatExp(resleeve.agility_exp)} exp)<br />` +
|
||||
`Charisma: ${numeralWrapper.formatSkill(resleeve.charisma)} (${numeralWrapper.formatExp(resleeve.charisma_exp)} exp)<br />` +
|
||||
`# Augmentations: ${resleeve.augmentations.length}`,
|
||||
});
|
||||
elems.multipliersButton = createElement("button", {
|
||||
@ -301,7 +305,7 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
`Bladeburner Stamina Gain multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_stamina_gain_mult)}`,
|
||||
`Bladeburner Field Analysis multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_analysis_mult)}`,
|
||||
`Bladeburner Success Chance multiplier: ${numeralWrapper.formatPercentage(resleeve.bladeburner_success_chance_mult)}`
|
||||
].join("<br>"), false
|
||||
].join("<br />"), false
|
||||
)
|
||||
}
|
||||
});
|
||||
@ -324,7 +328,7 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
const cost: number = resleeve.getCost();
|
||||
elems.costPanel = createElement("div", { class: "resleeve-panel", width: "20%" });
|
||||
elems.costText = createElement("p", {
|
||||
innerText: `It costs ${numeralWrapper.formatMoney(cost)} ` +
|
||||
innerHTML: `It costs ${renderToStaticMarkup(Money(cost))} ` +
|
||||
`to purchase this Sleeve.`,
|
||||
});
|
||||
elems.buyButton = createElement("button", {
|
||||
@ -332,7 +336,7 @@ function createResleeveUi(resleeve: Resleeve): IResleeveUIElems {
|
||||
innerText: "Purchase",
|
||||
clickListener: () => {
|
||||
if (purchaseResleeve(resleeve, playerRef!)) {
|
||||
dialogBoxCreate(`You re-sleeved for ${numeralWrapper.formatMoney(cost)}!`, false);
|
||||
dialogBoxCreate((<>You re-sleeved for {Money(cost)}!</>), false);
|
||||
} else {
|
||||
dialogBoxCreate(`You cannot afford to re-sleeve into this body`, false);
|
||||
}
|
@ -11,6 +11,7 @@ import { Augmentation } from "../../Augmentation/Augmentation";
|
||||
import { Augmentations } from "../../Augmentation/Augmentations";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
@ -19,6 +20,8 @@ import { createPopup } from "../../../utils/uiHelpers/createPopup";
|
||||
import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton";
|
||||
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
||||
|
||||
import { renderToStaticMarkup } from "react-dom/server"
|
||||
|
||||
export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) {
|
||||
// Array of all owned Augmentations. Names only
|
||||
const ownedAugNames: string[] = sleeve.augmentations.map((e) => {return e.name});
|
||||
@ -86,7 +89,7 @@ export function createSleevePurchaseAugsPopup(sleeve: Sleeve, p: IPlayer) {
|
||||
innerHTML:
|
||||
[
|
||||
`<h2>${aug.name}</h2><br>`,
|
||||
`Cost: ${numeralWrapper.formatMoney(aug.startingCost)}<br><br>`,
|
||||
`Cost: ${renderToStaticMarkup(Money(aug.startingCost))}<br><br>`,
|
||||
`${aug.info}`
|
||||
].join(" "),
|
||||
padding: "2px",
|
||||
|
@ -40,11 +40,15 @@ import { removeElement } from "../../../utils/uiHelpers/removeElement";
|
||||
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
||||
|
||||
import { EarningsTableElement } from "./ui/EarningsTableElement";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { ReputationRate } from "../../ui/React/ReputationRate";
|
||||
import { StatsElement } from "./ui/StatsElement";
|
||||
import { MoreStatsContent } from "./ui/MoreStatsContent";
|
||||
import { MoreEarningsContent } from "./ui/MoreEarningsContent";
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import { renderToStaticMarkup } from "react-dom/server"
|
||||
|
||||
// Object that keeps track of all DOM elements for the UI for a single Sleeve
|
||||
interface ISleeveUIElems {
|
||||
@ -218,9 +222,9 @@ function createSleeveUi(sleeve: Sleeve, allSleeves: Sleeve[]): ISleeveUIElems {
|
||||
const popupArguments: HTMLElement[] = [];
|
||||
popupArguments.push(createPopupCloseButton(popupId, { class: "std-button" }));
|
||||
popupArguments.push(createElement("p", {
|
||||
innerText: "Have this sleeve travel to a different city. This affects " +
|
||||
innerHTML: "Have this sleeve travel to a different city. This affects " +
|
||||
"the gyms and universities at which this sleeve can study. " +
|
||||
`Traveling to a different city costs ${numeralWrapper.formatMoney(CONSTANTS.TravelCost)}. ` +
|
||||
`Traveling to a different city costs ${renderToStaticMarkup(Money(CONSTANTS.TravelCost))}. ` +
|
||||
"It will also CANCEL the sleeve's current task (setting it to idle)",
|
||||
}));
|
||||
for (const cityName in Cities) {
|
||||
@ -331,13 +335,13 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) {
|
||||
|
||||
if (sleeve.currentTask === SleeveTaskType.Crime) {
|
||||
const data = [
|
||||
[`Money`, numeralWrapper.formatMoney(parseFloat(sleeve.currentTaskLocation)), `(on success)`],
|
||||
[`Hacking Exp`, numeralWrapper.format(sleeve.gainRatesForTask.hack, "0.00"), `(2x on success)`],
|
||||
[`Strength Exp`, numeralWrapper.format(sleeve.gainRatesForTask.str, "0.00"), `(2x on success)`],
|
||||
[`Defense Exp`, numeralWrapper.format(sleeve.gainRatesForTask.def, "0.00"), `(2x on success)`],
|
||||
[`Dexterity Exp`, numeralWrapper.format(sleeve.gainRatesForTask.dex, "0.00"), `(2x on success)`],
|
||||
[`Agility Exp`, numeralWrapper.format(sleeve.gainRatesForTask.agi, "0.00"), `(2x on success)`],
|
||||
[`Charisma Exp`, numeralWrapper.format(sleeve.gainRatesForTask.cha, "0.00"), `(2x on success)`]
|
||||
[`Money`, Money(parseFloat(sleeve.currentTaskLocation)), `(on success)`],
|
||||
[`Hacking Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.hack), `(2x on success)`],
|
||||
[`Strength Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.str), `(2x on success)`],
|
||||
[`Defense Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.def), `(2x on success)`],
|
||||
[`Dexterity Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.dex), `(2x on success)`],
|
||||
[`Agility Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.agi), `(2x on success)`],
|
||||
[`Charisma Exp`, numeralWrapper.formatExp(sleeve.gainRatesForTask.cha), `(2x on success)`]
|
||||
];
|
||||
ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo!)
|
||||
|
||||
@ -347,18 +351,18 @@ function updateSleeveUi(sleeve: Sleeve, elems: ISleeveUIElems) {
|
||||
});
|
||||
} else {
|
||||
const data = [
|
||||
[`Money:`, `${numeralWrapper.formatMoney(5 * sleeve.gainRatesForTask.money)} / s`],
|
||||
[`Hacking Exp:`, `${numeralWrapper.format(5 * sleeve.gainRatesForTask.hack, "0.00")} / s`],
|
||||
[`Strength Exp:`, `${numeralWrapper.format(5 * sleeve.gainRatesForTask.str, "0.00")} / s`],
|
||||
[`Defense Exp:`, `${numeralWrapper.format(5 * sleeve.gainRatesForTask.def, "0.00")} / s`],
|
||||
[`Dexterity Exp:`, `${numeralWrapper.format(5 * sleeve.gainRatesForTask.dex, "0.00")} / s`],
|
||||
[`Agility Exp:`, `${numeralWrapper.format(5 * sleeve.gainRatesForTask.agi, "0.00")} / s`],
|
||||
[`Charisma Exp:`, `${numeralWrapper.format(5 * sleeve.gainRatesForTask.cha, "0.00")} / s`]
|
||||
[`Money:`, MoneyRate(5 * sleeve.gainRatesForTask.money)],
|
||||
[`Hacking Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.hack)} / s`],
|
||||
[`Strength Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.str)} / s`],
|
||||
[`Defense Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.def)} / s`],
|
||||
[`Dexterity Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.dex)} / s`],
|
||||
[`Agility Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.agi)} / s`],
|
||||
[`Charisma Exp:`, `${numeralWrapper.formatExp(5 * sleeve.gainRatesForTask.cha)} / s`]
|
||||
];
|
||||
let repGainText: string = "";
|
||||
if (sleeve.currentTask === SleeveTaskType.Company || sleeve.currentTask === SleeveTaskType.Faction) {
|
||||
const repGain: number = sleeve.getRepGain(playerRef!);
|
||||
data.push([`Reputation:`, `${numeralWrapper.format(5 * repGain, "0.00")} / s`]);
|
||||
data.push([`Reputation:`, ReputationRate(5 * repGain)]);
|
||||
}
|
||||
ReactDOM.render(EarningsTableElement('Earnings (Pre-Synchronization)', data), elems.currentEarningsInfo!)
|
||||
|
||||
|
@ -16,6 +16,7 @@ import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
|
||||
import { PopupCloseButton } from "../../../ui/React/PopupCloseButton";
|
||||
import { StdButton } from "../../../ui/React/StdButton";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../../../utils/DialogBox";
|
||||
|
||||
@ -92,7 +93,7 @@ export class CovenantPurchasesRoot extends React.Component<IProps, IState> {
|
||||
<PopupCloseButton popup={PopupId} text={"Close"} />
|
||||
<p>
|
||||
Would you like to purchase an additional Duplicate Sleeve from The Covenant
|
||||
for {numeralWrapper.formatMoney(this.purchaseCost())}?
|
||||
for {Money(this.purchaseCost())}?
|
||||
</p>
|
||||
<br />
|
||||
<p>
|
||||
|
@ -9,6 +9,7 @@ import { IPlayer } from "../../IPlayer";
|
||||
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { StdButton } from "../../../ui/React/StdButton";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
|
||||
interface IProps {
|
||||
index: number;
|
||||
@ -68,13 +69,13 @@ export class CovenantSleeveMemoryUpgrade extends React.Component<IProps, IState>
|
||||
// Purchase button props
|
||||
const cost = this.getPurchaseCost();
|
||||
const purchaseBtnDisabled = !this.props.p.canAfford(cost);
|
||||
let purchaseBtnText;
|
||||
let purchaseBtnContent;
|
||||
if (isNaN(this.state.amt)) {
|
||||
purchaseBtnText = "Invalid value";
|
||||
purchaseBtnContent = <>Invalid value</>;
|
||||
} else if (this.state.amt > maxMemory) {
|
||||
purchaseBtnText = `Memory cannot exceed 100`;
|
||||
purchaseBtnContent = <>Memory cannot exceed 100?</>;
|
||||
} else {
|
||||
purchaseBtnText = `Purchase ${this.state.amt} memory - ${numeralWrapper.formatMoney(cost)}`;
|
||||
purchaseBtnContent = <>Purchase {this.state.amt} memory - {Money(cost)}?</>;
|
||||
}
|
||||
|
||||
return (
|
||||
@ -82,7 +83,7 @@ export class CovenantSleeveMemoryUpgrade extends React.Component<IProps, IState>
|
||||
<h2><u>Upgrade Memory</u></h2>
|
||||
<p>
|
||||
Purchase a memory upgrade for your sleeve. Note that a sleeve's max memory
|
||||
is 100 (current: {numeralWrapper.format(this.props.sleeve.memory, "0")})
|
||||
is 100 (current: {numeralWrapper.formatMemory(this.props.sleeve.memory)})
|
||||
</p>
|
||||
|
||||
<label htmlFor={inputId}>
|
||||
@ -90,7 +91,7 @@ export class CovenantSleeveMemoryUpgrade extends React.Component<IProps, IState>
|
||||
</label>
|
||||
<input id={inputId} onChange={this.changePurchaseAmount} type={"number"} value={isNaN(this.state.amt) ? this.state.amt.toString() : this.state.amt} />
|
||||
<br />
|
||||
<StdButton disabled={purchaseBtnDisabled} onClick={this.purchaseMemory} text={purchaseBtnText} />
|
||||
<StdButton disabled={purchaseBtnDisabled} onClick={this.purchaseMemory} text={purchaseBtnContent} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { numeralWrapper } from "../../../ui/numeralFormat";
|
||||
import { Money } from "../../../ui/React/Money";
|
||||
import * as React from "react";
|
||||
import { StatsTable } from "../../../ui/React/StatsTable";
|
||||
|
||||
@ -8,33 +9,33 @@ export function MoreEarningsContent(sleeve: Sleeve): React.ReactElement {
|
||||
style = {textAlign: 'right'};
|
||||
return (<>
|
||||
{StatsTable([
|
||||
['Money ', numeralWrapper.formatMoney(sleeve.earningsForTask.money)],
|
||||
['Hacking Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.hack)],
|
||||
['Strength Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.str)],
|
||||
['Defense Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.def)],
|
||||
['Dexterity Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.dex)],
|
||||
['Agility Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.agi)],
|
||||
['Charisma Exp ', numeralWrapper.formatBigNumber(sleeve.earningsForTask.cha)],
|
||||
['Money ', Money(sleeve.earningsForTask.money)],
|
||||
['Hacking Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.hack)],
|
||||
['Strength Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.str)],
|
||||
['Defense Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.def)],
|
||||
['Dexterity Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.dex)],
|
||||
['Agility Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.agi)],
|
||||
['Charisma Exp ', numeralWrapper.formatExp(sleeve.earningsForTask.cha)],
|
||||
], 'Earnings for Current Task:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Money: ', numeralWrapper.formatMoney(sleeve.earningsForPlayer.money)],
|
||||
['Hacking Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForPlayer.cha)],
|
||||
['Money: ', Money(sleeve.earningsForPlayer.money)],
|
||||
['Hacking Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatExp(sleeve.earningsForPlayer.cha)],
|
||||
], 'Total Earnings for Host Consciousness:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
['Money: ', numeralWrapper.formatMoney(sleeve.earningsForSleeves.money)],
|
||||
['Hacking Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatBigNumber(sleeve.earningsForSleeves.cha)],
|
||||
['Money: ', Money(sleeve.earningsForSleeves.money)],
|
||||
['Hacking Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.hack)],
|
||||
['Strength Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.str)],
|
||||
['Defense Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.def)],
|
||||
['Dexterity Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.dex)],
|
||||
['Agility Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.agi)],
|
||||
['Charisma Exp: ', numeralWrapper.formatExp(sleeve.earningsForSleeves.cha)],
|
||||
], 'Total Earnings for Other Sleeves:')}
|
||||
<br />
|
||||
</>);
|
||||
|
@ -8,12 +8,12 @@ export function MoreStatsContent(sleeve: Sleeve): React.ReactElement {
|
||||
style = {textAlign: 'right'};
|
||||
return (<>
|
||||
{StatsTable([
|
||||
['Hacking: ', sleeve.hacking_skill, `(${numeralWrapper.formatBigNumber(sleeve.hacking_exp)} exp)`],
|
||||
['Strength: ', sleeve.strength, `(${numeralWrapper.formatBigNumber(sleeve.strength_exp)} exp)`],
|
||||
['Defense: ', sleeve.defense, `(${numeralWrapper.formatBigNumber(sleeve.defense_exp)} exp)`],
|
||||
['Dexterity: ', sleeve.dexterity, `(${numeralWrapper.formatBigNumber(sleeve.dexterity_exp)} exp)`],
|
||||
['Agility: ', sleeve.agility, `(${numeralWrapper.formatBigNumber(sleeve.agility_exp)} exp)`],
|
||||
['Charisma: ', sleeve.charisma, `(${numeralWrapper.formatBigNumber(sleeve.charisma_exp)} exp)`],
|
||||
['Hacking: ', sleeve.hacking_skill, `(${numeralWrapper.formatExp(sleeve.hacking_exp)} exp)`],
|
||||
['Strength: ', sleeve.strength, `(${numeralWrapper.formatExp(sleeve.strength_exp)} exp)`],
|
||||
['Defense: ', sleeve.defense, `(${numeralWrapper.formatExp(sleeve.defense_exp)} exp)`],
|
||||
['Dexterity: ', sleeve.dexterity, `(${numeralWrapper.formatExp(sleeve.dexterity_exp)} exp)`],
|
||||
['Agility: ', sleeve.agility, `(${numeralWrapper.formatExp(sleeve.agility_exp)} exp)`],
|
||||
['Charisma: ', sleeve.charisma, `(${numeralWrapper.formatExp(sleeve.charisma_exp)} exp)`],
|
||||
], 'Stats:')}
|
||||
<br />
|
||||
{StatsTable([
|
||||
|
@ -10,7 +10,7 @@ export function StatsElement(sleeve: Sleeve): React.ReactElement {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td className="character-hp-cell">HP: </td>
|
||||
<td className="character-hp-cell" style={style}>{numeralWrapper.format(sleeve.hp, "0,0")} / {numeralWrapper.format(sleeve.max_hp, "0,0")}</td>
|
||||
<td className="character-hp-cell" style={style}>{numeralWrapper.formatHp(sleeve.hp)} / {numeralWrapper.formatHp(sleeve.max_hp)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>City: </td>
|
||||
@ -18,39 +18,39 @@ export function StatsElement(sleeve: Sleeve): React.ReactElement {
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-hack-cell">Hacking: </td>
|
||||
<td className="character-hack-cell" style={style}>{numeralWrapper.format(sleeve.hacking_skill, "0,0")}</td>
|
||||
<td className="character-hack-cell" style={style}>{numeralWrapper.formatSkill(sleeve.hacking_skill)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Strength: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.format(sleeve.strength, "0,0")}</td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.strength)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Defense: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.format(sleeve.defense, "0,0")}</td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.defense)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Dexterity: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.format(sleeve.dexterity, "0,0")}</td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.dexterity)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-combat-cell">Agility: </td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.format(sleeve.agility, "0,0")}</td>
|
||||
<td className="character-combat-cell" style={style}>{numeralWrapper.formatSkill(sleeve.agility)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-cha-cell">Charisma: </td>
|
||||
<td className="character-cha-cell" style={style}>{numeralWrapper.format(sleeve.charisma, "0,0")}</td>
|
||||
<td className="character-cha-cell" style={style}>{numeralWrapper.formatSkill(sleeve.charisma)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Shock: </td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.format(100 - sleeve.shock, "0,0.000")}</td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.formatShock(100 - sleeve.shock)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Sync: </td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.format(sleeve.sync, "0,0.000")}</td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.formatSync(sleeve.sync)}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td className="character-int-cell">Memory: </td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.format(sleeve.memory, "0")}</td>
|
||||
<td className="character-int-cell" style={style}>{numeralWrapper.formatMemory(sleeve.memory)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
3
src/PersonObjects/formulas/intelligence.ts
Normal file
3
src/PersonObjects/formulas/intelligence.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export function calculateIntelligenceBonus(intelligence: number, weight: number = 1): number {
|
||||
return 1+(weight*Math.pow(intelligence, 0.8)/600);
|
||||
}
|
7
src/PersonObjects/formulas/skill.ts
Normal file
7
src/PersonObjects/formulas/skill.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export function calculateSkill(exp: number, mult: number = 1): number {
|
||||
return Math.max(Math.floor(mult*(32 * Math.log(exp + 534.5) - 200)), 1);
|
||||
}
|
||||
|
||||
export function calculateExp(skill: number, mult: number = 1): number {
|
||||
return Math.exp((skill / mult + 200) / 32) - 534.6
|
||||
}
|
@ -471,7 +471,7 @@ function loadImportedGame(saveObj, saveString) {
|
||||
});
|
||||
var gotitBtn = createElement("a", {
|
||||
class:"a-link-button", float:"right", padding:"6px", innerText:"Got it!",
|
||||
clickListener:()=>{
|
||||
clickListener:() => {
|
||||
removeElementById(popupId);
|
||||
}
|
||||
});
|
||||
@ -508,8 +508,8 @@ function loadImportedGame(saveObj, saveString) {
|
||||
// Hacknet Nodes offline progress
|
||||
var offlineProductionFromHacknetNodes = processHacknetEarnings(numCyclesOffline);
|
||||
const hacknetProdInfo = hasHacknetServers() ?
|
||||
`${numeralWrapper.format(offlineProductionFromHacknetNodes, "0.000a")} hashes` :
|
||||
`${numeralWrapper.formatMoney(offlineProductionFromHacknetNodes)}`;
|
||||
<>Hashes(offlineProductionFromHacknetNodes)} hashes</> :
|
||||
Money(offlineProductionFromHacknetNodes);
|
||||
|
||||
// Passive faction rep gain offline
|
||||
processPassiveFactionRepGain(numCyclesOffline);
|
||||
@ -532,10 +532,9 @@ function loadImportedGame(saveObj, saveString) {
|
||||
Player.lastUpdate = Engine._lastUpdate;
|
||||
Engine.start(); // Run main game loop and Scripts loop
|
||||
const timeOfflineString = convertTimeMsToTimeElapsedString(time);
|
||||
dialogBoxCreate(`Offline for ${timeOfflineString}. While you were offline, your scripts ` +
|
||||
"generated <span class='money-gold'>" +
|
||||
numeralWrapper.formatMoney(offlineProductionFromScripts) + "</span> " +
|
||||
"and your Hacknet Nodes generated <span class='money-gold'>" + hacknetProdInfo + "</span>");
|
||||
dialogBoxCreate(<>Offline for {timeOfflineString}. While you were offline, your scripts
|
||||
generated {Money(offlineProductionFromScripts)}
|
||||
and your Hacknet Nodes generated hacknetProdInfo</>);
|
||||
return true;
|
||||
}
|
||||
|
@ -191,7 +191,7 @@ export async function updateScriptEditorContent() {
|
||||
var codeCopy = code.repeat(1);
|
||||
var ramUsage = await calculateRamUsage(codeCopy, Player.getCurrentServer().scripts);
|
||||
if (ramUsage > 0) {
|
||||
scriptEditorRamText.innerText = "RAM: " + numeralWrapper.format(ramUsage, '0.00') + " GB";
|
||||
scriptEditorRamText.innerText = "RAM: " + numeralWrapper.formatRAM(ramUsage);
|
||||
} else {
|
||||
switch (ramUsage) {
|
||||
case RamCalculationErrorCode.ImportError:
|
||||
@ -334,7 +334,7 @@ export function scriptCalculateOfflineProduction(runningScriptObj) {
|
||||
if (serv == null) {continue;}
|
||||
var timesGrown = Math.round(0.5 * runningScriptObj.dataMap[ip][2] / runningScriptObj.onlineRunningTime * timePassed);
|
||||
runningScriptObj.log("Called grow() on " + serv.hostname + " " + timesGrown + " times while offline");
|
||||
var growth = processSingleServerGrowth(serv, timesGrown * 450, Player);
|
||||
var growth = processSingleServerGrowth(serv, timesGrown, Player);
|
||||
runningScriptObj.log(serv.hostname + " grown by " + numeralWrapper.format(growth * 100 - 100, '0.000000%') + " from grow() calls made while offline");
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
ipExists,
|
||||
} from "./AllServers";
|
||||
import { Server, IConstructorParams } from "./Server";
|
||||
import { calculateServerGrowth } from "./formulas/grow";
|
||||
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
@ -59,21 +60,8 @@ export function numCycleForGrowth(server: Server, growth: number, p: IPlayer) {
|
||||
}
|
||||
|
||||
//Applied server growth for a single server. Returns the percentage growth
|
||||
export function processSingleServerGrowth(server: Server, numCycles: number, p: IPlayer) {
|
||||
//Server growth processed once every 450 game cycles
|
||||
const numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
|
||||
|
||||
//Get adjusted growth rate, which accounts for server security
|
||||
const growthRate = CONSTANTS.ServerBaseGrowthRate;
|
||||
var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty;
|
||||
if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;}
|
||||
|
||||
//Calculate adjusted server growth rate based on parameters
|
||||
const serverGrowthPercentage = server.serverGrowth / 100;
|
||||
const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
|
||||
|
||||
//Apply serverGrowth for the calculated number of growth cycles
|
||||
let serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * p.hacking_grow_mult);
|
||||
export function processSingleServerGrowth(server: Server, threads: number, p: IPlayer) {
|
||||
let serverGrowth = calculateServerGrowth(server, threads, p);
|
||||
if (serverGrowth < 1) {
|
||||
console.warn("serverGrowth calculated to be less than 1");
|
||||
serverGrowth = 1;
|
||||
|
20
src/Server/formulas/grow.ts
Normal file
20
src/Server/formulas/grow.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Server } from "../Server";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
|
||||
export function calculateServerGrowth(server: Server, threads: number, p: IPlayer) {
|
||||
const numServerGrowthCycles = Math.max(Math.floor(threads), 0);
|
||||
|
||||
//Get adjusted growth rate, which accounts for server security
|
||||
const growthRate = CONSTANTS.ServerBaseGrowthRate;
|
||||
let adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty;
|
||||
if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;}
|
||||
|
||||
//Calculate adjusted server growth rate based on parameters
|
||||
const serverGrowthPercentage = server.serverGrowth / 100;
|
||||
const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
|
||||
|
||||
//Apply serverGrowth for the calculated number of growth cycles
|
||||
return Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * p.hacking_grow_mult);
|
||||
}
|
@ -16,9 +16,14 @@ import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { Player } from "../Player";
|
||||
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import { Money } from "../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
|
||||
import * as React from "react";
|
||||
import * as ReactDOM from "react-dom";
|
||||
import { renderToStaticMarkup } from "react-dom/server"
|
||||
|
||||
/**
|
||||
* Each function takes an optional config object as its last argument
|
||||
*/
|
||||
@ -58,7 +63,7 @@ export function buyStock(stock: Stock, shares: number, workerScript: WorkerScrip
|
||||
if (tixApi) {
|
||||
workerScript!.log("buyStock", `You do not have enough money to purchase this position. You need ${numeralWrapper.formatMoney(totalPrice)}.`);
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate(`You do not have enough money to purchase this. You need ${numeralWrapper.formatMoney(totalPrice)}`);
|
||||
dialogBoxCreate(<>You do not have enough money to purchase this. You need {Money(totalPrice)}</>);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -69,7 +74,7 @@ export function buyStock(stock: Stock, shares: number, workerScript: WorkerScrip
|
||||
if (tixApi) {
|
||||
workerScript!.log("buyStock", `Purchasing '${shares + stock.playerShares + stock.playerShortShares}' shares would exceed ${stock.symbol}'s maximum (${stock.maxShares}) number of shares`);
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate(`You cannot purchase this many shares. ${stock.symbol} has a maximum of ${numeralWrapper.formatBigNumber(stock.maxShares)} shares.`);
|
||||
dialogBoxCreate(`You cannot purchase this many shares. ${stock.symbol} has a maximum of ${numeralWrapper.formatShares(stock.maxShares)} shares.`);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -85,12 +90,12 @@ export function buyStock(stock: Stock, shares: number, workerScript: WorkerScrip
|
||||
opts.rerenderFn();
|
||||
}
|
||||
|
||||
const resultTxt = `Bought ${numeralWrapper.format(shares, '0,0')} shares of ${stock.symbol} for ${numeralWrapper.formatMoney(totalPrice)}. ` +
|
||||
`Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`
|
||||
if (tixApi) {
|
||||
const resultTxt = `Bought ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} for ${numeralWrapper.formatMoney(totalPrice)}. ` +
|
||||
`Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} in commission fees.`
|
||||
workerScript!.log("buyStock", resultTxt)
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate(resultTxt);
|
||||
dialogBoxCreate(<>Bought {numeralWrapper.formatShares(shares)} shares of {stock.symbol} for {Money(totalPrice)}. Paid {Money(CONSTANTS.StockMarketCommission)} in commission fees.</>);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -143,12 +148,13 @@ export function sellStock(stock: Stock, shares: number, workerScript: WorkerScri
|
||||
opts.rerenderFn();
|
||||
}
|
||||
|
||||
const resultTxt = `Sold ${numeralWrapper.format(shares, '0,0')} shares of ${stock.symbol}. ` +
|
||||
`After commissions, you gained a total of ${numeralWrapper.formatMoney(gains)}.`;
|
||||
|
||||
if (tixApi) {
|
||||
const resultTxt = `Sold ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` +
|
||||
`After commissions, you gained a total of ${numeralWrapper.formatMoney(gains)}.`;
|
||||
workerScript!.log("sellStock", resultTxt)
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate(resultTxt);
|
||||
dialogBoxCreate(<>Sold {numeralWrapper.formatShares(shares)} shares of {stock.symbol}. After commissions, you gained a total of {Money(gains)}.</>);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -187,8 +193,7 @@ export function shortStock(stock: Stock, shares: number, workerScript: WorkerScr
|
||||
"money to purchase this short position. You need " +
|
||||
numeralWrapper.formatMoney(totalPrice));
|
||||
} else if (opts.suppressDialog !== true) {
|
||||
dialogBoxCreate("You do not have enough money to purchase this short position. You need " +
|
||||
numeralWrapper.formatMoney(totalPrice));
|
||||
dialogBoxCreate(<>You do not have enough money to purchase this short position. You need {Money(totalPrice)}</>);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -216,13 +221,13 @@ export function shortStock(stock: Stock, shares: number, workerScript: WorkerScr
|
||||
opts.rerenderFn();
|
||||
}
|
||||
|
||||
const resultTxt = `Bought a short position of ${numeralWrapper.format(shares, '0,0')} shares of ${stock.symbol} ` +
|
||||
`for ${numeralWrapper.formatMoney(totalPrice)}. Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} ` +
|
||||
`in commission fees.`;
|
||||
if (tixApi) {
|
||||
const resultTxt = `Bought a short position of ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol} ` +
|
||||
`for ${numeralWrapper.formatMoney(totalPrice)}. Paid ${numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} ` +
|
||||
`in commission fees.`;
|
||||
workerScript!.log("shortStock", resultTxt);
|
||||
} else if (!opts.suppressDialog) {
|
||||
dialogBoxCreate(resultTxt);
|
||||
dialogBoxCreate(<>Bought a short position of {numeralWrapper.formatShares(shares)} shares of {stock.symbol} for {Money(totalPrice)}. Paid {Money(CONSTANTS.StockMarketCommission)} in commission fees.</>);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -283,12 +288,12 @@ export function sellShort(stock: Stock, shares: number, workerScript: WorkerScri
|
||||
opts.rerenderFn();
|
||||
}
|
||||
|
||||
const resultTxt = `Sold your short position of ${numeralWrapper.format(shares, '0,0')} shares of ${stock.symbol}. ` +
|
||||
`After commissions, you gained a total of ${numeralWrapper.formatMoney(totalGain)}`;
|
||||
if (tixApi) {
|
||||
const resultTxt = `Sold your short position of ${numeralWrapper.formatShares(shares)} shares of ${stock.symbol}. ` +
|
||||
`After commissions, you gained a total of ${numeralWrapper.formatMoney(totalGain)}`;
|
||||
workerScript!.log("sellShort", resultTxt);
|
||||
} else if (!opts.suppressDialog) {
|
||||
dialogBoxCreate(resultTxt);
|
||||
dialogBoxCreate(<>Sold your short position of {numeralWrapper.formatShares(shares)} shares of {stock.symbol}. After commissions, you gained a total of {Money(totalGain)}</>);
|
||||
}
|
||||
|
||||
return true;
|
@ -19,9 +19,12 @@ import { PositionTypes } from "./data/PositionTypes";
|
||||
import { IMap } from "../types";
|
||||
|
||||
import { numeralWrapper } from "../ui/numeralFormat";
|
||||
import { Money } from "../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../utils/DialogBox";
|
||||
|
||||
import * as React from "react";
|
||||
|
||||
export interface IProcessOrderRefs {
|
||||
rerenderFn: () => void;
|
||||
stockMarket: IStockMarket;
|
||||
@ -147,8 +150,7 @@ function executeOrder(order: Order, refs: IProcessOrderRefs) {
|
||||
for (let i = 0; i < stockOrders.length; ++i) {
|
||||
if (order == stockOrders[i]) {
|
||||
stockOrders.splice(i, 1);
|
||||
dialogBoxCreate(`${order.type} for ${stock.symbol} @ ${numeralWrapper.formatMoney(order.price)} (${pos}) was filled ` +
|
||||
`(${numeralWrapper.formatBigNumber(Math.round(order.shares))} shares)`);
|
||||
dialogBoxCreate(<>{order.type} for {stock.symbol} @ {Money(order.price)} ({pos}) was filled ({numeralWrapper.formatShares(Math.round(order.shares))} shares)</>);
|
||||
refs.rerenderFn();
|
||||
return;
|
||||
}
|
||||
@ -158,8 +160,7 @@ function executeOrder(order: Order, refs: IProcessOrderRefs) {
|
||||
console.error(order);
|
||||
} else {
|
||||
if (isBuy) {
|
||||
dialogBoxCreate(`Failed to execute ${order.type} for ${stock.symbol} @ ${numeralWrapper.formatMoney(order.price)} (${pos}). ` +
|
||||
`This is most likely because you do not have enough money or the order would exceed the stock's maximum number of shares`);
|
||||
dialogBoxCreate(<>Failed to execute {order.type} for {stock.symbol} @ {Money(order.price)} ({pos}). This is most likely because you do not have enough money or the order would exceed the stock's maximum number of shares</>);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { StdButton } from "../../ui/React/StdButton";
|
||||
import { StdButtonPurchased } from "../../ui/React/StdButtonPurchased";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
|
||||
@ -107,7 +108,7 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
||||
<StdButton
|
||||
disabled={!this.props.p.canAfford(cost)}
|
||||
onClick={this.purchaseWseAccount}
|
||||
text={`Buy WSE Account - ${numeralWrapper.formatMoney(cost)}`}
|
||||
text={<>Buy WSE Account - {Money(cost)}</>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -125,7 +126,7 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
||||
disabled={!this.props.p.canAfford(cost) || !this.props.p.hasWseAccount}
|
||||
onClick={this.purchaseTixApiAccess}
|
||||
style={blockStyleMarkup}
|
||||
text={`Buy Trade Information eXchange (TIX) API Access - ${numeralWrapper.formatMoney(cost)}`}
|
||||
text={<>Buy Trade Information eXchange (TIX) API Access - {Money(cost)}</>}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -145,7 +146,7 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
||||
<StdButton
|
||||
disabled={!this.props.p.canAfford(cost) || !this.props.p.hasWseAccount}
|
||||
onClick={this.purchase4SMarketData}
|
||||
text={`Buy 4S Market Data Access - ${numeralWrapper.formatMoney(cost)}`}
|
||||
text={<>Buy 4S Market Data Access - {Money(cost)}</>}
|
||||
tooltip={"Lets you view additional pricing and volatility information about stocks"}
|
||||
/>
|
||||
)
|
||||
@ -174,7 +175,7 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
||||
<StdButton
|
||||
disabled={!this.props.p.canAfford(cost)}
|
||||
onClick={this.purchase4SMarketDataTixApiAccess}
|
||||
text={`Buy 4S Market Data TIX API Access - ${numeralWrapper.formatMoney(cost)}`}
|
||||
text={<>Buy 4S Market Data TIX API Access - {Money(cost)}</>}
|
||||
tooltip={"Let you access 4S Market Data through Netscript"}
|
||||
/>
|
||||
)
|
||||
@ -216,7 +217,7 @@ export class InfoAndPurchases extends React.Component<IProps, any> {
|
||||
{this.renderPurchase4SMarketDataTixApiAccessButton()}
|
||||
<p>
|
||||
Commission Fees: Every transaction you make has
|
||||
a {numeralWrapper.formatMoney(CONSTANTS.StockMarketCommission)} commission fee.
|
||||
a {Money(CONSTANTS.StockMarketCommission)} commission fee.
|
||||
</p><br />
|
||||
<p>
|
||||
WARNING: When you reset after installing Augmentations, the Stock
|
||||
|
@ -22,6 +22,7 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { SourceFileFlags } from "../../SourceFile/SourceFileFlags";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Accordion } from "../../ui/React/Accordion";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
|
||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||
import {
|
||||
@ -70,8 +71,8 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
qty: "",
|
||||
}
|
||||
|
||||
this.getBuyTransactionCostText = this.getBuyTransactionCostText.bind(this);
|
||||
this.getSellTransactionCostText = this.getSellTransactionCostText.bind(this);
|
||||
this.getBuyTransactionCostContent = this.getBuyTransactionCostContent.bind(this);
|
||||
this.getSellTransactionCostContent = this.getSellTransactionCostContent.bind(this);
|
||||
this.handleBuyButtonClick = this.handleBuyButtonClick.bind(this);
|
||||
this.handleBuyMaxButtonClick = this.handleBuyMaxButtonClick.bind(this);
|
||||
this.handleHeaderClick = this.handleHeaderClick.bind(this);
|
||||
@ -106,46 +107,40 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
yesNoTxtInpBoxCreate(popupTxt);
|
||||
}
|
||||
|
||||
getBuyTransactionCostText(): string {
|
||||
getBuyTransactionCostContent(): JSX.Element | null {
|
||||
const stock = this.props.stock;
|
||||
const qty: number = this.getQuantity();
|
||||
if (isNaN(qty)) { return ""; }
|
||||
if (isNaN(qty)) { return null; }
|
||||
|
||||
const cost = getBuyTransactionCost(stock, qty, this.state.position);
|
||||
if (cost == null) { return ""; }
|
||||
if (cost == null) { return null; }
|
||||
|
||||
let costTxt = `Purchasing ${numeralWrapper.formatBigNumber(qty)} shares (${this.state.position === PositionTypes.Long ? "Long" : "Short"}) ` +
|
||||
`will cost ${numeralWrapper.formatMoney(cost)}. `;
|
||||
|
||||
return costTxt;
|
||||
return <>Purchasing {numeralWrapper.formatShares(qty)} shares ({this.state.position === PositionTypes.Long ? "Long" : "Short"}) will cost {Money(cost)}.</>;
|
||||
}
|
||||
|
||||
getQuantity(): number {
|
||||
return Math.round(parseFloat(this.state.qty));
|
||||
}
|
||||
|
||||
getSellTransactionCostText(): string {
|
||||
getSellTransactionCostContent(): JSX.Element | null {
|
||||
const stock = this.props.stock;
|
||||
const qty: number = this.getQuantity();
|
||||
if (isNaN(qty)) { return ""; }
|
||||
if (isNaN(qty)) { return null; }
|
||||
|
||||
if (this.state.position === PositionTypes.Long) {
|
||||
if (qty > stock.playerShares) {
|
||||
return `You do not have this many shares in the Long position`;
|
||||
return <>You do not have this many shares in the Long position</>;
|
||||
}
|
||||
} else {
|
||||
if (qty > stock.playerShortShares) {
|
||||
return `You do not have this many shares in the Short position`;
|
||||
return <>You do not have this many shares in the Short position</>;
|
||||
}
|
||||
}
|
||||
|
||||
const cost = getSellTransactionGain(stock, qty, this.state.position);
|
||||
if (cost == null) { return ""; }
|
||||
if (cost == null) { return null; }
|
||||
|
||||
let costTxt = `Selling ${numeralWrapper.formatBigNumber(qty)} shares (${this.state.position === PositionTypes.Long ? "Long" : "Short"}) ` +
|
||||
`will result in a gain of ${numeralWrapper.formatMoney(cost)}. `;
|
||||
|
||||
return costTxt;
|
||||
return <>Selling {numeralWrapper.formatShares(qty)} shares ({this.state.position === PositionTypes.Long ? "Long" : "Short"}) will result in a gain of {Money(cost)}.</>;
|
||||
}
|
||||
|
||||
handleBuyButtonClick() {
|
||||
@ -380,8 +375,8 @@ export class StockTicker extends React.Component<IProps, IState> {
|
||||
}
|
||||
</select>
|
||||
|
||||
<StockTickerTxButton onClick={this.handleBuyButtonClick} text={"Buy"} tooltip={this.getBuyTransactionCostText()} />
|
||||
<StockTickerTxButton onClick={this.handleSellButtonClick} text={"Sell"} tooltip={this.getSellTransactionCostText()} />
|
||||
<StockTickerTxButton onClick={this.handleBuyButtonClick} text={"Buy"} tooltip={this.getBuyTransactionCostContent()} />
|
||||
<StockTickerTxButton onClick={this.handleSellButtonClick} text={"Sell"} tooltip={this.getSellTransactionCostContent()} />
|
||||
<StockTickerTxButton onClick={this.handleBuyMaxButtonClick} text={"Buy MAX"} />
|
||||
<StockTickerTxButton onClick={this.handleSellAllButtonClick} text={"Sell ALL"} />
|
||||
<StockTickerPositionText p={this.props.p} stock={this.props.stock} />
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user