Merge pull request #305 from danielyxie/dev

v0.38.1
This commit is contained in:
danielyxie 2018-06-15 14:18:41 -05:00 committed by GitHub
commit 30946f5993
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 7739 additions and 158654 deletions

2
.gitignore vendored

@ -2,3 +2,5 @@ Changelog.txt
Netburner.txt Netburner.txt
/node_modules /node_modules
/dist/*.map /dist/*.map
/tests/*.map
/tests/*.bundle.*

@ -486,6 +486,33 @@
width: 50%; 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%;
}
.dev-text-input {
color: var(--my-font-color);
border: 1px solid white;
background-color:black;
}
.dev-dropdown-input {
color: var(--my-font-color);
border: 1px solid white;
background-color:black;
}
/* Location */ /* Location */
#location-container { #location-container {
position: fixed; position: fixed;

@ -138,6 +138,11 @@ a:link, a:visited {
padding: 5px; padding: 5px;
margin: 5px; margin: 5px;
border: 1px solid #333333; border: 1px solid #333333;
-moz-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
-webkit-user-select: none;
} }
.a-link-button:hover { .a-link-button:hover {

10265
dist/engine.bundle.js vendored

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -387,6 +387,34 @@ ls
Returns an array with the filenames of all files on the specified server (as strings). The returned array Returns an array with the filenames of all files on the specified server (as strings). The returned array
is sorted in alphabetic order 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 hasRootAccess
^^^^^^^^^^^^^ ^^^^^^^^^^^^^

@ -1,3 +1,5 @@
.. _netscriptjs:
NetscriptJS (Netscript 2.0) NetscriptJS (Netscript 2.0)
=========================== ===========================
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that

@ -326,6 +326,8 @@
<li><a href="netscriptfunctions.html#print">print() (built-in function)</a> <li><a href="netscriptfunctions.html#print">print() (built-in function)</a>
</li> </li>
<li><a href="netscriptfunctions.html#prompt">prompt() (built-in function)</a> <li><a href="netscriptfunctions.html#prompt">prompt() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#ps">ps() (built-in function)</a>
</li> </li>
</ul></td> </ul></td>
<td style="width: 33%; vertical-align: top;"><ul> <td style="width: 33%; vertical-align: top;"><ul>

@ -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#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#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#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#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#gethostname">getHostname</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</a></li> <li class="toctree-l3"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</a></li>

@ -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#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#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#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#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#gethostname">getHostname</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html#gethackinglevel">getHackingLevel</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>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></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="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul> </ul>
<div role="search"> <div role="search">

@ -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> is sorted in alphabetic order</p>
</dd></dl> </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">&#39;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">&quot;home&quot;</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">&lt;</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">&#39; &#39;</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>
<div class="section" id="hasrootaccess"> <div class="section" id="hasrootaccess">
<h2>hasRootAccess<a class="headerlink" href="#hasrootaccess" title="Permalink to this headline"></a></h2> <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="#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="#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="#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="#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="#gethostname">getHostname</a></li>
<li class="toctree-l3"><a class="reference internal" href="#gethackinglevel">getHackingLevel</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>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></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="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul> </ul>
<div role="search"> <div role="search">

@ -52,7 +52,7 @@
<div class="body" role="main"> <div class="body" role="main">
<div class="section" id="netscriptjs-netscript-2-0"> <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 <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 allows users to write (almost) full-fledged Javascript code in their scripts, while
still being able to access the Netscript functions.</p> still being able to access the Netscript functions.</p>
@ -278,6 +278,7 @@ NetscriptJS and report any serious exploits.</p>
</li> </li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></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="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul> </ul>
<div role="search"> <div role="search">

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -387,6 +387,34 @@ ls
Returns an array with the filenames of all files on the specified server (as strings). The returned array Returns an array with the filenames of all files on the specified server (as strings). The returned array
is sorted in alphabetic order 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 hasRootAccess
^^^^^^^^^^^^^ ^^^^^^^^^^^^^

@ -1,3 +1,5 @@
.. _netscriptjs:
NetscriptJS (Netscript 2.0) NetscriptJS (Netscript 2.0)
=========================== ===========================
Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that Netscript 2.0, or Netscript JS, is the new and improved version of Netscript that

@ -88,6 +88,9 @@
<li id="options-tab" class="mainmenu-accordion-panel"> <li id="options-tab" class="mainmenu-accordion-panel">
<a id="options-menu-link"> Options </a> <a id="options-menu-link"> Options </a>
</li> </li>
<li id="dev-tab" class="mainmenu-accordion-panel">
<a id="dev-menu-link"> Dev </a>
</li>
</ul> </ul>
</div> </div>
@ -475,6 +478,58 @@
<p id="tutorial-text"> </p> <p id="tutorial-text"> </p>
</div> </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="dev-dropdown-input"></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="dev-text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="dev-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="dev-dropdown-input"></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="dev-dropdown-input"></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="dev-dropdown-input"></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="dev-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="dev-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="dev-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="dev-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="dev-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="dev-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="dev-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) --> <!-- Location (visiting a location in World) -->
<div id="location-container" class="generic-menupage-container"> <div id="location-container" class="generic-menupage-container">
<a id="location-return-to-world-button" class="a-link-button"> Return to World </a> <a id="location-return-to-world-button" class="a-link-button"> Return to World </a>
@ -821,6 +876,16 @@
<input type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites"> <input type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites">
</fieldset> </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 --> <!-- Disable Terminal and Navigation Shortcuts -->
<fieldset> <fieldset>
<label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys: <label for="settingsDisableHotkeys" class="tooltip">Disable Hotkeys:

11608
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -10,35 +10,27 @@
"acorn-dynamic-import": "^2.0.0", "acorn-dynamic-import": "^2.0.0",
"ajv": "^5.1.5", "ajv": "^5.1.5",
"ajv-keywords": "^2.0.0", "ajv-keywords": "^2.0.0",
"async": "^2.1.2", "async": "^2.6.1",
"bluebird": "^3.5.1", "bluebird": "^3.5.1",
"brace": "^0.11.1", "brace": "^0.11.1",
"decimal.js": "7.2.3", "decimal.js": "7.2.3",
"enhanced-resolve": "^3.4.0", "enhanced-resolve": "^4.0.0",
"escope": "^3.6.0", "escope": "^3.6.0",
"file-saver": "^1.3.3", "file-saver": "^1.3.8",
"interpret": "^1.0.0", "interpret": "^1.0.0",
"jquery": "^3.3.1", "jquery": "^3.3.1",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"json5": "^0.5.1",
"jsplumb": "^2.6.8", "jsplumb": "^2.6.8",
"jszip": "^3.1.5", "jszip": "^3.1.5",
"loader-runner": "^2.3.0", "loader-runner": "^2.3.0",
"loader-utils": "^1.1.0", "loader-utils": "^1.1.0",
"memory-fs": "~0.4.1", "memory-fs": "~0.4.1",
"mkdirp": "~0.5.0",
"node-libs-browser": "^2.0.0",
"numeral": "2.0.6", "numeral": "2.0.6",
"source-map": "^0.5.3",
"sprintf-js": "^1.1.1", "sprintf-js": "^1.1.1",
"supports-color": "^4.2.1", "tapable": "^1.0.0",
"tapable": "^0.2.7", "uglifyjs-webpack-plugin": "^1.2.5",
"uglifyjs-webpack-plugin": "^0.4.6",
"uuid": "^3.2.1", "uuid": "^3.2.1",
"w3c-blob": "0.0.1", "w3c-blob": "0.0.1"
"watchpack": "^1.4.0",
"webpack-sources": "^1.0.1",
"yargs": "^8.0.2"
}, },
"description": "A cyberpunk-themed incremental game", "description": "A cyberpunk-themed incremental game",
"devDependencies": { "devDependencies": {
@ -47,45 +39,36 @@
"bundle-loader": "~0.5.0", "bundle-loader": "~0.5.0",
"chai": "^4.1.2", "chai": "^4.1.2",
"chai-as-promised": "^7.1.1", "chai-as-promised": "^7.1.1",
"codacy-coverage": "^2.0.1", "css-loader": "^0.28.11",
"codecov.io": "^0.1.2",
"coffee-loader": "~0.7.1",
"coffee-script": "^1.10.0",
"coveralls": "^2.11.2",
"css-loader": "^0.28.3",
"es6-promise-polyfill": "^1.1.1", "es6-promise-polyfill": "^1.1.1",
"eslint": "^4.3.0", "eslint": "^4.19.1",
"eslint-plugin-node": "^5.1.1", "eslint-plugin-node": "^6.0.1",
"express": "~4.13.1", "file-loader": "^1.1.11",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^0.11.2",
"i18n-webpack-plugin": "^1.0.0", "i18n-webpack-plugin": "^1.0.0",
"istanbul": "^0.4.5", "istanbul": "^0.4.5",
"jade": "^1.11.0",
"jade-loader": "~0.8.0",
"js-beautify": "^1.5.10", "js-beautify": "^1.5.10",
"less": "^2.5.1", "json5": "^1.0.1",
"less-loader": "^4.0.3", "less": "^3.0.4",
"lodash": "^4.17.4", "less-loader": "^4.1.0",
"lodash": "^4.17.10",
"mkdirp": "^0.5.1",
"mocha": "^3.2.0", "mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.0.0", "mocha-lcov-reporter": "^1.0.0",
"nsp": "^2.6.1", "nsp": "^3.2.1",
"raw-loader": "~0.5.0", "raw-loader": "~0.5.0",
"react": "^15.2.1",
"react-dom": "^15.2.1",
"script-loader": "~0.7.0", "script-loader": "~0.7.0",
"should": "^11.1.1", "should": "^11.1.1",
"simple-git": "^1.65.0", "simple-git": "^1.96.0",
"sinon": "^2.3.2", "sinon": "^2.3.2",
"style-loader": "^0.18.1", "source-map": "^0.7.3",
"url-loader": "~0.5.0", "style-loader": "^0.21.0",
"val-loader": "^1.0.2", "url-loader": "^1.0.1",
"vm-browserify": "~0.0.0", "watchpack": "^1.6.0",
"webpack": "^4.1.1", "webpack": "^4.12.0",
"webpack-cli": "^2.0.12", "webpack-cli": "^3.0.4",
"webpack-dev-middleware": "^1.9.0", "webpack-dev-middleware": "^3.1.3",
"webpack-dev-server": "^3.1.4", "webpack-dev-server": "^3.1.4",
"worker-loader": "^0.8.0" "worker-loader": "^2.0.0"
}, },
"engines": { "engines": {
"node": ">=4.3.0 <5.0.0 || >=5.10" "node": ">=4.3.0 <5.0.0 || >=5.10"
@ -98,7 +81,11 @@
"url": "git+https://github.com/danielyxie/bitburner.git" "url": "git+https://github.com/danielyxie/bitburner.git"
}, },
"scripts": { "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" "version": "0.35.1"
} }

@ -231,7 +231,8 @@ let MaterialSizes = {
Chemicals: 0.05, Chemicals: 0.05,
Drugs: 0.02, Drugs: 0.02,
Robots: 0.5, Robots: 0.5,
"AICores": 0.1 AICores: 0.1,
RealEstate: 0,
} }
function Product(params={}) { 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 //If Market Research upgrades are unlocked, add competition and demand info
var cmpAndDmdText = ""; var cmpAndDmdText = "";
if (company.unlockUpgrades[2] === 1) { if (company.unlockUpgrades[2] === 1) {
cmpAndDmdText += "<br>Competition: " + formatNumber(mat.cmp, 3); cmpAndDmdText += "<br>Demand: " + formatNumber(mat.dmd, 3);
} }
if (company.unlockUpgrades[3] === 1) { 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) + var innerTxt = "<p class='tooltip'>" + mat.name + ": " + formatNumber(mat.qty, 3) +
"(" + formatNumber(totalGain, 3) + "/s)" + "(" + formatNumber(totalGain, 3) + "/s)" +
@ -2695,11 +2696,12 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
//Completed products //Completed products
var cmpAndDmdText = ""; var cmpAndDmdText = "";
if (company.unlockUpgrades[2] === 1) { if (company.unlockUpgrades[2] === 1) {
cmpAndDmdText += "<br>Competition: " + formatNumber(product.cmp, 3);
}
if (company.unlockUpgrades[3] === 1) {
cmpAndDmdText += "<br>Demand: " + formatNumber(product.dmd, 3); 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 var totalGain = product.data[city][1] - product.data[city][2]; //Production - sale
div.appendChild(createElement("p", { div.appendChild(createElement("p", {
innerHTML: "<p class='tooltip'>" + product.name + ": " + formatNumber(product.data[city][0], 3) + //Quantity innerHTML: "<p class='tooltip'>" + product.name + ": " + formatNumber(product.data[city][0], 3) + //Quantity

@ -1,5 +1,5 @@
let CONSTANTS = { let CONSTANTS = {
Version: "0.38.0", Version: "0.38.1",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -43,6 +43,7 @@ let CONSTANTS = {
/* Netscript Constants */ /* Netscript Constants */
//RAM Costs for different commands //RAM Costs for different commands
ScriptBaseRamCost: 1.4, ScriptBaseRamCost: 1.4,
ScriptDomRamCost: 100,
ScriptWhileRamCost: 0.2, ScriptWhileRamCost: 0.2,
ScriptForRamCost: 0.2, ScriptForRamCost: 0.2,
ScriptIfRamCost: 0.15, ScriptIfRamCost: 0.15,
@ -488,20 +489,19 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>", "World Stock Exchange account and TIX API Access<br>",
LatestUpdate: LatestUpdate:
"v0.38.0<br>" + "v0.38.1<br>" +
"* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame<br>" + "* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS<br>" +
"* Bladeburner Changes:<br>" + "* Implemented by Github user hydroflame:<br>" +
"*** Bladeburner progress is no longer reset when installing Augmentations<br>" + "*** Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)<br>" +
"*** The number of successess needed to increase a Contract/Operation's max level now scales with the current max level (gradually gets harder)<br>" + "*** Added game option to suppress travel confirmation<br>" +
"*** All Bladeburner Augmentations are now slightly more expensive and require more reputation<br>" + "*** Text on buttons can no longer be highlighted<br>" +
"*** Black Operations now give higher rank rewards<br>" + "*** Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations<br>" +
"*** Doubled the base amount of money gained from Contracts<br>" + "*** Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)<br>" +
"*** Increased the amount of experience gained from Contracts/Actions<br>" + "*** Added ps() Netscript function<br>" +
"*** Added a new Augmentation: The Blade's Simulacrum<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>" +
"*** Bladeburner faction reputation gain is now properly affected by favor<br>" + "*** Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips<br>" +
"* Hacking is now slightly less profitable in BitNode-3<br>" + "*** Bug Fix: Sever's security level should now properly increase when its money is grown to max value"
"* Updated Hacknet Nodes UI - Implemented by Github user kopelli<br>" +
"* Bug Fix: Fixed an exploit that allowed calling any Netscript function without incurring any RAM Cost in NetscriptJS<br>"
} }
export {CONSTANTS}; export {CONSTANTS};

@ -11,6 +11,7 @@ import {Player} from "./Player.js";
import {Server, AllServers, AddToAllServers} from "./Server.js"; import {Server, AllServers, AddToAllServers} from "./Server.js";
import {purchaseServer, import {purchaseServer,
purchaseRamForHomeComputer} from "./ServerPurchases.js"; purchaseRamForHomeComputer} from "./ServerPurchases.js";
import {Settings} from "./Settings.js";
import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js"; import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js";
import {dialogBoxCreate} from "../utils/DialogBox.js"; import {dialogBoxCreate} from "../utils/DialogBox.js";
@ -278,7 +279,10 @@ function displayLocationContent() {
purchase256gb.innerHTML = "Purchase 256GB Server - $" + formatNumber(256*CONSTANTS.BaseCostFor1GBOfRamServer, 2); purchase256gb.innerHTML = "Purchase 256GB Server - $" + formatNumber(256*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
purchase512gb.innerHTML = "Purchase 512GB Server - $" + formatNumber(512*CONSTANTS.BaseCostFor1GBOfRamServer, 2); purchase512gb.innerHTML = "Purchase 512GB Server - $" + formatNumber(512*CONSTANTS.BaseCostFor1GBOfRamServer, 2);
purchase1tb.innerHTML = "Purchase 1TB Server - $" + formatNumber(1024*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); purchaseTor.innerHTML = "Purchase TOR Router - $" + formatNumber(CONSTANTS.TorRouterCost, 2);
}
travelAgencyText.style.display = "none"; travelAgencyText.style.display = "none";
travelToAevum.style.display = "none"; travelToAevum.style.display = "none";
@ -326,9 +330,9 @@ function displayLocationContent() {
repGain = repGain[0]; repGain = repGain[0];
jobReputation.innerHTML = "Company reputation: " + formatNumber(company.playerReputation, 4) + jobReputation.innerHTML = "Company reputation: " + formatNumber(company.playerReputation, 4) +
"<span class='tooltiptext'>You will earn " + "<span class='tooltiptext'>You will earn " +
formatNumber(repGain, 4) + formatNumber(repGain, 0) +
" faction favor upon resetting after installing an Augmentation</span>"; " 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 " + "<span class='tooltiptext'>Company favor increases the rate at which " +
"you earn reputation for this company by 1% per favor. Company favor " + "you earn reputation for this company by 1% per favor. Company favor " +
"is gained whenever you reset after installing an Augmentation. The amount of " + "is gained whenever you reset after installing an Augmentation. The amount of " +
@ -2002,11 +2006,13 @@ function purchaseTorRouter() {
AddToAllServers(darkweb); AddToAllServers(darkweb);
SpecialServerIps.addIp("Darkweb Server", darkweb.ip); 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); Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
darkweb.serversOnNetwork.push(Player.getHomeComputer().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) { function displayUniversityLocationContent(costMult) {
@ -2144,6 +2150,10 @@ function setJobRequirementTooltip(loc, entryPosType, btn) {
} }
function travelBoxCreate(destCityName, cost) { function travelBoxCreate(destCityName, cost) {
if(Settings.SuppressTravelConfirmation) {
travelToCity(destCityName, cost);
return;
}
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton(); var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
yesBtn.innerHTML = "Yes"; yesBtn.innerHTML = "Yes";
noBtn.innerHTML = "No"; noBtn.innerHTML = "No";

@ -833,7 +833,9 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
return Promise.resolve(false); return Promise.resolve(false);
} else { } else {
//Able to run script //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..."); 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); var runningScriptObj = new RunningScript(script, args);
runningScriptObj.threads = threads; runningScriptObj.threads = threads;
server.runningScripts.push(runningScriptObj); //Push onto runningScripts server.runningScripts.push(runningScriptObj); //Push onto runningScripts

@ -14,6 +14,7 @@ import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js"; import {Programs} from "./CreateProgram.js";
import {parseDarkwebItemPrice, DarkWebItems} from "./DarkWeb.js"; import {parseDarkwebItemPrice, DarkWebItems} from "./DarkWeb.js";
import {Engine} from "./engine.js"; import {Engine} from "./engine.js";
import {AllGangs} from "./Gang.js";
import {Factions, Faction, joinFaction, import {Factions, Faction, joinFaction,
factionExists, purchaseAugmentation} from "./Faction.js"; factionExists, purchaseAugmentation} from "./Faction.js";
import {getCostOfNextHacknetNode, purchaseHacknet} from "./HacknetNode.js"; import {getCostOfNextHacknetNode, purchaseHacknet} from "./HacknetNode.js";
@ -80,6 +81,8 @@ var possibleLogs = {
relaysmtp: true, relaysmtp: true,
httpworm: true, httpworm: true,
sqlinject: true, sqlinject: true,
run:true,
exec:true,
spawn: true, spawn: true,
kill: true, kill: true,
killall: true, killall: true,
@ -308,8 +311,10 @@ function NetscriptFunctions(workerScript) {
} }
return netscriptDelay(growTime, workerScript).then(function() { return netscriptDelay(growTime, workerScript).then(function() {
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);} if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
const moneyBefore = server.moneyAvailable;
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
var growthPercentage = processSingleServerGrowth(server, 450 * threads); var growthPercentage = processSingleServerGrowth(server, 450 * threads);
const moneyAfter = server.moneyAvailable;
workerScript.scriptRef.recordGrow(server.ip, threads); workerScript.scriptRef.recordGrow(server.ip, threads);
var expGain = scriptCalculateExpGain(server) * threads; var expGain = scriptCalculateExpGain(server) * threads;
if (growthPercentage == 1) { if (growthPercentage == 1) {
@ -317,12 +322,12 @@ function NetscriptFunctions(workerScript) {
} }
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.grow == null) { if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.grow == null) {
workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " + workerScript.scriptRef.log("Available money on " + server.hostname + " grown by " +
formatNumber(growthPercentage*100 - 100, 6) + "%. Gained " + formatNumber((moneyAfter/moneyBefore)*100 - 100, 6) + "%. Gained " +
formatNumber(expGain, 4) + " hacking exp (t=" + threads +")"); formatNumber(expGain, 4) + " hacking exp (t=" + threads +")");
} }
workerScript.scriptRef.onlineExpGained += expGain; workerScript.scriptRef.onlineExpGained += expGain;
Player.gainHackingExp(expGain); Player.gainHackingExp(expGain);
return Promise.resolve(growthPercentage); return Promise.resolve(moneyAfter/moneyBefore);
}); });
}, },
weaken : function(ip){ weaken : function(ip){
@ -948,6 +953,23 @@ function NetscriptFunctions(workerScript) {
allFiles.sort(); allFiles.sort();
return allFiles; return allFiles;
}, },
ps : function(ip=workerScript.serverIp) {
if (workerScript.checkingRam) {
return updateStaticRam("ps", CONSTANTS.ScriptScanRamCost);
}
updateDynamicRam("ps", CONSTANTS.ScriptScanRamCost);
var server = getServer(ip);
if (server == null){
workerScript.scriptRef.log("ps() failed. Invalid IP or hostname passed in: " + ip);
throw makeRuntimeRejectMsg(workerScript, "ps() failed. Invalid IP or hostname passed in: " + ip);
}
const processes = [];
for(const i in server.runningScripts) {
const script = server.runningScripts[i];
processes.push({filename:script.filename, threads: script.threads, args: script.args.slice()})
}
return processes;
},
hasRootAccess : function(ip) { hasRootAccess : function(ip) {
if (workerScript.checkingRam) { if (workerScript.checkingRam) {
return updateStaticRam("hasRootAccess", CONSTANTS.ScriptHasRootAccessRamCost); return updateStaticRam("hasRootAccess", CONSTANTS.ScriptHasRootAccessRamCost);
@ -2272,7 +2294,9 @@ function NetscriptFunctions(workerScript) {
AddToAllServers(darkweb); AddToAllServers(darkweb);
SpecialServerIps.addIp("Darkweb Server", darkweb.ip); 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); Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
darkweb.serversOnNetwork.push(Player.getHomeComputer().ip); darkweb.serversOnNetwork.push(Player.getHomeComputer().ip);
@ -2777,6 +2801,12 @@ function NetscriptFunctions(workerScript) {
} }
} }
// if the player is in a gang and the target faction is any of the gang faction, fail
if(Player.inGang() && AllGangs[name] !== undefined) {
workerScript.scriptRef.log("ERROR: Faction specified in workForFaction() does not offer work at the moment.");
return;
}
if (inMission) { if (inMission) {
workerScript.scriptRef.log("ERROR: workForFaction() failed because you are in the middle of a mission."); workerScript.scriptRef.log("ERROR: workForFaction() failed because you are in the middle of a mission.");
return; return;

@ -413,6 +413,14 @@ PlayerObject.prototype.getUpgradeHomeRamCost = function() {
return cost; 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 //Calculates skill level based on experience. The same formula will be used for every skill
PlayerObject.prototype.calculateSkill = function(exp) { PlayerObject.prototype.calculateSkill = function(exp) {
return Math.max(Math.floor(32 * Math.log(exp + 534.5) - 200), 1); return Math.max(Math.floor(32 * Math.log(exp + 534.5) - 200), 1);
@ -579,6 +587,9 @@ PlayerObject.prototype.gainHackingExp = function(exp) {
console.log("ERR: NaN passed into Player.gainHackingExp()"); return; console.log("ERR: NaN passed into Player.gainHackingExp()"); return;
} }
this.hacking_exp += exp; this.hacking_exp += exp;
if(this.hacking_exp < 0) {
this.hacking_exp = 0;
}
} }
PlayerObject.prototype.gainStrengthExp = function(exp) { PlayerObject.prototype.gainStrengthExp = function(exp) {
@ -586,6 +597,9 @@ PlayerObject.prototype.gainStrengthExp = function(exp) {
console.log("ERR: NaN passed into Player.gainStrengthExp()"); return; console.log("ERR: NaN passed into Player.gainStrengthExp()"); return;
} }
this.strength_exp += exp; this.strength_exp += exp;
if(this.strength_exp < 0) {
this.strength_exp = 0;
}
} }
PlayerObject.prototype.gainDefenseExp = function(exp) { PlayerObject.prototype.gainDefenseExp = function(exp) {
@ -593,6 +607,9 @@ PlayerObject.prototype.gainDefenseExp = function(exp) {
console.log("ERR: NaN passed into player.gainDefenseExp()"); return; console.log("ERR: NaN passed into player.gainDefenseExp()"); return;
} }
this.defense_exp += exp; this.defense_exp += exp;
if(this.defense_exp < 0) {
this.defense_exp = 0;
}
} }
PlayerObject.prototype.gainDexterityExp = function(exp) { PlayerObject.prototype.gainDexterityExp = function(exp) {
@ -600,6 +617,9 @@ PlayerObject.prototype.gainDexterityExp = function(exp) {
console.log("ERR: NaN passed into Player.gainDexterityExp()"); return; console.log("ERR: NaN passed into Player.gainDexterityExp()"); return;
} }
this.dexterity_exp += exp; this.dexterity_exp += exp;
if(this.dexterity_exp < 0) {
this.dexterity_exp = 0;
}
} }
PlayerObject.prototype.gainAgilityExp = function(exp) { PlayerObject.prototype.gainAgilityExp = function(exp) {
@ -607,6 +627,9 @@ PlayerObject.prototype.gainAgilityExp = function(exp) {
console.log("ERR: NaN passed into Player.gainAgilityExp()"); return; console.log("ERR: NaN passed into Player.gainAgilityExp()"); return;
} }
this.agility_exp += exp; this.agility_exp += exp;
if(this.agility_exp < 0) {
this.agility_exp = 0;
}
} }
PlayerObject.prototype.gainCharismaExp = function(exp) { PlayerObject.prototype.gainCharismaExp = function(exp) {
@ -614,6 +637,9 @@ PlayerObject.prototype.gainCharismaExp = function(exp) {
console.log("ERR: NaN passed into Player.gainCharismaExp()"); return; console.log("ERR: NaN passed into Player.gainCharismaExp()"); return;
} }
this.charisma_exp += exp; this.charisma_exp += exp;
if(this.charisma_exp < 0) {
this.charisma_exp = 0;
}
} }
PlayerObject.prototype.gainIntelligenceExp = function(exp) { PlayerObject.prototype.gainIntelligenceExp = function(exp) {
@ -2315,6 +2341,25 @@ PlayerObject.prototype.setBitNodeNumber = function(n) {
this.bitNodeN = 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 */ /* Functions for saving and loading the Player data */
function loadPlayer(saveString) { function loadPlayer(saveString) {
Player = JSON.parse(saveString, Reviver); Player = JSON.parse(saveString, Reviver);

@ -448,6 +448,7 @@ function parseOnlyRamCalculate(server, code, workerScript) {
if (ref == specialReferenceFOR) ram += CONSTANTS.ScriptForRamCost; if (ref == specialReferenceFOR) ram += CONSTANTS.ScriptForRamCost;
if (ref == specialReferenceWHILE) ram += CONSTANTS.ScriptWhileRamCost; if (ref == specialReferenceWHILE) ram += CONSTANTS.ScriptWhileRamCost;
if (ref == "hacknetnodes") ram += CONSTANTS.ScriptHacknetNodesRamCost; 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 // 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 // get its RAM cost. We do this by calling it, which works because the running script
@ -508,11 +509,15 @@ function parseOnlyCalculateDeps(code, currentModule) {
s.add(name); // For builtins like hack. 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. // 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. // walkDeeper is for doing recursive walks of expressions in composites that we handle.
function commonVisitors() { function commonVisitors() {
return { return {
Identifier: (node, st, walkDeeper) => { Identifier: (node, st, walkDeeper) => {
if (objectPrototypeProperties.includes(node.name)) {return;}
addRef(st.key, node.name); addRef(st.key, node.name);
}, },
WhileStatement: (node, st, walkDeeper) => { 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 //Applied server growth for a single server. Returns the percentage growth
function processSingleServerGrowth(server, numCycles) { function processSingleServerGrowth(server, numCycles) {
//Server growth processed once every 450 game cycles //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 //Get adjusted growth rate, which accounts for server security
var growthRate = CONSTANTS.ServerBaseGrowthRate; const growthRate = CONSTANTS.ServerBaseGrowthRate;
var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty; var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty;
if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;} if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;}
//Calculate adjusted server growth rate based on parameters //Calculate adjusted server growth rate based on parameters
var serverGrowthPercentage = server.serverGrowth / 100; const serverGrowthPercentage = server.serverGrowth / 100;
var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate; const numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
//Apply serverGrowth for the calculated number of growth cycles //Apply serverGrowth for the calculated number of growth cycles
var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult); var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult);
@ -789,19 +801,26 @@ function processSingleServerGrowth(server, numCycles) {
serverGrowth = 1; serverGrowth = 1;
} }
var oldMoneyAvailable = server.moneyAvailable; const oldMoneyAvailable = server.moneyAvailable;
server.moneyAvailable *= serverGrowth; server.moneyAvailable *= serverGrowth;
// in case of data corruption
if (server.moneyMax && isNaN(server.moneyAvailable)) { if (server.moneyMax && isNaN(server.moneyAvailable)) {
server.moneyAvailable = server.moneyMax; server.moneyAvailable = server.moneyMax;
} }
// cap at max
if (server.moneyMax && server.moneyAvailable > server.moneyMax) { if (server.moneyMax && server.moneyAvailable > 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 //Growing increases server security twice as much as hacking
server.fortify(2 * CONSTANTS.ServerFortifyAmount * numServerGrowthCycles); const usedCycles = numCycleForGrowth(server, server.moneyAvailable / oldMoneyAvailable);
return serverGrowth; server.fortify(2 * CONSTANTS.ServerFortifyAmount * Math.ceil(usedCycles));
}
return server.moneyAvailable / oldMoneyAvailable;
} }
function prestigeHomeComputer(homeComp) { function prestigeHomeComputer(homeComp) {
@ -873,9 +892,11 @@ function GetServerByHostname(hostname) {
function getServer(s) { function getServer(s) {
if (!isValidIPAddress(s)) { if (!isValidIPAddress(s)) {
return GetServerByHostname(s); return GetServerByHostname(s);
} else { }
if(AllServers[s] !== undefined) {
return AllServers[s]; return AllServers[s];
} }
return null;
} }
//Debugging tool //Debugging tool

@ -7,6 +7,7 @@ let Settings = {
MaxPortCapacity: 50, MaxPortCapacity: 50,
SuppressMessages: false, SuppressMessages: false,
SuppressFactionInvites: false, SuppressFactionInvites: false,
SuppressTravelConfirmation: false,
AutosaveInterval: 60, AutosaveInterval: 60,
DisableHotkeys: false, DisableHotkeys: false,
ThemeHighlightColor: "#ffffff", ThemeHighlightColor: "#ffffff",
@ -26,6 +27,7 @@ function initSettings() {
Settings.MaxPortCapacity = 50; Settings.MaxPortCapacity = 50;
Settings.SuppressMessages = false; Settings.SuppressMessages = false;
Settings.SuppressFactionInvites = false; Settings.SuppressFactionInvites = false;
Settings.SuppressTravelConfirmation = false,
Settings.AutosaveInterval = 60; Settings.AutosaveInterval = 60;
Settings.DisableHotkeys = false; Settings.DisableHotkeys = false;
} }
@ -36,6 +38,7 @@ function setSettingsLabels() {
var nsPortLimit = document.getElementById("settingsNSPortRangeValLabel"); var nsPortLimit = document.getElementById("settingsNSPortRangeValLabel");
var suppressMsgs = document.getElementById("settingsSuppressMessages"); var suppressMsgs = document.getElementById("settingsSuppressMessages");
var suppressFactionInv = document.getElementById("settingsSuppressFactionInvites") var suppressFactionInv = document.getElementById("settingsSuppressFactionInvites")
var suppressTravelConfirmation = document.getElementById("settingsSuppressTravelConfirmation");
var autosaveInterval = document.getElementById("settingsAutosaveIntervalValLabel"); var autosaveInterval = document.getElementById("settingsAutosaveIntervalValLabel");
var disableHotkeys = document.getElementById("settingsDisableHotkeys"); var disableHotkeys = document.getElementById("settingsDisableHotkeys");
@ -45,6 +48,7 @@ function setSettingsLabels() {
nsPortLimit.innerHTML = Settings.MaxPortCapacity; nsPortLimit.innerHTML = Settings.MaxPortCapacity;
suppressMsgs.checked = Settings.SuppressMessages; suppressMsgs.checked = Settings.SuppressMessages;
suppressFactionInv.checked = Settings.SuppressFactionInvites; suppressFactionInv.checked = Settings.SuppressFactionInvites;
suppressTravelConfirmation.checked = Settings.SuppressTravelConfirmation;
autosaveInterval.innerHTML = Settings.AutosaveInterval; autosaveInterval.innerHTML = Settings.AutosaveInterval;
disableHotkeys.checked = Settings.DisableHotkeys; disableHotkeys.checked = Settings.DisableHotkeys;
@ -91,6 +95,10 @@ function setSettingsLabels() {
Settings.SuppressFactionInvites = this.checked; Settings.SuppressFactionInvites = this.checked;
}; };
suppressTravelConfirmation.onclick = function() {
Settings.SuppressTravelConfirmation = this.checked;
};
disableHotkeys.onclick = function() { disableHotkeys.onclick = function() {
Settings.DisableHotkeys = this.checked; Settings.DisableHotkeys = this.checked;
} }

@ -12,7 +12,8 @@ import {loxBoxCreate, logBoxUpdateText,
import {updateActiveScriptsItems} from "./ActiveScriptsUI.js"; import {updateActiveScriptsItems} from "./ActiveScriptsUI.js";
import {Augmentations, installAugmentations, import {Augmentations, installAugmentations,
initAugmentations, AugmentationNames, initAugmentations, AugmentationNames,
displayAugmentationsContent} from "./Augmentations.js"; displayAugmentationsContent,
PlayerOwnedAugmentation} from "./Augmentations.js";
import {BitNodes, initBitNodes, import {BitNodes, initBitNodes,
initBitNodeMultipliers} from "./BitNode.js"; initBitNodeMultipliers} from "./BitNode.js";
import {Bladeburner} from "./Bladeburner.js"; import {Bladeburner} from "./Bladeburner.js";
@ -44,13 +45,14 @@ import {updateOnlineScriptTimes,
import {Player} from "./Player.js"; import {Player} from "./Player.js";
import {prestigeAugmentation, import {prestigeAugmentation,
prestigeSourceFile} from "./Prestige.js"; prestigeSourceFile} from "./Prestige.js";
import {redPillFlag} from "./RedPill.js"; import {redPillFlag, hackWorldDaemon} from "./RedPill.js";
import {saveObject, loadGame} from "./SaveObject.js"; import {saveObject, loadGame} from "./SaveObject.js";
import {loadAllRunningScripts, scriptEditorInit, import {loadAllRunningScripts, scriptEditorInit,
updateScriptEditorContent} from "./Script.js"; updateScriptEditorContent} from "./Script.js";
import {AllServers, Server, initForeignServers} from "./Server.js"; import {AllServers, Server, initForeignServers} from "./Server.js";
import {Settings, setSettingsLabels} from "./Settings.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 {SpecialServerIps, initSpecialServerIps} from "./SpecialServerIps.js";
import {StockMarket, StockSymbols, import {StockMarket, StockSymbols,
SymbolToStockMap, initStockSymbols, SymbolToStockMap, initStockSymbols,
@ -145,6 +147,7 @@ let Engine = {
factionsMainMenuButton: null, factionsMainMenuButton: null,
augmentationsMainMenuButton: null, augmentationsMainMenuButton: null,
tutorialMainMenuButton: null, tutorialMainMenuButton: null,
devMainMenuButton: null,
saveMainMenuButton: null, saveMainMenuButton: null,
deleteMainMenuButton: null, deleteMainMenuButton: null,
@ -158,6 +161,41 @@ let Engine = {
tutorialFactionsButton: null, tutorialFactionsButton: null,
tutorialAugmentationsButton: null, tutorialAugmentationsButton: null,
tutorialBackButton: 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 //Display objects
@ -183,6 +221,7 @@ let Engine = {
factionAugmentationsContent: null, factionAugmentationsContent: null,
augmentationsContent: null, augmentationsContent: null,
tutorialContent: null, tutorialContent: null,
devMenuContent: null,
infiltrationContent: null, infiltrationContent: null,
stockMarketContent: null, stockMarketContent: null,
locationContent: null, locationContent: null,
@ -208,6 +247,7 @@ let Engine = {
Faction: "Faction", Faction: "Faction",
Augmentations: "Augmentations", Augmentations: "Augmentations",
Tutorial: "Tutorial", Tutorial: "Tutorial",
DevMenu: "Dev Menu",
Location: "Location", Location: "Location",
workInProgress: "WorkInProgress", workInProgress: "WorkInProgress",
RedPill: "RedPill", RedPill: "RedPill",
@ -319,6 +359,14 @@ let Engine = {
document.getElementById("tutorial-menu-link").classList.add("active"); 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() { loadLocationContent: function() {
Engine.hideAllContent(); Engine.hideAllContent();
Engine.Display.locationContent.style.display = "block"; Engine.Display.locationContent.style.display = "block";
@ -455,6 +503,7 @@ let Engine = {
Engine.Display.factionAugmentationsContent.style.display = "none"; Engine.Display.factionAugmentationsContent.style.display = "none";
Engine.Display.augmentationsContent.style.display = "none"; Engine.Display.augmentationsContent.style.display = "none";
Engine.Display.tutorialContent.style.display = "none"; Engine.Display.tutorialContent.style.display = "none";
Engine.Display.devMenuContent.style.display = "none";
Engine.Display.locationContent.style.display = "none"; Engine.Display.locationContent.style.display = "none";
Engine.Display.workInProgressContent.style.display = "none"; Engine.Display.workInProgressContent.style.display = "none";
Engine.Display.redPillContent.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("city-menu-link").classList.remove("active");
document.getElementById("tutorial-menu-link").classList.remove("active"); document.getElementById("tutorial-menu-link").classList.remove("active");
document.getElementById("options-menu-link").classList.remove("active"); document.getElementById("options-menu-link").classList.remove("active");
document.getElementById("dev-menu-link").classList.remove("active");
}, },
displayCharacterOverviewInfo: function() { displayCharacterOverviewInfo: function() {
@ -784,6 +834,43 @@ let Engine = {
document.getElementById("tutorial-text").style.display = "none"; 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 //Displays the text when a section of the Tutorial is opened
displayTutorialPage: function(text) { displayTutorialPage: function(text) {
document.getElementById("tutorial-getting-started-link").style.display = "none"; document.getElementById("tutorial-getting-started-link").style.display = "none";
@ -1182,6 +1269,7 @@ let Engine = {
var job = document.getElementById("job-tab"); var job = document.getElementById("job-tab");
var tutorial = document.getElementById("tutorial-tab"); var tutorial = document.getElementById("tutorial-tab");
var options = document.getElementById("options-tab"); var options = document.getElementById("options-tab");
var dev = document.getElementById("dev-tab");
//Load game from save or create new game //Load game from save or create new game
if (loadGame(saveString)) { if (loadGame(saveString)) {
@ -1258,7 +1346,7 @@ let Engine = {
formatNumber(offlineProductionFromHacknetNodes, 2)); formatNumber(offlineProductionFromHacknetNodes, 2));
//Close main menu accordions for loaded game //Close main menu accordions for loaded game
var visibleMenuTabs = [terminal, createScript, activeScripts, stats, var visibleMenuTabs = [terminal, createScript, activeScripts, stats,
hacknetnodes, city, tutorial, options]; hacknetnodes, city, tutorial, options, dev];
if (Player.firstFacInvRecvd) {visibleMenuTabs.push(factions);} if (Player.firstFacInvRecvd) {visibleMenuTabs.push(factions);}
else {factions.style.display = "none";} else {factions.style.display = "none";}
if (Player.firstAugPurchased) {visibleMenuTabs.push(augmentations);} if (Player.firstAugPurchased) {visibleMenuTabs.push(augmentations);}
@ -1312,7 +1400,7 @@ let Engine = {
Engine.openMainMenuHeader( Engine.openMainMenuHeader(
[terminal, createScript, activeScripts, stats, [terminal, createScript, activeScripts, stats,
hacknetnodes, city, hacknetnodes, city,
tutorial, options] tutorial, options, dev]
); );
//Start interactive tutorial //Start interactive tutorial
@ -1365,6 +1453,9 @@ let Engine = {
Engine.Display.tutorialContent = document.getElementById("tutorial-container"); Engine.Display.tutorialContent = document.getElementById("tutorial-container");
Engine.Display.tutorialContent.style.display = "none"; 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 = document.getElementById("infiltration-container");
Engine.Display.infiltrationContent.style.display = "none"; Engine.Display.infiltrationContent.style.display = "none";
@ -1452,9 +1543,195 @@ let Engine = {
Engine.displayTutorialContent(); 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 DarkWeb already purchased, disable the button
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) { 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";
} }
}, },
@ -1549,16 +1826,16 @@ let Engine = {
var options = document.getElementById("options-tab"); var options = document.getElementById("options-tab");
var optionsLink = document.getElementById("options-menu-link"); var optionsLink = document.getElementById("options-menu-link");
this.classList.toggle("opened"); 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) { if (tutorial.style.maxHeight) {
Engine.toggleMainMenuHeader(false, Engine.toggleMainMenuHeader(false, elems, links);
[tutorial, options],
[tutorialLink, optionsLink]
);
} else { } else {
Engine.toggleMainMenuHeader(true, Engine.toggleMainMenuHeader(true, elems, links);
[tutorial, options],
[tutorialLink, optionsLink]
);
} }
} }
@ -1636,6 +1913,12 @@ let Engine = {
return false; return false;
}); });
Engine.Clickables.devMainMenuButton = clearEventListeners("dev-menu-link");
Engine.Clickables.devMainMenuButton.addEventListener("click", function() {
Engine.loadDevMenuContent();
return false;
});
//Active scripts list //Active scripts list
Engine.ActiveScriptsList = document.getElementById("active-scripts-list"); Engine.ActiveScriptsList = document.getElementById("active-scripts-list");

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,9 +1,12 @@
var path = require('path'); var path = require('path');
var webpack = require('webpack'); var webpack = require('webpack');
module.exports = { module.exports = (env, argv) => ({
mode: "development", //mode: "development",
plugins: [ 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 // http://stackoverflow.com/questions/29080148/expose-jquery-to-real-window-object-with-webpack
new webpack.ProvidePlugin({ new webpack.ProvidePlugin({
// Automtically detect jQuery and $ as free var in modules // Automtically detect jQuery and $ as free var in modules
@ -12,7 +15,7 @@ module.exports = {
jquery: "jquery", jquery: "jquery",
jQuery: "jquery", jQuery: "jquery",
$: "jquery" $: "jquery"
}), })
], ],
target: "web", target: "web",
entry: { entry: {
@ -25,12 +28,7 @@ module.exports = {
filename: "[name].bundle.js" filename: "[name].bundle.js"
}, },
module: { module: {
rules: [ rules: []
/* {
test: /\.css$/,
use: "style!css"
}*/
]
}, },
optimization: { optimization: {
removeAvailableModules: true, removeAvailableModules: true,
@ -50,4 +48,4 @@ module.exports = {
devServer: { devServer: {
publicPath: "/dist", publicPath: "/dist",
} }
}; });