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
/node_modules
/dist/*.map
/tests/*.map
/tests/*.bundle.*

@ -486,6 +486,33 @@
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-container {
position: fixed;

@ -138,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 {

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
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

@ -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>

@ -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>

@ -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">

@ -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">&#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 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">

@ -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">

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
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

@ -88,6 +88,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>
@ -475,6 +478,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="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) -->
<div id="location-container" class="generic-menupage-container">
<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">
</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:

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",
"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",
"numeral": "2.0.6",
"source-map": "^0.5.3",
"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": {
@ -47,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"
@ -98,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"
}

@ -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)" +
@ -2695,11 +2696,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

@ -1,5 +1,5 @@
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
//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 */
//RAM Costs for different commands
ScriptBaseRamCost: 1.4,
ScriptDomRamCost: 100,
ScriptWhileRamCost: 0.2,
ScriptForRamCost: 0.2,
ScriptIfRamCost: 0.15,
@ -488,20 +489,19 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.38.0<br>" +
"* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame<br>" +
"* Bladeburner Changes:<br>" +
"*** Bladeburner progress is no longer reset when installing Augmentations<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>" +
"*** All Bladeburner Augmentations are now slightly more expensive and require more reputation<br>" +
"*** Black Operations now give higher rank rewards<br>" +
"*** Doubled the base amount of money gained from Contracts<br>" +
"*** Increased the amount of experience gained from Contracts/Actions<br>" +
"*** Added a new Augmentation: The Blade's Simulacrum<br>" +
"*** Bladeburner faction reputation gain is now properly affected by favor<br>" +
"* Hacking is now slightly less profitable in BitNode-3<br>" +
"* 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>"
"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};

@ -11,6 +11,7 @@ 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";
@ -278,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";
@ -326,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 " +
@ -2002,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) {
@ -2144,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

@ -14,6 +14,7 @@ import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {parseDarkwebItemPrice, DarkWebItems} from "./DarkWeb.js";
import {Engine} from "./engine.js";
import {AllGangs} from "./Gang.js";
import {Factions, Faction, joinFaction,
factionExists, purchaseAugmentation} from "./Faction.js";
import {getCostOfNextHacknetNode, purchaseHacknet} from "./HacknetNode.js";
@ -80,6 +81,8 @@ var possibleLogs = {
relaysmtp: true,
httpworm: true,
sqlinject: true,
run:true,
exec:true,
spawn: true,
kill: true,
killall: true,
@ -308,8 +311,10 @@ function NetscriptFunctions(workerScript) {
}
return netscriptDelay(growTime, workerScript).then(function() {
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
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
const moneyAfter = server.moneyAvailable;
workerScript.scriptRef.recordGrow(server.ip, threads);
var expGain = scriptCalculateExpGain(server) * threads;
if (growthPercentage == 1) {
@ -317,12 +322,12 @@ function NetscriptFunctions(workerScript) {
}
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.grow == null) {
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 +")");
}
workerScript.scriptRef.onlineExpGained += expGain;
Player.gainHackingExp(expGain);
return Promise.resolve(growthPercentage);
return Promise.resolve(moneyAfter/moneyBefore);
});
},
weaken : function(ip){
@ -948,6 +953,23 @@ function NetscriptFunctions(workerScript) {
allFiles.sort();
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) {
if (workerScript.checkingRam) {
return updateStaticRam("hasRootAccess", CONSTANTS.ScriptHasRootAccessRamCost);
@ -2272,7 +2294,9 @@ function NetscriptFunctions(workerScript) {
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);
@ -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) {
workerScript.scriptRef.log("ERROR: workForFaction() failed because you are in the middle of a mission.");
return;

@ -413,6 +413,14 @@ PlayerObject.prototype.getUpgradeHomeRamCost = function() {
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);
@ -579,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) {
@ -586,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) {
@ -593,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) {
@ -600,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) {
@ -607,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) {
@ -614,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) {
@ -2315,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);

@ -448,6 +448,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 +509,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;
}

@ -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() {
@ -784,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";
@ -1182,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)) {
@ -1258,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);}
@ -1312,7 +1400,7 @@ let Engine = {
Engine.openMainMenuHeader(
[terminal, createScript, activeScripts, stats,
hacknetnodes, city,
tutorial, options]
tutorial, options, dev]
);
//Start interactive tutorial
@ -1365,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";
@ -1452,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";
}
},
@ -1549,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);
}
}
@ -1636,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");

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 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,7 +15,7 @@ module.exports = {
jquery: "jquery",
jQuery: "jquery",
$: "jquery"
}),
})
],
target: "web",
entry: {
@ -25,12 +28,7 @@ module.exports = {
filename: "[name].bundle.js"
},
module: {
rules: [
/* {
test: /\.css$/,
use: "style!css"
}*/
]
rules: []
},
optimization: {
removeAvailableModules: true,
@ -50,4 +48,4 @@ module.exports = {
devServer: {
publicPath: "/dist",
}
};
});