Merge branch 'dev' into streamline-create-programs
2
.gitignore
vendored
@ -2,3 +2,5 @@ Changelog.txt
|
||||
Netburner.txt
|
||||
/node_modules
|
||||
/dist/*.map
|
||||
/tests/*.map
|
||||
/tests/*.bundle.*
|
||||
|
@ -22,12 +22,6 @@
|
||||
background-color: #777;
|
||||
}
|
||||
|
||||
/* Select industry type when creating a new division */
|
||||
.cmpy-mgmt-industry-select {
|
||||
color:white;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
/* Switch between Cities */
|
||||
.cmpy-mgmt-city-tab {
|
||||
display:inline-block;
|
||||
|
@ -288,30 +288,44 @@
|
||||
}
|
||||
|
||||
#hacknet-nodes-text,
|
||||
#hacknet-nodes-money,
|
||||
#hacknet-nodes-container li {
|
||||
width: 70%;
|
||||
margin: 10px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#hacknet-nodes-purchase-button {
|
||||
display: inline-block;
|
||||
#hacknet-nodes-container li {
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#hacknet-nodes-list {
|
||||
list-style: none;
|
||||
width: 82vw;
|
||||
}
|
||||
|
||||
#hacknet-nodes-money {
|
||||
margin: 10px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#hacknet-nodes-money-multipliers-div {
|
||||
display: inline-block;
|
||||
width: 70%;
|
||||
width: 70vw;
|
||||
}
|
||||
|
||||
#hacknet-nodes-multipliers {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#hacknet-nodes-purchase-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.hacknet-node {
|
||||
margin: 6px;
|
||||
padding: 6px;
|
||||
width: 85%;
|
||||
width: 34vw;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
-webkit-box-shadow:
|
||||
inset 0 0 8px rgba(0,0,0,0.1),
|
||||
@ -324,12 +338,28 @@
|
||||
0 0 16px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.hacknet-node-button-div a {
|
||||
display: block;
|
||||
.hacknet-node-container {
|
||||
display: inline-table;
|
||||
}
|
||||
|
||||
.hacknet-node-button-div:not(:last-child) {
|
||||
border-bottom: none;
|
||||
.hacknet-node-container .row {
|
||||
display: table-row;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.hacknet-node-container .row p {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.hacknet-node-container .upgradable-info {
|
||||
display: inline-block;
|
||||
margin: 0 4px; /* Don't want the vertical margin/padding, just left & right */
|
||||
padding: 0 4px;
|
||||
width: 48px; /* Four times font-size */
|
||||
}
|
||||
|
||||
.menu-page-text {
|
||||
width: 70vw;
|
||||
}
|
||||
|
||||
/* World */
|
||||
@ -456,6 +486,21 @@
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
/* Dev menu */
|
||||
#dev-menu-container {
|
||||
position: fixed;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#dev-menu-text {
|
||||
width: 70%;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#dev-menu-container a {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
/* Location */
|
||||
#location-container {
|
||||
position: fixed;
|
||||
|
@ -15,7 +15,10 @@ body {
|
||||
background-color: var(--my-background-color);
|
||||
}
|
||||
|
||||
p, pre, h2 {
|
||||
p,
|
||||
pre,
|
||||
h2,
|
||||
.text {
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
@ -135,6 +138,11 @@ a:link, a:visited {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
border: 1px solid #333333;
|
||||
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.a-link-button:hover {
|
||||
@ -189,6 +197,16 @@ a:link, a:visited {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
color:white;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
.text-input {
|
||||
color:white;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
/* Notification icon (for create program right now only) */
|
||||
#create-program-tab {
|
||||
position:relative;
|
||||
|
BIN
dist/android-chrome-192x192.png
vendored
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
dist/android-chrome-512x512.png
vendored
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
dist/apple-touch-icon.png
vendored
Normal file
After Width: | Height: | Size: 3.3 KiB |
9
dist/browserconfig.xml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square70x70logo src="dist/mstile-70x70.png"/>
|
||||
<TileColor>#000000</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
20886
dist/engine.bundle.js
vendored
BIN
dist/favicon-16x16.png
vendored
Normal file
After Width: | Height: | Size: 282 B |
BIN
dist/favicon-32x32.png
vendored
Normal file
After Width: | Height: | Size: 365 B |
BIN
dist/mstile-70x70.png
vendored
Normal file
After Width: | Height: | Size: 903 B |
1
dist/safari-pinned-tab.svg
vendored
Normal file
After Width: | Height: | Size: 8.2 KiB |
19
dist/site.webmanifest
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "Bitburner",
|
||||
"short_name": "Bitburner",
|
||||
"icons": [
|
||||
{
|
||||
"src": "android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
143601
dist/tests.bundle.js
vendored
BIN
doc/build/doctrees/changelog.doctree
vendored
BIN
doc/build/doctrees/environment.pickle
vendored
BIN
doc/build/doctrees/netscriptfunctions.doctree
vendored
BIN
doc/build/doctrees/netscriptjs.doctree
vendored
30
doc/build/html/_sources/changelog.rst.txt
vendored
@ -3,8 +3,34 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
v0.37.1
|
||||
-------
|
||||
v0.38.0 - 6/12/2018
|
||||
-------------------
|
||||
* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame
|
||||
* Bladeburner Changes:
|
||||
* Bladeburner progress is no longer reset when installing Augmentations
|
||||
* The number of successess needed to increase a Contract/Operation's max level now scales with the current max level (gradually gets harder)
|
||||
* All Bladeburner Augmentations are now slightly more expensive and require more reputation
|
||||
* Black Operations now give higher rank rewards
|
||||
* Doubled the base amount of money gained from Contracts
|
||||
* Increased the amount of experience gained from Contracts/Actions
|
||||
* Added a new Augmentation: The Blade's Simulacrum
|
||||
* Bladeburner faction reputation gain is now properly affected by favor
|
||||
* Hacking is now slightly less profitable in BitNode-3
|
||||
* Updated Hacknet Nodes UI - Implemented by Github user kopelli
|
||||
* Bug Fix: Fixed an exploit that allowed calling any Netscript function without incurring any RAM Cost in NetscriptJS
|
||||
|
||||
v0.37.2 - 6/2/2018
|
||||
------------------
|
||||
|
||||
* After joining the Bladeburners division, there is now a button to go to the Bladeburner content
|
||||
in the 'City' page
|
||||
* You now start with $250m in BitNode-8 (increased from $100m)
|
||||
* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)
|
||||
* Bug Fix: Bladeburners is no longer accessible in BN-8
|
||||
* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object
|
||||
|
||||
v0.37.1 - 5/22/2018
|
||||
-------------------
|
||||
* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based
|
||||
on the difficulty of the contract.
|
||||
* Completing Field Analysis in Bladeburner now grants 0.1 rank
|
||||
|
@ -387,6 +387,34 @@ ls
|
||||
Returns an array with the filenames of all files on the specified server (as strings). The returned array
|
||||
is sorted in alphabetic order
|
||||
|
||||
ps
|
||||
^^
|
||||
|
||||
.. js:function:: ps(hostname/ip=current ip)
|
||||
|
||||
:param string ip: Hostname or IP address of the target server.
|
||||
If not specified, it will be the current server's IP by default
|
||||
|
||||
Returns an array with general information about all scripts running on the specified
|
||||
target server. The information for each server is given in an object with
|
||||
the following structure::
|
||||
|
||||
{
|
||||
filename: Script name,
|
||||
threads: Number of threads script is running with,
|
||||
args: Script's arguments
|
||||
}
|
||||
|
||||
Example usage (using :doc:`netscriptjs`)::
|
||||
|
||||
export async function main(ns) {
|
||||
const ps = ns.ps("home");
|
||||
for (let i = 0; i < ps.length; ++i) {
|
||||
ns.tprint(ps[i].filename + ' ' + ps[i].threads);
|
||||
ns.tprint(ps[i].args);
|
||||
}
|
||||
}
|
||||
|
||||
hasRootAccess
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
|
2
doc/build/html/_sources/netscriptjs.rst.txt
vendored
@ -1,3 +1,5 @@
|
||||
.. _netscriptjs:
|
||||
|
||||
NetscriptJS (Netscript 2.0)
|
||||
===========================
|
||||
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
|
||||
|
43
doc/build/html/changelog.html
vendored
@ -50,8 +50,43 @@
|
||||
|
||||
<div class="section" id="changelog">
|
||||
<span id="id1"></span><h1>Changelog<a class="headerlink" href="#changelog" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="section" id="v0-37-1">
|
||||
<h2>v0.37.1<a class="headerlink" href="#v0-37-1" title="Permalink to this headline">¶</a></h2>
|
||||
<div class="section" id="v0-38-0-6-12-2018">
|
||||
<h2>v0.38.0 - 6/12/2018<a class="headerlink" href="#v0-38-0-6-12-2018" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li>New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame</li>
|
||||
<li><dl class="first docutils">
|
||||
<dt>Bladeburner Changes:</dt>
|
||||
<dd><ul class="first last">
|
||||
<li>Bladeburner progress is no longer reset when installing Augmentations</li>
|
||||
<li>The number of successess needed to increase a Contract/Operation's max level now scales with the current max level (gradually gets harder)</li>
|
||||
<li>All Bladeburner Augmentations are now slightly more expensive and require more reputation</li>
|
||||
<li>Black Operations now give higher rank rewards</li>
|
||||
<li>Doubled the base amount of money gained from Contracts</li>
|
||||
<li>Increased the amount of experience gained from Contracts/Actions</li>
|
||||
<li>Added a new Augmentation: The Blade's Simulacrum</li>
|
||||
<li>Bladeburner faction reputation gain is now properly affected by favor</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</li>
|
||||
<li>Hacking is now slightly less profitable in BitNode-3</li>
|
||||
<li>Updated Hacknet Nodes UI - Implemented by Github user kopelli</li>
|
||||
<li>Bug Fix: Fixed an exploit that allowed calling any Netscript function without incurring any RAM Cost in NetscriptJS</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="v0-37-2-6-2-2018">
|
||||
<h2>v0.37.2 - 6/2/2018<a class="headerlink" href="#v0-37-2-6-2-2018" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li>After joining the Bladeburners division, there is now a button to go to the Bladeburner content
|
||||
in the 'City' page</li>
|
||||
<li>You now start with $250m in BitNode-8 (increased from $100m)</li>
|
||||
<li>Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)</li>
|
||||
<li>Bug Fix: Bladeburners is no longer accessible in BN-8</li>
|
||||
<li>Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="v0-37-1-5-22-2018">
|
||||
<h2>v0.37.1 - 5/22/2018<a class="headerlink" href="#v0-37-1-5-22-2018" title="Permalink to this headline">¶</a></h2>
|
||||
<ul class="simple">
|
||||
<li>You now earn money from successfully completing Bladeburner contracts. The amount you earn is based
|
||||
on the difficulty of the contract.</li>
|
||||
@ -971,7 +1006,9 @@ on the difficulty of the contract.</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
|
||||
<li class="toctree-l1 current"><a class="current reference internal" href="#"> Changelog</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-37-1">v0.37.1</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-38-0-6-12-2018">v0.38.0 - 6/12/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-37-2-6-2-2018">v0.37.2 - 6/2/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-37-1-5-22-2018">v0.37.1 - 5/22/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-37-0-5-20-2018">v0.37.0 - 5/20/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-36-1-5-11-2018">v0.36.1 - 5/11/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="#v0-36-0-5-2-2018">v0.36.0 - 5/2/2018</a></li>
|
||||
|
2
doc/build/html/genindex.html
vendored
@ -326,6 +326,8 @@
|
||||
<li><a href="netscriptfunctions.html#print">print() (built-in function)</a>
|
||||
</li>
|
||||
<li><a href="netscriptfunctions.html#prompt">prompt() (built-in function)</a>
|
||||
</li>
|
||||
<li><a href="netscriptfunctions.html#ps">ps() (built-in function)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
|
5
doc/build/html/index.html
vendored
@ -110,6 +110,7 @@ secrets that you've been searching for.</p>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#exit">exit</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#scp">scp</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#ls">ls</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#ps">ps</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#hasrootaccess">hasRootAccess</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethostname">getHostname</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</a></li>
|
||||
@ -268,7 +269,9 @@ secrets that you've been searching for.</p>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-1">v0.37.1</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-38-0-6-12-2018">v0.38.0 - 6/12/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-2-6-2-2018">v0.37.2 - 6/2/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-1-5-22-2018">v0.37.1 - 5/22/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-0-5-20-2018">v0.37.0 - 5/20/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-36-1-5-11-2018">v0.36.1 - 5/11/2018</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-36-0-5-2-2018">v0.36.0 - 5/2/2018</a></li>
|
||||
|
2
doc/build/html/netscript.html
vendored
@ -111,6 +111,7 @@ to reach out to the developer!</p>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#exit">exit</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#scp">scp</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#ls">ls</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#ps">ps</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#hasrootaccess">hasRootAccess</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#gethostname">getHostname</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</a></li>
|
||||
@ -249,6 +250,7 @@ to reach out to the developer!</p>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
|
||||
</ul>
|
||||
|
||||
<div role="search">
|
||||
|
42
doc/build/html/netscriptfunctions.html
vendored
@ -671,6 +671,46 @@ then this function will return true if at least one of the files in the array is
|
||||
is sorted in alphabetic order</p>
|
||||
</dd></dl>
|
||||
|
||||
</div>
|
||||
<div class="section" id="ps">
|
||||
<h2>ps<a class="headerlink" href="#ps" title="Permalink to this headline">¶</a></h2>
|
||||
<dl class="function">
|
||||
<dt>
|
||||
<code class="descname">ps</code><span class="sig-paren">(</span><em>hostname/ip=current ip</em><span class="sig-paren">)</span></dt>
|
||||
<dd><table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
<tbody valign="top">
|
||||
<tr class="field-odd field"><th class="field-name">Arguments:</th><td class="field-body"><ul class="first last simple">
|
||||
<li><strong>ip</strong> (<em>string</em>) -- Hostname or IP address of the target server.
|
||||
If not specified, it will be the current server's IP by default</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Returns an array with general information about all scripts running on the specified
|
||||
target server. The information for each server is given in an object with
|
||||
the following structure:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="p">{</span>
|
||||
<span class="n">filename</span><span class="p">:</span> <span class="n">Script</span> <span class="n">name</span><span class="p">,</span>
|
||||
<span class="n">threads</span><span class="p">:</span> <span class="n">Number</span> <span class="n">of</span> <span class="n">threads</span> <span class="n">script</span> <span class="ow">is</span> <span class="n">running</span> <span class="k">with</span><span class="p">,</span>
|
||||
<span class="n">args</span><span class="p">:</span> <span class="n">Script</span><span class="s1">'s arguments</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Example usage (using <a class="reference internal" href="netscriptjs.html"><span class="doc">NetscriptJS (Netscript 2.0)</span></a>):</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">export</span> <span class="k">async</span> <span class="n">function</span> <span class="n">main</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">const</span> <span class="n">ps</span> <span class="o">=</span> <span class="n">ns</span><span class="o">.</span><span class="n">ps</span><span class="p">(</span><span class="s2">"home"</span><span class="p">);</span>
|
||||
<span class="k">for</span> <span class="p">(</span><span class="n">let</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">ps</span><span class="o">.</span><span class="n">length</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="n">ns</span><span class="o">.</span><span class="n">tprint</span><span class="p">(</span><span class="n">ps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">filename</span> <span class="o">+</span> <span class="s1">' '</span> <span class="o">+</span> <span class="n">ps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">threads</span><span class="p">);</span>
|
||||
<span class="n">ns</span><span class="o">.</span><span class="n">tprint</span><span class="p">(</span><span class="n">ps</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">args</span><span class="p">);</span>
|
||||
<span class="p">}</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</dd></dl>
|
||||
|
||||
</div>
|
||||
<div class="section" id="hasrootaccess">
|
||||
<h2>hasRootAccess<a class="headerlink" href="#hasrootaccess" title="Permalink to this headline">¶</a></h2>
|
||||
@ -1648,6 +1688,7 @@ you create in functions such as <a class="reference external" href="https://deve
|
||||
<li class="toctree-l3"><a class="reference internal" href="#exit">exit</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#scp">scp</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#ls">ls</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#ps">ps</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#hasrootaccess">hasRootAccess</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#gethostname">getHostname</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#gethackinglevel">getHackingLevel</a></li>
|
||||
@ -1702,6 +1743,7 @@ you create in functions such as <a class="reference external" href="https://deve
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
|
||||
</ul>
|
||||
|
||||
<div role="search">
|
||||
|
3
doc/build/html/netscriptjs.html
vendored
@ -52,7 +52,7 @@
|
||||
<div class="body" role="main">
|
||||
|
||||
<div class="section" id="netscriptjs-netscript-2-0">
|
||||
<h1>NetscriptJS (Netscript 2.0)<a class="headerlink" href="#netscriptjs-netscript-2-0" title="Permalink to this headline">¶</a></h1>
|
||||
<span id="netscriptjs"></span><h1>NetscriptJS (Netscript 2.0)<a class="headerlink" href="#netscriptjs-netscript-2-0" title="Permalink to this headline">¶</a></h1>
|
||||
<p>Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
|
||||
allows users to write (almost) full-fledged Javascript code in their scripts, while
|
||||
still being able to access the Netscript functions.</p>
|
||||
@ -278,6 +278,7 @@ NetscriptJS and report any serious exploits.</p>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
|
||||
</ul>
|
||||
|
||||
<div role="search">
|
||||
|
BIN
doc/build/html/objects.inv
vendored
2
doc/build/html/searchindex.js
vendored
@ -3,8 +3,49 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
v0.37.1
|
||||
-------
|
||||
v0.38.1 - 6/15/2018
|
||||
-------------------
|
||||
* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS
|
||||
* Implemented by Github user hydroflame:
|
||||
* Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)
|
||||
* Added game option to suppress travel confirmation
|
||||
* Text on buttons can no longer be highlighted
|
||||
* Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations
|
||||
* Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)
|
||||
* Added ps() Netscript function
|
||||
* Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money
|
||||
* Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips
|
||||
* Bug Fix: Sever's security level should now properly increase when its money is grown to max value
|
||||
|
||||
|
||||
v0.38.0 - 6/12/2018
|
||||
-------------------
|
||||
* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame
|
||||
* Bladeburner Changes:
|
||||
* Bladeburner progress is no longer reset when installing Augmentations
|
||||
* The number of successess needed to increase a Contract/Operation's max level now scales with the current max level (gradually gets harder)
|
||||
* All Bladeburner Augmentations are now slightly more expensive and require more reputation
|
||||
* Black Operations now give higher rank rewards
|
||||
* Doubled the base amount of money gained from Contracts
|
||||
* Increased the amount of experience gained from Contracts/Actions
|
||||
* Added a new Augmentation: The Blade's Simulacrum
|
||||
* Bladeburner faction reputation gain is now properly affected by favor
|
||||
* Hacking is now slightly less profitable in BitNode-3
|
||||
* Updated Hacknet Nodes UI - Implemented by Github user kopelli
|
||||
* Bug Fix: Fixed an exploit that allowed calling any Netscript function without incurring any RAM Cost in NetscriptJS
|
||||
|
||||
v0.37.2 - 6/2/2018
|
||||
------------------
|
||||
|
||||
* After joining the Bladeburners division, there is now a button to go to the Bladeburner content
|
||||
in the 'City' page
|
||||
* You now start with $250m in BitNode-8 (increased from $100m)
|
||||
* Bug Fix: You can now no longer directly edit Hacknet Node values through NetscriptJS (hopefully)
|
||||
* Bug Fix: Bladeburners is no longer accessible in BN-8
|
||||
* Bug Fix: getBitNodeMultipliers() Netscript function now returns a copy rather than the original object
|
||||
|
||||
v0.37.1 - 5/22/2018
|
||||
-------------------
|
||||
* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based
|
||||
on the difficulty of the contract.
|
||||
* Completing Field Analysis in Bladeburner now grants 0.1 rank
|
||||
|
@ -387,6 +387,34 @@ ls
|
||||
Returns an array with the filenames of all files on the specified server (as strings). The returned array
|
||||
is sorted in alphabetic order
|
||||
|
||||
ps
|
||||
^^
|
||||
|
||||
.. js:function:: ps(hostname/ip=current ip)
|
||||
|
||||
:param string ip: Hostname or IP address of the target server.
|
||||
If not specified, it will be the current server's IP by default
|
||||
|
||||
Returns an array with general information about all scripts running on the specified
|
||||
target server. The information for each server is given in an object with
|
||||
the following structure::
|
||||
|
||||
{
|
||||
filename: Script name,
|
||||
threads: Number of threads script is running with,
|
||||
args: Script's arguments
|
||||
}
|
||||
|
||||
Example usage (using :doc:`netscriptjs`)::
|
||||
|
||||
export async function main(ns) {
|
||||
const ps = ns.ps("home");
|
||||
for (let i = 0; i < ps.length; ++i) {
|
||||
ns.tprint(ps[i].filename + ' ' + ps[i].threads);
|
||||
ns.tprint(ps[i].args);
|
||||
}
|
||||
}
|
||||
|
||||
hasRootAccess
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
.. _netscriptjs:
|
||||
|
||||
NetscriptJS (Netscript 2.0)
|
||||
===========================
|
||||
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that
|
||||
|
BIN
favicon.ico
Normal file
After Width: | Height: | Size: 2.7 KiB |
119
index.html
@ -3,6 +3,17 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bitburner</title>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
|
||||
<link rel="manifest" href="dist/site.webmanifest">
|
||||
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<meta name="apple-mobile-web-app-title" content="Bitburner">
|
||||
<meta name="application-name" content="Bitburner">
|
||||
<meta name="msapplication-TileColor" content="#000000">
|
||||
<meta name="msapplication-config" content="dist/browserconfig.xml">
|
||||
<meta name="theme-color" content="#ffffff">
|
||||
<link rel="stylesheet" type="text/css" href="css/styles.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/terminal.css" />
|
||||
<link rel="stylesheet" type="text/css" href="css/menupages.css" />
|
||||
@ -23,7 +34,6 @@
|
||||
|
||||
ga('create', 'UA-100157497-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
@ -89,6 +99,9 @@
|
||||
<li id="options-tab" class="mainmenu-accordion-panel">
|
||||
<a id="options-menu-link"> Options </a>
|
||||
</li>
|
||||
<li id="dev-tab" class="mainmenu-accordion-panel">
|
||||
<a id="dev-menu-link"> Dev </a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -97,7 +110,7 @@
|
||||
|
||||
<div id="script-editor-filename-wrapper">
|
||||
<p id="script-editor-filename-tag"> <strong style="background-color:#555;">Script name: </strong></p>
|
||||
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1"> </input>
|
||||
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1" />
|
||||
</div>
|
||||
|
||||
<div id="javascript-editor"></div>
|
||||
@ -147,9 +160,7 @@
|
||||
|
||||
<fieldset>
|
||||
<label for="script-editor-option-maxerr" class="tooltip">Max Error Count</label>
|
||||
<input type="range" max="1000" min="50" value="200"
|
||||
step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr"
|
||||
</input>
|
||||
<input type="range" max="1000" min="50" value="200" step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr" />
|
||||
<em id="script-editor-option-maxerror-value-label" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
</div> <!-- End script editor options panel -->
|
||||
@ -160,8 +171,7 @@
|
||||
<table id="terminal">
|
||||
<tr id="terminal-input">
|
||||
<td id="terminal-input-td" tabindex="2">$
|
||||
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"
|
||||
onfocus="this.value = this.value;"/>
|
||||
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;"/>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@ -185,7 +195,7 @@
|
||||
<!-- Hacknet Nodes -->
|
||||
<div id="hacknet-nodes-container" class="generic-menupage-container">
|
||||
<h1 id="hacknet-nodes-title"> Hacknet Nodes </h1>
|
||||
<p id="hacknet-nodes-text">
|
||||
<p id="hacknet-nodes-text" class="menu-page-text">
|
||||
The Hacknet is a global, decentralized network of machines. It is used by hackers all around
|
||||
the world to anonymously share computing power and perform distributed cyberattacks without the
|
||||
fear of being traced.
|
||||
@ -199,8 +209,11 @@
|
||||
</p>
|
||||
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
||||
<br>
|
||||
<div id="hacknet-nodes-money-multipliers-div">"
|
||||
<p id="hacknet-nodes-money"> </p>
|
||||
<div id="hacknet-nodes-money-multipliers-div">
|
||||
<p id="hacknet-nodes-money">
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" ></span><br />
|
||||
<span>Total Hacknet Node Prodution:</span><span id="hacknet-nodes-total-production"></span>
|
||||
</p>
|
||||
<span id="hacknet-nodes-multipliers">
|
||||
<a id="hacknet-nodes-1x-multiplier" class="a-link-button-inactive"> x1 </a>
|
||||
<a id="hacknet-nodes-5x-multiplier" class="a-link-button"> x5 </a>
|
||||
@ -208,7 +221,7 @@
|
||||
<a id="hacknet-nodes-max-multiplier" class="a-link-button"> MAX </a>
|
||||
</span>
|
||||
</div>
|
||||
<ul id="hacknet-nodes-list" style="list-style : none;">
|
||||
<ul id="hacknet-nodes-list">
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@ -473,6 +486,58 @@
|
||||
<p id="tutorial-text"> </p>
|
||||
</div>
|
||||
|
||||
<!-- dev menu -->
|
||||
<div id="dev-menu-container" class="generic-menupage-container">
|
||||
<p id='dev-menu-text'>If you see this menu you can pretty much break the game. It's recommended that you use this menu only to setup a save file appropriate to test a new feature or bug fix.</p>
|
||||
|
||||
<p id='dev-menu-text'>Generic</p>
|
||||
<a id="dev-need-money" class="a-link-button">Add $1000t</a>
|
||||
<a id="dev-need-ram" class="a-link-button">Double home RAM</a>
|
||||
|
||||
<p id='dev-menu-text'>Augmentation related: </p>
|
||||
<!-- gets populated with the list of all augments -->
|
||||
<select id="dev-menu-aug-dropdown" class="dropdown"></select>
|
||||
<a id="dev-add-aug" class="a-link-button tooltip">Queue Augmentation<span class="tooltiptext">May require save + reload</span></a>
|
||||
|
||||
<input id="dev-sf-n" type="number" class="text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
|
||||
|
||||
<p id='dev-menu-text'>Faction related: </p>
|
||||
<select id="dev-menu-faction-dropdown" class="dropdown"></select>
|
||||
<a id="dev-add-faction" class="a-link-button tooltip">Receive invite<span class="tooltiptext">May require save + reload</span></a>
|
||||
|
||||
<p id='dev-menu-text'>Program related: </p>
|
||||
<select id="dev-menu-connect-dropdown" class="dropdown"></select>
|
||||
<a id="dev-connect" class="a-link-button tooltip">Connect<span class="tooltiptext">Connect to the target server.</span></a>
|
||||
|
||||
<select id="dev-menu-add-program-dropdown" class="dropdown"></select>
|
||||
<a id="dev-add-program" class="a-link-button tooltip">Add Program<span class="tooltiptext">Add this program to the player home server, won't add the same program twice.</span></a>
|
||||
|
||||
<a id="dev-bit-flume" class="a-link-button tooltip">Trigger BitFlume<span class="tooltiptext">Quick escape to change BN, does not give SFs</span></a>
|
||||
|
||||
<p id='dev-menu-text'>Server related: </p>
|
||||
<a id="dev-open-all" class="a-link-button tooltip">NUKE + ports all servers<span class="tooltiptext">Opens all ports, nukes all servers, gains root access to everything (still need the appropriate hacking level)</span></a>
|
||||
<a id="dev-min-security" class="a-link-button tooltip">minimize all servers security<span class="tooltiptext">All servers security will be set to their minimum security</span></a>
|
||||
<a id="dev-max-money" class="a-link-button tooltip">maximize all servers money<span class="tooltiptext">Set all servers available money to maximum for that server</span></a>
|
||||
|
||||
<p id='dev-menu-text'>Exp/stats related: </p>
|
||||
<input id="dev-hacking-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-hacking" class="a-link-button tooltip">add hacking exp<span class="tooltiptext">Add that many hacking experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<input id="dev-strength-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-strength" class="a-link-button tooltip">add strength exp<span class="tooltiptext">Add that many strength experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<input id="dev-defense-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-defense" class="a-link-button tooltip">add defense exp<span class="tooltiptext">Add that many defense experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<input id="dev-dexterity-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-dexterity" class="a-link-button tooltip">add dexterity exp<span class="tooltiptext">Add that many dexterity experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<input id="dev-agility-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-agility" class="a-link-button tooltip">add agility exp<span class="tooltiptext">Add that many agility experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<input id="dev-charisma-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-charisma" class="a-link-button tooltip">add charisma exp<span class="tooltiptext">Add that many charisma experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<input id="dev-intelligence-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
|
||||
<a id="dev-add-intelligence" class="a-link-button tooltip">add intelligence exp<span class="tooltiptext">Add that many intelligence experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
|
||||
<a id="dev-enable-intelligence" class="a-link-button tooltip"> enable intelligence<span class="tooltiptext">Enables the intelligence stat</span></a>
|
||||
<a id="dev-disable-intelligence" class="a-link-button tooltip"> disable intelligence<span class="tooltiptext">Disables the intelligence stat</span></a>
|
||||
</div>
|
||||
|
||||
<!-- Location (visiting a location in World) -->
|
||||
<div id="location-container" class="generic-menupage-container">
|
||||
<a id="location-return-to-world-button" class="a-link-button"> Return to World </a>
|
||||
@ -654,7 +719,7 @@
|
||||
<div id="yes-no-text-input-box-container" class="popup-box-container">
|
||||
<div id="yes-no-text-input-box-content" class="popup-box-content">
|
||||
<p id="yes-no-text-input-box-text"> </p>
|
||||
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"> </input>
|
||||
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30" />
|
||||
<span id="yes-no-text-input-box-yes" class="popup-box-button"> Yes </span>
|
||||
<span id="yes-no-text-input-box-no" class="popup-box-button"> No </span>
|
||||
</div>
|
||||
@ -744,9 +809,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type ="range" max="250" min="15"
|
||||
step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100">
|
||||
</input>
|
||||
<input type ="range" max="250" min="15" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100" />
|
||||
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -760,9 +823,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="20"
|
||||
step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50">
|
||||
</input>
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50" />
|
||||
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -776,9 +837,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="20"
|
||||
step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50">
|
||||
</input>
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50" />
|
||||
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -790,9 +849,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="600" min="0"
|
||||
step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60">
|
||||
</input>
|
||||
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60" />
|
||||
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -819,6 +876,16 @@
|
||||
<input type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites">
|
||||
</fieldset>
|
||||
|
||||
<!-- Suppress travel confirmation -->
|
||||
<fieldset>
|
||||
<label for="settingsSuppressTravelConfirmation" class="tooltip">Suppress Travel Confirmation:
|
||||
<span class="tooltiptext">
|
||||
If this is set, the confirmation message before traveling will not show up. You will automatically be deducted the travel cost as soon as you click.
|
||||
</span>
|
||||
</label>
|
||||
<input type="checkbox" name="settingsSuppressTravelConfirmation" id="settingsSuppressTravelConfirmation">
|
||||
</fieldset>
|
||||
|
||||
<!-- Disable Terminal and Navigation Shortcuts -->
|
||||
<fieldset>
|
||||
<label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys:
|
||||
@ -843,7 +910,7 @@
|
||||
<div id="game-options-right-panel">
|
||||
<a class="a-link-button" style="display:block;" href="https://bitburner.wikia.com/wiki/Changelog" target="_blank"> Changelog </a>
|
||||
<a class="a-link-button" style="display:block;" href="https://bitburner.wikia.com" target="_blank">Wiki</a>
|
||||
<a class="a-link-button" style="display:block;", href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
|
||||
<a class="a-link-button" style="display:block;" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
|
||||
<a id="save-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Save Game </a>
|
||||
<a id="delete-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Delete Game </a>
|
||||
<a id="export-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Export Game </a>
|
||||
@ -872,6 +939,6 @@
|
||||
<div class="loaderspinner"></div>
|
||||
<div class="loaderlabel">Loading Bitburner...</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="dist/engine.bundle.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -103,7 +103,7 @@ var NetscriptHighlightRules = function(options) {
|
||||
"JSON|Math|" + // Other
|
||||
"this|arguments|prototype|window|document" , // Pseudo
|
||||
"keyword":
|
||||
"const|yield|import|get|set|async|await|foop|" +
|
||||
"const|yield|import|get|set|async|await|" +
|
||||
"break|case|catch|continue|default|delete|do|else|finally|for|function|" +
|
||||
"if|in|of|instanceof|new|return|switch|throw|try|typeof|let|var|while|with|debugger|" +
|
||||
"__parent__|__count__|escape|unescape|with|__proto__|" +
|
||||
|
12134
package-lock.json
generated
74
package.json
@ -10,34 +10,27 @@
|
||||
"acorn-dynamic-import": "^2.0.0",
|
||||
"ajv": "^5.1.5",
|
||||
"ajv-keywords": "^2.0.0",
|
||||
"async": "^2.1.2",
|
||||
"async": "^2.6.1",
|
||||
"bluebird": "^3.5.1",
|
||||
"brace": "^0.11.1",
|
||||
"decimal.js": "7.2.3",
|
||||
"enhanced-resolve": "^3.4.0",
|
||||
"enhanced-resolve": "^4.0.0",
|
||||
"escope": "^3.6.0",
|
||||
"file-saver": "^1.3.3",
|
||||
"file-saver": "^1.3.8",
|
||||
"interpret": "^1.0.0",
|
||||
"jquery": "^3.3.1",
|
||||
"json-loader": "^0.5.4",
|
||||
"json5": "^0.5.1",
|
||||
"jsplumb": "^2.6.8",
|
||||
"jszip": "^3.1.5",
|
||||
"loader-runner": "^2.3.0",
|
||||
"loader-utils": "^1.1.0",
|
||||
"memory-fs": "~0.4.1",
|
||||
"mkdirp": "~0.5.0",
|
||||
"node-libs-browser": "^2.0.0",
|
||||
"source-map": "^0.5.3",
|
||||
"numeral": "2.0.6",
|
||||
"sprintf-js": "^1.1.1",
|
||||
"supports-color": "^4.2.1",
|
||||
"tapable": "^0.2.7",
|
||||
"uglifyjs-webpack-plugin": "^0.4.6",
|
||||
"tapable": "^1.0.0",
|
||||
"uglifyjs-webpack-plugin": "^1.2.5",
|
||||
"uuid": "^3.2.1",
|
||||
"w3c-blob": "0.0.1",
|
||||
"watchpack": "^1.4.0",
|
||||
"webpack-sources": "^1.0.1",
|
||||
"yargs": "^8.0.2"
|
||||
"w3c-blob": "0.0.1"
|
||||
},
|
||||
"description": "A cyberpunk-themed incremental game",
|
||||
"devDependencies": {
|
||||
@ -46,45 +39,36 @@
|
||||
"bundle-loader": "~0.5.0",
|
||||
"chai": "^4.1.2",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"codacy-coverage": "^2.0.1",
|
||||
"codecov.io": "^0.1.2",
|
||||
"coffee-loader": "~0.7.1",
|
||||
"coffee-script": "^1.10.0",
|
||||
"coveralls": "^2.11.2",
|
||||
"css-loader": "^0.28.3",
|
||||
"css-loader": "^0.28.11",
|
||||
"es6-promise-polyfill": "^1.1.1",
|
||||
"eslint": "^4.3.0",
|
||||
"eslint-plugin-node": "^5.1.1",
|
||||
"express": "~4.13.1",
|
||||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"file-loader": "^0.11.2",
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-plugin-node": "^6.0.1",
|
||||
"file-loader": "^1.1.11",
|
||||
"i18n-webpack-plugin": "^1.0.0",
|
||||
"istanbul": "^0.4.5",
|
||||
"jade": "^1.11.0",
|
||||
"jade-loader": "~0.8.0",
|
||||
"js-beautify": "^1.5.10",
|
||||
"less": "^2.5.1",
|
||||
"less-loader": "^4.0.3",
|
||||
"lodash": "^4.17.4",
|
||||
"json5": "^1.0.1",
|
||||
"less": "^3.0.4",
|
||||
"less-loader": "^4.1.0",
|
||||
"lodash": "^4.17.10",
|
||||
"mkdirp": "^0.5.1",
|
||||
"mocha": "^3.2.0",
|
||||
"mocha-lcov-reporter": "^1.0.0",
|
||||
"nsp": "^2.6.1",
|
||||
"nsp": "^3.2.1",
|
||||
"raw-loader": "~0.5.0",
|
||||
"react": "^15.2.1",
|
||||
"react-dom": "^15.2.1",
|
||||
"script-loader": "~0.7.0",
|
||||
"should": "^11.1.1",
|
||||
"simple-git": "^1.65.0",
|
||||
"simple-git": "^1.96.0",
|
||||
"sinon": "^2.3.2",
|
||||
"style-loader": "^0.18.1",
|
||||
"url-loader": "~0.5.0",
|
||||
"val-loader": "^1.0.2",
|
||||
"vm-browserify": "~0.0.0",
|
||||
"webpack": "^4.1.1",
|
||||
"webpack-cli": "^2.0.12",
|
||||
"webpack-dev-middleware": "^1.9.0",
|
||||
"source-map": "^0.7.3",
|
||||
"style-loader": "^0.21.0",
|
||||
"url-loader": "^1.0.1",
|
||||
"watchpack": "^1.6.0",
|
||||
"webpack": "^4.12.0",
|
||||
"webpack-cli": "^3.0.4",
|
||||
"webpack-dev-middleware": "^3.1.3",
|
||||
"webpack-dev-server": "^3.1.4",
|
||||
"worker-loader": "^0.8.0"
|
||||
"worker-loader": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.3.0 <5.0.0 || >=5.10"
|
||||
@ -97,7 +81,11 @@
|
||||
"url": "git+https://github.com/danielyxie/bitburner.git"
|
||||
},
|
||||
"scripts": {
|
||||
"start:dev": "webpack-dev-server"
|
||||
"start:dev": "webpack-dev-server",
|
||||
"build": "webpack --mode production",
|
||||
"build:dev": "webpack --mode development",
|
||||
"watch": "webpack --watch --mode production",
|
||||
"watch:dev": "webpack --watch --mode development"
|
||||
},
|
||||
"version": "0.35.1"
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import {printArray, createElement,
|
||||
createAccordionElement, removeElement,
|
||||
removeChildrenFromElement, exceptionAlert} from "../utils/HelperFunctions.js";
|
||||
import {logBoxCreate} from "../utils/LogBox.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
/* {
|
||||
|
@ -184,6 +184,7 @@ let AugmentationNames = {
|
||||
BladeArmorUnibeam: "BLADE-51b Tesla Armor: Unibeam Upgrade",
|
||||
BladeArmorOmnibeam: "BLADE-51b Tesla Armor: Omnibeam Upgrade",
|
||||
BladeArmorIPU: "BLADE-51b Tesla Armor: IPU Upgrade",
|
||||
BladesSimulacrum: "The Blade's Simulacrum",
|
||||
|
||||
//Wasteland Augs
|
||||
//PepBoy: "P.E.P-Boy", Plasma Energy Projection System
|
||||
@ -1552,7 +1553,7 @@ function initAugmentations() {
|
||||
var BladeburnersFactionName = "Bladeburners";
|
||||
if (factionExists(BladeburnersFactionName)) {
|
||||
var EsperEyewear = new Augmentation({
|
||||
name:AugmentationNames.EsperEyewear, repCost:400, moneyCost:30e6,
|
||||
name:AugmentationNames.EsperEyewear, repCost:500, moneyCost:33e6,
|
||||
info:"Ballistic-grade protective and retractable eyewear that was designed specially " +
|
||||
"for Bladeburner units. This " +
|
||||
"is implanted by installing a mechanical frame in the skull's orbit. " +
|
||||
@ -1569,7 +1570,7 @@ function initAugmentations() {
|
||||
resetAugmentation(EsperEyewear);
|
||||
|
||||
var EMS4Recombination = new Augmentation({
|
||||
name:AugmentationNames.EMS4Recombination, repCost: 800, moneyCost:50e6,
|
||||
name:AugmentationNames.EMS4Recombination, repCost: 1e3, moneyCost:55e6,
|
||||
info:"A DNA recombination of the EMS-4 Gene. This genetic engineering " +
|
||||
"technique was originally used on Bladeburners during the Synthoid uprising " +
|
||||
"to induce wakefulness and concentration, suppress fear, reduce empathy, and " +
|
||||
@ -1583,7 +1584,7 @@ function initAugmentations() {
|
||||
resetAugmentation(EMS4Recombination);
|
||||
|
||||
var OrionShoulder = new Augmentation({
|
||||
name:AugmentationNames.OrionShoulder, repCost:2e3, moneyCost:100e6,
|
||||
name:AugmentationNames.OrionShoulder, repCost:2.5e3, moneyCost:110e6,
|
||||
info:"A bionic shoulder augmentation for the right shoulder. Using cybernetics, " +
|
||||
"the ORION-MKIV shoulder enhances the strength and dexterity " +
|
||||
"of the user's right arm. It also provides protection due to its " +
|
||||
@ -1597,7 +1598,7 @@ function initAugmentations() {
|
||||
resetAugmentation(OrionShoulder);
|
||||
|
||||
var HyperionV1 = new Augmentation({
|
||||
name:AugmentationNames.HyperionV1, repCost: 4e3, moneyCost:500e6,
|
||||
name:AugmentationNames.HyperionV1, repCost: 5e3, moneyCost:550e6,
|
||||
info:"A pair of mini plasma cannons embedded into the hands. The Hyperion is capable " +
|
||||
"of rapidly firing bolts of high-density plasma. The weapon is meant to " +
|
||||
"be used against augmented enemies as the ionized " +
|
||||
@ -1611,7 +1612,7 @@ function initAugmentations() {
|
||||
resetAugmentation(HyperionV1);
|
||||
|
||||
var HyperionV2 = new Augmentation({
|
||||
name:AugmentationNames.HyperionV2, repCost:8e3, moneyCost:1e9,
|
||||
name:AugmentationNames.HyperionV2, repCost:10e3, moneyCost:1.1e9,
|
||||
info:"A pair of mini plasma cannons embedded into the hands. This augmentation " +
|
||||
"is more advanced and powerful than the original V1 model. This V2 model is " +
|
||||
"more power-efficiency, more accurate, and can fire plasma bolts at a much " +
|
||||
@ -1624,7 +1625,7 @@ function initAugmentations() {
|
||||
resetAugmentation(HyperionV2);
|
||||
|
||||
var GolemSerum = new Augmentation({
|
||||
name:AugmentationNames.GolemSerum, repCost:10e3, moneyCost:2e9,
|
||||
name:AugmentationNames.GolemSerum, repCost:12.5e3, moneyCost:2.2e9,
|
||||
info:"A serum that permanently enhances many aspects of a human's capabilities, " +
|
||||
"including strength, speed, immune system performance, and mitochondrial efficiency. The " +
|
||||
"serum was originally developed by the Chinese military in an attempt to " +
|
||||
@ -1637,7 +1638,7 @@ function initAugmentations() {
|
||||
resetAugmentation(GolemSerum);
|
||||
|
||||
var VangelisVirus = new Augmentation({
|
||||
name:AugmentationNames.VangelisVirus, repCost:6e3, moneyCost:500e6,
|
||||
name:AugmentationNames.VangelisVirus, repCost:7.5e3, moneyCost:550e6,
|
||||
info:"A synthetic symbiotic virus that is injected into the human brain tissue. The Vangelis virus " +
|
||||
"heightens the senses and focus of its host, and also enhances its intuition.<br><br>" +
|
||||
"This augmentation:<br>" +
|
||||
@ -1649,7 +1650,7 @@ function initAugmentations() {
|
||||
resetAugmentation(VangelisVirus);
|
||||
|
||||
var VangelisVirus3 = new Augmentation({
|
||||
name:AugmentationNames.VangelisVirus3, repCost:12e3, moneyCost:2e9,
|
||||
name:AugmentationNames.VangelisVirus3, repCost:15e3, moneyCost:2.2e9,
|
||||
info:"An improved version of Vangelis, a synthetic symbiotic virus that is " +
|
||||
"injected into the human brain tissue. On top of the benefits of the original " +
|
||||
"virus, this also grants an accelerated healing factor and enhanced " +
|
||||
@ -1664,7 +1665,7 @@ function initAugmentations() {
|
||||
resetAugmentation(VangelisVirus3);
|
||||
|
||||
var INTERLINKED = new Augmentation({
|
||||
name:AugmentationNames.INTERLINKED, repCost:8e3, moneyCost:1e9,
|
||||
name:AugmentationNames.INTERLINKED, repCost:10e3, moneyCost:1.1e9,
|
||||
info:"The DNA is genetically modified to enhance the human's body " +
|
||||
"extracellular matrix (ECM). This improves the ECM's ability to " +
|
||||
"structurally support the body and grants heightened strength and " +
|
||||
@ -1677,7 +1678,7 @@ function initAugmentations() {
|
||||
resetAugmentation(INTERLINKED);
|
||||
|
||||
var BladeRunner = new Augmentation({
|
||||
name:AugmentationNames.BladeRunner, repCost:8e3, moneyCost:1.5e9,
|
||||
name:AugmentationNames.BladeRunner, repCost:8e3, moneyCost:1.65e9,
|
||||
info:"A cybernetic foot augmentation that was specially created for Bladeburners " +
|
||||
"during the Synthoid Uprising. The organic musculature of the human foot " +
|
||||
"is enhanced with flexible carbon nanotube matrices that are controlled by " +
|
||||
@ -1691,7 +1692,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeRunner);
|
||||
|
||||
var BladeArmor = new Augmentation({
|
||||
name:AugmentationNames.BladeArmor, repCost:4e3, moneyCost:250e6,
|
||||
name:AugmentationNames.BladeArmor, repCost:5e3, moneyCost:275e6,
|
||||
info:"A powered exoskeleton suit (exosuit) designed as armor for Bladeburner units. This " +
|
||||
"exoskeleton is incredibly adaptable and can protect the wearer from blunt, piercing, " +
|
||||
"concussive, thermal, chemical, and electric trauma. It also enhances the user's " +
|
||||
@ -1705,7 +1706,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmor);
|
||||
|
||||
var BladeArmorPowerCells = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorPowerCells, repCost:6e3, moneyCost:500e6,
|
||||
name:AugmentationNames.BladeArmorPowerCells, repCost:7.5e3, moneyCost:550e6,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with Ion Power Cells, which are capable of " +
|
||||
"more efficiently storing and using power.<br><br>" +
|
||||
"This augmentation:<br>" +
|
||||
@ -1718,7 +1719,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorPowerCells);
|
||||
|
||||
var BladeArmorEnergyShielding = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorEnergyShielding, repCost:7e3, moneyCost:1e9,
|
||||
name:AugmentationNames.BladeArmorEnergyShielding, repCost:8.5e3, moneyCost:1.1e9,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with a plasma energy propulsion system " +
|
||||
"that is capable of projecting an energy shielding force field.<br><br>" +
|
||||
"This augmentation:<br>" +
|
||||
@ -1730,7 +1731,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorEnergyShielding);
|
||||
|
||||
var BladeArmorUnibeam = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorUnibeam, repCost:10e3, moneyCost:3e9,
|
||||
name:AugmentationNames.BladeArmorUnibeam, repCost:12.5e3, moneyCost:3.3e9,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with a concentrated deuterium-fluoride laser " +
|
||||
"weapon. It's precision an accuracy makes it useful for quickly neutralizing " +
|
||||
"threats while keeping casualties to a minimum.<br><br>" +
|
||||
@ -1742,7 +1743,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorUnibeam);
|
||||
|
||||
var BladeArmorOmnibeam = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorOmnibeam, repCost:20e3, moneyCost:5e9,
|
||||
name:AugmentationNames.BladeArmorOmnibeam, repCost:25e3, moneyCost:5.5e9,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor Unibeam augmentation to use " +
|
||||
"multiple-fiber system. The upgraded weapon uses multiple fiber laser " +
|
||||
"modules that combine together to form a single, more powerful beam of up to " +
|
||||
@ -1755,7 +1756,7 @@ function initAugmentations() {
|
||||
resetAugmentation(BladeArmorOmnibeam);
|
||||
|
||||
var BladeArmorIPU = new Augmentation({
|
||||
name:AugmentationNames.BladeArmorIPU, repCost: 5e3, moneyCost:200e6,
|
||||
name:AugmentationNames.BladeArmorIPU, repCost: 6e3, moneyCost:220e6,
|
||||
info:"Upgrades the BLADE-51b Tesla Armor with an AI Information Processing " +
|
||||
"Unit that was specially designed to analyze Synthoid related data and " +
|
||||
"information.<br><br>" +
|
||||
@ -1766,6 +1767,19 @@ function initAugmentations() {
|
||||
});
|
||||
BladeArmorIPU.addToFactions([BladeburnersFactionName]);
|
||||
resetAugmentation(BladeArmorIPU);
|
||||
|
||||
var BladesSimulacrum = new Augmentation({
|
||||
name:AugmentationNames.BladesSimulacrum, repCost:6e3, moneyCost:75e9,
|
||||
info:"A highly-advanced matter phase-shifter module that is embedded " +
|
||||
"in the brainstem and cerebellum. This augmentation allows " +
|
||||
"the user to project and control a holographic simulacrum within an " +
|
||||
"extremely large radius. These specially-modified holograms were specially " +
|
||||
"weaponized by Bladeburner units to be used against Synthoids.<br><br>" +
|
||||
"This augmentation allows you to perform Bladeburner actions and other " +
|
||||
"actions (such as working, commiting crimes, etc.) at the same time."
|
||||
});
|
||||
BladesSimulacrum.addToFactions([BladeburnersFactionName]);
|
||||
resetAugmentation(BladesSimulacrum);
|
||||
}
|
||||
|
||||
//Update costs based on how many have been purchased
|
||||
@ -1777,8 +1791,6 @@ function initAugmentations() {
|
||||
}
|
||||
|
||||
Player.reapplyAllAugmentations();
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Resets an Augmentation during (re-initizliation)
|
||||
@ -2350,6 +2362,8 @@ function applyAugmentation(aug, reapply=false) {
|
||||
Player.bladeburner_analysis_mult *= 1.15;
|
||||
Player.bladeburner_success_chance_mult *= 1.02;
|
||||
break;
|
||||
case AugmentationNames.BladesSimulacrum: //No multiplier effect
|
||||
break;
|
||||
default:
|
||||
throw new Error("ERROR: No such augmentation!");
|
||||
return;
|
||||
@ -2594,8 +2608,9 @@ function displaySourceFiles(listElement, sourceFiles) {
|
||||
console.log("ERROR: Invalid source file number: " + sourceFiles[i].n);
|
||||
continue;
|
||||
}
|
||||
const maxLevel = sourceFiles[i].n == 12 ? "∞" : "3";
|
||||
var accordion = createAccordionElement({
|
||||
hdrText:sourceFileObject.name + "<br>" + "Level " + (sourceFiles[i].lvl) + " / 3",
|
||||
hdrText:sourceFileObject.name + "<br>" + "Level " + (sourceFiles[i].lvl) + " / "+maxLevel,
|
||||
panelText:sourceFileObject.info
|
||||
});
|
||||
|
||||
|
@ -54,7 +54,7 @@ function initBitNodes() {
|
||||
"The starting and maximum amount of money on servers is reduced by 75%<br>" +
|
||||
"Server growth rate is reduced by 80%<br>" +
|
||||
"You will start out with $150b so that you can start your corporation<br>" +
|
||||
"You now only need 75 reputation with a faction in order to donate to it, rather than 150<br><br>" +
|
||||
"You now only need 75 favour with a faction in order to donate to it, rather than 150<br><br>" +
|
||||
"Destroying this BitNode will give you Source-File 3, or if you already have this Source-File it will " +
|
||||
"upgrade its level up to a maximum of 3. This Source-File lets you create corporations on other BitNodes (although " +
|
||||
"some BitNodes will disable this mechanic). This Source-File also increases your charisma and company salary multipliers by:<br>" +
|
||||
@ -156,10 +156,13 @@ function initBitNodes() {
|
||||
"Level 1: 24%<br>" +
|
||||
"Level 2: 36%<br>" +
|
||||
"Level 3: 42%");
|
||||
|
||||
BitNodes["BitNode12"] = new BitNode(12, "The Recursion", "Repeat.",
|
||||
"To iterate is human, to recurse divine.<br><br>" +
|
||||
"Every time this BitNode is destroyed, it becomes slightly harder. Destroying this BitNode will give your Souce-File 12, or " +
|
||||
"if you already have this Source-File it will upgrade its level. There is no maximum level for Source-File 12. Each level " +
|
||||
"of Source-File 12 will increase all of your multipliers by 1%.");
|
||||
//Books: Frontera, Shiner
|
||||
BitNodes["BitNode12"] = new BitNode(12, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode13"] = new BitNode(13, "", "COMING SOON");
|
||||
BitNodes["BitNode13"] = new BitNode(13, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
|
||||
BitNodes["BitNode15"] = new BitNode(15, "", "COMING SOON");
|
||||
BitNodes["BitNode16"] = new BitNode(16, "", "COMING SOON");
|
||||
@ -232,10 +235,10 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.RepToDonateToFaction = 0.5;
|
||||
BitNodeMultipliers.AugmentationRepCost = 3;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 3;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.25;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.25;
|
||||
BitNodeMultipliers.ServerGrowthRate = 0.20;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.25;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.2;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.2;
|
||||
BitNodeMultipliers.ServerGrowthRate = 0.2;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.2;
|
||||
BitNodeMultipliers.CompanyWorkMoney = 0.25;
|
||||
BitNodeMultipliers.CrimeMoney = 0.25;
|
||||
BitNodeMultipliers.HacknetNodeMoney = 0.25;
|
||||
@ -304,10 +307,56 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.InfiltrationRep = 2.5;
|
||||
BitNodeMultipliers.CorporationValuation = 0.01;
|
||||
break;
|
||||
case 12: //The Recursion
|
||||
let sf12Lvl = 0;
|
||||
for (let i = 0; i < Player.sourceFiles.length; i++) {
|
||||
if (Player.sourceFiles[i].n === 12) {
|
||||
sf12Lvl = Player.sourceFiles[i].lvl;
|
||||
}
|
||||
}
|
||||
const inc = Math.pow(1.01, sf12Lvl);
|
||||
const dec = Math.pow(0.99, sf12Lvl);
|
||||
BitNodeMultipliers.HackingLevelMultiplier = dec;
|
||||
|
||||
BitNodeMultipliers.ServerMaxMoney = dec;
|
||||
BitNodeMultipliers.ServerStartingMoney = dec;
|
||||
BitNodeMultipliers.ServerGrowthRate = dec;
|
||||
BitNodeMultipliers.ServerWeakenRate = dec;
|
||||
|
||||
//Does not scale, otherwise security might start at 300+
|
||||
BitNodeMultipliers.ServerStartingSecurity = 1.5;
|
||||
|
||||
BitNodeMultipliers.ManualHackMoney = dec;
|
||||
BitNodeMultipliers.ScriptHackMoney = dec;
|
||||
BitNodeMultipliers.CompanyWorkMoney = dec;
|
||||
BitNodeMultipliers.CrimeMoney = dec;
|
||||
BitNodeMultipliers.HacknetNodeMoney = dec;
|
||||
|
||||
BitNodeMultipliers.CompanyWorkExpGain = dec;
|
||||
BitNodeMultipliers.ClassGymExpGain = dec;
|
||||
BitNodeMultipliers.FactionWorkExpGain = dec;
|
||||
BitNodeMultipliers.HackExpGain = dec;
|
||||
BitNodeMultipliers.CrimeExpGain = dec;
|
||||
|
||||
BitNodeMultipliers.FactionWorkRepGain = dec;
|
||||
BitNodeMultipliers.FactionPassiveRepGain = dec;
|
||||
BitNodeMultipliers.RepToDonateToFaction = inc;
|
||||
|
||||
BitNodeMultipliers.AugmentationRepCost = inc;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = inc;
|
||||
|
||||
BitNodeMultipliers.InfiltrationMoney = dec;
|
||||
BitNodeMultipliers.InfiltrationRep = dec;
|
||||
|
||||
BitNodeMultipliers.CorporationValuation = dec;
|
||||
default:
|
||||
console.log("WARNING: Player.bitNodeN invalid");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export {initBitNodes, BitNode, BitNodes, BitNodeMultipliers, initBitNodeMultipliers};
|
||||
export {initBitNodes,
|
||||
BitNode,
|
||||
BitNodes,
|
||||
BitNodeMultipliers,
|
||||
initBitNodeMultipliers};
|
||||
|
@ -1,10 +1,11 @@
|
||||
import {Augmentations, AugmentationNames} from "./Augmentations.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Faction, Factions, factionExists,
|
||||
joinFaction, displayFactionContent} from "./Faction.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {hackWorldDaemon} from "./RedPill.js";
|
||||
import {hackWorldDaemon, redPillFlag} from "./RedPill.js";
|
||||
import {KEY} from "./Terminal.js";
|
||||
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
@ -15,7 +16,7 @@ import {getRandomInt, addOffset, clearObject,
|
||||
createProgressBarText} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
|
||||
@ -29,10 +30,16 @@ var MaxStaminaToGainFactor = 70000; //Max Stamina is divided by this to get
|
||||
|
||||
var DifficultyToTimeFactor = 10; //Action Difficulty divided by this to get base action time
|
||||
|
||||
//The difficulty multiplier affects stamina loss and hp loss of an action. Its formula is:
|
||||
//The difficulty multiplier affects stamina loss and hp loss of an action. Also affects
|
||||
//experience gain. Its formula is:
|
||||
//difficulty ^ exponentialFactor + difficulty / linearFactor
|
||||
var DiffMultExponentialFactor = 0.28;
|
||||
var DiffMultLinearFactor = 670;
|
||||
var DiffMultLinearFactor = 650;
|
||||
|
||||
var EffAgiLinearFactor = 90e3;
|
||||
var EffDexLinearFactor = 90e3;
|
||||
var EffAgiExponentialFactor = 0.031;
|
||||
var EffDexExponentialFactor = 0.03;
|
||||
|
||||
var BaseRecruitmentTimeNeeded = 300; //Base time needed (s) to complete a Recruitment action
|
||||
|
||||
@ -45,13 +52,14 @@ var BaseIntGain = 0.001; //Base intelligence stat gain
|
||||
var ActionCountGrowthPeriod = 300; //Time (s) it takes for action count to grow by its specified value
|
||||
|
||||
var RankToFactionRepFactor = 2; //Delta Faction Rep = this * Delta Rank
|
||||
var RankNeededForFaction = 25;
|
||||
|
||||
var ContractSuccessesPerLevel = 15; //How many successes you need to level up a contract
|
||||
var OperationSuccessesPerLevel = 10; //How many successes you need to level up an op
|
||||
var ContractSuccessesPerLevel = 3; //How many successes you need to level up a contract
|
||||
var OperationSuccessesPerLevel = 2.5; //How many successes you need to level up an op
|
||||
|
||||
var RanksPerSkillPoint = 4; //How many ranks needed to get 1 Skill Point
|
||||
|
||||
var ContractBaseMoneyGain = 5e3; //Base Money Gained per contract
|
||||
var ContractBaseMoneyGain = 10e3; //Base Money Gained per contract
|
||||
|
||||
//DOM related variables
|
||||
var ActiveActionCssClass = "bladeburner-active-action";
|
||||
@ -518,7 +526,10 @@ Action.prototype.getActionTime = function(inst) {
|
||||
|
||||
var effAgility = Player.agility * inst.skillMultipliers.effAgi;
|
||||
var effDexterity = Player.dexterity * inst.skillMultipliers.effDex;
|
||||
var statFac = 0.5 * (Math.pow(effAgility, 0.03) + Math.pow(effDexterity, 0.03)); //Always > 1
|
||||
var statFac = 0.5 * (Math.pow(effAgility, EffAgiExponentialFactor) +
|
||||
Math.pow(effDexterity, EffDexExponentialFactor) +
|
||||
(effAgility / EffAgiLinearFactor) +
|
||||
(effDexterity / EffDexLinearFactor)); //Always > 1
|
||||
|
||||
baseTime = Math.max(1, baseTime * skillFac / statFac);
|
||||
|
||||
@ -533,6 +544,16 @@ Action.prototype.getActionTime = function(inst) {
|
||||
}
|
||||
}
|
||||
|
||||
Action.prototype.getSuccessesNeededForNextLevel = function(baseSuccessesPerLevel) {
|
||||
return Math.ceil((0.5) * (this.maxLevel) * (2 * baseSuccessesPerLevel + (this.maxLevel-1)));
|
||||
}
|
||||
|
||||
Action.prototype.setMaxLevel = function(baseSuccessesPerLevel) {
|
||||
if (this.successes >= this.getSuccessesNeededForNextLevel(baseSuccessesPerLevel)) {
|
||||
++this.maxLevel;
|
||||
}
|
||||
}
|
||||
|
||||
Action.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Action", this);
|
||||
}
|
||||
@ -684,6 +705,14 @@ function Bladeburner(params={}) {
|
||||
if (params.new) {this.create();}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.prestige = function() {
|
||||
this.resetAction();
|
||||
var bladeburnerFac = Factions["Bladeburners"];
|
||||
if (this.rank >= RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.create = function() {
|
||||
this.contracts["Tracking"] = new Contract({
|
||||
name:"Tracking",
|
||||
@ -804,8 +833,13 @@ Bladeburner.prototype.storeCycles = function(numCycles=1) {
|
||||
}
|
||||
|
||||
Bladeburner.prototype.process = function() {
|
||||
//Extreme condition...if Operation Daedalus is complete trigger the BitNode
|
||||
if (redPillFlag === false && this.blackops.hasOwnProperty("Operation Daedalus")) {
|
||||
return hackWorldDaemon(Player.bitNodeN);
|
||||
}
|
||||
|
||||
//If the Player starts doing some other actions, set action to idle and alert
|
||||
if (Player.isWorking) {
|
||||
if (Augmentations[AugmentationNames.BladesSimulacrum].owned === false && Player.isWorking) {
|
||||
if (this.action.type !== ActionTypes["Idle"]) {
|
||||
dialogBoxCreate("Your Bladeburner action was cancelled because you started " +
|
||||
"doing something else");
|
||||
@ -909,7 +943,8 @@ Bladeburner.prototype.changeRank = function(change) {
|
||||
throw new Error("Could not properly get Bladeburner Faction object in Bladeburner UI Overview Faction button");
|
||||
}
|
||||
if (bladeburnerFac.isMember) {
|
||||
bladeburnerFac.playerReputation += (RankToFactionRepFactor * change * Player.faction_rep_mult);
|
||||
var favorBonus = 1 + (bladeburnerFac.favor / 100);
|
||||
bladeburnerFac.playerReputation += (RankToFactionRepFactor * change * Player.faction_rep_mult * favorBonus);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1021,6 +1056,7 @@ Bladeburner.prototype.resetAction = function() {
|
||||
}
|
||||
|
||||
Bladeburner.prototype.startAction = function(actionId) {
|
||||
if (actionId == null) {return;}
|
||||
this.action = actionId;
|
||||
this.actionTimeCurrent = 0;
|
||||
switch (actionId.type) {
|
||||
@ -1067,10 +1103,7 @@ Bladeburner.prototype.startAction = function(actionId) {
|
||||
this.actionTimeToComplete = 30;
|
||||
break;
|
||||
case ActionTypes["Recruitment"]:
|
||||
var effCharisma = Player.charisma * this.skillMultipliers.effCha;
|
||||
var charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90;
|
||||
var time = Math.max(10, Math.round(BaseRecruitmentTimeNeeded - charismaFactor));
|
||||
this.actionTimeToComplete = time;
|
||||
this.actionTimeToComplete = this.getRecruitmentTime();
|
||||
break;
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
@ -1130,9 +1163,9 @@ Bladeburner.prototype.completeAction = function() {
|
||||
}
|
||||
|
||||
if (isOperation) {
|
||||
action.maxLevel = Math.floor(action.successes / OperationSuccessesPerLevel) + 1;
|
||||
action.setMaxLevel(OperationSuccessesPerLevel);
|
||||
} else {
|
||||
action.maxLevel = Math.floor(action.successes / ContractSuccessesPerLevel) + 1;
|
||||
action.setMaxLevel(ContractSuccessesPerLevel);
|
||||
}
|
||||
if (action.rankGain) {
|
||||
var gain = addOffset(action.rankGain * rewardMultiplier, 10);
|
||||
@ -1301,7 +1334,7 @@ Bladeburner.prototype.completeAction = function() {
|
||||
this.startAction(this.action); //Repeat action
|
||||
break;
|
||||
case ActionTypes["Recruitment"]:
|
||||
var successChance = Math.pow(Player.charisma, 0.45) / (this.teamSize + 1);
|
||||
var successChance = this.getRecruitmentSuccessChance();
|
||||
console.log("Bladeburner recruitment success chance: " + successChance);
|
||||
if (Math.random() < successChance) {
|
||||
var expGain = 2 * BaseStatGain * this.actionTimeToComplete;
|
||||
@ -1437,6 +1470,16 @@ Bladeburner.prototype.completeOperation = function(success) {
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getRecruitmentTime = function() {
|
||||
var effCharisma = Player.charisma * this.skillMultipliers.effCha;
|
||||
var charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90;
|
||||
return Math.max(10, Math.round(BaseRecruitmentTimeNeeded - charismaFactor));
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getRecruitmentSuccessChance = function() {
|
||||
return Math.pow(Player.charisma, 0.45) / (this.teamSize + 1);
|
||||
}
|
||||
|
||||
//Process stat gains from Contracts, Operations, and Black Operations
|
||||
//@action(Action obj) - Derived action class
|
||||
//@success(bool) - Whether action was successful
|
||||
@ -1445,7 +1488,7 @@ Bladeburner.prototype.gainActionStats = function(action, success) {
|
||||
|
||||
//Gain multiplier based on difficulty. If this changes then the
|
||||
//same variable calculated in completeAction() needs to change too
|
||||
var difficultyMult = Math.pow(difficulty, 0.21);
|
||||
var difficultyMult = Math.pow(difficulty, DiffMultExponentialFactor) + difficulty / DiffMultLinearFactor;
|
||||
|
||||
var time = this.actionTimeToComplete;
|
||||
var successMult = success ? 1 : 0.5;
|
||||
@ -1621,6 +1664,7 @@ Bladeburner.prototype.initializeDomElementRefs = function() {
|
||||
operations: {},
|
||||
blackops: {},
|
||||
skills: {},
|
||||
skillPointsDisplay: null,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1682,6 +1726,7 @@ Bladeburner.prototype.createContent = function() {
|
||||
document.getElementById("entire-game-container").appendChild(DomElems.bladeburnerDiv);
|
||||
|
||||
this.postToConsole("Bladeburner Console BETA");
|
||||
this.postToConsole("Type 'help' to see console commands");
|
||||
DomElems.consoleInput.focus();
|
||||
}
|
||||
|
||||
@ -1836,7 +1881,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
}));
|
||||
|
||||
//Faction button
|
||||
var bladeburnersFactionName = "Bladeburners";
|
||||
const bladeburnersFactionName = "Bladeburners";
|
||||
if (factionExists(bladeburnersFactionName)) {
|
||||
var bladeburnerFac = Factions[bladeburnersFactionName];
|
||||
if (!(bladeburnerFac instanceof Faction)) {
|
||||
@ -1850,7 +1895,7 @@ Bladeburner.prototype.createOverviewContent = function() {
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(bladeburnersFactionName);
|
||||
} else {
|
||||
if (this.rank >= 25) {
|
||||
if (this.rank >= RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
dialogBoxCreate("Congratulations! You were accepted into the Bladeburners faction");
|
||||
removeChildrenFromElement(DomElems.overviewDiv);
|
||||
@ -2112,9 +2157,10 @@ Bladeburner.prototype.createSkillsContent = function() {
|
||||
}
|
||||
|
||||
//Skill Points
|
||||
DomElems.actionAndSkillsDiv.appendChild(createElement("p", {
|
||||
DomElems.skillPointsDisplay = createElement("p", {
|
||||
innerHTML:"<br><strong>Skill Points: " + formatNumber(this.skillPoints, 0) + "</strong>"
|
||||
}));
|
||||
});
|
||||
DomElems.actionAndSkillsDiv.appendChild(DomElems.skillPointsDisplay);
|
||||
|
||||
//UI Element for each skill
|
||||
for (var skillName in Skills) {
|
||||
@ -2226,6 +2272,8 @@ Bladeburner.prototype.updateActionAndSkillsContent = function() {
|
||||
}
|
||||
break;
|
||||
case "skills":
|
||||
DomElems.skillPointsDisplay.innerHTML = "<br><strong>Skill Points: " + formatNumber(this.skillPoints, 0) + "</strong>";
|
||||
|
||||
var skillElems = Object.keys(DomElems.skills);
|
||||
for (var i = 0; i < skillElems.length; ++i) {
|
||||
var skillElem = DomElems.skills[skillElems[i]];
|
||||
@ -2321,7 +2369,9 @@ Bladeburner.prototype.updateContractsUIElement = function(el, action) {
|
||||
appendLineBreaks(el, 2);
|
||||
el.appendChild(createElement("pre", {
|
||||
display:"inline-block",
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel,
|
||||
tooltip:action.getSuccessesNeededForNextLevel(ContractSuccessesPerLevel) + " successes " +
|
||||
"needed for next level"
|
||||
}));
|
||||
el.appendChild(createElement("a", {
|
||||
class: maxLevel ? "a-link-button-inactive" : "a-link-button", innerHTML:"↑",
|
||||
@ -2453,7 +2503,9 @@ Bladeburner.prototype.updateOperationsUIElement = function(el, action) {
|
||||
appendLineBreaks(el, 2);
|
||||
el.appendChild(createElement("pre", {
|
||||
display:"inline-block",
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel
|
||||
innerText:"Level: " + action.level + " / " + action.maxLevel,
|
||||
tooltip:action.getSuccessesNeededForNextLevel(OperationSuccessesPerLevel) + " successes " +
|
||||
"needed for next level"
|
||||
}));
|
||||
el.appendChild(createElement("a", {
|
||||
class: maxLevel ? "a-link-button-inactive" : "a-link-button", innerHTML:"↑",
|
||||
@ -2632,6 +2684,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
||||
class: canLevel && !maxLvl ? "a-link-button" : "a-link-button-inactive",
|
||||
margin:"3px", padding:"3px",
|
||||
clickListener:()=>{
|
||||
if (this.skillPoints < pointCost) {return;}
|
||||
this.skillPoints -= pointCost;
|
||||
this.upgradeSkill(skill);
|
||||
this.createActionAndSkillsContent();
|
||||
@ -3142,6 +3195,397 @@ Bladeburner.prototype.executeStartConsoleCommand = function(args) {
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
|
||||
if (type === "" || name === "") {return null;}
|
||||
var action = new ActionIdentifier();
|
||||
var convertedType = type.toLowerCase().trim();
|
||||
var convertedName = name.toLowerCase().trim();
|
||||
switch (convertedType) {
|
||||
case "contract":
|
||||
case "contracts":
|
||||
action.type = ActionTypes["Contract"];
|
||||
if (this.contracts.hasOwnProperty(name)) {
|
||||
action.name = name;
|
||||
return action;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case "operation":
|
||||
case "operations":
|
||||
case "op":
|
||||
case "ops":
|
||||
action.type = ActionTypes["Operation"];
|
||||
if (this.operations.hasOwnProperty(name)) {
|
||||
action.name = name;
|
||||
return action;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case "blackoperation":
|
||||
case "black operation":
|
||||
case "black operations":
|
||||
case "black op":
|
||||
case "black ops":
|
||||
case "blackop":
|
||||
case "blackops":
|
||||
action.type = ActionTypes["BlackOp"];
|
||||
if (BlackOperations.hasOwnProperty(name)) {
|
||||
action.name = name;
|
||||
return action;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
case "general":
|
||||
case "general action":
|
||||
case "gen":
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
if (convertedType.startsWith("gen")) {
|
||||
switch (convertedName) {
|
||||
case "training":
|
||||
action.type = ActionTypes["Training"];
|
||||
break;
|
||||
case "recruitment":
|
||||
case "recruit":
|
||||
action.type = ActionTypes["Recruitment"];
|
||||
break;
|
||||
case "field analysis":
|
||||
case "fieldanalysis":
|
||||
action.type = ActionTypes["Field Analysis"];
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isContractNameNetscriptFn = function(name) {
|
||||
return this.contracts.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isOperationNameNetscriptFn = function(name) {
|
||||
return this.operations.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isBlackOpNameNetscriptFn = function(name) {
|
||||
return BlackOperations.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isGeneralActionNameNetscriptFn = function(name) {
|
||||
return GeneralActions.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.isSkillNameNetscriptFn = function(name) {
|
||||
return Skills.hasOwnProperty(name);
|
||||
}
|
||||
|
||||
Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.startAction() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
this.startAction(actionId);
|
||||
if (workerScript.shouldLog("startAction")) {
|
||||
workerScript.scriptRef.log("Starting Bladeburner action with type " + type + " and name " + name);
|
||||
}
|
||||
return true;
|
||||
} catch(e) {
|
||||
this.resetAction();
|
||||
workerScript.scriptRef.log("ERROR: Bladeburner.startAction() failed to start action of type " + type + " due to invalid name: " + name +
|
||||
"Note that this name is case-sensitive and whitespace-sensitive");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionTimeNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getActionTime() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
return actionObj.getActionTime(this);
|
||||
case ActionTypes["Training"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
return 30;
|
||||
case ActionTypes["Recruitment"]:
|
||||
return this.getRecruitmentTime();
|
||||
default:
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionEstimatedSuccessChanceNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getActionEstimatedSuccessChance() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
return actionObj.getSuccessChance(this);
|
||||
case ActionTypes["Training"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
return 1;
|
||||
case ActionTypes["Recruitment"]:
|
||||
return this.getRecruitmentSuccessChance();
|
||||
default:
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getActionCountRemainingNetscriptFn = function(type, name, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getActionCountRemaining() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
return actionObj.count;
|
||||
case ActionTypes["Training"]:
|
||||
case ActionTypes["Field Analysis"]:
|
||||
case ActionTypes["FieldAnalysis"]:
|
||||
return Infinity;
|
||||
default:
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getSkillLevelNetscriptFn = function(skillName, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.getSkillLevel() failed due to an invalid skill specified: " +
|
||||
skillName + ". Note that the name of the skill is case-sensitive";
|
||||
|
||||
if (skillName === "") {
|
||||
//If skill name isn't specified, return an object with all of the player's skill levels
|
||||
let copy = Object.assign({}, this.Skills);
|
||||
return copy;
|
||||
}
|
||||
|
||||
if (!Skills.hasOwnProperty(skillName)) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Skills[skillName];
|
||||
}
|
||||
|
||||
Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.upgradeSkill() failed due to an invalid skill specified: " +
|
||||
skillName + ". Note that the name of the skill is case-sensitive";
|
||||
if (!Skills.hasOwnProperty(skillName)) {
|
||||
workerScript.log(errorLogText);
|
||||
return false;
|
||||
}
|
||||
|
||||
var skill = Skills[skillName];
|
||||
var currentLevel = 0;
|
||||
if (this.skills[skillName] && !isNaN(this.skills[skillName])) {
|
||||
currentLevel = this.skills[skillName];
|
||||
}
|
||||
var cost = skill.baseCost + (currentLevel * skill.costInc);
|
||||
|
||||
if (this.skillPoints < cost) {
|
||||
if (workerScript.shouldLog("upgradeSkill")) {
|
||||
workerScript.log("Bladeburner.upgradeSkill() failed because you do not have enough " +
|
||||
"skill points to upgrade " + skillName + " (You have " +
|
||||
this.skillPoints + ", you need " + cost + ")");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
this.skillPoints -= cost;
|
||||
this.upgradeSkill(skill);
|
||||
if (Engine.currentPage === Engine.Page.Bladeburner && DomElems.currentTab.toLowerCase() === "skills") {
|
||||
this.createActionAndSkillsContent();
|
||||
}
|
||||
if (workerScript.shouldLog("upgradeSkill")) {
|
||||
workerScript.log(skillName + " successfully upgraded to level " + this.skills[skillName]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getTeamSizeNetscriptFn = function(type, name, workerScript) {
|
||||
if (type === "" && name === "") {
|
||||
return this.teamSize;
|
||||
}
|
||||
|
||||
var errorLogText = "ERROR: Bladeburner.getTeamSize() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actionId.type === ActionTypes["Operation"] ||
|
||||
actionId.type === ActionTypes["BlackOp"] ||
|
||||
actionId.type === ActionTypes["BlackOperation"]) {
|
||||
return actionObj.teamCount;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.setTeamSizeNetscriptFn = function(type, name, size, workerScript) {
|
||||
var errorLogText = "ERROR: Bladeburner.setTeamSize() failed due to an invalid action specified. " +
|
||||
"Type: " + type + ", Name: " + name + ". Note that for contracts and operations, the " +
|
||||
"name of the operation is case-sensitive.";
|
||||
var actionId = this.getActionIdFromTypeAndName(type, name);
|
||||
if (actionId == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (actionId.type !== ActionTypes["Operation"] ||
|
||||
actionId.type !== ActionTypes["BlackOp"] ||
|
||||
actionId.type !== ActionTypes["BlackOperation"]) {
|
||||
workerScript.log("ERROR: Bladeburner.setTeamSize() failed. This function " +
|
||||
"only works for Operations and BlackOps");
|
||||
return -1;
|
||||
}
|
||||
|
||||
var actionObj = this.getActionObject(actionId);
|
||||
if (actionObj == null) {
|
||||
workerScript.log(errorLogText);
|
||||
return -1;
|
||||
}
|
||||
|
||||
var sanitizedSize = Math.round(size);
|
||||
if (isNaN(sanitizedSize)) {
|
||||
workerScript.log("ERROR: Bladeburner.setTeamSize() failed due to an invalid 'size' argument: " + size);
|
||||
return -1;
|
||||
}
|
||||
if (this.teamSize < sanitizedSize) {sanitizedSize = this.teamSize;}
|
||||
actionObj.teamCount = sanitizedSize;
|
||||
if (workerScript.shouldLog("setTeamSize")) {
|
||||
workerScript.log("Team size for " + name + " set to " + sanitizedSize);
|
||||
}
|
||||
return sanitizedSize;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getCityEstimatedPopulationNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.getCityEstimatedPopulation() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return -1;
|
||||
}
|
||||
return this.cities[cityName].popEst;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getCityEstimatedCommunitiesNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.getCityEstimatedCommunities() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return -1;
|
||||
}
|
||||
return this.cities[cityName].commsEst;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.getCityChaosNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.getCityChaos() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return -1;
|
||||
}
|
||||
return this.cities[cityName].chaos;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.switchCityNetscriptFn = function(cityName, workerScript) {
|
||||
if (!this.cities.hasOwnProperty(cityName)) {
|
||||
workerScript.log("ERROR: Bladeburner.switchCity() failed because the specified " +
|
||||
"city was invalid: " + cityName + ". Note that this city argument is case-sensitive");
|
||||
return false;
|
||||
}
|
||||
this.city = cityName;
|
||||
return true;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.joinBladeburnerFactionNetscriptFn = function(workerScript) {
|
||||
var bladeburnerFac = Factions["Bladeburners"];
|
||||
if (bladeburnerFac.isMember) {
|
||||
return true;
|
||||
} else if (this.rank >= RankNeededForFaction) {
|
||||
joinFaction(bladeburnerFac);
|
||||
if (workerScript.shouldLog("joinBladeburnerFaction")) {
|
||||
workerScript.log("Joined Bladeburners Faction");
|
||||
}
|
||||
if (Engine.currentPage === Engine.Page.Bladeburner) {
|
||||
removeChildrenFromElement(DomElems.overviewDiv);
|
||||
this.createOverviewContent();
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if (workerScript.shouldLog("joinBladeburnerFaction")) {
|
||||
workerScript.log("Failed to join Bladeburners Faction because " +
|
||||
"you do not have the required " + RankNeededForFaction + " rank");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Bladeburner.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Bladeburner", this);
|
||||
@ -3185,7 +3629,7 @@ function initBladeburner() {
|
||||
Skills[SkillNames.Overclock] = new Skill({
|
||||
name:SkillNames.Overclock,
|
||||
desc:"Each level of this skill decreases the time it takes " +
|
||||
"to attempt a contract or operation by 1% (Max Level: 99)",
|
||||
"to attempt a contract or operation by 1% (Max Level: 95)",
|
||||
baseCost:5, costInc:1, maxLvl:95,
|
||||
actionTime:1
|
||||
});
|
||||
@ -3271,7 +3715,7 @@ function initBladeburner() {
|
||||
"Zenyatta and RedWater by any means necessary. After the task " +
|
||||
"is completed, the actions must be covered up from the general public.",
|
||||
baseDifficulty:2000, reqdRank:2.5e3,
|
||||
rankGain:25, rankLoss:10, hpLoss:100,
|
||||
rankGain:50, rankLoss:10, hpLoss:100,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3288,7 +3732,7 @@ function initBladeburner() {
|
||||
"fabricated as a last resort. Be warned that AeroCorp has some of " +
|
||||
"the most advanced security measures in the world.",
|
||||
baseDifficulty:2500, reqdRank:5e3,
|
||||
rankGain:30, rankLoss:15, hpLoss:50,
|
||||
rankGain:60, rankLoss:15, hpLoss:50,
|
||||
weights:{hack:0.2,str:0.15,def:0.15,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isStealth:true
|
||||
@ -3307,7 +3751,7 @@ function initBladeburner() {
|
||||
"investigate the sewer systems, and eliminate Samizdat. They must " +
|
||||
"never publish anything again.",
|
||||
baseDifficulty:3000, reqdRank:7.5e3,
|
||||
rankGain:30, rankLoss:15, hpLoss:100,
|
||||
rankGain:75, rankLoss:15, hpLoss:100,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3325,7 +3769,7 @@ function initBladeburner() {
|
||||
"also to destroy any information or research at the facility that " +
|
||||
"is relevant to the Synthoids and their goals.",
|
||||
baseDifficulty:4000, reqdRank:10e3,
|
||||
rankGain:40, rankLoss:20, hpLoss:100,
|
||||
rankGain:100, rankLoss:20, hpLoss:100,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3339,7 +3783,7 @@ function initBladeburner() {
|
||||
"that this deal does not happen.<br><br>" +
|
||||
"Your task is to intercept the deal. Leave no survivors.",
|
||||
baseDifficulty:5000, reqdRank:12.5e3,
|
||||
rankGain:40, rankLoss:20, hpLoss:200,
|
||||
rankGain:125, rankLoss:20, hpLoss:200,
|
||||
weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3354,7 +3798,7 @@ function initBladeburner() {
|
||||
"the Red Rabbit brothel. Try to limit the number of other casualties, " +
|
||||
"but do what you must to complete the mission.",
|
||||
baseDifficulty:7500, reqdRank:15e3,
|
||||
rankGain:50, rankLoss:20, hpLoss:25,
|
||||
rankGain:200, rankLoss:20, hpLoss:25,
|
||||
weights:{hack:0,str:0.2,def:0.2,dex:0.3,agi:0.3,cha:0, int:0},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3371,7 +3815,7 @@ function initBladeburner() {
|
||||
"have thus enlisted our help.<br><br>" +
|
||||
"Your mission is to eradicate Juggernaut and his followers.",
|
||||
baseDifficulty:10e3, reqdRank:20e3,
|
||||
rankGain:75, rankLoss:40, hpLoss:300,
|
||||
rankGain:300, rankLoss:40, hpLoss:300,
|
||||
weights:{hack:0,str:0.25,def:0.25,dex:0.25,agi:0.25,cha:0, int:0},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3387,7 +3831,7 @@ function initBladeburner() {
|
||||
"in Los Angeles. Intelligence tells us that their base houses " +
|
||||
"one of their Synthoid manufacturing units.",
|
||||
baseDifficulty:12.5e3, reqdRank:25e3,
|
||||
rankGain:100, rankLoss:50, hpLoss:500,
|
||||
rankGain:500, rankLoss:50, hpLoss:500,
|
||||
weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3407,7 +3851,7 @@ function initBladeburner() {
|
||||
"operation. Your goal is to destroy this technology and eliminate" +
|
||||
"anyone who was involved in its creation.",
|
||||
baseDifficulty:15e3, reqdRank:30e3,
|
||||
rankGain:120, rankLoss:60, hpLoss:1000,
|
||||
rankGain:750, rankLoss:60, hpLoss:1000,
|
||||
weights:{hack:0.05,str:0.2,def:0.2,dex:0.25,agi:0.25,cha:0, int:0.05},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3422,7 +3866,7 @@ function initBladeburner() {
|
||||
"The goal of Operation Deckard is to hunt down these Synthoids and retire " +
|
||||
"them. I don't need to tell you how critical this mission is.",
|
||||
baseDifficulty:20e3, reqdRank:40e3,
|
||||
rankGain:150, rankLoss:75, hpLoss:200,
|
||||
rankGain:1e3, rankLoss:75, hpLoss:200,
|
||||
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04},
|
||||
decays:{hack:0,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3438,7 +3882,7 @@ function initBladeburner() {
|
||||
"with Augmentations. Your task is to hunt down the associated Dark Army " +
|
||||
"members and eliminate them.",
|
||||
baseDifficulty:25e3, reqdRank:50e3,
|
||||
rankGain:200, rankLoss:100, hpLoss:500,
|
||||
rankGain:1.5e3, rankLoss:100, hpLoss:500,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true,
|
||||
@ -3457,7 +3901,7 @@ function initBladeburner() {
|
||||
"The goal of Operation Wallace is to destroy the Dark Army and " +
|
||||
"Syndicate factions in Aevum immediately. Leave no survivors.",
|
||||
baseDifficulty:30e3, reqdRank:75e3,
|
||||
rankGain:500, rankLoss:150, hpLoss:1500,
|
||||
rankGain:2e3, rankLoss:150, hpLoss:1500,
|
||||
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3473,7 +3917,7 @@ function initBladeburner() {
|
||||
"successfully return. In the event of failure, all of the operation's " +
|
||||
"team members must not let themselves be captured alive.",
|
||||
baseDifficulty:35e3, reqdRank:100e3,
|
||||
rankGain:1e3, rankLoss:500, hpLoss:1500,
|
||||
rankGain:2.5e3, rankLoss:500, hpLoss:1500,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isStealth:true
|
||||
@ -3495,7 +3939,7 @@ function initBladeburner() {
|
||||
"Infiltrate the compound, delete and destroy the work, and then find and kill the " +
|
||||
"project lead.",
|
||||
baseDifficulty:40e3, reqdRank:125e3,
|
||||
rankGain:2e3, rankLoss:1e3, hpLoss:500,
|
||||
rankGain:3e3, rankLoss:1e3, hpLoss:500,
|
||||
weights:{hack:0.1,str:0.2,def:0.2,dex:0.2,agi:0.2,cha:0, int:0.1},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
@ -3512,7 +3956,7 @@ function initBladeburner() {
|
||||
"The mission is to destroy this broadcast tower. Speed and " +
|
||||
"stealth are of the upmost important for this.",
|
||||
baseDifficulty:45e3, reqdRank:150e3,
|
||||
rankGain:5e3, rankLoss:1e3, hpLoss:100,
|
||||
rankGain:4e3, rankLoss:1e3, hpLoss:100,
|
||||
weights:{hack:0.05,str:0.15,def:0.15,dex:0.3,agi:0.3,cha:0, int:0.05},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isStealth:true
|
||||
@ -3541,7 +3985,7 @@ function initBladeburner() {
|
||||
"'The Covenant'. We have no prior intelligence about this " +
|
||||
"organization, so you are going in blind.",
|
||||
baseDifficulty:55e3, reqdRank:200e3,
|
||||
rankGain:5e3, rankLoss:1e3, hpLoss:10e3,
|
||||
rankGain:7.5e3, rankLoss:1e3, hpLoss:10e3,
|
||||
weights:{hack:0,str:0.24,def:0.24,dex:0.24,agi:0.24,cha:0, int:0.04},
|
||||
decays:{hack:0.6,str:0.8,def:0.8,dex:0.8,agi:0.8,cha:0, int:0.75},
|
||||
isKill:true
|
||||
|
@ -13,7 +13,7 @@ import {getRandomInt, removeElementById,
|
||||
clearSelector} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber, isString, generateRandomString} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
@ -231,7 +231,8 @@ let MaterialSizes = {
|
||||
Chemicals: 0.05,
|
||||
Drugs: 0.02,
|
||||
Robots: 0.5,
|
||||
"AICores": 0.1
|
||||
AICores: 0.1,
|
||||
RealEstate: 0,
|
||||
}
|
||||
|
||||
function Product(params={}) {
|
||||
@ -2334,10 +2335,10 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
//If Market Research upgrades are unlocked, add competition and demand info
|
||||
var cmpAndDmdText = "";
|
||||
if (company.unlockUpgrades[2] === 1) {
|
||||
cmpAndDmdText += "<br>Competition: " + formatNumber(mat.cmp, 3);
|
||||
cmpAndDmdText += "<br>Demand: " + formatNumber(mat.dmd, 3);
|
||||
}
|
||||
if (company.unlockUpgrades[3] === 1) {
|
||||
cmpAndDmdText += "<br>Demand: " + formatNumber(mat.dmd, 3);
|
||||
cmpAndDmdText += "<br>Competition: " + formatNumber(mat.cmp, 3);
|
||||
}
|
||||
var innerTxt = "<p class='tooltip'>" + mat.name + ": " + formatNumber(mat.qty, 3) +
|
||||
"(" + formatNumber(totalGain, 3) + "/s)" +
|
||||
@ -2430,8 +2431,9 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
});
|
||||
|
||||
//Select industry and city to export to
|
||||
var citySelector = createElement("select");
|
||||
var citySelector = createElement("select", {class: "dropdown"});
|
||||
var industrySelector = createElement("select", {
|
||||
class: "dropdown",
|
||||
changeListener:()=>{
|
||||
var industryName = industrySelector.options[industrySelector.selectedIndex].value;
|
||||
for (var foo = 0; foo < company.divisions.length; ++foo) {
|
||||
@ -2474,6 +2476,7 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
|
||||
//Select amount to export
|
||||
var exportAmount = createElement("input", {
|
||||
class: "text-input",
|
||||
placeholder:"Export amount / s"
|
||||
});
|
||||
|
||||
@ -2695,11 +2698,12 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
//Completed products
|
||||
var cmpAndDmdText = "";
|
||||
if (company.unlockUpgrades[2] === 1) {
|
||||
cmpAndDmdText += "<br>Competition: " + formatNumber(product.cmp, 3);
|
||||
}
|
||||
if (company.unlockUpgrades[3] === 1) {
|
||||
cmpAndDmdText += "<br>Demand: " + formatNumber(product.dmd, 3);
|
||||
}
|
||||
if (company.unlockUpgrades[3] === 1) {
|
||||
cmpAndDmdText += "<br>Competition: " + formatNumber(product.cmp, 3);
|
||||
}
|
||||
|
||||
var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale
|
||||
div.appendChild(createElement("p", {
|
||||
innerHTML: "<p class='tooltip'>" + product.name + ": " + formatNumber(product.data[city][0], 3) + //Quantity
|
||||
@ -3421,15 +3425,14 @@ Corporation.prototype.updateUIHeaderTabs = function() {
|
||||
innerHTML: "Create a new division to expand into a new industry:",
|
||||
});
|
||||
var selector = createElement("select", {
|
||||
class:"cmpy-mgmt-industry-select"
|
||||
class:"dropdown"
|
||||
});
|
||||
var industryDescription = createElement("p", {});
|
||||
var yesBtn;
|
||||
var nameInput = createElement("input", {
|
||||
type:"text",
|
||||
id:"cmpy-mgmt-expand-industry-name-input",
|
||||
color:"white",
|
||||
backgroundColor:"black",
|
||||
class: "text-input",
|
||||
display:"block",
|
||||
maxLength: 30,
|
||||
pattern:"[a-zA-Z0-9-_]",
|
||||
@ -4067,7 +4070,7 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
|
||||
innerText: "Would you like to expand into a new city by opening an office? " +
|
||||
"This would cost " + numeral(OfficeInitialCost).format('$0.000a'),
|
||||
});
|
||||
var citySelector = createElement("select", {margin:"5px"});
|
||||
var citySelector = createElement("select", {class: "dropdown", margin:"5px"});
|
||||
for (var cityName in division.offices) {
|
||||
if (division.offices.hasOwnProperty(cityName)) {
|
||||
if (!(division.offices[cityName] instanceof OfficeSpace)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
let CONSTANTS = {
|
||||
Version: "0.37.1",
|
||||
Version: "0.38.1",
|
||||
|
||||
//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
|
||||
@ -14,6 +14,8 @@ let CONSTANTS = {
|
||||
BaseCostFor1GBOfRamServer: 55000, //1 GB of RAM
|
||||
BaseCostFor1GBOfRamHacknetNode: 30000,
|
||||
|
||||
TravelCost: 200000,
|
||||
|
||||
BaseCostForHacknetNode: 1000,
|
||||
BaseCostForHacknetNodeCore: 500000,
|
||||
|
||||
@ -41,6 +43,7 @@ let CONSTANTS = {
|
||||
/* Netscript Constants */
|
||||
//RAM Costs for different commands
|
||||
ScriptBaseRamCost: 1.4,
|
||||
ScriptDomRamCost: 100,
|
||||
ScriptWhileRamCost: 0.2,
|
||||
ScriptForRamCost: 0.2,
|
||||
ScriptIfRamCost: 0.15,
|
||||
@ -79,6 +82,8 @@ let CONSTANTS = {
|
||||
ScriptSingularityFn2RamCost: 2,
|
||||
ScriptSingularityFn3RamCost: 3,
|
||||
|
||||
ScriptBladeburnerApiBaseRamCost: 4,
|
||||
|
||||
MultithreadingRAMCost: 1,
|
||||
|
||||
NumNetscriptPorts: 20,
|
||||
@ -484,16 +489,19 @@ let CONSTANTS = {
|
||||
"World Stock Exchange account and TIX API Access<br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.37.1<br>" +
|
||||
"* You now earn money from successfully completing Bladeburner contracts. The amount you earn is based " +
|
||||
"on the difficulty of the contract.<br>" +
|
||||
"* Completing Field Analysis in Bladeburner now grants 0.1 rank<br>" +
|
||||
"* The maximum RAM you can get on a purchased server is now 1,048,576GB (2^20)<br>" +
|
||||
"* Bug Fix: Fixed Netscript syntax highlighting issues with the new NetscriptJS<br>" +
|
||||
"* Bug Fix: Netscript Functions now properly incur RAM costs in NetscriptJS<br>" +
|
||||
"* Bug Fix: deleteServer() now fails if its called on the server you are currently connected to<br>" +
|
||||
"* Removed in-game Netscript documentation, since it was outdated and difficult to maintain.<br>" +
|
||||
"* Bug Fix: Updated the gymWorkout() Singularity function with the new exp/cost values for gyms<br>"
|
||||
"v0.38.1<br>" +
|
||||
"* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS<br>" +
|
||||
"* Implemented by Github user hydroflame:<br>" +
|
||||
"*** Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)<br>" +
|
||||
"*** Added game option to suppress travel confirmation<br>" +
|
||||
"*** Text on buttons can no longer be highlighted<br>" +
|
||||
"*** Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations<br>" +
|
||||
"*** Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)<br>" +
|
||||
"*** Added ps() Netscript function<br>" +
|
||||
"*** Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money<br>" +
|
||||
"*** Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips<br>" +
|
||||
"*** Bug Fix: Sever's security level should now properly increase when its money is grown to max value"
|
||||
|
||||
}
|
||||
|
||||
export {CONSTANTS};
|
||||
|
484
src/Crimes.js
@ -2,143 +2,232 @@ import {CONSTANTS} from "./Constants.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
|
||||
/* Crimes.js */
|
||||
function commitShopliftCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeShoplift;
|
||||
var time = 2000;
|
||||
Player.startCrime(0, 0, 0, 2/div, 2/div, 0, 15000/div, time, singParams); //$7500/s, 1 exp/s
|
||||
return time;
|
||||
|
||||
function Crime(name, type, time, money, difficulty, karma, params) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.time = time;
|
||||
this.money = money;
|
||||
this.difficulty = difficulty;
|
||||
this.karma = karma;
|
||||
|
||||
this.hacking_success_weight = params.hacking_success_weight ? params.hacking_success_weight : 0;
|
||||
this.strength_success_weight = params.strength_success_weight ? params.strength_success_weight : 0;
|
||||
this.defense_success_weight = params.defense_success_weight ? params.defense_success_weight : 0;
|
||||
this.dexterity_success_weight = params.dexterity_success_weight ? params.dexterity_success_weight : 0;
|
||||
this.agility_success_weight = params.agility_success_weight ? params.agility_success_weight : 0;
|
||||
this.charisma_success_weight = params.charisma_success_weight ? params.charisma_success_weight : 0;
|
||||
|
||||
this.hacking_exp = params.hacking_exp ? params.hacking_exp : 0;
|
||||
this.strength_exp = params.strength_exp ? params.strength_exp : 0;
|
||||
this.defense_exp = params.defense_exp ? params.defense_exp : 0;
|
||||
this.dexterity_exp = params.dexterity_exp ? params.dexterity_exp : 0;
|
||||
this.agility_exp = params.agility_exp ? params.agility_exp : 0;
|
||||
this.charisma_exp = params.charisma_exp ? params.charisma_exp : 0;
|
||||
this.intelligence_exp = params.intelligence_exp ? params.intelligence_exp : 0;
|
||||
|
||||
this.kills = params.kills ? params.kills : 0;
|
||||
}
|
||||
|
||||
function commitRobStoreCrime(div=1, singParams=null) {
|
||||
Crime.prototype.commit = function(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeRobStore;
|
||||
var time = 60000;
|
||||
Player.startCrime(30/div, 0, 0, 45/div, 45/div, 0, 400000/div, time, singParams); //$6666,6/2, 0.5exp/s, 0.75exp/s
|
||||
return time;
|
||||
Player.crimeType = this.type;
|
||||
Player.startCrime(
|
||||
this.hacking_exp/div,
|
||||
this.strength_exp/div,
|
||||
this.defense_exp/div,
|
||||
this.dexterity_exp/div,
|
||||
this.agility_exp/div,
|
||||
this.charisma_exp/div,
|
||||
this.money/div, this.time, singParams);
|
||||
return this.time;
|
||||
}
|
||||
|
||||
function commitMugCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeMug;
|
||||
var time = 4000;
|
||||
Player.startCrime(0, 3/div, 3/div, 3/div, 3/div, 0, 36000/div, time, singParams); //$9000/s, .66 exp/s
|
||||
return time;
|
||||
Crime.prototype.successRate = function() {
|
||||
var chance = (this.hacking_success_weight * Player.hacking_skill +
|
||||
this.strength_success_weight * Player.strength +
|
||||
this.defense_success_weight * Player.defense +
|
||||
this.dexterity_success_weight * Player.dexterity +
|
||||
this.agility_success_weight * Player.agility +
|
||||
this.charisma_success_weight * Player.charisma +
|
||||
CONSTANTS.IntelligenceCrimeWeight * Player.intelligence);
|
||||
chance /= CONSTANTS.MaxSkillLevel;
|
||||
chance /= this.difficulty;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function commitLarcenyCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeLarceny;
|
||||
var time = 90000;
|
||||
Player.startCrime(45/div, 0, 0, 60/div, 60/div, 0, 800000/div, time, singParams) // $8888.88/s, .5 exp/s, .66 exp/s
|
||||
return time;
|
||||
}
|
||||
const Crimes = {
|
||||
Shoplift: new Crime("Shoplift", CONSTANTS.CrimeShoplift, 2e3, 15e3, 1/20, 0.1, {
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
function commitDealDrugsCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeDrugs;
|
||||
var time = 10000;
|
||||
Player.startCrime(0, 0, 0, 5/div, 5/div, 10/div, 120000/div, time, singParams); //$12000/s, .5 exp/s, 1 exp/s
|
||||
return time;
|
||||
}
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
}),
|
||||
|
||||
function commitBondForgeryCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeBondForgery;
|
||||
var time = 300000;
|
||||
Player.startCrime(100/div, 0, 0, 150/div, 0, 15/div, 4500000/div, time, singParams); //$15000/s, 0.33 hack exp/s, .5 dex exp/s, .05 cha exp
|
||||
return time;
|
||||
}
|
||||
RobStore: new Crime("Rob Store", CONSTANTS.CrimeRobStore, 60e3, 400e3, 1/5, 0.5, {
|
||||
hacking_exp: 30,
|
||||
dexterity_exp: 45,
|
||||
agility_exp: 45,
|
||||
|
||||
function commitTraffickArmsCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeTraffickArms;
|
||||
var time = 40000;
|
||||
Player.startCrime(0, 20/div, 20/div, 20/div, 20/div, 40/div, 600000/div, time, singParams); //$15000/s, .5 combat exp/s, 1 cha exp/s
|
||||
return time;
|
||||
}
|
||||
hacking_success_weight: 0.5 ,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
|
||||
function commitHomicideCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeHomicide;
|
||||
var time = 3000;
|
||||
Player.startCrime(0, 2/div, 2/div, 2/div, 2/div, 0, 45000/div, time, singParams); //$15000/s, 0.66 combat exp/s
|
||||
return time;
|
||||
}
|
||||
intelligence_exp: 0.25 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
function commitGrandTheftAutoCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeGrandTheftAuto;
|
||||
var time = 80000;
|
||||
Player.startCrime(0, 20/div, 20/div, 20/div, 80/div, 40/div, 1600000/div, time, singParams); //$20000/s, .25 exp/s, 1 exp/s, .5 exp/s
|
||||
return time;
|
||||
}
|
||||
Mug: new Crime("Mug", CONSTANTS.CrimeMug, 4e3, 36e3, 1/5, 0.25, {
|
||||
strength_exp: 3,
|
||||
defense_exp: 3,
|
||||
dexterity_exp: 3,
|
||||
agility_exp: 3,
|
||||
|
||||
function commitKidnapCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeKidnap;
|
||||
var time = 120000;
|
||||
Player.startCrime(0, 80/div, 80/div, 80/div, 80/div, 80/div, 3600000/div, time, singParams); //$30000/s. .66 exp/s
|
||||
return time;
|
||||
}
|
||||
strength_success_weight: 1.5,
|
||||
defense_success_weight: 0.5,
|
||||
dexterity_success_weight: 1.5,
|
||||
agility_success_weight: 0.5,
|
||||
}),
|
||||
|
||||
function commitAssassinationCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeAssassination;
|
||||
var time = 300000;
|
||||
Player.startCrime(0, 300/div, 300/div, 300/div, 300/div, 0, 12000000/div, time, singParams); //$40000/s, 1 exp/s
|
||||
return time;
|
||||
}
|
||||
Larceny: new Crime("Larceny", CONSTANTS.CrimeLarceny, 90e3, 800e3, 1/3, 1.5, {
|
||||
hacking_exp: 45,
|
||||
dexterity_exp: 60,
|
||||
agility_exp: 60,
|
||||
|
||||
function commitHeistCrime(div=1, singParams=null) {
|
||||
if (div <= 0) {div = 1;}
|
||||
Player.crimeType = CONSTANTS.CrimeHeist;
|
||||
var time = 600000;
|
||||
Player.startCrime(450/div, 450/div, 450/div, 450/div, 450/div, 450/div, 120000000/div, time, singParams); //$200000/s, .75exp/s
|
||||
return time;
|
||||
}
|
||||
hacking_skill_success_weight: 0.5,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
function determineCrimeSuccess(crime, moneyGained) {
|
||||
intelligence_exp: 0.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
DealDrugs: new Crime("Deal Drugs", CONSTANTS.CrimeDrugs, 10e3, 120e3, 1, 0.5, {
|
||||
dexterity_exp: 5,
|
||||
agility_exp: 5,
|
||||
charisma_exp: 10,
|
||||
|
||||
charisma_success_weight: 3,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
|
||||
BondForgery: new Crime("Bond Forgery", CONSTANTS.CrimeBondForgery, 300e3, 4.5e6, 1/2, 0.1, {
|
||||
hacking_exp: 100,
|
||||
dexterity_exp: 150,
|
||||
charisma_exp: 15,
|
||||
|
||||
hacking_skill_success_weight: 0.05,
|
||||
dexterity_success_weight: 1.25,
|
||||
|
||||
intelligence_exp: 2 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
TraffickArms: new Crime("Traffick Arms", CONSTANTS.CrimeTraffickArms, 40e3, 600e3, 2, 1, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 20,
|
||||
charisma_exp: 40,
|
||||
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
|
||||
Homicide: new Crime("Homicide", CONSTANTS.CrimeHomicide, 3e3, 45e3, 1, 3, {
|
||||
strength_exp: 2,
|
||||
defense_exp: 2,
|
||||
dexterity_exp: 2,
|
||||
agility_exp: 2,
|
||||
|
||||
strength_success_weight: 2,
|
||||
defense_success_weight: 2,
|
||||
dexterity_success_weight: 0.5,
|
||||
agility_success_weight: 0.5,
|
||||
|
||||
kills: 1,
|
||||
}),
|
||||
|
||||
GrandTheftAuto: new Crime("Grand Theft Auto", CONSTANTS.CrimeGrandTheftAuto, 80e3, 1.6e6, 8, 5, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 40,
|
||||
|
||||
hacking_skill_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 4,
|
||||
agility_success_weight: 2,
|
||||
charisma_success_weight: 2,
|
||||
|
||||
intelligence_exp: CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Kidnap: new Crime("Kidnap", CONSTANTS.CrimeKidnap, 120e3, 3.6e6, 5, 6, {
|
||||
strength_exp: 80,
|
||||
defense_exp: 80,
|
||||
dexterity_exp: 80,
|
||||
agility_exp: 80,
|
||||
charisma_exp: 80,
|
||||
|
||||
charisma_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
intelligence_exp: 2 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Assassination: new Crime("Assassination", CONSTANTS.CrimeAssassination, 300e3, 12e6, 8, 10, {
|
||||
strength_exp: 300,
|
||||
defense_exp: 300,
|
||||
dexterity_exp: 300,
|
||||
agility_exp: 300,
|
||||
|
||||
strength_success_weight: 1,
|
||||
dexterity_success_weight: 2,
|
||||
agility_success_weight: 1,
|
||||
|
||||
intelligence_exp: 5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
|
||||
kills: 1,
|
||||
}),
|
||||
|
||||
Heist: new Crime("Heist", CONSTANTS.CrimeHeist, 600e3, 120e6, 18, 15, {
|
||||
hacking_exp: 450,
|
||||
strength_exp: 450,
|
||||
defense_exp: 450,
|
||||
dexterity_exp: 450,
|
||||
agility_exp: 450,
|
||||
charisma_exp: 450,
|
||||
|
||||
hacking_skill_success_weight: 1,
|
||||
strength_success_weight: 1,
|
||||
defense_success_weight: 1,
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
charisma_success_weight: 1,
|
||||
|
||||
intelligence_exp: 10 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
};
|
||||
|
||||
function determineCrimeSuccess(type, moneyGained) {
|
||||
var chance = 0;
|
||||
switch (crime) {
|
||||
case CONSTANTS.CrimeShoplift:
|
||||
chance = determineCrimeChanceShoplift();
|
||||
var found = false;
|
||||
for(const i in Crimes) {
|
||||
const crime = Crimes[i];
|
||||
if(crime.type == type) {
|
||||
chance = crime.successRate();
|
||||
found = true;
|
||||
break;
|
||||
case CONSTANTS.CrimeRobStore:
|
||||
chance = determineCrimeChanceRobStore();
|
||||
break;
|
||||
case CONSTANTS.CrimeMug:
|
||||
chance = determineCrimeChanceMug();
|
||||
break;
|
||||
case CONSTANTS.CrimeLarceny:
|
||||
chance = determineCrimeChanceLarceny();
|
||||
break;
|
||||
case CONSTANTS.CrimeDrugs:
|
||||
chance = determineCrimeChanceDealDrugs();
|
||||
break;
|
||||
case CONSTANTS.CrimeBondForgery:
|
||||
chance = determineCrimeChanceBondForgery();
|
||||
break;
|
||||
case CONSTANTS.CrimeTraffickArms:
|
||||
chance = determineCrimeChanceTraffickArms();
|
||||
break;
|
||||
case CONSTANTS.CrimeHomicide:
|
||||
chance = determineCrimeChanceHomicide();
|
||||
break;
|
||||
case CONSTANTS.CrimeGrandTheftAuto:
|
||||
chance = determineCrimeChanceGrandTheftAuto();
|
||||
break;
|
||||
case CONSTANTS.CrimeKidnap:
|
||||
chance = determineCrimeChanceKidnap();
|
||||
break;
|
||||
case CONSTANTS.CrimeAssassination:
|
||||
chance = determineCrimeChanceAssassination();
|
||||
break;
|
||||
case CONSTANTS.CrimeHeist:
|
||||
chance = determineCrimeChanceHeist();
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if(!found) {
|
||||
console.log(crime);
|
||||
dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer");
|
||||
return;
|
||||
@ -154,134 +243,33 @@ function determineCrimeSuccess(crime, moneyGained) {
|
||||
}
|
||||
}
|
||||
|
||||
let intWgt = CONSTANTS.IntelligenceCrimeWeight;
|
||||
let maxLvl = CONSTANTS.MaxSkillLevel;
|
||||
|
||||
function determineCrimeChanceShoplift() {
|
||||
var chance = (Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 20;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
function findCrime(roughName) {
|
||||
if (roughName.includes("shoplift")) {
|
||||
return Crimes.Shoplift;
|
||||
} else if (roughName.includes("rob") && roughName.includes("store")) {
|
||||
return Crimes.RobStore;
|
||||
} else if (roughName.includes("mug")) {
|
||||
return Crimes.Mug;
|
||||
} else if (roughName.includes("larceny")) {
|
||||
return Crimes.Larceny;
|
||||
} else if (roughName.includes("drugs")) {
|
||||
return Crimes.DealDrugs;
|
||||
} else if (roughName.includes("bond") && roughName.includes("forge")) {
|
||||
return Crimes.BondForgery;
|
||||
} else if (roughName.includes("traffick") && roughName.includes("arms")) {
|
||||
return Crimes.TraffickArms;
|
||||
} else if (roughName.includes("homicide")) {
|
||||
return Crimes.Homicide;
|
||||
} else if (roughName.includes("grand") && roughName.includes("auto")) {
|
||||
return Crimes.GrandTheftAuto;
|
||||
} else if (roughName.includes("kidnap")) {
|
||||
return Crimes.Kidnap;
|
||||
} else if (roughName.includes("assassinate")) {
|
||||
return Crimes.Assassination;
|
||||
} else if (roughName.includes("heist")) {
|
||||
return Crimes.Heist;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function determineCrimeChanceRobStore() {
|
||||
var chance = (0.5 * Player.hacking_skill / maxLvl +
|
||||
2 * Player.dexterity / maxLvl +
|
||||
1 * Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 5;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceMug() {
|
||||
var chance = (1.5 * Player.strength / maxLvl +
|
||||
0.5 * Player.defense / maxLvl +
|
||||
1.5 * Player.dexterity / maxLvl +
|
||||
0.5 * Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 5;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceLarceny() {
|
||||
var chance = (0.5 * Player.hacking_skill / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) * 3;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceDealDrugs() {
|
||||
var chance = (3*Player.charisma / maxLvl +
|
||||
2*Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl);
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceBondForgery() {
|
||||
var chance = (0.1*Player.hacking_skill / maxLvl +
|
||||
2.5*Player.dexterity / maxLvl +
|
||||
2*intWgt*Player.intelligence / maxLvl);
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceTraffickArms() {
|
||||
var chance = (Player.charisma / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
Player.defense / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 2;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceHomicide() {
|
||||
var chance = (2 * Player.strength / maxLvl +
|
||||
2 * Player.defense / maxLvl +
|
||||
0.5 * Player.dexterity / maxLvl +
|
||||
0.5 * Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl);
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceGrandTheftAuto() {
|
||||
var chance = (Player.hacking_skill / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
4 * Player.dexterity / maxLvl +
|
||||
2 * Player.agility / maxLvl +
|
||||
2 * Player.charisma / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 8;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceKidnap() {
|
||||
var chance = (Player.charisma / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 5;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceAssassination() {
|
||||
var chance = (Player.strength / maxLvl +
|
||||
2 * Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 8;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
function determineCrimeChanceHeist() {
|
||||
var chance = (Player.hacking_skill / maxLvl +
|
||||
Player.strength / maxLvl +
|
||||
Player.defense / maxLvl +
|
||||
Player.dexterity / maxLvl +
|
||||
Player.agility / maxLvl +
|
||||
Player.charisma / maxLvl +
|
||||
intWgt * Player.intelligence / maxLvl) / 18;
|
||||
chance *= Player.crime_success_mult;
|
||||
return Math.min(chance, 1);
|
||||
}
|
||||
|
||||
export {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
|
||||
commitLarcenyCrime, commitDealDrugsCrime, commitBondForgeryCrime,
|
||||
commitTraffickArmsCrime,
|
||||
commitHomicideCrime, commitGrandTheftAutoCrime, commitKidnapCrime,
|
||||
commitAssassinationCrime, commitHeistCrime, determineCrimeSuccess,
|
||||
determineCrimeChanceShoplift, determineCrimeChanceRobStore,
|
||||
determineCrimeChanceMug, determineCrimeChanceLarceny,
|
||||
determineCrimeChanceDealDrugs, determineCrimeChanceBondForgery,
|
||||
determineCrimeChanceTraffickArms,
|
||||
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
|
||||
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
|
||||
determineCrimeChanceHeist};
|
||||
export {determineCrimeSuccess,findCrime,Crimes};
|
||||
|
191
src/DarkWeb.js
@ -19,7 +19,6 @@ function checkIfConnectedToDarkweb() {
|
||||
"to purchase an item");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Handler for dark web commands. The terminal's executeCommand() function will pass
|
||||
@ -49,150 +48,68 @@ function executeDarkwebTerminalCommand(commandArray) {
|
||||
}
|
||||
|
||||
function listAllDarkwebItems() {
|
||||
for (var item in DarkWebItems) {
|
||||
if (DarkWebItems.hasOwnProperty(item)) {
|
||||
var item = DarkWebItems[item];
|
||||
//Convert string using toLocaleString
|
||||
var split = item.split(" - ");
|
||||
if (split.length == 3 && split[1].charAt(0) == '$') {
|
||||
split[1] = split[1].slice(1);
|
||||
split[1] = split[1].replace(/,/g, '');
|
||||
var price = parseFloat(split[1]);
|
||||
if (isNaN(price)) {
|
||||
post(item);
|
||||
return;
|
||||
for(const key in DarkWebItems) {
|
||||
const item = DarkWebItems[key];
|
||||
post(item.toString());
|
||||
}
|
||||
price = formatNumber(price, 0);
|
||||
split[1] = "$" + price.toString();
|
||||
post(split.join(" - "));
|
||||
} else {
|
||||
post(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var priceString = split[1];
|
||||
//Check for errors
|
||||
if (priceString.length == 0 || priceString.charAt(0) != '$') {
|
||||
return -1;
|
||||
}
|
||||
//Remove dollar sign and commas
|
||||
priceString = priceString.slice(1);
|
||||
priceString = priceString.replace(/,/g, '');
|
||||
|
||||
//Convert string to numeric
|
||||
var price = parseFloat(priceString);
|
||||
if (isNaN(price)) {return -1;}
|
||||
else {return price;}
|
||||
}
|
||||
|
||||
function buyDarkwebItem(itemName) {
|
||||
if (itemName.toLowerCase() == Programs.BruteSSHProgram.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.BruteSSHProgram.name);
|
||||
post("You have purchased the BruteSSH.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else if (itemName.toLowerCase() == Programs.FTPCrackProgram.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.FTPCrackProgram.name);
|
||||
post("You have purchased the FTPCrack.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else if (itemName.toLowerCase() == Programs.RelaySMTPProgram.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram.name);
|
||||
post("You have purchased the relaySMTP.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else if (itemName.toLowerCase() == Programs.HTTPWormProgram.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.HTTPWormProgram.name);
|
||||
post("You have purchased the HTTPWorm.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else if (itemName.toLowerCase() == Programs.SQLInjectProgram.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.SQLInjectProgram.name);
|
||||
post("You have purchased the SQLInject.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else if (itemName.toLowerCase() == Programs.DeepscanV1.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.DeepscanV1.name);
|
||||
post("You have purchased the DeepscanV1.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else if (itemName.toLowerCase() == Programs.DeepscanV2.name.toLowerCase()) {
|
||||
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program);
|
||||
if (price > 0 && Player.money.gt(price)) {
|
||||
Player.loseMoney(price);
|
||||
Player.getHomeComputer().programs.push(Programs.DeepscanV2.name);
|
||||
post("You have purchased the DeepscanV2.exe program. The new program " +
|
||||
"can be found on your home computer.");
|
||||
} else {
|
||||
post("Not enough money to purchase " + itemName);
|
||||
}
|
||||
} else {
|
||||
post("Unrecognized item");
|
||||
itemName = itemName.toLowerCase();
|
||||
|
||||
// find the program that matches, if any
|
||||
let item = null;
|
||||
for(const key in DarkWebItems) {
|
||||
const i = DarkWebItems[key];
|
||||
if(i.program.toLowerCase() == itemName) {
|
||||
item = i;
|
||||
}
|
||||
}
|
||||
|
||||
function parseDarkwebItemPrice(itemDesc) {
|
||||
var split = itemDesc.split(" - ");
|
||||
if (split.length == 3) {
|
||||
var priceString = split[1];
|
||||
//Check for errors
|
||||
if (priceString.length == 0 || priceString.charAt(0) != '$') {
|
||||
return -1;
|
||||
}
|
||||
//Remove dollar sign and commas
|
||||
priceString = priceString.slice(1);
|
||||
priceString = priceString.replace(/,/g, '');
|
||||
|
||||
//Convert string to numeric
|
||||
var price = parseFloat(priceString);
|
||||
if (isNaN(price)) {return -1;}
|
||||
else {return price;}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
// return if invalid
|
||||
if(item === null) {
|
||||
post("Unrecognized item: "+itemName);
|
||||
return;
|
||||
}
|
||||
|
||||
let DarkWebItems = {
|
||||
BruteSSHProgram: "BruteSSH.exe - $500,000 - Opens up SSH Ports",
|
||||
FTPCrackProgram: "FTPCrack.exe - $1,500,000 - Opens up FTP Ports",
|
||||
RelaySMTPProgram: "relaySMTP.exe - $5,000,000 - Opens up SMTP Ports",
|
||||
HTTPWormProgram: "HTTPWorm.exe - $30,000,000 - Opens up HTTP Ports",
|
||||
SQLInjectProgram: "SQLInject.exe - $250,000,000 - Opens up SQL Ports",
|
||||
DeepScanV1Program: "DeepscanV1.exe - $500,000 - Enables 'scan-analyze' with a depth up to 5",
|
||||
DeepScanV2Program: "DeepscanV2.exe - $25,000,000 - Enables 'scan-analyze' with a depth up to 10",
|
||||
// return if the player already has it.
|
||||
if(Player.hasProgram(item.program)) {
|
||||
post('You already have the '+item.program+' program');
|
||||
return;
|
||||
}
|
||||
|
||||
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand,
|
||||
listAllDarkwebItems, buyDarkwebItem, parseDarkwebItemPrice,
|
||||
DarkWebItems};
|
||||
// return if the player doesn't have enough money
|
||||
if(Player.money.lt(item.price)) {
|
||||
post("Not enough money to purchase " + item.program);
|
||||
return;
|
||||
}
|
||||
|
||||
// buy and push
|
||||
Player.loseMoney(item.price);
|
||||
Player.getHomeComputer().programs.push(item.program);
|
||||
post('You have purchased the '+item.program+' program. The new program can be found on your home computer.');
|
||||
}
|
||||
|
||||
function DarkWebItem(program, price, description) {
|
||||
this.program = program;
|
||||
this.price = price;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
// formats the item for the terminal (eg. "BruteSSH.exe - $500,000 - Opens up SSH Ports")
|
||||
DarkWebItem.prototype.toString = function() {
|
||||
return [this.program, "$"+formatNumber(this.price), this.description].join(' - ');
|
||||
}
|
||||
|
||||
const DarkWebItems = {
|
||||
BruteSSHProgram: new DarkWebItem(Programs.BruteSSHProgram, 500000, "Opens up SSH Ports"),
|
||||
FTPCrackProgram: new DarkWebItem(Programs.FTPCrackProgram, 1500000, "Opens up FTP Ports"),
|
||||
RelaySMTPProgram: new DarkWebItem(Programs.RelaySMTPProgram, 5000000, "Opens up SMTP Ports"),
|
||||
HTTPWormProgram: new DarkWebItem(Programs.HTTPWormProgram, 30000000, "Opens up HTTP Ports"),
|
||||
SQLInjectProgram: new DarkWebItem(Programs.SQLInjectProgram, 250000000, "Opens up SQL Ports"),
|
||||
DeepscanV1: new DarkWebItem(Programs.DeepscanV1, 500000, "Enables 'scan-analyze' with a depth up to 5"),
|
||||
DeepscanV2: new DarkWebItem(Programs.DeepscanV2, 25000000, "Enables 'scan-analyze' with a depth up to 10"),
|
||||
};
|
||||
|
||||
|
||||
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand, DarkWebItems};
|
||||
|
430
src/Faction.js
@ -3,7 +3,7 @@ import {Augmentations, AugmentationNames,
|
||||
import {BitNodeMultipliers} from "./BitNode.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {FactionInfo} from "./FactionInfo.js";
|
||||
import {FactionInfos} from "./FactionInfo.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {HackingMission, setInMission} from "./Missions.js";
|
||||
import {Player} from "./Player.js";
|
||||
@ -15,7 +15,7 @@ import {clearEventListeners, createElement,
|
||||
removeChildrenFromElement} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
|
||||
@ -23,7 +23,6 @@ import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
function Faction(name="") {
|
||||
this.name = name;
|
||||
this.augmentations = []; //Name of augmentation only
|
||||
this.info = ""; //Introductory/informational text about the faction
|
||||
|
||||
//Player-related properties for faction
|
||||
this.isMember = false; //Whether player is member
|
||||
@ -31,22 +30,17 @@ function Faction(name="") {
|
||||
this.playerReputation = 0; //"Reputation" within faction
|
||||
this.alreadyInvited = false;
|
||||
|
||||
//Multipliers for unlocking and purchasing augmentations
|
||||
this.augmentationPriceMult = 1;
|
||||
this.augmentationRepRequirementMult = 1;
|
||||
|
||||
//Faction favor
|
||||
this.favor = 0;
|
||||
this.rolloverRep = 0;
|
||||
};
|
||||
|
||||
Faction.prototype.setAugmentationMultipliers = function(price, rep) {
|
||||
this.augmentationPriceMult = price;
|
||||
this.augmentationRepRequirementMult = rep;
|
||||
Faction.prototype.getInfo = function() {
|
||||
const info = FactionInfos[this.name];
|
||||
if(info == null) {
|
||||
throw new Error("Missing faction from FactionInfos: " + this.name+" this probably means the faction got corrupted somehow");
|
||||
}
|
||||
|
||||
Faction.prototype.setInfo = function(inf) {
|
||||
this.info = inf;
|
||||
return info;
|
||||
}
|
||||
|
||||
Faction.prototype.gainFavor = function() {
|
||||
@ -119,142 +113,9 @@ function factionExists(name) {
|
||||
//TODO Augmentation price and rep requirement mult are 1 for everything right now,
|
||||
// This might change in the future for balance
|
||||
function initFactions() {
|
||||
//Endgame
|
||||
var Illuminati = new Faction("Illuminati");
|
||||
Illuminati.setInfo(FactionInfo.IlluminatiInfo);
|
||||
resetFaction(Illuminati);
|
||||
|
||||
var Daedalus = new Faction("Daedalus");
|
||||
Daedalus.setInfo(FactionInfo.DaedalusInfo);
|
||||
resetFaction(Daedalus);
|
||||
|
||||
var Covenant = new Faction("The Covenant");
|
||||
Covenant.setInfo(FactionInfo.CovenantInfo);
|
||||
resetFaction(Covenant);
|
||||
|
||||
//Megacorporations, each forms its own faction
|
||||
var ECorp = new Faction("ECorp");
|
||||
ECorp.setInfo(FactionInfo.ECorpInfo);
|
||||
resetFaction(ECorp);
|
||||
|
||||
var MegaCorp = new Faction("MegaCorp");
|
||||
MegaCorp.setInfo(FactionInfo.MegaCorpInfo);
|
||||
resetFaction(MegaCorp);
|
||||
|
||||
var BachmanAndAssociates = new Faction("Bachman & Associates");
|
||||
BachmanAndAssociates.setInfo(FactionInfo.BachmanAndAssociatesInfo);
|
||||
resetFaction(BachmanAndAssociates);
|
||||
|
||||
var BladeIndustries = new Faction("Blade Industries");
|
||||
BladeIndustries.setInfo(FactionInfo.BladeIndustriesInfo);
|
||||
resetFaction(BladeIndustries);
|
||||
|
||||
var NWO = new Faction("NWO");
|
||||
NWO.setInfo(FactionInfo.NWOInfo);
|
||||
resetFaction(NWO);
|
||||
|
||||
var ClarkeIncorporated = new Faction("Clarke Incorporated");
|
||||
ClarkeIncorporated.setInfo(FactionInfo.ClarkeIncorporatedInfo);
|
||||
resetFaction(ClarkeIncorporated);
|
||||
|
||||
var OmniTekIncorporated = new Faction("OmniTek Incorporated");
|
||||
OmniTekIncorporated.setInfo(FactionInfo.OmniTekIncorporatedInfo);
|
||||
resetFaction(OmniTekIncorporated);
|
||||
|
||||
var FourSigma = new Faction("Four Sigma");
|
||||
FourSigma.setInfo(FactionInfo.FourSigmaInfo);
|
||||
resetFaction(FourSigma);
|
||||
|
||||
var KuaiGongInternational = new Faction("KuaiGong International");
|
||||
KuaiGongInternational.setInfo(FactionInfo.KuaiGongInternationalInfo);
|
||||
resetFaction(KuaiGongInternational);
|
||||
|
||||
//Other corporations
|
||||
var FulcrumTechnologies = new Faction("Fulcrum Secret Technologies");
|
||||
FulcrumTechnologies.setInfo(FactionInfo.FulcrumSecretTechnologiesInfo);
|
||||
resetFaction(FulcrumTechnologies);
|
||||
|
||||
//Hacker groups
|
||||
var BitRunners = new Faction("BitRunners");
|
||||
BitRunners.setInfo(FactionInfo.BitRunnersInfo);
|
||||
resetFaction(BitRunners);
|
||||
|
||||
var BlackHand = new Faction("The Black Hand");
|
||||
BlackHand.setInfo(FactionInfo.BlackHandInfo);
|
||||
resetFaction(BlackHand);
|
||||
|
||||
var NiteSec = new Faction("NiteSec");
|
||||
NiteSec.setInfo(FactionInfo.NiteSecInfo);
|
||||
resetFaction(NiteSec);
|
||||
|
||||
//City factions, essentially governments
|
||||
var Chongqing = new Faction("Chongqing");
|
||||
Chongqing.setInfo(FactionInfo.ChongqingInfo);
|
||||
resetFaction(Chongqing);
|
||||
|
||||
var Sector12 = new Faction("Sector-12");
|
||||
Sector12.setInfo(FactionInfo.Sector12Info);
|
||||
resetFaction(Sector12);
|
||||
|
||||
var NewTokyo = new Faction("New Tokyo");
|
||||
NewTokyo.setInfo(FactionInfo.NewTokyoInfo);
|
||||
resetFaction(NewTokyo);
|
||||
|
||||
var Aevum = new Faction("Aevum");
|
||||
Aevum.setInfo(FactionInfo.AevumInfo);
|
||||
resetFaction(Aevum);
|
||||
|
||||
var Ishima = new Faction("Ishima");
|
||||
Ishima.setInfo(FactionInfo.Ishima);
|
||||
resetFaction(Ishima);
|
||||
|
||||
var Volhaven = new Faction("Volhaven");
|
||||
Volhaven.setInfo(FactionInfo.VolhavenInfo);
|
||||
resetFaction(Volhaven);
|
||||
|
||||
//Criminal Organizations/Gangs
|
||||
var SpeakersForTheDead = new Faction("Speakers for the Dead");
|
||||
SpeakersForTheDead.setInfo(FactionInfo.SpeakersForTheDeadInfo);
|
||||
resetFaction(SpeakersForTheDead);
|
||||
|
||||
var DarkArmy = new Faction("The Dark Army");
|
||||
DarkArmy.setInfo(FactionInfo.DarkArmyInfo);
|
||||
resetFaction(DarkArmy);
|
||||
|
||||
var TheSyndicate = new Faction("The Syndicate");
|
||||
TheSyndicate.setInfo(FactionInfo.TheSyndicateInfo);
|
||||
resetFaction(TheSyndicate);
|
||||
|
||||
var Silhouette = new Faction("Silhouette");
|
||||
Silhouette.setInfo(FactionInfo.SilhouetteInfo);
|
||||
resetFaction(Silhouette);
|
||||
|
||||
var Tetrads = new Faction("Tetrads"); //Low-medium level asian crime gang
|
||||
Tetrads.setInfo(FactionInfo.TetradsInfo);
|
||||
resetFaction(Tetrads);
|
||||
|
||||
var SlumSnakes = new Faction("Slum Snakes"); //Low level crime gang
|
||||
SlumSnakes.setInfo(FactionInfo.SlumSnakesInfo);
|
||||
resetFaction(SlumSnakes);
|
||||
|
||||
//Earlygame factions - factions the player will prestige with early on that don't
|
||||
//belong in other categories
|
||||
var Netburners = new Faction("Netburners");
|
||||
Netburners.setInfo(FactionInfo.NetburnersInfo);
|
||||
resetFaction(Netburners);
|
||||
|
||||
var TianDiHui = new Faction("Tian Di Hui"); //Society of the Heaven and Earth
|
||||
TianDiHui.setInfo(FactionInfo.TianDiHuiInfo);
|
||||
resetFaction(TianDiHui);
|
||||
|
||||
var CyberSec = new Faction("CyberSec");
|
||||
CyberSec.setInfo(FactionInfo.CyberSecInfo);
|
||||
resetFaction(CyberSec);
|
||||
|
||||
//Special Factions
|
||||
var Bladeburners = new Faction("Bladeburners");
|
||||
Bladeburners.setInfo(FactionInfo.BladeburnersInfo);
|
||||
resetFaction(Bladeburners);
|
||||
for(const name in FactionInfos) {
|
||||
resetFaction(new Faction(name));
|
||||
}
|
||||
}
|
||||
|
||||
//Resets a faction during (re-)initialization. Saves the favor in the new
|
||||
@ -287,36 +148,12 @@ function inviteToFaction(faction) {
|
||||
function joinFaction(faction) {
|
||||
faction.isMember = true;
|
||||
Player.factions.push(faction.name);
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
//Determine what factions you are banned from now that you have joined this faction
|
||||
if (faction.name == "Chongqing") {
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Sector-12") {
|
||||
Factions["Chongqing"].isBanned = true;
|
||||
Factions["New Tokyo"].isBanned = true;
|
||||
Factions["Ishima"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "New Tokyo") {
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Aevum") {
|
||||
Factions["Chongqing"].isBanned = true;
|
||||
Factions["New Tokyo"].isBanned = true;
|
||||
Factions["Ishima"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Ishima") {
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Volhaven"].isBanned = true;
|
||||
} else if (faction.name == "Volhaven") {
|
||||
Factions["Chongqing"].isBanned = true;
|
||||
Factions["Sector-12"].isBanned = true;
|
||||
Factions["New Tokyo"].isBanned = true;
|
||||
Factions["Aevum"].isBanned = true;
|
||||
Factions["Ishima"].isBanned = true;
|
||||
for(const i in factionInfo.enemies) {
|
||||
const enemy = factionInfo.enemies[i];
|
||||
Factions[enemy].isBanned = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,6 +163,8 @@ function displayFactionContent(factionName) {
|
||||
if (faction == null) {
|
||||
throw new Error("Invalid factionName passed into displayFactionContent: " + factionName);
|
||||
}
|
||||
var factionInfo = faction.getInfo();
|
||||
|
||||
removeChildrenFromElement(Engine.Display.factionContent);
|
||||
var elements = [];
|
||||
|
||||
@ -334,7 +173,7 @@ function displayFactionContent(factionName) {
|
||||
innerText:factionName
|
||||
}));
|
||||
elements.push(createElement("pre", {
|
||||
innerHTML:"<i>" + faction.info + "</i>"
|
||||
innerHTML:"<i>" + factionInfo.infoText + "</i>"
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
@ -346,14 +185,14 @@ function displayFactionContent(factionName) {
|
||||
favorGain = favorGain[0];
|
||||
elements.push(createElement("p", {
|
||||
innerText: "Reputation: " + formatNumber(faction.playerReputation, 4),
|
||||
tooltip:"You will earn " + formatNumber(favorGain, 4) +
|
||||
tooltip:"You will earn " + formatNumber(favorGain, 0) +
|
||||
" faction favor upon resetting after installing an Augmentation"
|
||||
}))
|
||||
elements.push(createElement("p", {
|
||||
innerText:"---------------",
|
||||
}));
|
||||
elements.push(createElement("p", {
|
||||
innerText:"Faction Favor: " + formatNumber(faction.favor, 4),
|
||||
innerText:"Faction Favor: " + formatNumber(faction.favor, 0),
|
||||
tooltip:"Faction favor increases the rate at which " +
|
||||
"you earn reputation for this faction by 1% per favor. Faction favor " +
|
||||
"is gained whenever you reset after installing an Augmentation. The amount of " +
|
||||
@ -583,214 +422,17 @@ function displayFactionContent(factionName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (faction.isMember) {
|
||||
if (faction.favor >= (150 * BitNodeMultipliers.RepToDonateToFaction)) {
|
||||
donateDiv.style.display = "inline";
|
||||
} else {
|
||||
donateDiv.style.display = "none";
|
||||
}
|
||||
|
||||
switch(faction.name) {
|
||||
case "Illuminati":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Daedalus":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "The Covenant":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "ECorp":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "MegaCorp":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Bachman & Associates":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Blade Industries":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "NWO":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Clarke Incorporated":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "OmniTek Incorporated":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Four Sigma":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "KuaiGong International":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Fulcrum Secret Technologies":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "BitRunners":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "The Black Hand":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "NiteSec":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Chongqing":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Sector-12":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "New Tokyo":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Aevum":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Ishima":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Volhaven":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Speakers for the Dead":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "The Dark Army":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "The Syndicate":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Silhouette":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Tetrads":
|
||||
hackMissionDiv.style.display = "none";
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Slum Snakes":
|
||||
hackMissionDiv.style.display = "none";
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "inline";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "Netburners":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Tian Di Hui":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "inline";
|
||||
break;
|
||||
case "CyberSec":
|
||||
hackMissionDiv.style.display = "inline";
|
||||
hackDiv.style.display = "inline";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
case "Bladeburners":
|
||||
hackMissionDiv.style.display = "none";
|
||||
hackDiv.style.display = "none";
|
||||
fieldWorkDiv.style.display = "none";
|
||||
securityWorkDiv.style.display = "none";
|
||||
break;
|
||||
default:
|
||||
console.log("Faction does not exist");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (!faction.isMember) {
|
||||
throw new Error("Not a member of this faction, cannot display faction information");
|
||||
}
|
||||
|
||||
donateDiv.style.display = faction.favor >= (150 * BitNodeMultipliers.RepToDonateToFaction) ? "inline" : "none";
|
||||
|
||||
hackMissionDiv.style.display = factionInfo.offerHackingMission ? "inline": "none";
|
||||
hackDiv.style.display = factionInfo.offerHackingWork ? "inline" : "none";
|
||||
fieldWorkDiv.style.display = factionInfo.offerFieldWork ? "inline" : "none";
|
||||
securityWorkDiv.style.display = factionInfo.offerSecurityWork ? "inline" : "none";
|
||||
|
||||
//Display all elements
|
||||
for (var i = 0; i < elements.length; ++i) {
|
||||
Engine.Display.factionContent.appendChild(elements[i]);
|
||||
@ -915,6 +557,8 @@ function displayFactionAugmentations(factionName) {
|
||||
// @augs Array of Aug names
|
||||
// @faction Faction for which to display Augmentations
|
||||
function createFactionAugmentationDisplayElements(augmentationsList, augs, faction) {
|
||||
const factionInfo = faction.getInfo();
|
||||
|
||||
for (var i = 0; i < augs.length; ++i) {
|
||||
(function () {
|
||||
var aug = Augmentations[augs[i]];
|
||||
@ -955,7 +599,7 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
||||
var pElem = createElement("p", {
|
||||
display:"inline",
|
||||
})
|
||||
var req = aug.baseRepRequirement * faction.augmentationRepRequirementMult;
|
||||
var req = aug.baseRepRequirement * factionInfo.augmentationRepRequirementMult;
|
||||
var hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
if (!hasPrereqs) {
|
||||
aElem.setAttribute("class", "a-link-button-inactive");
|
||||
@ -966,10 +610,10 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
||||
pElem.innerHTML = "ALREADY OWNED";
|
||||
} else if (faction.playerReputation >= req) {
|
||||
aElem.setAttribute("class", "a-link-button");
|
||||
pElem.innerHTML = "UNLOCKED - " + numeral(aug.baseCost * faction.augmentationPriceMult).format("$0.000a");
|
||||
pElem.innerHTML = "UNLOCKED - " + numeral(aug.baseCost * factionInfo.augmentationPriceMult).format("$0.000a");
|
||||
} else {
|
||||
aElem.setAttribute("class", "a-link-button-inactive");
|
||||
pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - " + numeral(aug.baseCost * faction.augmentationPriceMult).format("$0.000a");
|
||||
pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - " + numeral(aug.baseCost * factionInfo.augmentationPriceMult).format("$0.000a");
|
||||
pElem.style.color = "red";
|
||||
}
|
||||
aDiv.appendChild(aElem);
|
||||
@ -982,6 +626,7 @@ function createFactionAugmentationDisplayElements(augmentationsList, augs, facti
|
||||
}
|
||||
|
||||
function purchaseAugmentationBoxCreate(aug, fac) {
|
||||
const factionInfo = fac.getInfo();
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Purchase";
|
||||
noBtn.innerHTML = "Cancel";
|
||||
@ -995,7 +640,7 @@ function purchaseAugmentationBoxCreate(aug, fac) {
|
||||
yesNoBoxCreate("<h2>" + aug.name + "</h2><br>" +
|
||||
aug.info + "<br><br>" +
|
||||
"<br>Would you like to purchase the " + aug.name + " Augmentation for $" +
|
||||
formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?");
|
||||
formatNumber(aug.baseCost * factionInfo.augmentationPriceMult, 2) + "?");
|
||||
}
|
||||
|
||||
//Returns a boolean indicating whether the player has the prerequisites for the
|
||||
@ -1026,12 +671,13 @@ function hasAugmentationPrereqs(aug) {
|
||||
}
|
||||
|
||||
function purchaseAugmentation(aug, fac, sing=false) {
|
||||
const factionInfo = fac.getInfo();
|
||||
var hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
if (!hasPrereqs) {
|
||||
var txt = "You must first purchase or install " + aug.prereqs.join(",") + " before you can " +
|
||||
"purchase this one.";
|
||||
if (sing) {return txt;} else {dialogBoxCreate(txt);}
|
||||
} else if (Player.money.lt(aug.baseCost * fac.augmentationPriceMult)) {
|
||||
} else if (Player.money.lt(aug.baseCost * factionInfo.augmentationPriceMult)) {
|
||||
let txt = "You don't have enough money to purchase " + aug.name;
|
||||
if (sing) {return txt;}
|
||||
dialogBoxCreate(txt);
|
||||
@ -1039,7 +685,7 @@ function purchaseAugmentation(aug, fac, sing=false) {
|
||||
let txt = "You don't have enough faction reputation to purchase " + aug.name;
|
||||
if (sing) {return txt;}
|
||||
dialogBoxCreate(txt);
|
||||
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
|
||||
} else if (Player.money.gte(aug.baseCost * factionInfo.augmentationPriceMult)) {
|
||||
if (Player.firstAugPurchased === false) {
|
||||
Player.firstAugPurchased = true;
|
||||
document.getElementById("augmentations-tab").style.display = "list-item";
|
||||
@ -1053,7 +699,7 @@ function purchaseAugmentation(aug, fac, sing=false) {
|
||||
}
|
||||
Player.queuedAugmentations.push(queuedAugmentation);
|
||||
|
||||
Player.loseMoney((aug.baseCost * fac.augmentationPriceMult));
|
||||
Player.loseMoney((aug.baseCost * factionInfo.augmentationPriceMult));
|
||||
|
||||
//If you just purchased Neuroflux Governor, recalculate the cost
|
||||
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
|
||||
|
@ -1,68 +1,81 @@
|
||||
//Contains the "information" property for all the Factions, which is just a description
|
||||
//of each faction
|
||||
let FactionInfo = {
|
||||
function FactionInfo(infoText, enemies, offerHackingMission, offerHackingWork, offerFieldWork, offerSecurityWork) {
|
||||
this.infoText = infoText;
|
||||
this.enemies = enemies;
|
||||
this.offerHackingMission = offerHackingMission;
|
||||
this.offerHackingWork = offerHackingWork;
|
||||
this.offerFieldWork = offerFieldWork;
|
||||
this.offerSecurityWork = offerSecurityWork;
|
||||
|
||||
// these are always all 1 for now.
|
||||
this.augmentationPriceMult = 1;
|
||||
this.augmentationRepRequirementMult = 1;
|
||||
}
|
||||
|
||||
const FactionInfos = {
|
||||
//Endgame
|
||||
IlluminatiInfo: "Humanity never changes. No matter how civilized society becomes, it will eventually fall back " +
|
||||
"into chaos. And from this chaos, we are the Invisible hand that guides them to order. ",
|
||||
"Illuminati": new FactionInfo("Humanity never changes. No matter how civilized society becomes, it will eventually fall back " +
|
||||
"into chaos. And from this chaos, we are the Invisible hand that guides them to order. ", [], true, true, true, false),
|
||||
|
||||
DaedalusInfo: "Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.",
|
||||
"Daedalus": new FactionInfo("Yesterday we obeyed kings and bent our necks to emperors. Today we kneel only to truth.", [], true, true, true, false),
|
||||
|
||||
CovenantInfo: "Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
||||
"The Covenant": new FactionInfo("Surrender yourself. Give up your empty individuality to become part of something great, something eternal. " +
|
||||
"Become a slave. Submit your mind, body, and soul. Only then can you set yourself free.<br><br> " +
|
||||
"Only then can you discover immortality.",
|
||||
"Only then can you discover immortality.", [], true, true, true, false),
|
||||
|
||||
//Megacorporations, each forms its own faction
|
||||
ECorpInfo: "ECorp's mission is simple: to connect the world of today with the technology of tomorrow. " +
|
||||
"ECorp": new FactionInfo("ECorp's mission is simple: to connect the world of today with the technology of tomorrow. " +
|
||||
"With our wide range of Internet-related software and commercial hardware, ECorp makes the world's " +
|
||||
"information universally accessible.",
|
||||
"information universally accessible.", [], true, true, true, true),
|
||||
|
||||
MegaCorpInfo: "MegaCorp does things that others don't. We imagine. We create. We invent. We build things that " +
|
||||
"MegaCorp": new FactionInfo("MegaCorp does things that others don't. We imagine. We create. We invent. We build things that " +
|
||||
"others have never even dreamed of. Our work fills the world's needs for food, water, power, and " +
|
||||
"transporation on an unprecendented scale, in ways that no other company can.<br><br>" +
|
||||
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.",
|
||||
"In our labs and factories and on the ground with customers, MegaCorp is ushering in a new era for the world.", [], true, true, true, true),
|
||||
|
||||
BachmanAndAssociatesInfo: "Where Law and Business meet - thats where we are. <br><br>" +
|
||||
"Legal Insight - Business Instinct - Experience Innovation",
|
||||
"Bachman & Associates": new FactionInfo("Where Law and Business meet - thats where we are. <br><br>" +
|
||||
"Legal Insight - Business Instinct - Experience Innovation", [], true, true, true, true),
|
||||
|
||||
BladeIndustriesInfo: "Augmentation is salvation",
|
||||
"Blade Industries": new FactionInfo("Augmentation is salvation", [], true, true, true, true),
|
||||
|
||||
NWOInfo: "The human being does not truly desire freedom. It wants " +
|
||||
"NWO": new FactionInfo("The human being does not truly desire freedom. It wants " +
|
||||
"to be observed, understood, and judged. It wants to be given purpose and " +
|
||||
"direction in its life. That is why humans created God. " +
|
||||
"And that is why humans created civilization - " +
|
||||
"not because of willingness, " +
|
||||
"but because of a need to be incorporated into higher orders of structure and meaning.",
|
||||
"but because of a need to be incorporated into higher orders of structure and meaning.", [], true, true, true, true),
|
||||
|
||||
ClarkeIncorporatedInfo: "Unlocking the power of the genome",
|
||||
"Clarke Incorporated": new FactionInfo("Unlocking the power of the genome", [], true, true, true, true),
|
||||
|
||||
OmniTekIncorporatedInfo: "Simply put, our mission is to design and build robots that make a difference",
|
||||
"OmniTek Incorporated": new FactionInfo("Simply put, our mission is to design and build robots that make a difference", [], true, true, true, true),
|
||||
|
||||
FourSigmaInfo: "The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
|
||||
"deep learning and innovative ideas. And improved by iteration. That's Four Sigma.",
|
||||
"Four Sigma": new FactionInfo("The scientific method is the best way to approach investing. Big strategies backed up with big data. Driven by " +
|
||||
"deep learning and innovative ideas. And improved by iteration. That's Four Sigma.", [], true, true, true, true),
|
||||
|
||||
KuaiGongInternationalInfo: "Dream big. Work hard. Make history.",
|
||||
"KuaiGong International": new FactionInfo("Dream big. Work hard. Make history.", [], true, true, true, true),
|
||||
|
||||
//Other Corporations
|
||||
FulcrumSecretTechnologiesInfo: "The human organism has an innate desire to worship. " +
|
||||
"Fulcrum Secret Technologies": new FactionInfo("The human organism has an innate desire to worship. " +
|
||||
"That is why they created gods. If there were no gods, " +
|
||||
"it would be necessary to create them. And now we can.",
|
||||
"it would be necessary to create them. And now we can.", [], true, true, false, true),
|
||||
|
||||
//Hacker groups
|
||||
BitRunnersInfo: "Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. "+
|
||||
"BitRunners": new FactionInfo("Our entire lives are controlled by bits. All of our actions, our thoughts, our personal information. "+
|
||||
"It's all transformed into bits, stored in bits, communicated through bits. It’s impossible for any person " +
|
||||
"to move, to live, to operate at any level without the use of bits. " +
|
||||
"And when a person moves, lives, and operates, they leave behind their bits, mere traces of seemingly " +
|
||||
"meaningless fragments of information. But these bits can be reconstructed. Transformed. Used.<br><br>" +
|
||||
"Those who run the bits, run the world",
|
||||
"Those who run the bits, run the world", [], true, true, false, false),
|
||||
|
||||
|
||||
BlackHandInfo: "The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
|
||||
"The Black Hand": new FactionInfo("The world, so afraid of strong government, now has no government. Only power - Digital power. Financial power. " +
|
||||
"Technological power. " +
|
||||
"And those at the top rule with an invisible hand. They built a society where the rich get richer, " +
|
||||
"and everyone else suffers.<br><br>" +
|
||||
"So much pain. So many lives. Their darkness must end.",
|
||||
"So much pain. So many lives. Their darkness must end.", [], true, true, true, false),
|
||||
|
||||
NiteSecInfo:
|
||||
"NiteSec": new FactionInfo(
|
||||
" __..__ <br>" +
|
||||
" _.nITESECNIt. <br>" +
|
||||
" .-'NITESECNITESEc. <br>" +
|
||||
@ -97,47 +110,47 @@ let FactionInfo = {
|
||||
" / .d$$$$; , ; <br>" +
|
||||
" d .dNITESEC $ | <br>" +
|
||||
" :bp.__.gNITESEC$$ :$ ; <br>" +
|
||||
" NITESECNITESECNIT $$b : <br>",
|
||||
" NITESECNITESECNIT $$b : <br>", [], true, true, false, false),
|
||||
|
||||
//City factions, essentially governments
|
||||
ChongqingInfo: "Serve the people",
|
||||
Sector12Info: "The City of the Future",
|
||||
HongKongInfo: "Asia's World City",
|
||||
AevumInfo: "The Silicon City",
|
||||
IshimaInfo: "The East Asian Order of the Future",
|
||||
VolhavenInfo: "Benefit, Honour, and Glory",
|
||||
"Chongqing": new FactionInfo("Serve the people", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
||||
"Sector-12": new FactionInfo("The City of the Future", ["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
|
||||
"New Tokyo": new FactionInfo("Asia's World City", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
||||
"Aevum": new FactionInfo("The Silicon City", ["Chongqing", "New Tokyo", "Ishima", "Volhaven"], true, true, true, true),
|
||||
"Ishima": new FactionInfo("The East Asian Order of the Future", ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
|
||||
"Volhaven": new FactionInfo("Benefit, Honour, and Glory", ["Chongqing", "Sector-12", "New Tokyo", "Aevum", "Ishima"], true, true, true, true),
|
||||
|
||||
//Criminal Organizations/Gangs
|
||||
SpeakersForTheDeadInfo: "It is better to reign in hell than to serve in heaven.",
|
||||
"Speakers for the Dead": new FactionInfo("It is better to reign in hell than to serve in heaven.", [], true, true, true, true),
|
||||
|
||||
DarkArmyInfo: "The World doesn't care about right or wrong. It's all about power.",
|
||||
"The Dark Army": new FactionInfo("The World doesn't care about right or wrong. It's all about power.", [], true, true, true, false),
|
||||
|
||||
TheSyndicateInfo: "Honor holds you back",
|
||||
"The Syndicate": new FactionInfo("Honor holds you back", [], true, true, true, true),
|
||||
|
||||
SilhouetteInfo: "Corporations have filled the void of power left behind by the collapse of Western government. The issue is they've become so big " +
|
||||
"Silhouette": new FactionInfo("Corporations have filled the void of power left behind by the collapse of Western government. The issue is they've become so big " +
|
||||
"that you don't know who they're working for. And if you're employed at one of these corporations, you don't even know who you're working " +
|
||||
"for.\n\n" +
|
||||
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.",
|
||||
"That's terror. Terror, fear, and corruption. All born into the system, all propagated by the system.", [], true, true, true, false),
|
||||
|
||||
TetradsInfo: "Following the Mandate of Heaven and Carrying out the Way",
|
||||
"Tetrads": new FactionInfo("Following the Mandate of Heaven and Carrying out the Way", [], false, false, true, true),
|
||||
|
||||
SlumSnakesInfo: "Slum Snakes rule!",
|
||||
"Slum Snakes": new FactionInfo("Slum Snakes rule!", [], false, false, true, true),
|
||||
|
||||
//Earlygame factions - factions the player will prestige with early on that don't
|
||||
//belong in other categories
|
||||
NetburnersInfo: "~~//*>H4CK|\|3T 8URN3R5**>?>\\~~",
|
||||
"Netburners": new FactionInfo("~~//*>H4CK|\|3T 8URN3R5**>?>\\~~", [], true, true, false, false),
|
||||
|
||||
TianDiHuiInfo: "Obey Heaven and Work Righteousness",
|
||||
"Tian Di Hui": new FactionInfo("Obey Heaven and Work Righteousness", [], true, true, false, true),
|
||||
|
||||
CyberSecInfo: "The Internet is the first thing that humanity has built that humanity doesn’t understand, " +
|
||||
"CyberSec": new FactionInfo("The Internet is the first thing that humanity has built that humanity doesn’t understand, " +
|
||||
"the largest experiment in anarchy that we have ever had. And as the world becomes increasingly " +
|
||||
"dominated by the internet, society approaches the brink of total chaos. " +
|
||||
"We serve only to protect society, to protect humanity, to protect the world from its imminent collapse.",
|
||||
"We serve only to protect society, to protect humanity, to protect the world from its imminent collapse.", [], true, true, false, false),
|
||||
|
||||
//Special Factions
|
||||
BladeburnersInfo: "It's too bad they won't live. But then again, who does?<br><br>" +
|
||||
"Bladeburners": new FactionInfo("It's too bad they won't live. But then again, who does?<br><br>" +
|
||||
"Note that for this faction, reputation can only be gained through Bladeburner actions. Completing " +
|
||||
"Bladeburner contracts/operations will increase your reputation.",
|
||||
"Bladeburner contracts/operations will increase your reputation.", [], false, false, false, false),
|
||||
}
|
||||
|
||||
export {FactionInfo};
|
||||
export {FactionInfos};
|
||||
|
@ -10,7 +10,7 @@ import {getRandomInt, createElement,
|
||||
removeChildrenFromElement,
|
||||
createAccordionElement, createPopup,
|
||||
removeElementById, removeElement} from "../utils/HelperFunctions.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
|
@ -5,42 +5,48 @@ import {iTutorialSteps, iTutorialNextStep,
|
||||
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {clearEventListeners} from "../utils/HelperFunctions.js";
|
||||
import {clearEventListeners, createElement,
|
||||
getElementById} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
/**
|
||||
* Overwrites the inner text of the specified HTML element if it is different from what currently exists.
|
||||
* @param {string} elementId The HTML ID to find the first instance of.
|
||||
* @param {string} text The inner text that should be set.
|
||||
*/
|
||||
function updateText(elementId, text) {
|
||||
var el = getElementById(elementId);
|
||||
if (el.innerText != text) {
|
||||
el.innerText = text;
|
||||
}
|
||||
};
|
||||
|
||||
/* HacknetNode.js */
|
||||
function hacknetNodesInit() {
|
||||
var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
|
||||
mult1x.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 1;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
|
||||
mult5x.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 5;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
|
||||
mult10x.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 10;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
var multMax = document.getElementById("hacknet-nodes-max-multiplier");
|
||||
multMax.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = 0;
|
||||
var performMapping = function(x) {
|
||||
getElementById("hacknet-nodes-" + x.id + "-multiplier")
|
||||
.addEventListener("click", function() {
|
||||
hacknetNodePurchaseMultiplier = x.multiplier;
|
||||
updateHacknetNodesMultiplierButtons();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
var mappings = [
|
||||
{ id: "1x", multiplier: 1 },
|
||||
{ id: "5x", multiplier: 5 },
|
||||
{ id: "10x", multiplier: 10 },
|
||||
{ id: "max", multiplier: 0 }
|
||||
];
|
||||
for (var elem of mappings) {
|
||||
// Encapsulate in a function so that the appropriate scope is kept in the click handler.
|
||||
performMapping(elem);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
|
||||
|
||||
function HacknetNode(name) {
|
||||
@ -56,6 +62,7 @@ function HacknetNode(name) {
|
||||
this.moneyGainRatePerSecond = 0;
|
||||
}
|
||||
|
||||
|
||||
HacknetNode.prototype.updateMoneyGainRate = function() {
|
||||
//How much extra $/s is gained per level
|
||||
var gainPerLevel = CONSTANTS.HacknetNodeMoneyGainPerLevel;
|
||||
@ -75,7 +82,10 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
|
||||
|
||||
HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
|
||||
levels = Math.round(levels);
|
||||
if (isNaN(levels) || levels < 1) {return 0;}
|
||||
if (isNaN(levels) || levels < 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var mult = CONSTANTS.HacknetNodeUpgradeLevelMult;
|
||||
var totalMultiplier = 0; //Summed
|
||||
var currLevel = this.level;
|
||||
@ -83,6 +93,7 @@ HacknetNode.prototype.calculateLevelUpgradeCost = function(levels=1) {
|
||||
totalMultiplier += Math.pow(mult, currLevel);
|
||||
++currLevel;
|
||||
}
|
||||
|
||||
return CONSTANTS.BaseCostForHacknetNode / 2 * totalMultiplier * Player.hacknet_node_level_cost_mult;
|
||||
}
|
||||
|
||||
@ -94,12 +105,19 @@ HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
|
||||
HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
|
||||
levels = Math.round(levels);
|
||||
var cost = this.calculateLevelUpgradeCost(levels);
|
||||
if (isNaN(cost) || levels < 0) {return false;}
|
||||
if (isNaN(cost) || levels < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.level + levels > CONSTANTS.HacknetNodeMaxLevel) {
|
||||
var diff = Math.max(0, CONSTANTS.HacknetNodeMaxLevel - this.level);
|
||||
return this.purchaseLevelUpgrade(diff);
|
||||
}
|
||||
if (Player.money.lt(cost)) {return false;}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.loseMoney(cost);
|
||||
this.level += levels;
|
||||
this.updateMoneyGainRate();
|
||||
@ -108,7 +126,9 @@ HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeLevel = function(levels=1) {
|
||||
return this.purchaseLevelUpgrade(levels);
|
||||
let res = this.purchaseLevelUpgrade(levels);
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return res;
|
||||
}
|
||||
|
||||
HacknetNode.prototype.calculateRamUpgradeCost = function() {
|
||||
@ -128,9 +148,18 @@ HacknetNode.prototype.getRamUpgradeCost = function() {
|
||||
|
||||
HacknetNode.prototype.purchaseRamUpgrade = function() {
|
||||
var cost = this.calculateRamUpgradeCost();
|
||||
if (isNaN(cost)) {return false;}
|
||||
if (Player.money.lt(cost)) {return false;}
|
||||
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {return false;}
|
||||
if (isNaN(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.ram >= CONSTANTS.HacknetNodeMaxRam) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.loseMoney(cost);
|
||||
this.ram *= 2; //Ram is always doubled
|
||||
this.updateMoneyGainRate();
|
||||
@ -139,7 +168,9 @@ HacknetNode.prototype.purchaseRamUpgrade = function() {
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeRam = function() {
|
||||
return this.purchaseRamUpgrade();
|
||||
let res = this.purchaseRamUpgrade();
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return res;
|
||||
}
|
||||
|
||||
HacknetNode.prototype.calculateCoreUpgradeCost = function() {
|
||||
@ -150,14 +181,25 @@ HacknetNode.prototype.calculateCoreUpgradeCost = function() {
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.getCoreUpgradeCost = function() {
|
||||
return this.calculateCoreUpgradeCost();
|
||||
let res = this.calculateCoreUpgradeCost();
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return res;
|
||||
}
|
||||
|
||||
HacknetNode.prototype.purchaseCoreUpgrade = function() {
|
||||
var cost = this.calculateCoreUpgradeCost();
|
||||
if (isNaN(cost)) {return false;}
|
||||
if (Player.money.lt(cost)) {return false;}
|
||||
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {return false;}
|
||||
if (isNaN(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.loseMoney(cost);
|
||||
++this.cores;
|
||||
this.updateMoneyGainRate();
|
||||
@ -180,6 +222,36 @@ HacknetNode.fromJSON = function(value) {
|
||||
|
||||
Reviver.constructors.HacknetNode = HacknetNode;
|
||||
|
||||
var HacknetNodeWrapper = function(hacknetNodeObj) {
|
||||
var _node = hacknetNodeObj;
|
||||
return {
|
||||
name : _node.name,
|
||||
level : _node.level,
|
||||
ram : _node.ram,
|
||||
cores : _node.cores,
|
||||
totalMoneyGenerated : _node.totalMoneyGenerated,
|
||||
onlineTimeSeconds : _node.onlineTimeSeconds,
|
||||
moneyGainRatePerSecond : _node.moneyGainRatePerSecond,
|
||||
upgradeLevel : function(n) {
|
||||
return _node.upgradeLevel(n);
|
||||
},
|
||||
upgradeRam : function() {
|
||||
return _node.upgradeRam();
|
||||
},
|
||||
upgradeCore : function() {
|
||||
return _node.upgradeCore();
|
||||
},
|
||||
getLevelUpgradeCost : function(n) {
|
||||
return _node.getLevelUpgradeCost(n);
|
||||
},
|
||||
getRamUpgradeCost : function() {
|
||||
return _node.getRamUpgradeCost();
|
||||
},
|
||||
getCoreUpgradeCost : function() {
|
||||
return _node.getCoreUpgradeCost();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function purchaseHacknet() {
|
||||
/* INTERACTIVE TUTORIAL */
|
||||
@ -194,7 +266,10 @@ function purchaseHacknet() {
|
||||
/* END INTERACTIVE TUTORIAL */
|
||||
|
||||
var cost = getCostOfNextHacknetNode();
|
||||
if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
|
||||
if (isNaN(cost)) {
|
||||
throw new Error("Cost is NaN");
|
||||
}
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
//dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
|
||||
return false;
|
||||
@ -209,7 +284,10 @@ function purchaseHacknet() {
|
||||
Player.loseMoney(cost);
|
||||
Player.hacknetNodes.push(node);
|
||||
|
||||
if (Engine.currentPage === Engine.Page.HacknetNodes) {
|
||||
displayHacknetNodesContent();
|
||||
}
|
||||
createPlayerHacknetNodeWrappers();
|
||||
updateTotalHacknetProduction();
|
||||
return numOwned;
|
||||
}
|
||||
@ -259,7 +337,10 @@ function updateHacknetNodesMultiplierButtons() {
|
||||
//Calculate the maximum number of times the Player can afford to upgrade
|
||||
//a Hacknet Node's level"
|
||||
function getMaxNumberLevelUpgrades(nodeObj) {
|
||||
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;}
|
||||
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var min = 1;
|
||||
var max = CONSTANTS.HacknetNodeMaxLevel - 1;
|
||||
var levelsToMax = CONSTANTS.HacknetNodeMaxLevel - nodeObj.level;
|
||||
@ -306,6 +387,7 @@ function displayHacknetNodesContent() {
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
createHacknetNodeDomElement(Player.hacknetNodes[i]);
|
||||
}
|
||||
|
||||
updateHacknetNodesContent();
|
||||
}
|
||||
|
||||
@ -313,8 +395,11 @@ function displayHacknetNodesContent() {
|
||||
function updateHacknetNodesContent() {
|
||||
//Set purchase button to inactive if not enough money, and update its price display
|
||||
var cost = getCostOfNextHacknetNode();
|
||||
var purchaseButton = document.getElementById("hacknet-nodes-purchase-button");
|
||||
purchaseButton.innerHTML = "Purchase Hacknet Node - $" + formatNumber(cost, 2);
|
||||
var purchaseButton = getElementById("hacknet-nodes-purchase-button");
|
||||
var formattedCost = formatNumber(cost, 2);
|
||||
|
||||
updateText("hacknet-nodes-purchase-button", "Purchase Hacknet Node - $" + formattedCost);
|
||||
|
||||
if (Player.money.lt(cost)) {
|
||||
purchaseButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -322,9 +407,8 @@ function updateHacknetNodesContent() {
|
||||
}
|
||||
|
||||
//Update player's money
|
||||
var moneyElem = document.getElementById("hacknet-nodes-money");
|
||||
moneyElem.innerHTML = "Money: $" + formatNumber(Player.money.toNumber(), 2) + "<br>" +
|
||||
"Total production from all Hacknet Nodes: $" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second";
|
||||
updateText("hacknet-nodes-player-money", "$" + formatNumber(Player.money.toNumber(), 2));
|
||||
updateText("hacknet-nodes-total-production", "$" + formatNumber(Player.totalHacknetNodeProduction, 2) + " / second");
|
||||
|
||||
//Update information in each owned hacknet node
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
@ -336,29 +420,46 @@ function updateHacknetNodesContent() {
|
||||
function createHacknetNodeDomElement(nodeObj) {
|
||||
var nodeName = nodeObj.name;
|
||||
|
||||
var listItem = document.createElement("li");
|
||||
listItem.setAttribute("class", "hacknet-node");
|
||||
var nodeLevelContainer = createElement("div", {
|
||||
class: "hacknet-node-level-container row",
|
||||
innerHTML: "<p>Level:</p><span class=\"text upgradable-info\" id=\"hacknet-node-level-" + nodeName + "\"></span>"
|
||||
});
|
||||
|
||||
var span = document.createElement("span");
|
||||
span.style.display = "inline";
|
||||
var nodeRamContainer = createElement("div", {
|
||||
class: "hacknet-node-ram-container row",
|
||||
innerHTML: "<p>RAM:</p><span class=\"text upgradable-info\" id=\"hacknet-node-ram-" + nodeName + "\"></span>"
|
||||
});
|
||||
|
||||
var buttonDiv = document.createElement("div");
|
||||
buttonDiv.setAttribute("class", "hacknet-node-button-div");
|
||||
var nodeCoresContainer = createElement("div", {
|
||||
class: "hacknet-node-cores-container row",
|
||||
innerHTML: "<p>Cores:</p><span class=\"text upgradable-info\" id=\"hacknet-node-cores-" + nodeName + "\"><span>"
|
||||
})
|
||||
var containingDiv = createElement("div", {
|
||||
class: "hacknet-node-container",
|
||||
innerHTML: "<div class=\"hacknet-node-name-container row\">" +
|
||||
"<p>Node name:</p>" +
|
||||
"<span class=\"text\" id=\"hacknet-node-name-" + nodeName + "\"></span>" +
|
||||
"</div>" +
|
||||
"<div class=\"hacknet-node-production-container row\">" +
|
||||
"<p>Production:</p>" +
|
||||
"<span class=\"text\" id=\"hacknet-node-total-production-" + nodeName + "\"></span>" +
|
||||
"<span class=\"text\" id=\"hacknet-node-production-rate-" + nodeName + "\"></span>" +
|
||||
"</div>"
|
||||
});
|
||||
containingDiv.appendChild(nodeLevelContainer);
|
||||
containingDiv.appendChild(nodeRamContainer);
|
||||
containingDiv.appendChild(nodeCoresContainer);
|
||||
|
||||
//Text
|
||||
var txt = document.createElement("p");
|
||||
//txt.setAttribute("id", "hacknet-node-text-" + nodeName);
|
||||
txt.id = "hacknet-node-text-" + nodeName;
|
||||
var listItem = createElement("li", {
|
||||
class: "hacknet-node"
|
||||
});
|
||||
listItem.appendChild(containingDiv);
|
||||
|
||||
//Upgrade buttons
|
||||
var upgradeLevelButton = document.createElement("a");
|
||||
var upgradeRamButton = document.createElement("a");
|
||||
var upgradeCoreButton = document.createElement("a");
|
||||
|
||||
//upgradeLevelButton.setAttribute("id", "hacknet-node-upgrade-level-" + nodeName);
|
||||
upgradeLevelButton.id = "hacknet-node-upgrade-level-" + nodeName;
|
||||
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
|
||||
upgradeLevelButton.addEventListener("click", function() {
|
||||
nodeLevelContainer.appendChild(createElement("a", {
|
||||
id: "hacknet-node-upgrade-level-" + nodeName,
|
||||
class: "a-link-button-inactive",
|
||||
clickListener: function() {
|
||||
var numUpgrades = hacknetNodePurchaseMultiplier;
|
||||
if (hacknetNodePurchaseMultiplier == 0) {
|
||||
numUpgrades = getMaxNumberLevelUpgrades(nodeObj);
|
||||
@ -366,31 +467,28 @@ function createHacknetNodeDomElement(nodeObj) {
|
||||
nodeObj.purchaseLevelUpgrade(numUpgrades);
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
//upgradeRamButton.setAttribute("id", "hacknet-node-upgrade-ram-" + nodeName);
|
||||
upgradeRamButton.id = "hacknet-node-upgrade-ram-" + nodeName;
|
||||
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
|
||||
upgradeRamButton.addEventListener("click", function() {
|
||||
}
|
||||
}));
|
||||
|
||||
nodeRamContainer.appendChild(createElement("a", {
|
||||
id: "hacknet-node-upgrade-ram-" + nodeName,
|
||||
class: "a-link-button-inactive",
|
||||
clickListener: function() {
|
||||
nodeObj.purchaseRamUpgrade();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
//upgradeCoreButton.setAttribute("id", "hacknet-node-upgrade-core-" + nodeName);
|
||||
upgradeCoreButton.id = "hacknet-node-upgrade-core-" + nodeName;
|
||||
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
|
||||
upgradeCoreButton.addEventListener("click", function() {
|
||||
}
|
||||
}));
|
||||
|
||||
nodeCoresContainer.appendChild(createElement("a", {
|
||||
id: "hacknet-node-upgrade-core-" + nodeName,
|
||||
class: "a-link-button-inactive",
|
||||
clickListener: function() {
|
||||
nodeObj.purchaseCoreUpgrade();
|
||||
updateHacknetNodesContent();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Put all the components together in the li element
|
||||
span.appendChild(txt);
|
||||
buttonDiv.appendChild(upgradeLevelButton);
|
||||
buttonDiv.appendChild(upgradeRamButton);
|
||||
buttonDiv.appendChild(upgradeCoreButton);
|
||||
span.appendChild(buttonDiv);
|
||||
listItem.appendChild(span);
|
||||
}
|
||||
}));
|
||||
|
||||
document.getElementById("hacknet-nodes-list").appendChild(listItem);
|
||||
|
||||
@ -401,20 +499,19 @@ function createHacknetNodeDomElement(nodeObj) {
|
||||
//Updates information on a single hacknet node DOM element
|
||||
function updateHacknetNodeDomElement(nodeObj) {
|
||||
var nodeName = nodeObj.name;
|
||||
var txt = document.getElementById("hacknet-node-text-" + nodeName);
|
||||
if (txt == null) {throw new Error("Cannot find text element");}
|
||||
txt.innerHTML = "Node name: " + nodeName + "<br>" +
|
||||
"Production: $" + formatNumber(nodeObj.totalMoneyGenerated, 2) +
|
||||
" ($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
|
||||
"Level: " + nodeObj.level + "<br>" +
|
||||
"RAM: " + nodeObj.ram + "GB<br>" +
|
||||
"Cores: " + nodeObj.cores;
|
||||
|
||||
updateText("hacknet-node-name-" + nodeName, nodeName);
|
||||
updateText("hacknet-node-total-production-" + nodeName, "$" + formatNumber(nodeObj.totalMoneyGenerated, 2));
|
||||
updateText("hacknet-node-production-rate-" + nodeName, "($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second)");
|
||||
updateText("hacknet-node-level-" + nodeName, nodeObj.level);
|
||||
updateText("hacknet-node-ram-" + nodeName, nodeObj.ram + "GB");
|
||||
updateText("hacknet-node-cores-" + nodeName, nodeObj.cores);
|
||||
|
||||
//Upgrade level
|
||||
var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
|
||||
if (upgradeLevelButton == null) {throw new Error("Cannot find upgrade level button element");}
|
||||
var upgradeLevelButton = getElementById("hacknet-node-upgrade-level-" + nodeName);
|
||||
|
||||
if (nodeObj.level >= CONSTANTS.HacknetNodeMaxLevel) {
|
||||
upgradeLevelButton.innerHTML = "MAX LEVEL";
|
||||
updateText("hacknet-node-upgrade-level-" + nodeName, "MAX LEVEL");
|
||||
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
var multiplier = 0;
|
||||
@ -427,8 +524,7 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
|
||||
var upgradeLevelCost = nodeObj.calculateLevelUpgradeCost(multiplier);
|
||||
upgradeLevelButton.innerHTML = "Upgrade Hacknet Node Level x" + multiplier +
|
||||
" - $" + formatNumber(upgradeLevelCost, 2);
|
||||
updateText("hacknet-node-upgrade-level-" + nodeName, "Upgrade x" + multiplier + " - $" + formatNumber(upgradeLevelCost, 2))
|
||||
if (Player.money.lt(upgradeLevelCost)) {
|
||||
upgradeLevelButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -437,14 +533,14 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
|
||||
//Upgrade RAM
|
||||
var upgradeRamButton = document.getElementById("hacknet-node-upgrade-ram-" + nodeName);
|
||||
if (upgradeRamButton == null) {throw new Error("Cannot find upgrade ram button element");}
|
||||
var upgradeRamButton = getElementById("hacknet-node-upgrade-ram-" + nodeName);
|
||||
|
||||
if (nodeObj.ram >= CONSTANTS.HacknetNodeMaxRam) {
|
||||
upgradeRamButton.innerHTML = "MAX RAM";
|
||||
updateText("hacknet-node-upgrade-ram-" + nodeName, "MAX RAM");
|
||||
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
|
||||
upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM - $" + formatNumber(upgradeRamCost, 2);
|
||||
updateText("hacknet-node-upgrade-ram-" + nodeName, "Upgrade - $" + formatNumber(upgradeRamCost, 2));
|
||||
if (Player.money.lt(upgradeRamCost)) {
|
||||
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -453,14 +549,14 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
|
||||
//Upgrade Cores
|
||||
var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
|
||||
if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");}
|
||||
var upgradeCoreButton = getElementById("hacknet-node-upgrade-core-" + nodeName);
|
||||
|
||||
if (nodeObj.cores >= CONSTANTS.HacknetNodeMaxCores) {
|
||||
upgradeCoreButton.innerHTML = "MAX CORES";
|
||||
updateText("hacknet-node-upgrade-core-" + nodeName, "MAX CORES");
|
||||
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
var upgradeCoreCost = nodeObj.calculateCoreUpgradeCost();
|
||||
upgradeCoreButton.innerHTML = "Purchase additional CPU Core - $" + formatNumber(upgradeCoreCost, 2);
|
||||
updateText("hacknet-node-upgrade-core-" + nodeName, "Upgrade - $" + formatNumber(upgradeCoreCost, 2));
|
||||
if (Player.money.lt(upgradeCoreCost)) {
|
||||
upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
@ -469,11 +565,39 @@ function updateHacknetNodeDomElement(nodeObj) {
|
||||
}
|
||||
}
|
||||
|
||||
function createPlayerHacknetNodeWrappers() {
|
||||
Player.hacknetNodeWrappers.length = Player.hacknetNodes.length;
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
Player.hacknetNodeWrappers[i] = new HacknetNodeWrapper(Player.hacknetNodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function updatePlayerHacknetNodeWrappers() {
|
||||
if (Player.hacknetNodeWrappers.length !== Player.hacknetNodes.length) {
|
||||
return createPlayerHacknetNodeWrappers();
|
||||
}
|
||||
|
||||
for (var i = 0; i < Player.hacknetNodeWrappers.length; ++i) {
|
||||
if (!(Player.hacknetNodeWrappers[i] instanceof HacknetNodeWrapper)) {
|
||||
return createPlayerHacknetNodeWrappers();
|
||||
}
|
||||
|
||||
Player.hacknetNodeWrappers[i].level = Player.hacknetNodes[i].level;
|
||||
Player.hacknetNodeWrappers[i].ram = Player.hacknetNodes[i].ram;
|
||||
Player.hacknetNodeWrappers[i].cores = Player.hacknetNodes[i].cores;
|
||||
Player.hacknetNodeWrappers[i].totalMoneyGenerated = Player.hacknetNodes[i].totalMoneyGenerated;
|
||||
Player.hacknetNodeWrappers[i].onlineTimeSeconds = Player.hacknetNodes[i].onlineTimeSeconds;
|
||||
Player.hacknetNodeWrappers[i].moneyGainRatePerSecond = Player.hacknetNodes[i].moneyGainRatePerSecond;
|
||||
}
|
||||
}
|
||||
|
||||
function processAllHacknetNodeEarnings(numCycles) {
|
||||
var total = 0;
|
||||
updatePlayerHacknetNodeWrappers();
|
||||
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
|
||||
total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]);
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
@ -481,9 +605,10 @@ function processSingleHacknetNodeEarnings(numCycles, nodeObj) {
|
||||
var cyclesPerSecond = 1000 / Engine._idleSpeed;
|
||||
var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond;
|
||||
if (isNaN(earningPerCycle)) {
|
||||
console.log("ERROR: Hacknet Node Calculated earnings is NaN");
|
||||
console.error("Hacknet Node '" + nodeObj.name + "' Calculated earnings is NaN");
|
||||
earningPerCycle = 0;
|
||||
}
|
||||
|
||||
var totalEarnings = numCycles * earningPerCycle;
|
||||
nodeObj.totalMoneyGenerated += totalEarnings;
|
||||
nodeObj.onlineTimeSeconds += (numCycles * (Engine._idleSpeed / 1000));
|
||||
@ -497,10 +622,21 @@ function getHacknetNode(name) {
|
||||
return Player.hacknetNodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export {hacknetNodesInit, HacknetNode, purchaseHacknet, updateTotalHacknetProduction,
|
||||
getCostOfNextHacknetNode, updateHacknetNodesMultiplierButtons, getMaxNumberLevelUpgrades,
|
||||
displayHacknetNodesContent, updateHacknetNodesContent, processAllHacknetNodeEarnings,
|
||||
getHacknetNode};
|
||||
export {
|
||||
HacknetNode,
|
||||
createPlayerHacknetNodeWrappers,
|
||||
displayHacknetNodesContent,
|
||||
getCostOfNextHacknetNode,
|
||||
getHacknetNode,
|
||||
getMaxNumberLevelUpgrades,
|
||||
hacknetNodesInit,
|
||||
processAllHacknetNodeEarnings,
|
||||
purchaseHacknet,
|
||||
updateHacknetNodesContent,
|
||||
updateHacknetNodesMultiplierButtons,
|
||||
updateTotalHacknetProduction
|
||||
};
|
||||
|
110
src/Location.js
@ -3,18 +3,7 @@ import {CompanyPositions, initCompanies,
|
||||
Companies, getJobRequirementText} from "./Company.js";
|
||||
import {Corporation} from "./CompanyManagement.js";
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
|
||||
commitLarcenyCrime, commitDealDrugsCrime, commitBondForgeryCrime,
|
||||
commitTraffickArmsCrime,
|
||||
commitHomicideCrime, commitGrandTheftAutoCrime, commitKidnapCrime,
|
||||
commitAssassinationCrime, commitHeistCrime, determineCrimeSuccess,
|
||||
determineCrimeChanceShoplift, determineCrimeChanceRobStore,
|
||||
determineCrimeChanceMug, determineCrimeChanceLarceny,
|
||||
determineCrimeChanceDealDrugs, determineCrimeChanceBondForgery,
|
||||
determineCrimeChanceTraffickArms,
|
||||
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
|
||||
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
|
||||
determineCrimeChanceHeist} from "./Crimes.js";
|
||||
import {Crimes} from "./Crimes.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {beginInfiltration} from "./Infiltration.js";
|
||||
import {hasBladeburnerSF} from "./NetscriptFunctions.js";
|
||||
@ -22,12 +11,13 @@ import {Player} from "./Player.js";
|
||||
import {Server, AllServers, AddToAllServers} from "./Server.js";
|
||||
import {purchaseServer,
|
||||
purchaseRamForHomeComputer} from "./ServerPurchases.js";
|
||||
import {Settings} from "./Settings.js";
|
||||
import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js";
|
||||
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {clearEventListeners, createElement} from "../utils/HelperFunctions.js";
|
||||
import {createRandomIp} from "../utils/IPAddress.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
@ -289,7 +279,10 @@ function displayLocationContent() {
|
||||
purchase256gb.innerHTML = "Purchase 256GB Server - $" + formatNumber(256*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
||||
purchase512gb.innerHTML = "Purchase 512GB Server - $" + formatNumber(512*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
||||
purchase1tb.innerHTML = "Purchase 1TB Server - $" + formatNumber(1024*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
|
||||
if (!SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
||||
purchaseTor.innerHTML = "Purchase TOR Router - $" + formatNumber(CONSTANTS.TorRouterCost, 2);
|
||||
}
|
||||
|
||||
|
||||
travelAgencyText.style.display = "none";
|
||||
travelToAevum.style.display = "none";
|
||||
@ -337,9 +330,9 @@ function displayLocationContent() {
|
||||
repGain = repGain[0];
|
||||
jobReputation.innerHTML = "Company reputation: " + formatNumber(company.playerReputation, 4) +
|
||||
"<span class='tooltiptext'>You will earn " +
|
||||
formatNumber(repGain, 4) +
|
||||
formatNumber(repGain, 0) +
|
||||
" faction favor upon resetting after installing an Augmentation</span>";
|
||||
companyFavor.innerHTML = "Company Favor: " + formatNumber(company.favor, 4) +
|
||||
companyFavor.innerHTML = "Company Favor: " + formatNumber(company.favor, 0) +
|
||||
"<span class='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 an Augmentation. The amount of " +
|
||||
@ -726,6 +719,7 @@ function displayLocationContent() {
|
||||
securityJob.style.display = "block";
|
||||
agentJob.style.display = "block";
|
||||
if (Player.bitNodeN === 6 || hasBladeburnerSF === true) {
|
||||
if (Player.bitNodeN === 8) {break;}
|
||||
if (Player.bladeburner instanceof Bladeburner) {
|
||||
//Note: Can't infiltrate NSA when part of bladeburner
|
||||
nsaBladeburner.innerText = "Enter Bladeburner Headquarters";
|
||||
@ -1057,18 +1051,18 @@ function displayLocationContent() {
|
||||
case Locations.NewTokyoSlums:
|
||||
case Locations.IshimaSlums:
|
||||
case Locations.VolhavenSlums:
|
||||
var shopliftChance = determineCrimeChanceShoplift();
|
||||
var robStoreChance = determineCrimeChanceRobStore();
|
||||
var mugChance = determineCrimeChanceMug();
|
||||
var larcenyChance = determineCrimeChanceLarceny();
|
||||
var drugsChance = determineCrimeChanceDealDrugs();
|
||||
var bondChance = determineCrimeChanceBondForgery();
|
||||
var armsChance = determineCrimeChanceTraffickArms();
|
||||
var homicideChance = determineCrimeChanceHomicide();
|
||||
var gtaChance = determineCrimeChanceGrandTheftAuto();
|
||||
var kidnapChance = determineCrimeChanceKidnap();
|
||||
var assassinateChance = determineCrimeChanceAssassination();
|
||||
var heistChance = determineCrimeChanceHeist();
|
||||
var shopliftChance = Crimes.Shoplift.successRate();
|
||||
var robStoreChance = Crimes.RobStore.successRate();
|
||||
var mugChance = Crimes.Mug.successRate();
|
||||
var larcenyChance = Crimes.Larceny.successRate();
|
||||
var drugsChance = Crimes.DealDrugs.successRate();
|
||||
var bondChance = Crimes.BondForgery.successRate();
|
||||
var armsChance = Crimes.TraffickArms.successRate();
|
||||
var homicideChance = Crimes.Homicide.successRate();
|
||||
var gtaChance = Crimes.GrandTheftAuto.successRate();
|
||||
var kidnapChance = Crimes.Kidnap.successRate();
|
||||
var assassinateChance = Crimes.Assassination.successRate();
|
||||
var heistChance = Crimes.Heist.successRate();
|
||||
|
||||
slumsDescText.style.display = "block";
|
||||
slumsShoplift.style.display = "block";
|
||||
@ -1771,16 +1765,8 @@ function initLocationButtons() {
|
||||
});
|
||||
|
||||
purchaseHomeRam.addEventListener("click", function() {
|
||||
//Calculate how many times ram has been upgraded (doubled)
|
||||
var currentRam = Player.getHomeComputer().maxRam;
|
||||
var newRam = currentRam * 2;
|
||||
var numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
|
||||
var mult = Math.pow(1.58, numUpgrades);
|
||||
cost = cost * mult;
|
||||
const cost = Player.getUpgradeHomeRamCost();
|
||||
const ram = Player.getHomeComputer().maxRam;
|
||||
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Purchase"; noBtn.innerHTML = "Cancel";
|
||||
@ -1792,8 +1778,8 @@ function initLocationButtons() {
|
||||
yesNoBoxClose();
|
||||
});
|
||||
yesNoBoxCreate("Would you like to purchase additional RAM for your home computer? <br><br>" +
|
||||
"This will upgrade your RAM from " + currentRam + "GB to " + newRam + "GB. <br><br>" +
|
||||
"This will cost $" + formatNumber(cost, 2));
|
||||
"This will upgrade your RAM from " + ram + "GB to " + ram*2 + "GB. <br><br>" +
|
||||
"This will cost " + numeral(cost).format('$0.000a'));
|
||||
});
|
||||
|
||||
purchaseHomeCores.addEventListener("click", function() {
|
||||
@ -1833,92 +1819,92 @@ function initLocationButtons() {
|
||||
});
|
||||
|
||||
travelToAevum.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Aevum, 200000);
|
||||
travelBoxCreate(Locations.Aevum, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToChongqing.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Chongqing, 200000);
|
||||
travelBoxCreate(Locations.Chongqing, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToSector12.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Sector12, 200000);
|
||||
travelBoxCreate(Locations.Sector12, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToNewTokyo.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.NewTokyo, 200000);
|
||||
travelBoxCreate(Locations.NewTokyo, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToIshima.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Ishima, 200000);
|
||||
travelBoxCreate(Locations.Ishima, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
travelToVolhaven.addEventListener("click", function() {
|
||||
travelBoxCreate(Locations.Volhaven, 200000);
|
||||
travelBoxCreate(Locations.Volhaven, CONSTANTS.TravelCost);
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsShoplift.addEventListener("click", function() {
|
||||
commitShopliftCrime();
|
||||
Crimes.Shoplift.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsRobStore.addEventListener("click", function() {
|
||||
commitRobStoreCrime();
|
||||
Crimes.RobStore.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsMug.addEventListener("click", function() {
|
||||
commitMugCrime();
|
||||
Crimes.Mug.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsLarceny.addEventListener("click", function() {
|
||||
commitLarcenyCrime();
|
||||
Crimes.Larceny.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsDealDrugs.addEventListener("click", function() {
|
||||
commitDealDrugsCrime();
|
||||
Crimes.DealDrugs.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsBondForgery.addEventListener("click", function() {
|
||||
commitBondForgeryCrime();
|
||||
Crimes.BondForgery.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsTrafficArms.addEventListener("click", function() {
|
||||
commitTraffickArmsCrime();
|
||||
Crimes.TraffickArms.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsHomicide.addEventListener("click", function() {
|
||||
commitHomicideCrime();
|
||||
Crimes.Homicide.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsGta.addEventListener("click", function() {
|
||||
commitGrandTheftAutoCrime();
|
||||
Crimes.GrandTheftAuto.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsKidnap.addEventListener("click", function() {
|
||||
commitKidnapCrime();
|
||||
Crimes.Kidnap.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsAssassinate.addEventListener("click", function() {
|
||||
commitAssassinationCrime();
|
||||
Crimes.Assassination.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
slumsHeist.addEventListener("click", function() {
|
||||
commitHeistCrime();
|
||||
Crimes.Heist.commit();
|
||||
return false;
|
||||
});
|
||||
|
||||
@ -2020,11 +2006,13 @@ function purchaseTorRouter() {
|
||||
AddToAllServers(darkweb);
|
||||
SpecialServerIps.addIp("Darkweb Server", darkweb.ip);
|
||||
|
||||
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button-inactive");
|
||||
const purchaseTor = document.getElementById("location-purchase-tor");
|
||||
purchaseTor.setAttribute("class", "a-link-button-bought");
|
||||
purchaseTor.innerHTML = "TOR Router - Purchased";
|
||||
|
||||
Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
|
||||
darkweb.serversOnNetwork.push(Player.getHomeComputer().ip);
|
||||
dialogBoxCreate("You have purchased a Tor router!<br>You now have access to the dark web from your home computer<br>Use the scan/netstat commands to search for the dark web connection.");
|
||||
dialogBoxCreate("You have purchased a Tor router!<br>You now have access to the dark web from your home computer<br>Use the scan/scan-analyze commands to search for the dark web connection.");
|
||||
}
|
||||
|
||||
function displayUniversityLocationContent(costMult) {
|
||||
@ -2162,6 +2150,10 @@ function setJobRequirementTooltip(loc, entryPosType, btn) {
|
||||
}
|
||||
|
||||
function travelBoxCreate(destCityName, cost) {
|
||||
if(Settings.SuppressTravelConfirmation) {
|
||||
travelToCity(destCityName, cost);
|
||||
return;
|
||||
}
|
||||
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
|
||||
yesBtn.innerHTML = "Yes";
|
||||
noBtn.innerHTML = "No";
|
||||
|
@ -833,7 +833,9 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
|
||||
return Promise.resolve(false);
|
||||
} else {
|
||||
//Able to run script
|
||||
if(workerScript.disableLogs.ALL == null && workerScript.disableLogs.exec == null && workerScript.disableLogs.run == null && workerScript.disableLogs.spawn == null) {
|
||||
workerScript.scriptRef.log("Running script: " + scriptname + " on " + server.hostname + " with " + threads + " threads and args: " + printArray(args) + ". May take a few seconds to start up...");
|
||||
}
|
||||
var runningScriptObj = new RunningScript(script, args);
|
||||
runningScriptObj.threads = threads;
|
||||
server.runningScripts.push(runningScriptObj); //Push onto runningScripts
|
||||
|
@ -31,8 +31,12 @@ function WorkerScript(runningScriptObj) {
|
||||
this.delay = null;
|
||||
this.fnWorker = null; //Workerscript for a function call
|
||||
this.checkingRam = false;
|
||||
this.loadedFns = {}; //Stores names of fns that are "loaded" by this script, thus using RAM
|
||||
this.loadedFns = {}; //Stores names of fns that are "loaded" by this script, thus using RAM. Used for static RAM evaluation
|
||||
this.disableLogs = {}; //Stores names of fns that should have logs disabled
|
||||
|
||||
//Properties used for dynamic RAM evaluation
|
||||
this.dynamicRamUsage = 1.4;
|
||||
this.dynamicLoadedFns = {};
|
||||
}
|
||||
|
||||
//Returns the server on which the workerScript is running
|
||||
@ -52,6 +56,14 @@ WorkerScript.prototype.getScript = function() {
|
||||
return null;
|
||||
}
|
||||
|
||||
WorkerScript.prototype.shouldLog = function(fn) {
|
||||
return (this.disableLogs.ALL == null && this.disableLogs[fn] == null);
|
||||
}
|
||||
|
||||
WorkerScript.prototype.log = function(txt) {
|
||||
this.scriptRef.log(txt);
|
||||
}
|
||||
|
||||
//Array containing all scripts that are running across all servers, to easily run them all
|
||||
let workerScripts = [];
|
||||
|
||||
|
133
src/Player.js
@ -8,7 +8,7 @@ import {Company, Companies, getNextCompanyPosition,
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Corporation} from "./CompanyManagement.js";
|
||||
import {Programs} from "./CreateProgram.js";
|
||||
import {determineCrimeSuccess} from "./Crimes.js";
|
||||
import {determineCrimeSuccess, Crimes} from "./Crimes.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Factions, Faction,
|
||||
displayFactionContent} from "./Faction.js";
|
||||
@ -25,7 +25,7 @@ import {clearEventListeners} from "../utils/HelperFunctions.j
|
||||
import {createRandomIp} from "../utils/IPAddress.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber,
|
||||
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
@ -99,6 +99,7 @@ function PlayerObject() {
|
||||
this.currentServer = ""; //IP address of Server currently being accessed through terminal
|
||||
this.purchasedServers = []; //IP Addresses of purchased servers
|
||||
this.hacknetNodes = [];
|
||||
this.hacknetNodeWrappers = [];
|
||||
this.totalHacknetNodeProduction = 0;
|
||||
|
||||
//Factions
|
||||
@ -298,8 +299,6 @@ PlayerObject.prototype.prestigeAugmentation = function() {
|
||||
|
||||
this.hacknetNodes.length = 0;
|
||||
this.totalHacknetNodeProduction = 0;
|
||||
|
||||
this.bladeburner = 0;
|
||||
}
|
||||
|
||||
PlayerObject.prototype.prestigeSourceFile = function() {
|
||||
@ -390,16 +389,6 @@ PlayerObject.prototype.prestigeSourceFile = function() {
|
||||
if (this.bitNodeN === 3) {this.money = new Decimal(150e9);}
|
||||
this.corporation = 0;
|
||||
|
||||
//Reset Bladeburner
|
||||
this.bladeburner = 0;
|
||||
|
||||
//BitNode 8: Ghost of Wall Street
|
||||
if (this.bitNodeN === 8) {this.money = new Decimal(100000000);}
|
||||
if (this.bitNodeN === 8 || hasWallStreetSF) {
|
||||
this.hasWseAccount = true;
|
||||
this.hasTixApiAccess = true;
|
||||
}
|
||||
|
||||
this.playtimeSinceLastAug = 0;
|
||||
this.scriptProdSinceLastAug = 0;
|
||||
}
|
||||
@ -412,6 +401,26 @@ PlayerObject.prototype.getHomeComputer = function() {
|
||||
return AllServers[this.homeComputer];
|
||||
}
|
||||
|
||||
PlayerObject.prototype.getUpgradeHomeRamCost = function() {
|
||||
//Calculate how many times ram has been upgraded (doubled)
|
||||
const currentRam = Player.getHomeComputer().maxRam;
|
||||
const numUpgrades = Math.log2(currentRam);
|
||||
|
||||
//Calculate cost
|
||||
//Have cost increase by some percentage each time RAM has been upgraded
|
||||
const mult = Math.pow(1.58, numUpgrades);
|
||||
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult;
|
||||
return cost;
|
||||
}
|
||||
|
||||
PlayerObject.prototype.receiveInvite = function(factionName) {
|
||||
if(this.factionInvitations.includes(factionName) || this.factions.includes(factionName)) {
|
||||
return;
|
||||
}
|
||||
this.firstFacInvRecvd = true;
|
||||
this.factionInvitations.push(factionName);
|
||||
}
|
||||
|
||||
//Calculates skill level based on experience. The same formula will be used for every skill
|
||||
PlayerObject.prototype.calculateSkill = function(exp) {
|
||||
return Math.max(Math.floor(32 * Math.log(exp + 534.5) - 200), 1);
|
||||
@ -578,6 +587,9 @@ PlayerObject.prototype.gainHackingExp = function(exp) {
|
||||
console.log("ERR: NaN passed into Player.gainHackingExp()"); return;
|
||||
}
|
||||
this.hacking_exp += exp;
|
||||
if(this.hacking_exp < 0) {
|
||||
this.hacking_exp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerObject.prototype.gainStrengthExp = function(exp) {
|
||||
@ -585,6 +597,9 @@ PlayerObject.prototype.gainStrengthExp = function(exp) {
|
||||
console.log("ERR: NaN passed into Player.gainStrengthExp()"); return;
|
||||
}
|
||||
this.strength_exp += exp;
|
||||
if(this.strength_exp < 0) {
|
||||
this.strength_exp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerObject.prototype.gainDefenseExp = function(exp) {
|
||||
@ -592,6 +607,9 @@ PlayerObject.prototype.gainDefenseExp = function(exp) {
|
||||
console.log("ERR: NaN passed into player.gainDefenseExp()"); return;
|
||||
}
|
||||
this.defense_exp += exp;
|
||||
if(this.defense_exp < 0) {
|
||||
this.defense_exp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerObject.prototype.gainDexterityExp = function(exp) {
|
||||
@ -599,6 +617,9 @@ PlayerObject.prototype.gainDexterityExp = function(exp) {
|
||||
console.log("ERR: NaN passed into Player.gainDexterityExp()"); return;
|
||||
}
|
||||
this.dexterity_exp += exp;
|
||||
if(this.dexterity_exp < 0) {
|
||||
this.dexterity_exp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerObject.prototype.gainAgilityExp = function(exp) {
|
||||
@ -606,6 +627,9 @@ PlayerObject.prototype.gainAgilityExp = function(exp) {
|
||||
console.log("ERR: NaN passed into Player.gainAgilityExp()"); return;
|
||||
}
|
||||
this.agility_exp += exp;
|
||||
if(this.agility_exp < 0) {
|
||||
this.agility_exp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerObject.prototype.gainCharismaExp = function(exp) {
|
||||
@ -613,6 +637,9 @@ PlayerObject.prototype.gainCharismaExp = function(exp) {
|
||||
console.log("ERR: NaN passed into Player.gainCharismaExp()"); return;
|
||||
}
|
||||
this.charisma_exp += exp;
|
||||
if(this.charisma_exp < 0) {
|
||||
this.charisma_exp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PlayerObject.prototype.gainIntelligenceExp = function(exp) {
|
||||
@ -1525,56 +1552,21 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
|
||||
var statusText = ""; //TODO, unique message for each crime when you succeed
|
||||
if (determineCrimeSuccess(this.crimeType, this.workMoneyGained)) {
|
||||
//Handle Karma and crime statistics
|
||||
switch(this.crimeType) {
|
||||
case CONSTANTS.CrimeShoplift:
|
||||
this.karma -= 0.1;
|
||||
let crime = null;
|
||||
for(const i in Crimes) {
|
||||
if(Crimes[i].type == this.crimeType) {
|
||||
crime = Crimes[i];
|
||||
break;
|
||||
case CONSTANTS.CrimeRobStore:
|
||||
this.karma -= 0.5;
|
||||
this.gainIntelligenceExp(0.25 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeMug:
|
||||
this.karma -= 0.25;
|
||||
break;
|
||||
case CONSTANTS.CrimeLarceny:
|
||||
this.karma -= 1.5;
|
||||
this.gainIntelligenceExp(0.5 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeDrugs:
|
||||
this.karma -= 0.5;
|
||||
break;
|
||||
case CONSTANTS.CrimeBondForgery:
|
||||
this.karma -= 0.1;
|
||||
this.gainIntelligenceExp(2 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeTraffickArms:
|
||||
this.karma -= 1;
|
||||
break;
|
||||
case CONSTANTS.CrimeHomicide:
|
||||
++this.numPeopleKilled;
|
||||
this.karma -= 3;
|
||||
break;
|
||||
case CONSTANTS.CrimeGrandTheftAuto:
|
||||
this.karma -= 5;
|
||||
this.gainIntelligenceExp(CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeKidnap:
|
||||
this.karma -= 6;
|
||||
this.gainIntelligenceExp(2 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeAssassination:
|
||||
++this.numPeopleKilled;
|
||||
this.karma -= 10;
|
||||
this.gainIntelligenceExp(5 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
case CONSTANTS.CrimeHeist:
|
||||
this.karma -= 15;
|
||||
this.gainIntelligenceExp(10 * CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if(crime == null) {
|
||||
console.log(this.crimeType);
|
||||
dialogBoxCreate("ERR: Unrecognized crime type. This is probably a bug please contact the developer");
|
||||
return;
|
||||
}
|
||||
this.karma -= crime.karma;
|
||||
this.numPeopleKilled += crime.kills;
|
||||
if(crime.intelligence_exp > 0) {
|
||||
this.gainIntelligenceExp(crime.intelligence_exp);
|
||||
}
|
||||
|
||||
//On a crime success, gain 2x exp
|
||||
@ -2349,6 +2341,25 @@ PlayerObject.prototype.setBitNodeNumber = function(n) {
|
||||
this.bitNodeN = n;
|
||||
}
|
||||
|
||||
PlayerObject.prototype.queueAugmentation = function(name) {
|
||||
for(const i in this.queuedAugmentations) {
|
||||
if(this.queuedAugmentations[i].name == name) {
|
||||
console.log('tried to queue '+name+' twice, this may be a bug');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(const i in this.augmentations) {
|
||||
if(this.augmentations[i].name == name) {
|
||||
console.log('tried to queue '+name+' but we already have that aug');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.firstAugPurchased = true;
|
||||
this.queuedAugmentations.push(new PlayerOwnedAugmentation(name));
|
||||
}
|
||||
|
||||
/* Functions for saving and loading the Player data */
|
||||
function loadPlayer(saveString) {
|
||||
Player = JSON.parse(saveString, Reviver);
|
||||
|
@ -2,6 +2,7 @@ import {deleteActiveScriptsItem} from "./ActiveScriptsUI.js";
|
||||
import {Augmentations, augmentationExists,
|
||||
initAugmentations, AugmentationNames} from "./Augmentations.js";
|
||||
import {initBitNodeMultipliers} from "./BitNode.js";
|
||||
import {Bladeburner} from "./Bladeburner.js";
|
||||
import {writeCinematicText} from "./CinematicText.js";
|
||||
import {Companies, Company, initCompanies} from "./Company.js";
|
||||
import {Programs} from "./CreateProgram.js";
|
||||
@ -34,6 +35,8 @@ import {createPopup, createElement,
|
||||
import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
|
||||
|
||||
let BitNode8StartingMoney = 250e6;
|
||||
|
||||
//Prestige by purchasing augmentation
|
||||
function prestigeAugmentation() {
|
||||
initBitNodeMultipliers();
|
||||
@ -123,11 +126,13 @@ function prestigeAugmentation() {
|
||||
}
|
||||
}
|
||||
|
||||
//Reset Bladeburner
|
||||
Player.bladeburner = null;
|
||||
//Cancel Bladeburner action
|
||||
if (Player.bladeburner instanceof Bladeburner) {
|
||||
Player.bladeburner.prestige();
|
||||
}
|
||||
|
||||
//BitNode 8: Ghost of Wall Street
|
||||
if (Player.bitNodeN === 8) {Player.money = new Decimal(100e6);}
|
||||
if (Player.bitNodeN === 8) {Player.money = new Decimal(BitNode8StartingMoney);}
|
||||
if (Player.bitNodeN === 8 || hasWallStreetSF) {
|
||||
Player.hasWseAccount = true;
|
||||
Player.hasTixApiAccess = true;
|
||||
@ -305,6 +310,13 @@ function prestigeSourceFile() {
|
||||
|
||||
}
|
||||
|
||||
//BitNode 8: Ghost of Wall Street
|
||||
if (Player.bitNodeN === 8) {Player.money = new Decimal(BitNode8StartingMoney);}
|
||||
if (Player.bitNodeN === 8 || hasWallStreetSF) {
|
||||
Player.hasWseAccount = true;
|
||||
Player.hasTixApiAccess = true;
|
||||
}
|
||||
|
||||
//Gain int exp
|
||||
Player.gainIntelligenceExp(5);
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ function giveSourceFile(bitNodeNumber) {
|
||||
}
|
||||
|
||||
if (alreadyOwned && ownedSourceFile) {
|
||||
if (ownedSourceFile.lvl >= 3) {
|
||||
if (ownedSourceFile.lvl >= 3 && ownedSourceFile.n !== 12) {
|
||||
dialogBoxCreate("The Source-File for the BitNode you just destroyed, " + sourceFile.name + ", " +
|
||||
"is already at max level!");
|
||||
} else {
|
||||
@ -208,7 +208,7 @@ function loadBitVerse(destroyedBitNodeNum, flume=false) {
|
||||
var elemId = "bitnode-" + i.toString();
|
||||
var elem = clearEventListeners(elemId);
|
||||
if (elem == null) {return;}
|
||||
if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11) {
|
||||
if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11 || i === 12) {
|
||||
elem.addEventListener("click", function() {
|
||||
var bitNodeKey = "BitNode" + i;
|
||||
var bitNode = BitNodes[bitNodeKey];
|
||||
|
@ -8,7 +8,8 @@ import {loadFactions, Factions,
|
||||
processPassiveFactionRepGain} from "./Faction.js";
|
||||
import {FconfSettings, loadFconf} from "./Fconf.js";
|
||||
import {loadAllGangs, AllGangs} from "./Gang.js";
|
||||
import {processAllHacknetNodeEarnings} from "./HacknetNode.js";
|
||||
import {processAllHacknetNodeEarnings,
|
||||
createPlayerHacknetNodeWrappers} from "./HacknetNode.js";
|
||||
import {loadMessages, initMessages, Messages} from "./Message.js";
|
||||
import {Player, loadPlayer} from "./Player.js";
|
||||
import {loadAllRunningScripts} from "./Script.js";
|
||||
@ -227,6 +228,8 @@ function loadGame(saveString) {
|
||||
}
|
||||
}
|
||||
|
||||
//Re-initialize Hacknet Node Wrappers
|
||||
createPlayerHacknetNodeWrappers();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -443,6 +446,9 @@ function loadImportedGame(saveObj, saveString) {
|
||||
}
|
||||
}
|
||||
|
||||
//Re-initialize Hacknet Node Wrappers
|
||||
createPlayerHacknetNodeWrappers();
|
||||
|
||||
var popupId = "import-game-restart-game-notice";
|
||||
var txt = createElement("p", {
|
||||
innerText:"Imported game! I would suggest saving the game and then reloading the page " +
|
||||
|
@ -1,4 +1,5 @@
|
||||
var ace = require('brace');
|
||||
var beautify = require('js-beautify').js_beautify;
|
||||
require('brace/mode/javascript');
|
||||
require('../netscript');
|
||||
require('brace/theme/chaos');
|
||||
@ -57,6 +58,15 @@ function scriptEditorInit() {
|
||||
console.log("Error finding 'script-editor-buttons-wrapper'");
|
||||
return;
|
||||
}
|
||||
var beautifyButton = createElement("a", {
|
||||
class:"a-link-button", display:"inline-block",
|
||||
innerText:"beautify",
|
||||
clickListener:()=>{
|
||||
beautifyScript();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
var closeButton = createElement("a", {
|
||||
class:"a-link-button", display:"inline-block",
|
||||
innerText:"Save & Close (Ctrl/Cmd + b)",
|
||||
@ -90,6 +100,7 @@ function scriptEditorInit() {
|
||||
target:"_blank"
|
||||
});
|
||||
|
||||
wrapper.appendChild(beautifyButton);
|
||||
wrapper.appendChild(closeButton);
|
||||
wrapper.appendChild(scriptEditorRamText);
|
||||
wrapper.appendChild(scriptEditorRamCheck);
|
||||
@ -243,6 +254,13 @@ $(document).keydown(function(e) {
|
||||
}
|
||||
});
|
||||
|
||||
function beautifyScript() {
|
||||
var editor = ace.edit('javascript-editor');
|
||||
var code = editor.getValue();
|
||||
code = beautify(code, { indent_size: 4 })
|
||||
editor.setValue(code);
|
||||
}
|
||||
|
||||
function saveAndCloseScriptEditor() {
|
||||
var filename = document.getElementById("script-editor-filename").value;
|
||||
var editor = ace.edit('javascript-editor');
|
||||
@ -448,6 +466,7 @@ function parseOnlyRamCalculate(server, code, workerScript) {
|
||||
if (ref == specialReferenceFOR) ram += CONSTANTS.ScriptForRamCost;
|
||||
if (ref == specialReferenceWHILE) ram += CONSTANTS.ScriptWhileRamCost;
|
||||
if (ref == "hacknetnodes") ram += CONSTANTS.ScriptHacknetNodesRamCost;
|
||||
if (ref == "document" || ref == "window") ram += CONSTANTS.ScriptDomRamCost;
|
||||
|
||||
// Check if this ident is a function in the workerscript env. If it is, then we need to
|
||||
// get its RAM cost. We do this by calling it, which works because the running script
|
||||
@ -508,11 +527,15 @@ function parseOnlyCalculateDeps(code, currentModule) {
|
||||
s.add(name); // For builtins like hack.
|
||||
}
|
||||
|
||||
//A list of identifiers that resolve to "native Javascript code"
|
||||
const objectPrototypeProperties = Object.getOwnPropertyNames(Object.prototype);
|
||||
|
||||
// If we discover a dependency identifier, state.key is the dependent identifier.
|
||||
// walkDeeper is for doing recursive walks of expressions in composites that we handle.
|
||||
function commonVisitors() {
|
||||
return {
|
||||
Identifier: (node, st, walkDeeper) => {
|
||||
if (objectPrototypeProperties.includes(node.name)) {return;}
|
||||
addRef(st.key, node.name);
|
||||
},
|
||||
WhileStatement: (node, st, walkDeeper) => {
|
||||
|
@ -768,19 +768,31 @@ function initForeignServers() {
|
||||
}
|
||||
}
|
||||
|
||||
function numCycleForGrowth(server, growth) {
|
||||
let ajdGrowthRate = 1 + (CONSTANTS.ServerBaseGrowthRate - 1) / server.hackDifficulty;
|
||||
if(ajdGrowthRate > CONSTANTS.ServerMaxGrowthRate) {
|
||||
ajdGrowthRate = CONSTANTS.ServerMaxGrowthRate;
|
||||
}
|
||||
|
||||
const serverGrowthPercentage = server.serverGrowth / 100;
|
||||
|
||||
const cycles = Math.log(growth)/(Math.log(ajdGrowthRate)*Player.hacking_grow_mult*serverGrowthPercentage);
|
||||
return cycles;
|
||||
}
|
||||
|
||||
//Applied server growth for a single server. Returns the percentage growth
|
||||
function processSingleServerGrowth(server, numCycles) {
|
||||
//Server growth processed once every 450 game cycles
|
||||
var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
|
||||
const numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
|
||||
|
||||
//Get adjusted growth rate, which accounts for server security
|
||||
var growthRate = CONSTANTS.ServerBaseGrowthRate;
|
||||
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
|
||||
var serverGrowthPercentage = server.serverGrowth / 100;
|
||||
var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
|
||||
const serverGrowthPercentage = server.serverGrowth / 100;
|
||||
const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
|
||||
|
||||
//Apply serverGrowth for the calculated number of growth cycles
|
||||
var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult);
|
||||
@ -789,19 +801,26 @@ function processSingleServerGrowth(server, numCycles) {
|
||||
serverGrowth = 1;
|
||||
}
|
||||
|
||||
var oldMoneyAvailable = server.moneyAvailable;
|
||||
const oldMoneyAvailable = server.moneyAvailable;
|
||||
server.moneyAvailable *= serverGrowth;
|
||||
|
||||
// in case of data corruption
|
||||
if (server.moneyMax && isNaN(server.moneyAvailable)) {
|
||||
server.moneyAvailable = server.moneyMax;
|
||||
}
|
||||
|
||||
// cap at max
|
||||
if (server.moneyMax && server.moneyAvailable > server.moneyMax) {
|
||||
server.moneyAvailable = server.moneyMax;
|
||||
return server.moneyAvailable / oldMoneyAvailable;
|
||||
}
|
||||
|
||||
// if there was any growth at all, increase security
|
||||
if(oldMoneyAvailable !== server.moneyAvailable) {
|
||||
//Growing increases server security twice as much as hacking
|
||||
server.fortify(2 * CONSTANTS.ServerFortifyAmount * numServerGrowthCycles);
|
||||
return serverGrowth;
|
||||
const usedCycles = numCycleForGrowth(server, server.moneyAvailable / oldMoneyAvailable);
|
||||
server.fortify(2 * CONSTANTS.ServerFortifyAmount * Math.ceil(usedCycles));
|
||||
}
|
||||
return server.moneyAvailable / oldMoneyAvailable;
|
||||
}
|
||||
|
||||
function prestigeHomeComputer(homeComp) {
|
||||
@ -873,9 +892,11 @@ function GetServerByHostname(hostname) {
|
||||
function getServer(s) {
|
||||
if (!isValidIPAddress(s)) {
|
||||
return GetServerByHostname(s);
|
||||
} else {
|
||||
}
|
||||
if(AllServers[s] !== undefined) {
|
||||
return AllServers[s];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//Debugging tool
|
||||
|
@ -7,6 +7,7 @@ let Settings = {
|
||||
MaxPortCapacity: 50,
|
||||
SuppressMessages: false,
|
||||
SuppressFactionInvites: false,
|
||||
SuppressTravelConfirmation: false,
|
||||
AutosaveInterval: 60,
|
||||
DisableHotkeys: false,
|
||||
ThemeHighlightColor: "#ffffff",
|
||||
@ -26,6 +27,7 @@ function initSettings() {
|
||||
Settings.MaxPortCapacity = 50;
|
||||
Settings.SuppressMessages = false;
|
||||
Settings.SuppressFactionInvites = false;
|
||||
Settings.SuppressTravelConfirmation = false,
|
||||
Settings.AutosaveInterval = 60;
|
||||
Settings.DisableHotkeys = false;
|
||||
}
|
||||
@ -36,6 +38,7 @@ function setSettingsLabels() {
|
||||
var nsPortLimit = document.getElementById("settingsNSPortRangeValLabel");
|
||||
var suppressMsgs = document.getElementById("settingsSuppressMessages");
|
||||
var suppressFactionInv = document.getElementById("settingsSuppressFactionInvites")
|
||||
var suppressTravelConfirmation = document.getElementById("settingsSuppressTravelConfirmation");
|
||||
var autosaveInterval = document.getElementById("settingsAutosaveIntervalValLabel");
|
||||
var disableHotkeys = document.getElementById("settingsDisableHotkeys");
|
||||
|
||||
@ -45,6 +48,7 @@ function setSettingsLabels() {
|
||||
nsPortLimit.innerHTML = Settings.MaxPortCapacity;
|
||||
suppressMsgs.checked = Settings.SuppressMessages;
|
||||
suppressFactionInv.checked = Settings.SuppressFactionInvites;
|
||||
suppressTravelConfirmation.checked = Settings.SuppressTravelConfirmation;
|
||||
autosaveInterval.innerHTML = Settings.AutosaveInterval;
|
||||
disableHotkeys.checked = Settings.DisableHotkeys;
|
||||
|
||||
@ -91,6 +95,10 @@ function setSettingsLabels() {
|
||||
Settings.SuppressFactionInvites = this.checked;
|
||||
};
|
||||
|
||||
suppressTravelConfirmation.onclick = function() {
|
||||
Settings.SuppressTravelConfirmation = this.checked;
|
||||
};
|
||||
|
||||
disableHotkeys.onclick = function() {
|
||||
Settings.DisableHotkeys = this.checked;
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ function initSourceFiles() {
|
||||
"Level 1: 24%<br>" +
|
||||
"Level 2: 36%<br>" +
|
||||
"Level 3: 42%<br>");
|
||||
SourceFiles["SourceFile12"] = new SourceFile(12);
|
||||
SourceFiles["SourceFile12"] = new SourceFile(12, "This Source-File increases all your multipliers by 1% per level");
|
||||
}
|
||||
|
||||
function PlayerOwnedSourceFile(number, level) {
|
||||
@ -181,6 +181,42 @@ function applySourceFile(srcFile) {
|
||||
Player.work_money_mult *= incMult;
|
||||
Player.company_rep_mult *= incMult;
|
||||
break;
|
||||
case 12: //The testing ground
|
||||
const inc = Math.pow(1.01, srcFile.lvl);
|
||||
const dec = Math.pow(0.99, srcFile.lvl);
|
||||
|
||||
Player.hacking_chance_mult *= inc;
|
||||
Player.hacking_speed_mult *= inc;
|
||||
Player.hacking_money_mult *= inc;
|
||||
Player.hacking_grow_mult *= inc;
|
||||
Player.hacking_mult *= inc;
|
||||
|
||||
Player.strength_mult *= inc;
|
||||
Player.defense_mult *= inc;
|
||||
Player.dexterity_mult *= inc;
|
||||
Player.agility_mult *= inc;
|
||||
Player.charisma_mult *= inc;
|
||||
|
||||
Player.hacking_exp_mult *= inc;
|
||||
Player.strength_exp_mult *= inc;
|
||||
Player.defense_exp_mult *= inc;
|
||||
Player.dexterity_exp_mult *= inc;
|
||||
Player.agility_exp_mult *= inc;
|
||||
Player.charisma_exp_mult *= inc;
|
||||
|
||||
Player.company_rep_mult *= inc;
|
||||
Player.faction_rep_mult *= inc;
|
||||
|
||||
Player.crime_money_mult *= inc;
|
||||
Player.crime_success_mult *= inc;
|
||||
|
||||
Player.hacknet_node_money_mult *= inc;
|
||||
Player.hacknet_node_purchase_cost_mult *= dec;
|
||||
Player.hacknet_node_ram_cost_mult *= dec;
|
||||
Player.hacknet_node_core_cost_mult *= dec;
|
||||
Player.hacknet_node_level_cost_mult *= dec;
|
||||
|
||||
Player.work_money_mult *= inc;
|
||||
default:
|
||||
console.log("ERROR: Invalid source file number: " + srcFile.n);
|
||||
break;
|
||||
|
@ -11,7 +11,7 @@ import {clearEventListeners, getRandomInt,
|
||||
clearEventListenersEl} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
@ -703,7 +703,7 @@ function displayStockMarketContent() {
|
||||
if (!Player.hasWseAccount && Player.money.gte(CONSTANTS.WSEAccountCost)) {
|
||||
wseAccountButton.setAttribute("class", "a-link-button");
|
||||
} else if (Player.hasWseAccount){
|
||||
wseAccountButton.innerText = "WSE Account - acquired";
|
||||
wseAccountButton.innerText = "WSE Account - Purchased";
|
||||
wseAccountButton.setAttribute("class", "a-link-button-bought");
|
||||
} else {
|
||||
wseAccountButton.setAttribute("class", "a-link-button-inactive");
|
||||
@ -724,7 +724,7 @@ function displayStockMarketContent() {
|
||||
if (!Player.hasTixApiAccess && Player.money.gte(CONSTANTS.TIXAPICost)) {
|
||||
tixApiAccessButton.setAttribute("class", "a-link-button");
|
||||
} else if(Player.hasTixApiAccess) {
|
||||
tixApiAccessButton.innerText = "Trade Information eXchange (TIX) API Access - granted"
|
||||
tixApiAccessButton.innerText = "Trade Information eXchange (TIX) API Access - Purchased"
|
||||
tixApiAccessButton.setAttribute("class", "a-link-button-bought");
|
||||
} else {
|
||||
tixApiAccessButton.setAttribute("class", "a-link-button-inactive");
|
||||
|
326
src/engine.js
@ -3,7 +3,7 @@ import {gameOptionsBoxOpen, gameOptionsBoxClose}from "../utils/GameOptions.js";
|
||||
import {clearEventListeners, createElement,
|
||||
removeChildrenFromElement,
|
||||
exceptionAlert} from "../utils/HelperFunctions.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import numeral from "numeral/min/numeral.min";
|
||||
import {formatNumber,
|
||||
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions.js";
|
||||
import {loxBoxCreate, logBoxUpdateText,
|
||||
@ -12,7 +12,8 @@ import {loxBoxCreate, logBoxUpdateText,
|
||||
import {updateActiveScriptsItems} from "./ActiveScriptsUI.js";
|
||||
import {Augmentations, installAugmentations,
|
||||
initAugmentations, AugmentationNames,
|
||||
displayAugmentationsContent} from "./Augmentations.js";
|
||||
displayAugmentationsContent,
|
||||
PlayerOwnedAugmentation} from "./Augmentations.js";
|
||||
import {BitNodes, initBitNodes,
|
||||
initBitNodeMultipliers} from "./BitNode.js";
|
||||
import {Bladeburner} from "./Bladeburner.js";
|
||||
@ -44,13 +45,14 @@ import {updateOnlineScriptTimes,
|
||||
import {Player} from "./Player.js";
|
||||
import {prestigeAugmentation,
|
||||
prestigeSourceFile} from "./Prestige.js";
|
||||
import {redPillFlag} from "./RedPill.js";
|
||||
import {redPillFlag, hackWorldDaemon} from "./RedPill.js";
|
||||
import {saveObject, loadGame} from "./SaveObject.js";
|
||||
import {loadAllRunningScripts, scriptEditorInit,
|
||||
updateScriptEditorContent} from "./Script.js";
|
||||
import {AllServers, Server, initForeignServers} from "./Server.js";
|
||||
import {Settings, setSettingsLabels} from "./Settings.js";
|
||||
import {initSourceFiles, SourceFiles} from "./SourceFile.js";
|
||||
import {initSourceFiles, SourceFiles,
|
||||
PlayerOwnedSourceFile} from "./SourceFile.js";
|
||||
import {SpecialServerIps, initSpecialServerIps} from "./SpecialServerIps.js";
|
||||
import {StockMarket, StockSymbols,
|
||||
SymbolToStockMap, initStockSymbols,
|
||||
@ -145,6 +147,7 @@ let Engine = {
|
||||
factionsMainMenuButton: null,
|
||||
augmentationsMainMenuButton: null,
|
||||
tutorialMainMenuButton: null,
|
||||
devMainMenuButton: null,
|
||||
saveMainMenuButton: null,
|
||||
deleteMainMenuButton: null,
|
||||
|
||||
@ -158,6 +161,41 @@ let Engine = {
|
||||
tutorialFactionsButton: null,
|
||||
tutorialAugmentationsButton: null,
|
||||
tutorialBackButton: null,
|
||||
|
||||
//Dev menu
|
||||
devMenuGiveMoney: null,
|
||||
devMenuGiveRam: null,
|
||||
devMenuAugDropdown: null,
|
||||
devMenuAddAug: null,
|
||||
devMenuTriggerBitFlume: null,
|
||||
devMenuFactionDropdown: null,
|
||||
devMenuAddFaction: null,
|
||||
devMenuOpen: null,
|
||||
devMenuMinSecurity: null,
|
||||
devMenuMaxMoney: null,
|
||||
devMenuConnectDropdown: null,
|
||||
devMenuConnect: null,
|
||||
devMenuProgramsDropdown: null,
|
||||
devMenuAddProgram: null,
|
||||
devMenuHackingExp: null,
|
||||
devMenuAddHacking: null,
|
||||
devMenuStrengthExp: null,
|
||||
devMenuAddStrength: null,
|
||||
devMenuDefenseExp: null,
|
||||
devMenuAddDefense: null,
|
||||
devMenuDexterityExp: null,
|
||||
devMenuAddDexterity: null,
|
||||
devMenuAgilityExp: null,
|
||||
devMenuAddAgility: null,
|
||||
devMenuCharismaExp: null,
|
||||
devMenuAddCharisma: null,
|
||||
devMenuIntelligenceExp: null,
|
||||
devMenuAddIntelligence: null,
|
||||
devMenuEnableIntelligence: null,
|
||||
devMenuDisableIntelligence: null,
|
||||
devMenuSFN: null,
|
||||
devMenuSFLvl: null,
|
||||
devMenuAddSF: null,
|
||||
},
|
||||
|
||||
//Display objects
|
||||
@ -183,6 +221,7 @@ let Engine = {
|
||||
factionAugmentationsContent: null,
|
||||
augmentationsContent: null,
|
||||
tutorialContent: null,
|
||||
devMenuContent: null,
|
||||
infiltrationContent: null,
|
||||
stockMarketContent: null,
|
||||
locationContent: null,
|
||||
@ -208,6 +247,7 @@ let Engine = {
|
||||
Faction: "Faction",
|
||||
Augmentations: "Augmentations",
|
||||
Tutorial: "Tutorial",
|
||||
DevMenu: "Dev Menu",
|
||||
Location: "Location",
|
||||
workInProgress: "WorkInProgress",
|
||||
RedPill: "RedPill",
|
||||
@ -319,6 +359,14 @@ let Engine = {
|
||||
document.getElementById("tutorial-menu-link").classList.add("active");
|
||||
},
|
||||
|
||||
loadDevMenuContent: function() {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.devMenuContent.style.display = "block";
|
||||
Engine.displayDevMenuContent();
|
||||
Engine.currentPage = Engine.Page.DevMenu;
|
||||
document.getElementById("dev-menu-link").classList.add("active");
|
||||
},
|
||||
|
||||
loadLocationContent: function() {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.locationContent.style.display = "block";
|
||||
@ -455,6 +503,7 @@ let Engine = {
|
||||
Engine.Display.factionAugmentationsContent.style.display = "none";
|
||||
Engine.Display.augmentationsContent.style.display = "none";
|
||||
Engine.Display.tutorialContent.style.display = "none";
|
||||
Engine.Display.devMenuContent.style.display = "none";
|
||||
Engine.Display.locationContent.style.display = "none";
|
||||
Engine.Display.workInProgressContent.style.display = "none";
|
||||
Engine.Display.redPillContent.style.display = "none";
|
||||
@ -494,6 +543,7 @@ let Engine = {
|
||||
document.getElementById("city-menu-link").classList.remove("active");
|
||||
document.getElementById("tutorial-menu-link").classList.remove("active");
|
||||
document.getElementById("options-menu-link").classList.remove("active");
|
||||
document.getElementById("dev-menu-link").classList.remove("active");
|
||||
},
|
||||
|
||||
displayCharacterOverviewInfo: function() {
|
||||
@ -650,6 +700,7 @@ let Engine = {
|
||||
//Generic Locations (common to every city):
|
||||
// World Stock Exchange
|
||||
// Corporation (if applicable)
|
||||
// Bladeburner HQ (if applicable);
|
||||
var genericLocationsList = document.getElementById("generic-locations-list");
|
||||
genericLocationsList.style.display = "inline";
|
||||
removeChildrenFromElement(genericLocationsList);
|
||||
@ -676,6 +727,18 @@ let Engine = {
|
||||
}));
|
||||
genericLocationsList.appendChild(li);
|
||||
}
|
||||
|
||||
if (Player.bladeburner instanceof Bladeburner) {
|
||||
var li = createElement("li");
|
||||
li.appendChild(createElement("a", {
|
||||
innerText:"Bladeburner Headquarters", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
Engine.loadBladeburnerContent();
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
genericLocationsList.appendChild(li);
|
||||
}
|
||||
},
|
||||
|
||||
displayFactionsInfo: function() {
|
||||
@ -771,6 +834,43 @@ let Engine = {
|
||||
document.getElementById("tutorial-text").style.display = "none";
|
||||
},
|
||||
|
||||
displayDevMenuContent: function() {
|
||||
Engine.Clickables.devMenuGiveMoney.style.display = "block";
|
||||
Engine.Clickables.devMenuGiveRam.style.display = "block";
|
||||
Engine.Clickables.devMenuAugDropdown.style.display = "block";
|
||||
Engine.Clickables.devMenuAddAug.style.display = "block";
|
||||
Engine.Clickables.devMenuTriggerBitFlume.style.display = "block";
|
||||
Engine.Clickables.devMenuFactionDropdown.style.display = "block";
|
||||
Engine.Clickables.devMenuAddFaction.style.display = "block";
|
||||
Engine.Clickables.devMenuOpen.style.display = "block";
|
||||
Engine.Clickables.devMenuMinSecurity.style.display = "block";
|
||||
Engine.Clickables.devMenuMaxMoney.style.display = "block";
|
||||
Engine.Clickables.devMenuConnectDropdown.style.display = "block";
|
||||
Engine.Clickables.devMenuConnect.style.display = "block";
|
||||
Engine.Clickables.devMenuProgramsDropdown.style.display = "block";
|
||||
Engine.Clickables.devMenuAddProgram.style.display = "block";
|
||||
|
||||
Engine.Clickables.devMenuHackingExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddHacking.style.display = "block";
|
||||
Engine.Clickables.devMenuStrengthExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddStrength.style.display = "block";
|
||||
Engine.Clickables.devMenuDefenseExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddDefense.style.display = "block";
|
||||
Engine.Clickables.devMenuDexterityExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddDexterity.style.display = "block";
|
||||
Engine.Clickables.devMenuAgilityExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddAgility.style.display = "block";
|
||||
Engine.Clickables.devMenuCharismaExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddCharisma.style.display = "block";
|
||||
Engine.Clickables.devMenuIntelligenceExp.style.display = "block";
|
||||
Engine.Clickables.devMenuAddIntelligence.style.display = "block";
|
||||
Engine.Clickables.devMenuEnableIntelligence.style.display = "block";
|
||||
Engine.Clickables.devMenuDisableIntelligence.style.display = "block";
|
||||
Engine.Clickables.devMenuSFN.style.display = "block";
|
||||
Engine.Clickables.devMenuSFLvl.style.display = "block";
|
||||
Engine.Clickables.devMenuAddSF.style.display = "block";
|
||||
},
|
||||
|
||||
//Displays the text when a section of the Tutorial is opened
|
||||
displayTutorialPage: function(text) {
|
||||
document.getElementById("tutorial-getting-started-link").style.display = "none";
|
||||
@ -1169,6 +1269,7 @@ let Engine = {
|
||||
var job = document.getElementById("job-tab");
|
||||
var tutorial = document.getElementById("tutorial-tab");
|
||||
var options = document.getElementById("options-tab");
|
||||
var dev = document.getElementById("dev-tab");
|
||||
|
||||
//Load game from save or create new game
|
||||
if (loadGame(saveString)) {
|
||||
@ -1245,7 +1346,7 @@ let Engine = {
|
||||
formatNumber(offlineProductionFromHacknetNodes, 2));
|
||||
//Close main menu accordions for loaded game
|
||||
var visibleMenuTabs = [terminal, createScript, activeScripts, stats,
|
||||
hacknetnodes, city, tutorial, options];
|
||||
hacknetnodes, city, tutorial, options, dev];
|
||||
if (Player.firstFacInvRecvd) {visibleMenuTabs.push(factions);}
|
||||
else {factions.style.display = "none";}
|
||||
if (Player.firstAugPurchased) {visibleMenuTabs.push(augmentations);}
|
||||
@ -1299,7 +1400,7 @@ let Engine = {
|
||||
Engine.openMainMenuHeader(
|
||||
[terminal, createScript, activeScripts, stats,
|
||||
hacknetnodes, city,
|
||||
tutorial, options]
|
||||
tutorial, options, dev]
|
||||
);
|
||||
|
||||
//Start interactive tutorial
|
||||
@ -1352,6 +1453,9 @@ let Engine = {
|
||||
Engine.Display.tutorialContent = document.getElementById("tutorial-container");
|
||||
Engine.Display.tutorialContent.style.display = "none";
|
||||
|
||||
Engine.Display.devMenuContent = document.getElementById("dev-menu-container");
|
||||
Engine.Display.devMenuContent.style.display = "none";
|
||||
|
||||
Engine.Display.infiltrationContent = document.getElementById("infiltration-container");
|
||||
Engine.Display.infiltrationContent.style.display = "none";
|
||||
|
||||
@ -1439,9 +1543,195 @@ let Engine = {
|
||||
Engine.displayTutorialContent();
|
||||
});
|
||||
|
||||
// dev menu buttons
|
||||
Engine.Clickables.devMenuGiveMoney = document.getElementById("dev-need-money");
|
||||
Engine.Clickables.devMenuGiveMoney.addEventListener("click", function() {
|
||||
Player.gainMoney(1e15);
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuGiveRam = document.getElementById("dev-need-ram");
|
||||
Engine.Clickables.devMenuGiveRam.addEventListener("click", function() {
|
||||
Player.getHomeComputer().maxRam *= 2;
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuAugDropdown = document.getElementById("dev-menu-aug-dropdown");
|
||||
const augDD = Engine.Clickables.devMenuAugDropdown;
|
||||
for(const i in AugmentationNames) {
|
||||
augDD.options[augDD.options.length] = new Option(AugmentationNames[i], AugmentationNames[i]);
|
||||
}
|
||||
|
||||
Engine.Clickables.devMenuAddAug = document.getElementById("dev-add-aug");
|
||||
Engine.Clickables.devMenuAddAug.addEventListener("click", function() {
|
||||
Player.queueAugmentation(augDD.options[augDD.selectedIndex].value);
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuTriggerBitFlume = document.getElementById("dev-bit-flume");
|
||||
Engine.Clickables.devMenuTriggerBitFlume.addEventListener("click", function() {
|
||||
hackWorldDaemon(Player.bitNodeN, true);
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuFactionDropdown = document.getElementById("dev-menu-faction-dropdown");
|
||||
const facDD = Engine.Clickables.devMenuFactionDropdown;
|
||||
for(const i in Factions) {
|
||||
facDD.options[facDD.options.length] = new Option(Factions[i].name, Factions[i].name);
|
||||
}
|
||||
|
||||
Engine.Clickables.devMenuAddFaction = document.getElementById("dev-add-faction");
|
||||
Engine.Clickables.devMenuAddFaction.addEventListener("click", function() {
|
||||
const factionName = facDD.options[facDD.selectedIndex].value;
|
||||
Player.receiveInvite(factionName);
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuOpen = document.getElementById("dev-open-all");
|
||||
Engine.Clickables.devMenuOpen.addEventListener("click", function() {
|
||||
for(const i in AllServers) {
|
||||
AllServers[i].hasAdminRights = true;
|
||||
AllServers[i].sshPortOpen = true;
|
||||
AllServers[i].ftpPortOpen = true;
|
||||
AllServers[i].smtpPortOpen = true;
|
||||
AllServers[i].httpPortOpen = true;
|
||||
AllServers[i].sqlPortOpen = true;
|
||||
AllServers[i].openPortCount = 5;
|
||||
}
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuMinSecurity = document.getElementById("dev-min-security");
|
||||
Engine.Clickables.devMenuMinSecurity.addEventListener("click", function() {
|
||||
for(const i in AllServers) {
|
||||
AllServers[i].hackDifficulty = AllServers[i].minDifficulty;
|
||||
}
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuMaxMoney = document.getElementById("dev-max-money");
|
||||
Engine.Clickables.devMenuMaxMoney.addEventListener("click", function() {
|
||||
for(const i in AllServers) {
|
||||
AllServers[i].moneyAvailable = AllServers[i].moneyMax;
|
||||
}
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuConnectDropdown = document.getElementById("dev-menu-connect-dropdown");
|
||||
const connectDD = Engine.Clickables.devMenuConnectDropdown;
|
||||
for(const i in AllServers) {
|
||||
connectDD.options[connectDD.options.length] = new Option(AllServers[i].hostname, AllServers[i].hostname);
|
||||
}
|
||||
|
||||
Engine.Clickables.devMenuConnect = document.getElementById("dev-connect");
|
||||
Engine.Clickables.devMenuConnect.addEventListener("click", function() {
|
||||
const host = connectDD.options[connectDD.selectedIndex].value;
|
||||
Terminal.connectToServer(host);
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuProgramsDropdown = document.getElementById("dev-menu-add-program-dropdown");
|
||||
const programsDD = Engine.Clickables.devMenuProgramsDropdown;
|
||||
for(const i in Programs) {
|
||||
programsDD.options[programsDD.options.length] = new Option(Programs[i], Programs[i]);
|
||||
}
|
||||
|
||||
Engine.Clickables.devMenuAddProgram = document.getElementById("dev-add-program");
|
||||
Engine.Clickables.devMenuAddProgram.addEventListener("click", function() {
|
||||
const program = programsDD.options[programsDD.selectedIndex].value;;
|
||||
if(!Player.hasProgram(program)) {
|
||||
Player.getHomeComputer().programs.push(program);
|
||||
}
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuHackingExp = document.getElementById("dev-hacking-exp");
|
||||
Engine.Clickables.devMenuAddHacking = document.getElementById("dev-add-hacking");
|
||||
Engine.Clickables.devMenuAddHacking.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuHackingExp.value);
|
||||
Player.gainHackingExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuStrengthExp = document.getElementById("dev-strength-exp");
|
||||
Engine.Clickables.devMenuAddStrength = document.getElementById("dev-add-strength");
|
||||
Engine.Clickables.devMenuAddStrength.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuStrengthExp.value);
|
||||
Player.gainStrengthExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuDefenseExp = document.getElementById("dev-defense-exp");
|
||||
Engine.Clickables.devMenuAddDefense = document.getElementById("dev-add-defense");
|
||||
Engine.Clickables.devMenuAddDefense.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuDefenseExp.value);
|
||||
Player.gainDefenseExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuDexterityExp = document.getElementById("dev-dexterity-exp");
|
||||
Engine.Clickables.devMenuAddDexterity = document.getElementById("dev-add-dexterity");
|
||||
Engine.Clickables.devMenuAddDexterity.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuDexterityExp.value);
|
||||
Player.gainDexterityExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuAgilityExp = document.getElementById("dev-agility-exp");
|
||||
Engine.Clickables.devMenuAddAgility = document.getElementById("dev-add-agility");
|
||||
Engine.Clickables.devMenuAddAgility.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuAgilityExp.value);
|
||||
Player.gainAgilityExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuCharismaExp = document.getElementById("dev-charisma-exp");
|
||||
Engine.Clickables.devMenuAddCharisma = document.getElementById("dev-add-charisma");
|
||||
Engine.Clickables.devMenuAddCharisma.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuCharismaExp.value);
|
||||
Player.gainCharismaExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuIntelligenceExp = document.getElementById("dev-intelligence-exp");
|
||||
Engine.Clickables.devMenuAddIntelligence = document.getElementById("dev-add-intelligence");
|
||||
Engine.Clickables.devMenuAddIntelligence.addEventListener("click", function() {
|
||||
const exp = parseInt(Engine.Clickables.devMenuIntelligenceExp.value);
|
||||
Player.gainIntelligenceExp(exp);
|
||||
Player.updateSkillLevels();
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuEnableIntelligence = document.getElementById("dev-enable-intelligence");
|
||||
Engine.Clickables.devMenuEnableIntelligence.addEventListener("click", function() {
|
||||
Player.intelligence = 1;
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuDisableIntelligence = document.getElementById("dev-disable-intelligence");
|
||||
Engine.Clickables.devMenuDisableIntelligence.addEventListener("click", function() {
|
||||
Player.intelligence = 0;
|
||||
});
|
||||
|
||||
Engine.Clickables.devMenuSFN = document.getElementById("dev-sf-n");
|
||||
Engine.Clickables.devMenuSFLvl = document.getElementById("dev-sf-lvl");
|
||||
Engine.Clickables.devMenuAddSF = document.getElementById("dev-add-source-file");
|
||||
Engine.Clickables.devMenuAddSF.addEventListener("click", function() {
|
||||
const sfN = parseInt(Engine.Clickables.devMenuSFN.value);
|
||||
const sfLvl = parseInt(Engine.Clickables.devMenuSFLvl.value);
|
||||
let sfIndex = -1;
|
||||
for(const i in Player.sourceFiles) {
|
||||
if(Player.sourceFiles[i].n === sfN) {
|
||||
sfIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(sfIndex === -1) { // add fresh source file
|
||||
Player.sourceFiles.push(new PlayerOwnedSourceFile(sfN, sfLvl));
|
||||
} else if(sfLvl === 0) { // remove a source file.
|
||||
if(sfIndex === -1) { // doesn't have it anyway.
|
||||
return;
|
||||
}
|
||||
Player.sourceFiles.splice(sfIndex, 1);
|
||||
} else { // set source file level
|
||||
Player.sourceFiles[sfIndex].lvl=sfLvl;
|
||||
}
|
||||
});
|
||||
|
||||
//If DarkWeb already purchased, disable the button
|
||||
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
|
||||
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button-inactive");
|
||||
const purchaseTor = document.getElementById("location-purchase-tor");
|
||||
purchaseTor.setAttribute("class", "a-link-button-bought");
|
||||
purchaseTor.innerHTML = "TOR Router - Purchased";
|
||||
}
|
||||
},
|
||||
|
||||
@ -1536,16 +1826,16 @@ let Engine = {
|
||||
var options = document.getElementById("options-tab");
|
||||
var optionsLink = document.getElementById("options-menu-link");
|
||||
this.classList.toggle("opened");
|
||||
const elems = [tutorial, options];
|
||||
const links = [tutorialLink, optionsLink];
|
||||
if(process.env.NODE_ENV === "development") {
|
||||
elems.push(document.getElementById("dev-tab"));
|
||||
links.push(document.getElementById("dev-menu-link"));
|
||||
}
|
||||
if (tutorial.style.maxHeight) {
|
||||
Engine.toggleMainMenuHeader(false,
|
||||
[tutorial, options],
|
||||
[tutorialLink, optionsLink]
|
||||
);
|
||||
Engine.toggleMainMenuHeader(false, elems, links);
|
||||
} else {
|
||||
Engine.toggleMainMenuHeader(true,
|
||||
[tutorial, options],
|
||||
[tutorialLink, optionsLink]
|
||||
);
|
||||
Engine.toggleMainMenuHeader(true, elems, links);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1623,6 +1913,12 @@ let Engine = {
|
||||
return false;
|
||||
});
|
||||
|
||||
Engine.Clickables.devMainMenuButton = clearEventListeners("dev-menu-link");
|
||||
Engine.Clickables.devMainMenuButton.addEventListener("click", function() {
|
||||
Engine.loadDevMenuContent();
|
||||
return false;
|
||||
});
|
||||
|
||||
//Active scripts list
|
||||
Engine.ActiveScriptsList = document.getElementById("active-scripts-list");
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {executeJSScript} from "../src/NetscriptJSEvaluator.js";
|
||||
import {WorkerScript} from "../src/NetscriptWorker.js";
|
||||
|
||||
const chai = require("chai");
|
||||
const chaiAsPromised = require("chai-as-promised");
|
||||
@ -9,17 +10,19 @@ console.info('asdf');
|
||||
|
||||
describe('NSJS ScriptStore', function() {
|
||||
it('should run an imported function', async function() {
|
||||
const s = { filename: "", code: "export function main() { return 2; }" };
|
||||
chai.expect(await executeJSScript(s)).to.equal(2);
|
||||
const s = { filename: "", code: "export function main() { return 2; }", args:[]};
|
||||
const worker = new WorkerScript(s);
|
||||
chai.expect(await executeJSScript([], s)).to.equal(2);
|
||||
});
|
||||
|
||||
/*
|
||||
it('should handle recursive imports', async function() {
|
||||
const s1 = { filename: "s1.js", code: "export function iAmRecursiveImport(x) { return x + 2; }" };
|
||||
const s2 = { filename: "", code: `
|
||||
import {iAmRecursiveImport} from \"s1.js\";
|
||||
export function main() { return iAmRecursiveImport(3);
|
||||
}`};
|
||||
chai.expect(await executeJSScript(s2, [s1, s2])).to.equal(5);
|
||||
chai.expect(await executeJSScript([s1, s2], s2)).to.equal(5);
|
||||
});
|
||||
|
||||
it (`should correctly reference the passed global env`, async function() {
|
||||
@ -45,5 +48,5 @@ describe('NSJS ScriptStore', function() {
|
||||
export function main() {}
|
||||
`}
|
||||
executeJSScript(s2, [s1, s2]).should.eventually.throw();
|
||||
});
|
||||
});*/
|
||||
});
|
@ -11,7 +11,7 @@
|
||||
<script src="https://unpkg.com/mocha@4.0.1/mocha.js"></script>
|
||||
|
||||
<script>mocha.setup('bdd')</script>
|
||||
<script type="module" src="../dist/tests.bundle.js"></script>
|
||||
<script type="module" src="tests.bundle.js"></script>
|
||||
<script type="module">
|
||||
mocha.checkLeaks();
|
||||
mocha.run();
|
||||
|
@ -74,6 +74,21 @@ function removeChildrenFromElement(el) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a reference to the first object with the specified value of the ID or NAME attribute, throwing an error if it is unable to find it.
|
||||
* @param {string} elementId The HTML ID to retrieve the element by.
|
||||
* @returns {HTMLElement} The single element.
|
||||
* @throws {Error} When the 'idString' cannot be found.
|
||||
*/
|
||||
function getElementById(elementId) {
|
||||
var el = document.getElementById(elementId);
|
||||
if (el == null) {
|
||||
throw new Error("Unable to find element with id '" + elementId + "'");
|
||||
}
|
||||
|
||||
return el;
|
||||
}
|
||||
|
||||
function createElement(type, params={}) {
|
||||
var el = document.createElement(type);
|
||||
if (params.id) {el.id = params.id;}
|
||||
@ -260,4 +275,4 @@ export {sizeOfObject, clearObject, addOffset, clearEventListeners, getRandomInt,
|
||||
removeElementById, removeElement, createElement, createAccordionElement,
|
||||
appendLineBreaks,
|
||||
removeChildrenFromElement, createPopup, clearSelector, exceptionAlert,
|
||||
createProgressBarText};
|
||||
createProgressBarText, getElementById};
|
||||
|
7
utils/jsplumb.min.js
vendored
8
utils/numeral.min.js
vendored
@ -1,9 +1,12 @@
|
||||
var path = require('path');
|
||||
var webpack = require('webpack');
|
||||
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
module.exports = (env, argv) => ({
|
||||
//mode: "development",
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': argv.mode === 'development' ? "\"development\"" : "\"production\""
|
||||
}),
|
||||
// http://stackoverflow.com/questions/29080148/expose-jquery-to-real-window-object-with-webpack
|
||||
new webpack.ProvidePlugin({
|
||||
// Automtically detect jQuery and $ as free var in modules
|
||||
@ -12,26 +15,20 @@ module.exports = {
|
||||
jquery: "jquery",
|
||||
jQuery: "jquery",
|
||||
$: "jquery"
|
||||
}),
|
||||
})
|
||||
],
|
||||
target: "web",
|
||||
entry: {
|
||||
engine: "./src/engine.js",
|
||||
tests: "./tests/index.js",
|
||||
"dist/engine": "./src/engine.js",
|
||||
"tests/tests": "./tests/index.js",
|
||||
},
|
||||
devtool: "nosources-source-map",
|
||||
devtool: "source-map",
|
||||
output: {
|
||||
path: path.resolve(__dirname, "dist"),
|
||||
filename: "[name].bundle.js",
|
||||
devtoolModuleFilenameTemplate: "[id]"
|
||||
path: path.resolve(__dirname, "./"),
|
||||
filename: "[name].bundle.js"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
/* {
|
||||
test: /\.css$/,
|
||||
use: "style!css"
|
||||
}*/
|
||||
]
|
||||
rules: []
|
||||
},
|
||||
optimization: {
|
||||
removeAvailableModules: true,
|
||||
@ -51,4 +48,4 @@ module.exports = {
|
||||
devServer: {
|
||||
publicPath: "/dist",
|
||||
}
|
||||
};
|
||||
});
|
||||
|