mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-25 17:13:47 +01:00
V0.35.0. Adding netscript_tests in game testbench.
This commit is contained in:
parent
271932b287
commit
e3c435270b
@ -155,10 +155,18 @@ a:link, a:visited {
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
border: 1px solid #333333;
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.a-link-button-inactive:hover .tooltiptext,
|
||||
.a-link-button-inactive:hover .tooltiptexthigh,
|
||||
.a-link-button-inactive:hover .tooltiptextleft {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.a-link-button-inactive:active {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Notification icon (for create program right now only) */
|
||||
#create-program-tab {
|
||||
@ -332,6 +340,7 @@ a:link, a:visited {
|
||||
top:0px;
|
||||
-webkit-animation:status-text 3s 1;
|
||||
background-color: transparent;
|
||||
height: 15%;
|
||||
}
|
||||
|
||||
#status-text-container {
|
||||
|
@ -43,3 +43,15 @@
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
}
|
||||
|
||||
#terminal-input-td {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#terminal-input-header {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
#terminal-input-text-box {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
4641
dist/bundle.js
vendored
4641
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
BIN
doc/build/doctrees/environment.pickle
vendored
BIN
doc/build/doctrees/environment.pickle
vendored
Binary file not shown.
BIN
doc/build/doctrees/index.doctree
vendored
BIN
doc/build/doctrees/index.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscript.doctree
vendored
BIN
doc/build/doctrees/netscript.doctree
vendored
Binary file not shown.
Binary file not shown.
BIN
doc/build/doctrees/netscriptdatatypes.doctree
vendored
BIN
doc/build/doctrees/netscriptdatatypes.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscriptfunctions.doctree
vendored
BIN
doc/build/doctrees/netscriptfunctions.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscripthacknetnodeapi.doctree
vendored
BIN
doc/build/doctrees/netscripthacknetnodeapi.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscriptixapi.doctree
vendored
BIN
doc/build/doctrees/netscriptixapi.doctree
vendored
Binary file not shown.
Binary file not shown.
BIN
doc/build/doctrees/netscriptmisc.doctree
vendored
BIN
doc/build/doctrees/netscriptmisc.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscriptoperators.doctree
vendored
BIN
doc/build/doctrees/netscriptoperators.doctree
vendored
Binary file not shown.
BIN
doc/build/doctrees/netscriptscriptarguments.doctree
vendored
BIN
doc/build/doctrees/netscriptscriptarguments.doctree
vendored
Binary file not shown.
Binary file not shown.
@ -25,27 +25,27 @@ a value to these.
|
||||
|
||||
Note that these must be called on an element inside the *hacknetnodes* array, not the array itself.
|
||||
|
||||
.. js:function:: hacknetnodes[i].level
|
||||
.. js:attribute:: hacknetnodes[i].level
|
||||
|
||||
Returns the level of the corresponding Hacknet Node
|
||||
|
||||
.. js:function:: hacknetnodes[i].ram
|
||||
.. js:attribute:: hacknetnodes[i].ram
|
||||
|
||||
Returns the amount of RAM on the corresponding Hacknet Node
|
||||
|
||||
.. js:function:: hacknetnodes[i].cores
|
||||
.. js:attribute:: hacknetnodes[i].cores
|
||||
|
||||
Returns the number of cores on the corresponding Hacknet Node
|
||||
|
||||
.. js:function:: hacknetnodes[i].totalMoneyGenerated
|
||||
.. js:attribute:: hacknetnodes[i].totalMoneyGenerated
|
||||
|
||||
Returns the total amount of money that the corresponding Hacknet Node has earned
|
||||
|
||||
.. js:function:: hacknetnodes[i].onlineTimeSeconds
|
||||
.. js:attribute:: hacknetnodes[i].onlineTimeSeconds
|
||||
|
||||
Returns the total amount of time (in seconds) that the corresponding Hacknet Node has existed
|
||||
|
||||
.. js:function:: hacknetnodes[i].moneyGainRatePerSecond
|
||||
.. js:attribute:: hacknetnodes[i].moneyGainRatePerSecond
|
||||
|
||||
Returns the amount of income that the corresponding Hacknet Node earns
|
||||
|
||||
@ -57,7 +57,7 @@ The following is a list of supported functions/methods for a Hacknet Node object
|
||||
Note that these must be called on an element inside the *hacknetnodes* array, not the
|
||||
array itself.
|
||||
|
||||
.. js:function:: hacknetnodes[i].upgradeLevel(n);
|
||||
.. js:method:: hacknetnodes[i].upgradeLevel(n)
|
||||
|
||||
:param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer
|
||||
|
||||
@ -65,27 +65,27 @@ array itself.
|
||||
Hacknet Node's level is successfully upgraded *n* times or up to the max level (200), and false
|
||||
otherwise.
|
||||
|
||||
.. js:function:: hacknetnodes[i].upgradeRam()
|
||||
.. js:method:: hacknetnodes[i].upgradeRam()
|
||||
|
||||
Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the RAM is
|
||||
successfully upgraded and false otherwise.
|
||||
|
||||
.. js:function:: hacknetnodes[i].upgradeCore()
|
||||
.. js:method:: hacknetnodes[i].upgradeCore()
|
||||
|
||||
Tries to purchase an additional core for the corresponding Hacknet Node. Returns true if the
|
||||
additional core is successfully purchased, and false otherwise.
|
||||
|
||||
.. js:function:: hacknetnodes[i].getLevelUpgradeCost(n);
|
||||
.. js:method:: hacknetnodes[i].getLevelUpgradeCost(n)
|
||||
|
||||
:param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer
|
||||
|
||||
Returns the cost of upgrading the specified Hacknet Node by *n* levels
|
||||
|
||||
.. js:function:: hacknetnodes[i].getRamUpgradeCost()
|
||||
.. js:method:: hacknetnodes[i].getRamUpgradeCost()
|
||||
|
||||
Returns the cost of upgrading the RAM of the specified Hacknet Node. Upgrading a Node's RAM doubles it.
|
||||
|
||||
.. js:function:: hacknetnodes[i].getCoreUpgradeCost()
|
||||
.. js:method:: hacknetnodes[i].getCoreUpgradeCost()
|
||||
|
||||
Returns the cost of upgrading the number of cores of the specified Hacknet Node. Upgrading a Node's
|
||||
number of cores adds one additional core.
|
||||
|
139
doc/build/html/_sources/netscriptmisc.rst.txt
vendored
139
doc/build/html/_sources/netscriptmisc.rst.txt
vendored
@ -1,6 +1,135 @@
|
||||
Netscript Miscellaneous
|
||||
=======================
|
||||
|
||||
Netscript Ports
|
||||
---------------
|
||||
Netscript ports are endpoints that can be used to communicate between scripts.
|
||||
A port is implemented as a sort of serialized queue, where you can only write
|
||||
and read one element at a time from the port. When you read data from a port,
|
||||
the element that is read is removed from the port.
|
||||
|
||||
The :js:func:`read`, :js:func:`write`, :js:func:`clear`, and :js:func:`peek`
|
||||
Netscript functions can be used to interact with ports.
|
||||
|
||||
Right now, there are only 20 ports for Netscript, denoted by the number 1
|
||||
through 20. When using the functions above, the ports are specified
|
||||
by passing the number as the first argument.
|
||||
|
||||
IMPORTANT: The data inside ports are not saved! This means if you close and
|
||||
re-open the game, or reload the page then you will lose all of the data in
|
||||
the ports!
|
||||
|
||||
**Example Usage**
|
||||
|
||||
Here's a brief example of how ports work. For the sake of simplicity we'll only deal with port 1.
|
||||
|
||||
Let's assume Port 1 starts out empty (no data inside). We'll represent the port as such::
|
||||
|
||||
[]
|
||||
|
||||
Now assume we ran the following simple script::
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
write(1, i); //Writes the value of i to port 1
|
||||
}
|
||||
|
||||
After this script executes, our script will contain every number from 0 through 9, as so::
|
||||
|
||||
[0, 1, 2, 3, 4, 5, 6, 7 , 8, 9]
|
||||
|
||||
Then, assume we run the following script::
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
print(read(1)); //Reads a value from port 1 and then prints it
|
||||
}
|
||||
|
||||
This script above will read the first three values from port 1 and then print them to the script's log. The log will end up looking like::
|
||||
|
||||
0
|
||||
1
|
||||
2
|
||||
|
||||
And the data in port 1 will look like::
|
||||
|
||||
[3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
**Port Handles**
|
||||
|
||||
The :js:func:`getPortHandle` Netscript function can be used to get a handle to a Netscript Port.
|
||||
This handle allows you to access several new port-related functions and the
|
||||
port's underlying data structure, which is just a Javascript array. The functions are:
|
||||
|
||||
.. js:method:: NetscriptPort.write(data)
|
||||
|
||||
:param data: Data to write to the port
|
||||
:returns: If the port is full, the item that is removed from the port is returned.
|
||||
Otherwise, null is returned.
|
||||
|
||||
Writes `data` to the port. Works the same as the Netscript function `write`.
|
||||
|
||||
.. js:method:: NetscriptPort.tryWrite(data)
|
||||
|
||||
:param data: Data to try to write to the port
|
||||
:returns: True if the data is successfully written to the port, and false otherwise.
|
||||
|
||||
Attempts to write `data` to the Netscript port. If the port is full, the data will
|
||||
not be written. Otherwise, the data will be written normally.
|
||||
|
||||
.. js::method:: NetscriptPort.read()
|
||||
|
||||
:returns: The data read from the port. If the port is empty, "NULL PORT DATA" is returned
|
||||
|
||||
Removes and returns the first element from the port.
|
||||
Works the same as the Netscript function `read`
|
||||
|
||||
.. js::method:: NetscriptPort.peek()
|
||||
|
||||
:returns: The first element in the port, or "NULL PORT DATA" if the port is empty.
|
||||
|
||||
Returns the first element in the port, but does not remove it.
|
||||
Works the same as the Netscript function `peek`
|
||||
|
||||
.. js:method:: NetscriptPort.full()
|
||||
|
||||
:returns: True if the Netscript Port is full, and false otherwise
|
||||
|
||||
.. js:method:: NetscriptPort.empty()
|
||||
|
||||
:returns: True if the Netscript Port is empty, and false otherwise
|
||||
|
||||
.. js:method:: NetscriptPort.clear()
|
||||
|
||||
Clears all data from the port. Works the same as the Netscript function `clear`
|
||||
|
||||
.. js:attribute:: NetscriptPort.data
|
||||
|
||||
The Netscript port underlying data structure, which is just a Javascript array. All
|
||||
valid Javascript Array methods can be called on this.
|
||||
|
||||
Port Handle Example::
|
||||
|
||||
port = getPortHandle(5);
|
||||
back = port.data.pop(); //Get and remove last element in port
|
||||
|
||||
//Remove an element from the port
|
||||
i = port.data.findIndex("foo");
|
||||
if (i != -1) {
|
||||
port.data.slice(i, 1);
|
||||
}
|
||||
|
||||
//Wait for port data before reading
|
||||
while(port.empty()) {
|
||||
sleep(10000);
|
||||
}
|
||||
res = port.read();
|
||||
|
||||
//Wait for there to be room in a port before writing
|
||||
while (!port.tryWrite(5)) {
|
||||
sleep(5000);
|
||||
}
|
||||
|
||||
//Successfully wrote to port!
|
||||
|
||||
|
||||
Comments
|
||||
--------
|
||||
@ -35,3 +164,13 @@ However, since the 'new' operator does not work in Netscript, only the Date modu
|
||||
Example::
|
||||
|
||||
time = Date.now();
|
||||
|
||||
Javascript Number Module
|
||||
------------------------
|
||||
|
||||
The `Javascript Number module <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number>`_ is supported in Netscript.
|
||||
|
||||
Example::
|
||||
|
||||
tprint(Number.isInteger(1)); //True
|
||||
tprint(Number.isInteger(1.534059)); //False
|
||||
|
38
doc/build/html/genindex.html
vendored
38
doc/build/html/genindex.html
vendored
@ -229,41 +229,19 @@
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="netscriptfunctions.html#hack">hack() (built-in function)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].cores">hacknetnodes[i].cores() (hacknetnodes[i] method)</a>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].cores">hacknetnodes[i].cores (hacknetnodes[i] attribute)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].getCoreUpgradeCost">hacknetnodes[i].getCoreUpgradeCost() (hacknetnodes[i] method)</a>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].level">hacknetnodes[i].level (hacknetnodes[i] attribute)</a>
|
||||
</li>
|
||||
<li>
|
||||
hacknetnodes[i].getLevelUpgradeCost(n)
|
||||
|
||||
<ul>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].getLevelUpgradeCost(n);">() (hacknetnodes[i] method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].getRamUpgradeCost">hacknetnodes[i].getRamUpgradeCost() (hacknetnodes[i] method)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].level">hacknetnodes[i].level() (hacknetnodes[i] method)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].moneyGainRatePerSecond">hacknetnodes[i].moneyGainRatePerSecond() (hacknetnodes[i] method)</a>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].moneyGainRatePerSecond">hacknetnodes[i].moneyGainRatePerSecond (hacknetnodes[i] attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].onlineTimeSeconds">hacknetnodes[i].onlineTimeSeconds() (hacknetnodes[i] method)</a>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].onlineTimeSeconds">hacknetnodes[i].onlineTimeSeconds (hacknetnodes[i] attribute)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].ram">hacknetnodes[i].ram() (hacknetnodes[i] method)</a>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].ram">hacknetnodes[i].ram (hacknetnodes[i] attribute)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].totalMoneyGenerated">hacknetnodes[i].totalMoneyGenerated() (hacknetnodes[i] method)</a>
|
||||
</li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].upgradeCore">hacknetnodes[i].upgradeCore() (hacknetnodes[i] method)</a>
|
||||
</li>
|
||||
<li>
|
||||
hacknetnodes[i].upgradeLevel(n)
|
||||
|
||||
<ul>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].upgradeLevel(n);">() (hacknetnodes[i] method)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].upgradeRam">hacknetnodes[i].upgradeRam() (hacknetnodes[i] method)</a>
|
||||
<li><a href="netscripthacknetnodeapi.html#hacknetnodes[i].totalMoneyGenerated">hacknetnodes[i].totalMoneyGenerated (hacknetnodes[i] attribute)</a>
|
||||
</li>
|
||||
<li><a href="netscriptfunctions.html#hasRootAccess">hasRootAccess() (built-in function)</a>
|
||||
</li>
|
||||
@ -316,6 +294,10 @@
|
||||
|
||||
<h2 id="N">N</h2>
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="netscriptmisc.html#NetscriptPort.data">NetscriptPort.data (NetscriptPort attribute)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="netscriptfunctions.html#nuke">nuke() (built-in function)</a>
|
||||
</li>
|
||||
|
2
doc/build/html/index.html
vendored
2
doc/build/html/index.html
vendored
@ -196,9 +196,11 @@ secrets that you've been searching for.</p>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptmisc.html#netscript-ports">Netscript Ports</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptmisc.html#comments">Comments</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptmisc.html#javascript-math-module">Javascript Math Module</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptmisc.html#javascript-date-module">Javascript Date Module</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="netscriptmisc.html#javascript-number-module">Javascript Number Module</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
2
doc/build/html/netscript.html
vendored
2
doc/build/html/netscript.html
vendored
@ -197,9 +197,11 @@ to reach out to the developer!</p>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html#netscript-ports">Netscript Ports</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html#comments">Comments</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html#javascript-math-module">Javascript Math Module</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html#javascript-date-module">Javascript Date Module</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html#javascript-number-module">Javascript Number Module</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -122,6 +122,7 @@ will only give 10% of the money you would have received in BitNode-1. The object
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
1
doc/build/html/netscriptdatatypes.html
vendored
1
doc/build/html/netscriptdatatypes.html
vendored
@ -112,6 +112,7 @@ can also change. For example, if a variable initially holds a number, it can lat
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
45
doc/build/html/netscripthacknetnodeapi.html
vendored
45
doc/build/html/netscripthacknetnodeapi.html
vendored
@ -72,39 +72,39 @@ accessed using <em>hacknetnodes[0]</em>. The fourth Hacknet Node you purchase wi
|
||||
<p>The following is a list of member variables for a Hacknet Node object. These variables are read-only, which means you cannot assign
|
||||
a value to these.</p>
|
||||
<p>Note that these must be called on an element inside the <em>hacknetnodes</em> array, not the array itself.</p>
|
||||
<dl class="function">
|
||||
<dl class="attribute">
|
||||
<dt id="hacknetnodes[i].level">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">level</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].level" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">level</code><a class="headerlink" href="#hacknetnodes[i].level" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the level of the corresponding Hacknet Node</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="attribute">
|
||||
<dt id="hacknetnodes[i].ram">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">ram</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].ram" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">ram</code><a class="headerlink" href="#hacknetnodes[i].ram" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the amount of RAM on the corresponding Hacknet Node</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="attribute">
|
||||
<dt id="hacknetnodes[i].cores">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">cores</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].cores" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">cores</code><a class="headerlink" href="#hacknetnodes[i].cores" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the number of cores on the corresponding Hacknet Node</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="attribute">
|
||||
<dt id="hacknetnodes[i].totalMoneyGenerated">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">totalMoneyGenerated</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].totalMoneyGenerated" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">totalMoneyGenerated</code><a class="headerlink" href="#hacknetnodes[i].totalMoneyGenerated" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the total amount of money that the corresponding Hacknet Node has earned</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="attribute">
|
||||
<dt id="hacknetnodes[i].onlineTimeSeconds">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">onlineTimeSeconds</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].onlineTimeSeconds" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">onlineTimeSeconds</code><a class="headerlink" href="#hacknetnodes[i].onlineTimeSeconds" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the total amount of time (in seconds) that the corresponding Hacknet Node has existed</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="attribute">
|
||||
<dt id="hacknetnodes[i].moneyGainRatePerSecond">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">moneyGainRatePerSecond</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].moneyGainRatePerSecond" title="Permalink to this definition">¶</a></dt>
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">moneyGainRatePerSecond</code><a class="headerlink" href="#hacknetnodes[i].moneyGainRatePerSecond" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the amount of income that the corresponding Hacknet Node earns</p>
|
||||
</dd></dl>
|
||||
|
||||
@ -114,9 +114,9 @@ a value to these.</p>
|
||||
<p>The following is a list of supported functions/methods for a Hacknet Node object.</p>
|
||||
<p>Note that these must be called on an element inside the <em>hacknetnodes</em> array, not the
|
||||
array itself.</p>
|
||||
<dl class="function">
|
||||
<dt id="hacknetnodes[i].upgradeLevel(n);">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">upgradeLevel(n);</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].upgradeLevel(n);" title="Permalink to this definition">¶</a></dt>
|
||||
<dl class="method">
|
||||
<dt id="hacknetnodes[i].upgradeLevel">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">upgradeLevel</code><span class="sig-paren">(</span><em>n</em><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].upgradeLevel" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
@ -133,23 +133,23 @@ Hacknet Node's level is successfully upgraded <em>n</em> times or up to the max
|
||||
otherwise.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="method">
|
||||
<dt id="hacknetnodes[i].upgradeRam">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">upgradeRam</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].upgradeRam" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the RAM is
|
||||
successfully upgraded and false otherwise.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="method">
|
||||
<dt id="hacknetnodes[i].upgradeCore">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">upgradeCore</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].upgradeCore" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Tries to purchase an additional core for the corresponding Hacknet Node. Returns true if the
|
||||
additional core is successfully purchased, and false otherwise.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dt id="hacknetnodes[i].getLevelUpgradeCost(n);">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">getLevelUpgradeCost(n);</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].getLevelUpgradeCost(n);" title="Permalink to this definition">¶</a></dt>
|
||||
<dl class="method">
|
||||
<dt id="hacknetnodes[i].getLevelUpgradeCost">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">getLevelUpgradeCost</code><span class="sig-paren">(</span><em>n</em><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].getLevelUpgradeCost" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><table class="docutils field-list" frame="void" rules="none">
|
||||
<col class="field-name" />
|
||||
<col class="field-body" />
|
||||
@ -164,13 +164,13 @@ additional core is successfully purchased, and false otherwise.</p>
|
||||
<p>Returns the cost of upgrading the specified Hacknet Node by <em>n</em> levels</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="method">
|
||||
<dt id="hacknetnodes[i].getRamUpgradeCost">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">getRamUpgradeCost</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].getRamUpgradeCost" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the cost of upgrading the RAM of the specified Hacknet Node. Upgrading a Node's RAM doubles it.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="function">
|
||||
<dl class="method">
|
||||
<dt id="hacknetnodes[i].getCoreUpgradeCost">
|
||||
<code class="descclassname">hacknetnodes[i].</code><code class="descname">getCoreUpgradeCost</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#hacknetnodes[i].getCoreUpgradeCost" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Returns the cost of upgrading the number of cores of the specified Hacknet Node. Upgrading a Node's
|
||||
@ -241,6 +241,7 @@ Nodes to a level of at least 75, RAM to at least 8GB, and number of cores to at
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
1
doc/build/html/netscriptixapi.html
vendored
1
doc/build/html/netscriptixapi.html
vendored
@ -326,6 +326,7 @@ NOT case-sensitive.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
167
doc/build/html/netscriptmisc.html
vendored
167
doc/build/html/netscriptmisc.html
vendored
@ -50,6 +50,162 @@
|
||||
|
||||
<div class="section" id="netscript-miscellaneous">
|
||||
<h1>Netscript Miscellaneous<a class="headerlink" href="#netscript-miscellaneous" title="Permalink to this headline">¶</a></h1>
|
||||
<div class="section" id="netscript-ports">
|
||||
<h2>Netscript Ports<a class="headerlink" href="#netscript-ports" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Netscript ports are endpoints that can be used to communicate between scripts.
|
||||
A port is implemented as a sort of serialized queue, where you can only write
|
||||
and read one element at a time from the port. When you read data from a port,
|
||||
the element that is read is removed from the port.</p>
|
||||
<p>The <code class="xref js js-func docutils literal"><span class="pre">read()</span></code>, <code class="xref js js-func docutils literal"><span class="pre">write()</span></code>, <code class="xref js js-func docutils literal"><span class="pre">clear()</span></code>, and <code class="xref js js-func docutils literal"><span class="pre">peek()</span></code>
|
||||
Netscript functions can be used to interact with ports.</p>
|
||||
<p>Right now, there are only 20 ports for Netscript, denoted by the number 1
|
||||
through 20. When using the functions above, the ports are specified
|
||||
by passing the number as the first argument.</p>
|
||||
<p>IMPORTANT: The data inside ports are not saved! This means if you close and
|
||||
re-open the game, or reload the page then you will lose all of the data in
|
||||
the ports!</p>
|
||||
<p><strong>Example Usage</strong></p>
|
||||
<p>Here's a brief example of how ports work. For the sake of simplicity we'll only deal with port 1.</p>
|
||||
<p>Let's assume Port 1 starts out empty (no data inside). We'll represent the port as such:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="p">[]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Now assume we ran the following simple script:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">10</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">write</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span> <span class="o">//</span><span class="n">Writes</span> <span class="n">the</span> <span class="n">value</span> <span class="n">of</span> <span class="n">i</span> <span class="n">to</span> <span class="n">port</span> <span class="mi">1</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>After this script executes, our script will contain every number from 0 through 9, as so:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span> <span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>Then, assume we run the following script:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="mi">3</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span> <span class="o">//</span><span class="n">Reads</span> <span class="n">a</span> <span class="n">value</span> <span class="kn">from</span> <span class="nn">port</span> <span class="mi">1</span> <span class="ow">and</span> <span class="n">then</span> <span class="n">prints</span> <span class="n">it</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>This script above will read the first three values from port 1 and then print them to the script's log. The log will end up looking like:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="mi">0</span>
|
||||
<span class="mi">1</span>
|
||||
<span class="mi">2</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>And the data in port 1 will look like:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p><strong>Port Handles</strong></p>
|
||||
<p>The <code class="xref js js-func docutils literal"><span class="pre">getPortHandle()</span></code> Netscript function can be used to get a handle to a Netscript Port.
|
||||
This handle allows you to access several new port-related functions and the
|
||||
port's underlying data structure, which is just a Javascript array. The functions are:</p>
|
||||
<dl class="method">
|
||||
<dt id="NetscriptPort.write">
|
||||
<code class="descclassname">NetscriptPort.</code><code class="descname">write</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#NetscriptPort.write" title="Permalink to this definition">¶</a></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 simple">
|
||||
<li><strong>data</strong> -- Data to write to the port</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">If the port is full, the item that is removed from the port is returned.
|
||||
Otherwise, null is returned.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Writes <cite>data</cite> to the port. Works the same as the Netscript function <cite>write</cite>.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="NetscriptPort.tryWrite">
|
||||
<code class="descclassname">NetscriptPort.</code><code class="descname">tryWrite</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span><a class="headerlink" href="#NetscriptPort.tryWrite" title="Permalink to this definition">¶</a></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 simple">
|
||||
<li><strong>data</strong> -- Data to try to write to the port</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="field-even field"><th class="field-name">Returns:</th><td class="field-body"><p class="first last">True if the data is successfully written to the port, and false otherwise.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>Attempts to write <cite>data</cite> to the Netscript port. If the port is full, the data will
|
||||
not be written. Otherwise, the data will be written normally.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="NetscriptPort.full">
|
||||
<code class="descclassname">NetscriptPort.</code><code class="descname">full</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#NetscriptPort.full" title="Permalink to this definition">¶</a></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">Returns:</th><td class="field-body">True if the Netscript Port is full, and false otherwise</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="NetscriptPort.empty">
|
||||
<code class="descclassname">NetscriptPort.</code><code class="descname">empty</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#NetscriptPort.empty" title="Permalink to this definition">¶</a></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">Returns:</th><td class="field-body">True if the Netscript Port is empty, and false otherwise</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="method">
|
||||
<dt id="NetscriptPort.clear">
|
||||
<code class="descclassname">NetscriptPort.</code><code class="descname">clear</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#NetscriptPort.clear" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Clears all data from the port. Works the same as the Netscript function <cite>clear</cite></p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="attribute">
|
||||
<dt id="NetscriptPort.data">
|
||||
<code class="descclassname">NetscriptPort.</code><code class="descname">data</code><a class="headerlink" href="#NetscriptPort.data" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>The Netscript port underlying data structure, which is just a Javascript array. All
|
||||
valid Javascript Array methods can be called on this.</p>
|
||||
</dd></dl>
|
||||
|
||||
<p>Port Handle Example:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span>port = getPortHandle(5);
|
||||
back = port.data.pop(); //Get and remove last element in port
|
||||
|
||||
//Remove an element from the port
|
||||
i = port.data.findIndex("foo");
|
||||
if (i != -1) {
|
||||
port.data.slice(i, 1);
|
||||
}
|
||||
|
||||
//Wait for port data before reading
|
||||
while(port.empty()) {
|
||||
sleep(10000);
|
||||
}
|
||||
res = port.read();
|
||||
|
||||
//Wait for there to be room in a port before writing
|
||||
while (!port.tryWrite(5)) {
|
||||
sleep(5000);
|
||||
}
|
||||
|
||||
//Successfully wrote to port!
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="comments">
|
||||
<h2>Comments<a class="headerlink" href="#comments" title="Permalink to this headline">¶</a></h2>
|
||||
<p>Netscript supports comments using the same syntax as <a class="reference external" href="https://www.w3schools.com/js/js_comments.asp">Javascript comments</a>.
|
||||
@ -85,6 +241,15 @@ However, since the 'new' operator does not work in Netscript, only the Date modu
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="javascript-number-module">
|
||||
<h2>Javascript Number Module<a class="headerlink" href="#javascript-number-module" title="Permalink to this headline">¶</a></h2>
|
||||
<p>The <a class="reference external" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Javascript Number module</a> is supported in Netscript.</p>
|
||||
<p>Example:</p>
|
||||
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">tprint</span><span class="p">(</span><span class="n">Number</span><span class="o">.</span><span class="n">isInteger</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span> <span class="o">//</span><span class="kc">True</span>
|
||||
<span class="n">tprint</span><span class="p">(</span><span class="n">Number</span><span class="o">.</span><span class="n">isInteger</span><span class="p">(</span><span class="mf">1.534059</span><span class="p">));</span> <span class="o">//</span><span class="kc">False</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -107,9 +272,11 @@ However, since the 'new' operator does not work in Netscript, only the Date modu
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2 current"><a class="current reference internal" href="#"> Miscellaneous</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#netscript-ports">Netscript Ports</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#comments">Comments</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#javascript-math-module">Javascript Math Module</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#javascript-date-module">Javascript Date Module</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="#javascript-number-module">Javascript Number Module</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
1
doc/build/html/netscriptoperators.html
vendored
1
doc/build/html/netscriptoperators.html
vendored
@ -209,6 +209,7 @@ change the value of their operands. For example:</p>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
1
doc/build/html/netscriptscriptarguments.html
vendored
1
doc/build/html/netscriptscriptarguments.html
vendored
@ -87,6 +87,7 @@ script specified in the first argument with the amount of threads specified in t
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscripthacknetnodeapi.html"> Hacknet Node API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptixapi.html"> Trade Information eXchange (TIX) API</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html"> Singularity Functions</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
BIN
doc/build/html/objects.inv
vendored
BIN
doc/build/html/objects.inv
vendored
Binary file not shown.
2
doc/build/html/searchindex.js
vendored
2
doc/build/html/searchindex.js
vendored
File diff suppressed because one or more lines are too long
@ -25,27 +25,27 @@ a value to these.
|
||||
|
||||
Note that these must be called on an element inside the *hacknetnodes* array, not the array itself.
|
||||
|
||||
.. js:function:: hacknetnodes[i].level
|
||||
.. js:attribute:: hacknetnodes[i].level
|
||||
|
||||
Returns the level of the corresponding Hacknet Node
|
||||
|
||||
.. js:function:: hacknetnodes[i].ram
|
||||
.. js:attribute:: hacknetnodes[i].ram
|
||||
|
||||
Returns the amount of RAM on the corresponding Hacknet Node
|
||||
|
||||
.. js:function:: hacknetnodes[i].cores
|
||||
.. js:attribute:: hacknetnodes[i].cores
|
||||
|
||||
Returns the number of cores on the corresponding Hacknet Node
|
||||
|
||||
.. js:function:: hacknetnodes[i].totalMoneyGenerated
|
||||
.. js:attribute:: hacknetnodes[i].totalMoneyGenerated
|
||||
|
||||
Returns the total amount of money that the corresponding Hacknet Node has earned
|
||||
|
||||
.. js:function:: hacknetnodes[i].onlineTimeSeconds
|
||||
.. js:attribute:: hacknetnodes[i].onlineTimeSeconds
|
||||
|
||||
Returns the total amount of time (in seconds) that the corresponding Hacknet Node has existed
|
||||
|
||||
.. js:function:: hacknetnodes[i].moneyGainRatePerSecond
|
||||
.. js:attribute:: hacknetnodes[i].moneyGainRatePerSecond
|
||||
|
||||
Returns the amount of income that the corresponding Hacknet Node earns
|
||||
|
||||
@ -57,7 +57,7 @@ The following is a list of supported functions/methods for a Hacknet Node object
|
||||
Note that these must be called on an element inside the *hacknetnodes* array, not the
|
||||
array itself.
|
||||
|
||||
.. js:function:: hacknetnodes[i].upgradeLevel(n);
|
||||
.. js:method:: hacknetnodes[i].upgradeLevel(n)
|
||||
|
||||
:param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer
|
||||
|
||||
@ -65,27 +65,27 @@ array itself.
|
||||
Hacknet Node's level is successfully upgraded *n* times or up to the max level (200), and false
|
||||
otherwise.
|
||||
|
||||
.. js:function:: hacknetnodes[i].upgradeRam()
|
||||
.. js:method:: hacknetnodes[i].upgradeRam()
|
||||
|
||||
Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the RAM is
|
||||
successfully upgraded and false otherwise.
|
||||
|
||||
.. js:function:: hacknetnodes[i].upgradeCore()
|
||||
.. js:method:: hacknetnodes[i].upgradeCore()
|
||||
|
||||
Tries to purchase an additional core for the corresponding Hacknet Node. Returns true if the
|
||||
additional core is successfully purchased, and false otherwise.
|
||||
|
||||
.. js:function:: hacknetnodes[i].getLevelUpgradeCost(n);
|
||||
.. js:method:: hacknetnodes[i].getLevelUpgradeCost(n)
|
||||
|
||||
:param number n: Number of levels to upgrade. Must be positive. Rounded to nearest integer
|
||||
|
||||
Returns the cost of upgrading the specified Hacknet Node by *n* levels
|
||||
|
||||
.. js:function:: hacknetnodes[i].getRamUpgradeCost()
|
||||
.. js:method:: hacknetnodes[i].getRamUpgradeCost()
|
||||
|
||||
Returns the cost of upgrading the RAM of the specified Hacknet Node. Upgrading a Node's RAM doubles it.
|
||||
|
||||
.. js:function:: hacknetnodes[i].getCoreUpgradeCost()
|
||||
.. js:method:: hacknetnodes[i].getCoreUpgradeCost()
|
||||
|
||||
Returns the cost of upgrading the number of cores of the specified Hacknet Node. Upgrading a Node's
|
||||
number of cores adds one additional core.
|
||||
|
@ -1,6 +1,135 @@
|
||||
Netscript Miscellaneous
|
||||
=======================
|
||||
|
||||
Netscript Ports
|
||||
---------------
|
||||
Netscript ports are endpoints that can be used to communicate between scripts.
|
||||
A port is implemented as a sort of serialized queue, where you can only write
|
||||
and read one element at a time from the port. When you read data from a port,
|
||||
the element that is read is removed from the port.
|
||||
|
||||
The :js:func:`read`, :js:func:`write`, :js:func:`clear`, and :js:func:`peek`
|
||||
Netscript functions can be used to interact with ports.
|
||||
|
||||
Right now, there are only 20 ports for Netscript, denoted by the number 1
|
||||
through 20. When using the functions above, the ports are specified
|
||||
by passing the number as the first argument.
|
||||
|
||||
IMPORTANT: The data inside ports are not saved! This means if you close and
|
||||
re-open the game, or reload the page then you will lose all of the data in
|
||||
the ports!
|
||||
|
||||
**Example Usage**
|
||||
|
||||
Here's a brief example of how ports work. For the sake of simplicity we'll only deal with port 1.
|
||||
|
||||
Let's assume Port 1 starts out empty (no data inside). We'll represent the port as such::
|
||||
|
||||
[]
|
||||
|
||||
Now assume we ran the following simple script::
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
write(1, i); //Writes the value of i to port 1
|
||||
}
|
||||
|
||||
After this script executes, our script will contain every number from 0 through 9, as so::
|
||||
|
||||
[0, 1, 2, 3, 4, 5, 6, 7 , 8, 9]
|
||||
|
||||
Then, assume we run the following script::
|
||||
|
||||
for (i = 0; i < 3; ++i) {
|
||||
print(read(1)); //Reads a value from port 1 and then prints it
|
||||
}
|
||||
|
||||
This script above will read the first three values from port 1 and then print them to the script's log. The log will end up looking like::
|
||||
|
||||
0
|
||||
1
|
||||
2
|
||||
|
||||
And the data in port 1 will look like::
|
||||
|
||||
[3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
**Port Handles**
|
||||
|
||||
The :js:func:`getPortHandle` Netscript function can be used to get a handle to a Netscript Port.
|
||||
This handle allows you to access several new port-related functions and the
|
||||
port's underlying data structure, which is just a Javascript array. The functions are:
|
||||
|
||||
.. js:method:: NetscriptPort.write(data)
|
||||
|
||||
:param data: Data to write to the port
|
||||
:returns: If the port is full, the item that is removed from the port is returned.
|
||||
Otherwise, null is returned.
|
||||
|
||||
Writes `data` to the port. Works the same as the Netscript function `write`.
|
||||
|
||||
.. js:method:: NetscriptPort.tryWrite(data)
|
||||
|
||||
:param data: Data to try to write to the port
|
||||
:returns: True if the data is successfully written to the port, and false otherwise.
|
||||
|
||||
Attempts to write `data` to the Netscript port. If the port is full, the data will
|
||||
not be written. Otherwise, the data will be written normally.
|
||||
|
||||
.. js::method:: NetscriptPort.read()
|
||||
|
||||
:returns: The data read from the port. If the port is empty, "NULL PORT DATA" is returned
|
||||
|
||||
Removes and returns the first element from the port.
|
||||
Works the same as the Netscript function `read`
|
||||
|
||||
.. js::method:: NetscriptPort.peek()
|
||||
|
||||
:returns: The first element in the port, or "NULL PORT DATA" if the port is empty.
|
||||
|
||||
Returns the first element in the port, but does not remove it.
|
||||
Works the same as the Netscript function `peek`
|
||||
|
||||
.. js:method:: NetscriptPort.full()
|
||||
|
||||
:returns: True if the Netscript Port is full, and false otherwise
|
||||
|
||||
.. js:method:: NetscriptPort.empty()
|
||||
|
||||
:returns: True if the Netscript Port is empty, and false otherwise
|
||||
|
||||
.. js:method:: NetscriptPort.clear()
|
||||
|
||||
Clears all data from the port. Works the same as the Netscript function `clear`
|
||||
|
||||
.. js:attribute:: NetscriptPort.data
|
||||
|
||||
The Netscript port underlying data structure, which is just a Javascript array. All
|
||||
valid Javascript Array methods can be called on this.
|
||||
|
||||
Port Handle Example::
|
||||
|
||||
port = getPortHandle(5);
|
||||
back = port.data.pop(); //Get and remove last element in port
|
||||
|
||||
//Remove an element from the port
|
||||
i = port.data.findIndex("foo");
|
||||
if (i != -1) {
|
||||
port.data.slice(i, 1);
|
||||
}
|
||||
|
||||
//Wait for port data before reading
|
||||
while(port.empty()) {
|
||||
sleep(10000);
|
||||
}
|
||||
res = port.read();
|
||||
|
||||
//Wait for there to be room in a port before writing
|
||||
while (!port.tryWrite(5)) {
|
||||
sleep(5000);
|
||||
}
|
||||
|
||||
//Successfully wrote to port!
|
||||
|
||||
|
||||
Comments
|
||||
--------
|
||||
@ -35,3 +164,13 @@ However, since the 'new' operator does not work in Netscript, only the Date modu
|
||||
Example::
|
||||
|
||||
time = Date.now();
|
||||
|
||||
Javascript Number Module
|
||||
------------------------
|
||||
|
||||
The `Javascript Number module <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number>`_ is supported in Netscript.
|
||||
|
||||
Example::
|
||||
|
||||
tprint(Number.isInteger(1)); //True
|
||||
tprint(Number.isInteger(1.534059)); //False
|
||||
|
140
netscript_tests/tb_basic.script
Normal file
140
netscript_tests/tb_basic.script
Normal file
@ -0,0 +1,140 @@
|
||||
function test(name, val) {
|
||||
if (val) {
|
||||
tprint("Test " + name + ": OK");
|
||||
} else {
|
||||
tprint("Test " + name + ": FAILED");
|
||||
//A failed test prints failure to results text file
|
||||
write("tb_results.txt", "FAIL");
|
||||
}
|
||||
}
|
||||
|
||||
test("run", (args.length === 1 && args[0] === "OK"));
|
||||
|
||||
//Arithmetic
|
||||
test("arith1", 0 * 10 === 0);
|
||||
test("arith2", 0 + 1 === 1);
|
||||
test("arith3", 10 / 5 === 2);
|
||||
test("arith4", 6-3 === 3);
|
||||
test("arith5", 14 % 10 === 4);
|
||||
test("arith6", 5 === 24 / 6 + 1);
|
||||
test("arith7", 6 === 2 * 3);
|
||||
|
||||
//Logical operators
|
||||
test("logic1", true && true);
|
||||
test("logic2", !(true && false));
|
||||
test("logic3", true || false);
|
||||
test("logic4", !(false || false));
|
||||
test("logic5", 1 < 3);
|
||||
test("logic6", !(3 < 1));
|
||||
test("logic7", 5 >= 5);
|
||||
test("logic8", !(5 <= 4));
|
||||
test("logic9", true == true);
|
||||
test("logic10", true === true);
|
||||
test("logic11", !(0 != 0));
|
||||
|
||||
//Assignment
|
||||
i = 5;
|
||||
test("asgn1", i == 5);
|
||||
i = 0;
|
||||
test("asgn2", i === 0);
|
||||
test("asgn3", 10 === (i = 10));
|
||||
test("asgn4", i === 10);
|
||||
|
||||
|
||||
//Basic array functionality
|
||||
testArr = [1, 2, 3, 4, 5, "str1", "str2", "str3"];
|
||||
test("arr1", testArr[0] == 1);
|
||||
test("arr2", testArr[1] === 2);
|
||||
test("arr3", testArr[5] === "str1");
|
||||
test("arr4", testArr[7] === "str3");
|
||||
|
||||
x = 1;
|
||||
y = 2;
|
||||
z = 3;
|
||||
testArr = [];
|
||||
testArr.push(x);
|
||||
testArr.push(y);
|
||||
testArr.push(z);
|
||||
test("arr5", testArr.length === 3);
|
||||
test("arr6", 1 === testArr[0]);
|
||||
test("arr7", 3 === testArr[2]);
|
||||
|
||||
x = 10;
|
||||
y = 10;
|
||||
z = 10;
|
||||
test("arr8", testArr.toString() === "1,2,3");
|
||||
|
||||
testArr.push(4);
|
||||
testArr.push("some str");
|
||||
test("arr9", "1,2,3,4,some str" === testArr.toString());
|
||||
testArr.pop();
|
||||
test("arr10", "1,2,3,4" === testArr.toString());
|
||||
testArr.shift();
|
||||
test("arr11", "2,3,4" === testArr.toString());
|
||||
testArr.unshift(1);
|
||||
test("arr12", "1,2,3,4" === testArr.toString());
|
||||
|
||||
testArr[0] = 10;
|
||||
foo = 1;
|
||||
testArr[foo] = 11;
|
||||
foo = 2;
|
||||
testArr[foo] = 12;
|
||||
foo = 3;
|
||||
testArr[foo] = 13;
|
||||
test("arr13", "10,11,12,13" === testArr.join());
|
||||
testArr.splice(testArr.length, 2, 14, 15);
|
||||
test("arr14", testArr.length === 6);
|
||||
test("arr15", testArr.join() == "10,11,12,13,14,15");
|
||||
|
||||
//Short circuiting Logical Operators
|
||||
results = [];
|
||||
res = false || results.push("OK")
|
||||
res = (0 < -5) || results.push("OK")
|
||||
res = true && results.push("OK")
|
||||
res = (1 > 0) && results.push("OK")
|
||||
res = 5 && results.push("OK")
|
||||
|
||||
test("shortcircuit1", results.length === 5);
|
||||
for (i = 0; i < results.length; ++i) {
|
||||
test("shortcircuit" + (2 + i), results[i] === "OK");
|
||||
}
|
||||
|
||||
res = true || tprint('1');
|
||||
res = (true && true) || tprint('2');
|
||||
res = 1 > 0 || tprint('3');
|
||||
res = false && tprint('4');
|
||||
res = 1 < 0 && tprint('5');
|
||||
test("shortcircuit7", results.length === 5);
|
||||
|
||||
//Conditional Statements
|
||||
results = [];
|
||||
i = 1;
|
||||
if (i == 0) {
|
||||
results.push("FAIL");
|
||||
} else if (i == 2) {
|
||||
results.push("FAIL");
|
||||
} else if (i == 1) {
|
||||
results.push("OK");
|
||||
} else {
|
||||
results.push("FAIL");
|
||||
}
|
||||
|
||||
i = 5;
|
||||
if (i == 0) {
|
||||
results.push("FAIL");
|
||||
} else if (i == 2) {
|
||||
results.push("FAIL");
|
||||
} else if (i == 1) {
|
||||
results.push("FAIL");
|
||||
} else {
|
||||
results.push("OK");
|
||||
}
|
||||
|
||||
test("conditional1", results.length === 2);
|
||||
test("conditional2", results[0] === "OK");
|
||||
test("conditional3", results[1] === "OK");
|
||||
|
||||
run("tb_multiarray.script", 1, "OK");
|
||||
exec("tb_ports.script", "home", 1, "OK");
|
||||
|
||||
write("tb_results.txt", ",tb_basic");
|
4
netscript_tests/tb_foo.script
Normal file
4
netscript_tests/tb_foo.script
Normal file
@ -0,0 +1,4 @@
|
||||
while(true) {
|
||||
print("hi");
|
||||
sleep(5000);
|
||||
}
|
119
netscript_tests/tb_functions.script
Normal file
119
netscript_tests/tb_functions.script
Normal file
@ -0,0 +1,119 @@
|
||||
import {test} from "tb_basic.script";
|
||||
|
||||
test("run", (args.length === 1 && args[0] === "OK"));
|
||||
|
||||
//scan
|
||||
res = scan();
|
||||
test("scan1", res.includes("iron-gym") && res.includes("foodnstuff") &&
|
||||
res.includes("sigma-cosmetics") && res.includes("joesguns") &&
|
||||
res.includes("hong-fang-tea") && res.includes("harakiri-sushi"));
|
||||
test("scan2", res.length === 6);
|
||||
res = scan("foodnstuff");
|
||||
test("scan3", res.includes("home"));
|
||||
|
||||
//hasRootAccess and nuke
|
||||
svr = "foodnstuff";
|
||||
test("hasRootAccess1", !hasRootAccess(svr));
|
||||
test("nuke", nuke(svr));
|
||||
test("hasRootAccess2", hasRootAccess(svr));
|
||||
|
||||
//sleep and Date.now();
|
||||
time = Date.now();
|
||||
sleep(10000);
|
||||
time2 = Date.now();
|
||||
test("sleep", time2 - time > 8000);
|
||||
|
||||
//hack, grow, weaken, and their effects
|
||||
FORTIFYAMOUNT = 0.002;
|
||||
WEAKENAMOUNT = 0.05;
|
||||
|
||||
playerStartingMoney = getServerMoneyAvailable("home");
|
||||
serverStartingMoney = getServerMoneyAvailable("foodnstuff");
|
||||
startingSecLvl = getServerSecurityLevel("foodnstuff");
|
||||
|
||||
res = hack(svr);
|
||||
|
||||
playerEndingMoney = getServerMoneyAvailable("home");
|
||||
serverEndingMoney = getServerMoneyAvailable("foodnstuff");
|
||||
endingSecLvl = getServerSecurityLevel("foodnstuff");
|
||||
|
||||
success = !(res == 0);
|
||||
|
||||
if (success) {
|
||||
tprint("Hack succeeded");
|
||||
test("hackplyrmoney", res === (playerEndingMoney - playerStartingMoney));
|
||||
test("hacksvrmoney", res === (serverStartingMoney - serverEndingMoney));
|
||||
//Dumb JS precision
|
||||
test("seclevel", (endingSecLvl - startingSecLvl) - FORTIFYAMOUNT < 1e2 * Number.EPSILON);
|
||||
} else {
|
||||
tprint("Hack failed");
|
||||
test("hackres", res === 0);
|
||||
test("hackplymoney", playerEndingMoney === playerStartingMoney);
|
||||
test("hacksvrmoney", serverEndingMoney === serverStartingMoney);
|
||||
test("seclevel", endingSecLvl === startingSecLvl);
|
||||
}
|
||||
|
||||
serverStartingMoney = getServerMoneyAvailable(svr);
|
||||
res = grow(svr);
|
||||
serverEndingMoney = getServerMoneyAvailable(svr);
|
||||
test("grow", serverEndingMoney > serverStartingMoney);
|
||||
test("growtest", res * serverStartingMoney - serverEndingMoney < Number.EPSILON);
|
||||
|
||||
startingSecLvl = getServerSecurityLevel(svr);
|
||||
res = weaken(svr);
|
||||
endingSecLvl = getServerSecurityLevel(svr);
|
||||
test("weaken", res === WEAKENAMOUNT);
|
||||
test("weakenres", startingSecLvl - endingSecLvl - res < 1e2 * Number.EPSILON);
|
||||
|
||||
//misc getter functions
|
||||
test("getHostname", getHostname() === "home");
|
||||
test("getHackingLevel", getHackingLevel() >= 1); //Can vary based on aug mults
|
||||
res = getHackingMultipliers();
|
||||
test("getHackingMultipliers", res.chance >= 1 && res.speed >= 1 &&
|
||||
res.money >= 1 && res.growth >= 1);
|
||||
svr = "joesguns";
|
||||
baseSecLvl = getServerBaseSecurityLevel(svr);
|
||||
minSecLvl = getServerMinSecurityLevel(svr);
|
||||
test("getServerBase/MinSecurityLevel1", minSecLvl < baseSecLvl);
|
||||
test("getServerBase/MinSecurityLevel1", minSecLvl === Math.max(1, Math.round(baseSecLvl / 3)));
|
||||
test("getServerRequiredHackingLevel", getServerRequiredHackingLevel(svr) === 10);
|
||||
test("getServerMaxMoney", getServerMaxMoney(svr) > getServerMoneyAvailable(svr)); //Can vary by BN
|
||||
test("getServerGrowth", getServerGrowth(svr) >= 1); //Can vary by BN
|
||||
test("getServerNumPortsRequired1", getServerNumPortsRequired(svr) === 0);
|
||||
test("getServerNumPortsRequired1", getServerNumPortsRequired("neo-net") === 1);
|
||||
test("getServerRam", getServerRam("home")[0] === 8 ||
|
||||
getServerRam("home")[0] === 16 ||
|
||||
getServerRam("home")[0] === 32);
|
||||
test("serverExists1", serverExists("home"));
|
||||
test("serverExists2", !serverExists("foofooofofofof"));
|
||||
test("fileExists1", fileExists("tb_start.script"));
|
||||
test("fileExists2", !fileExists("tosdifoodafgbiofdagbaod.txt"));
|
||||
|
||||
//run a misc script
|
||||
test("isRunning1", !isRunning("tb_foo.script", "home"));
|
||||
run("tb_foo.script", 1, 1, 2, 3);
|
||||
test("isRunning2", !isRunning("tb_foo.script", "home", "foo"));
|
||||
test("isRunning3", isRunning("tb_foo.script", "home", 1, 2, 3));
|
||||
|
||||
//kill
|
||||
kill("tb_foo.script", "home", "fee");
|
||||
sleep(10000);
|
||||
test("isRunning4", isRunning("tb_foo.script", "home", 1, 2, 3));
|
||||
kill("tb_foo.script", "home", 1, 2, 3);
|
||||
sleep(10000);
|
||||
test("isRunning4", !isRunning("tb_foo.script", "home", 1, 2, 3));
|
||||
|
||||
//scp
|
||||
svr = "foodnstuff";
|
||||
test("fileExists3", !fileExists("tb_remote.script", svr));
|
||||
test("fileExists4", !fileExists("tb_basic.script", svr));
|
||||
scp("tb_remote.script", "home", svr);
|
||||
scp("tb_basic.script", svr);
|
||||
test("fileExists5", fileExists("tb_remote.script", svr));
|
||||
test("fileExists6", fileExists("tb_basic.script", svr));
|
||||
|
||||
write("tb_results.txt", ",tb_functions"); //Done, pretty much
|
||||
|
||||
//exec and spawn
|
||||
exec("tb_remote.script", "foodnstuff", 1, "OK");
|
||||
spawn("tb_functions2.script", 1, "OK");
|
90
netscript_tests/tb_multiarray.script
Normal file
90
netscript_tests/tb_multiarray.script
Normal file
@ -0,0 +1,90 @@
|
||||
//Tests for multidimensional arrays
|
||||
import {test} from "tb_basic.script";
|
||||
|
||||
runSuccess = (args.length === 1 && args[0] === "OK");
|
||||
test("run", runSuccess);
|
||||
|
||||
arr = [];
|
||||
arr[0] = [];
|
||||
arr[1] = [];
|
||||
arr.push([]);
|
||||
|
||||
test("multiarr1", arr.toString() === ",,");
|
||||
test("multiarr2", arr.length === 3);
|
||||
arr[0].push(0);
|
||||
arr[0].push(0);
|
||||
arr[0].push(0);
|
||||
test("multiarr3", arr[0].length === 3);
|
||||
test("multiarr4", arr[0].toString() === "0,0,0");
|
||||
arr[1] = [0, 0, 0];
|
||||
test("multiarr5", arr.length === 3);
|
||||
test("multiarr6", arr[1].length === 3);
|
||||
test("multiarr7", arr[1].toString() === "0,0,0");
|
||||
arr.pop();
|
||||
arr.push([0,0,0]);
|
||||
test("multiarr8", arr.length === 3);
|
||||
test("multiarr9", arr[2].length === 3);
|
||||
test("multiarr10", "0,0,0,0,0,0,0,0,0" === arr.toString());
|
||||
for (r = 0; r < arr.length; ++r) {
|
||||
for (c = 0; c < arr[r].length; ++c) {
|
||||
arr[r][c] = r * 3 + c + 1;
|
||||
}
|
||||
}
|
||||
test("multiarr11", "1,2,3,4,5,6,7,8,9" === arr.toString());
|
||||
|
||||
arr = [[0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0]];
|
||||
test("multiarr12", 4 === arr.length);
|
||||
for (i = 0; i < arr.length; ++i) {
|
||||
test("multiarr" + (13 + i), arr[i].length === 4);
|
||||
}
|
||||
|
||||
for (r = 0; r < arr.length; ++r) {
|
||||
for (c = 0; c < arr[r].length; ++c) {
|
||||
arr[r][c] = r * 10 + c + 1;
|
||||
}
|
||||
}
|
||||
|
||||
test("multiarr17", arr.toString() === "1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34");
|
||||
|
||||
|
||||
//3D array
|
||||
arr = [[], [], [], []];
|
||||
arr[0].push([0, 0, 0]);
|
||||
arr[0].push([0, 0, 0]);
|
||||
arr[0].push([0, 0, 0]);
|
||||
|
||||
arr[1].push([0, 0, 0]);
|
||||
arr[1].push([0, 0, 0]);
|
||||
arr[1].push([0, 0, 0]);
|
||||
|
||||
arr[2].push([0, 0, 0]);
|
||||
arr[2].push([0, 0, 0]);
|
||||
arr[2].push([0, 0, 0]);
|
||||
|
||||
arr[3].push([0, 0, 0]);
|
||||
arr[3].push([0, 0, 0]);
|
||||
arr[3].push([0, 0, 0]);
|
||||
|
||||
i = 0;
|
||||
|
||||
for (r = 0; r < arr.length; ++r) {
|
||||
for (c = 0; c < arr[r].length; ++c) {
|
||||
for (d = 0; d < arr[r][c].length; ++d) {
|
||||
arr[r][c][d] = i;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test("multiarr18", "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35" === arr.toString());
|
||||
ref = 0;
|
||||
for (r = 0; r < arr.length; ++r) {
|
||||
for (c = 0; c < arr[r].length; ++c) {
|
||||
for (d = 0; d < arr[r][c].length; ++d) {
|
||||
test("multiarr" + (19 + ref), arr[r][c][d] === ref);
|
||||
++ref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write("tb_results.txt", ",tb_multiarray");
|
73
netscript_tests/tb_ports.script
Normal file
73
netscript_tests/tb_ports.script
Normal file
@ -0,0 +1,73 @@
|
||||
import {test} from "tb_basic.script";
|
||||
|
||||
test("run", (args.length === 1 && args[0] === "OK"));
|
||||
|
||||
|
||||
MAXPORTS = 20;
|
||||
MAXPORTSIZE = 100;
|
||||
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
clear(i);
|
||||
}
|
||||
|
||||
//write
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
for (j = 1; j <= 5; ++j) {
|
||||
write(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
port = getPortHandle(i);
|
||||
test("write" + i, port.data.length === 5);
|
||||
}
|
||||
|
||||
//read
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
for (j = 1; j <= 2; ++j) {
|
||||
res = read(i);
|
||||
test("read-p" + i + "-" + j, res === j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
port = getPortHandle(i); //Check that read removes elements
|
||||
test("readpops" + i, port.data.length === 3);
|
||||
}
|
||||
|
||||
//peek
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
test("peek" + i, peek(i) === 3);
|
||||
port = getPortHandle(i);
|
||||
test("peeknopop" + i, port.data.length === 3);
|
||||
}
|
||||
|
||||
//clear and empty
|
||||
for (i = 1; i <= MAXPORTS; ++i) {
|
||||
clear(i);
|
||||
port = getPortHandle(i);
|
||||
test("clear" + i, port.data.length === 0);
|
||||
test("empty" + i, port.empty());
|
||||
}
|
||||
|
||||
//Write so that the port is full (only port 1 for this)
|
||||
for (i = 0; i < MAXPORTSIZE + 1; ++i) {
|
||||
write(1, i)
|
||||
}
|
||||
|
||||
//full
|
||||
port = getPortHandle(1);
|
||||
test("full", port.full());
|
||||
test("notempty", !port.empty());
|
||||
|
||||
//tryWrite
|
||||
firstElem = peek(1);
|
||||
test("trywritefails", !port.tryWrite("foo"));
|
||||
test("trywritenochange", peek(1) === firstElem);
|
||||
read(1);
|
||||
test("trywritesucceeds", port.tryWrite("foo"));
|
||||
test("trywritewrites", port.data.pop() === "foo");
|
||||
test("notfull", !port.full());
|
||||
|
||||
write("tb_results.txt", ",tb_ports");
|
||||
run("tb_functions.script", 1, "OK");
|
17
netscript_tests/tb_remote.script
Normal file
17
netscript_tests/tb_remote.script
Normal file
@ -0,0 +1,17 @@
|
||||
import {test} from "tb_basic.script";
|
||||
|
||||
test("run", args.length === 1 && args[0] === "OK");
|
||||
|
||||
svr = "foodnstuff";
|
||||
test("getHostname", getHostname() === svr);
|
||||
//ls
|
||||
res = ls(svr);
|
||||
test("ls1", res.includes("sector-12-crime.lit"));
|
||||
test("ls2", res.includes("tb_remote.script"));
|
||||
test("ls3", res.includes("tb_basic.script"));
|
||||
test("ls4", res.length === 3);
|
||||
res = ls(svr, ".lit");
|
||||
test("ls5", res.length === 1);
|
||||
test("ls6", res.includes("sector-12-crime.lit"));
|
||||
|
||||
write("tb_results.txt", "tb_remote");
|
35
netscript_tests/tb_start.script
Normal file
35
netscript_tests/tb_start.script
Normal file
@ -0,0 +1,35 @@
|
||||
tprint("Beginning testbench. A soft reset MUST be performed before running this.");
|
||||
tprint("This should be run on a Bitnode between 1 and 7, with $100k+, 16GB RAM+ " +
|
||||
"and access to Singularity functions otherwise some tests may fail");
|
||||
|
||||
run("tb_basic.script", 1, "OK");
|
||||
write("tb_results.txt", "tb_start", "w");
|
||||
|
||||
while(true) {
|
||||
sleep(10000);
|
||||
res = read("tb_results.txt");
|
||||
if (res.includes("FAIL")) {
|
||||
tprint("TESTBENCH FAILED");
|
||||
killall();
|
||||
}
|
||||
if (res.includes("tb_start") && res.includes("tb_basic") &&
|
||||
res.includes("tb_ports") && res.includes("tb_multiarray") &&
|
||||
res.includes("tb_functions")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Check remote
|
||||
scp("tb_results.txt", "foodnstuff", "home");
|
||||
res = read("tb_results.txt");
|
||||
if (res.includes("FAIL")) {
|
||||
tprint("TESTBENCH FAILED");
|
||||
killall();
|
||||
}
|
||||
if (res.includes("tb_remote")) {
|
||||
tprint("TESTBENCH SUCCESS");
|
||||
} else {
|
||||
tprint("TESTBENCH FAILED");
|
||||
killall();
|
||||
}
|
@ -51,7 +51,7 @@ function initBitNodes() {
|
||||
"In this BitNode you can create and manage your own corporation. Running a successful corporation " +
|
||||
"has the potential of generating massive profits. All other forms of income are reduced by 75%. Furthermore: <br><br>" +
|
||||
"The price and reputation cost of all Augmentations is tripled<br>" +
|
||||
"The starting and maximum amount of money on servers is halved<br>" +
|
||||
"The starting and maximum amount of money on servers is reduced by 75%<br>" +
|
||||
"Server growth rate is reduced by 80%<br>" +
|
||||
"You will start out with $150b so that you can start your corporation<br>" +
|
||||
"You now only need 75 reputation with a faction in order to donate to it, rather than 150<br><br>" +
|
||||
@ -81,6 +81,7 @@ function initBitNodes() {
|
||||
"The starting money on servers is halved, but the maximum money remains the same<br>" +
|
||||
"Most methods of earning money now give significantly less<br>" +
|
||||
"Infiltration gives 50% more reputation and money<br>" +
|
||||
"Corporations have 50% lower valuations and are therefore less profitable<br>" +
|
||||
"Augmentations are more expensive<br>" +
|
||||
"Hacking experience gain rates are reduced<br><br>" +
|
||||
"Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will " +
|
||||
@ -125,6 +126,7 @@ function initBitNodes() {
|
||||
"The growth rate of servers is halved<br>" +
|
||||
"Weakening a server is twice as effective<br>" +
|
||||
"Company wages are decreased by 50%<br>" +
|
||||
"Corporation valuations are 99% lower and are therefore significantly less profitable<br>" +
|
||||
"Hacknet Node production is significantly decreased<br>" +
|
||||
"Crime and Infiltration are more lucrative<br>" +
|
||||
"Augmentations are twice as expensive<br><br>" +
|
||||
@ -137,11 +139,11 @@ function initBitNodes() {
|
||||
"Level 3: 42%");
|
||||
|
||||
//Books: Frontera, Shiner
|
||||
BitNodes["BitNode12"] = new BitNode(12, "Eye of the World", "COMING SOON"); //Become AI
|
||||
BitNodes["BitNode12"] = new BitNode(12, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode13"] = new BitNode(13, "", "COMING SOON");
|
||||
BitNodes["BitNode14"] = new BitNode(14, "", "COMING SOON");
|
||||
BitNodes["BitNode15"] = new BitNode(15, "", "COMING SOON");
|
||||
BitNodes["BitNode16"] = new BitNode(16, "fOS", "COMING SOON"); //Unlocks the new game mode and the rest of the BitNodes
|
||||
BitNodes["BitNode16"] = new BitNode(16, "", "COMING SOON");
|
||||
BitNodes["BitNode17"] = new BitNode(17, "", "COMING SOON");
|
||||
BitNodes["BitNode18"] = new BitNode(18, "", "COMING SOON");
|
||||
BitNodes["BitNode19"] = new BitNode(19, "", "COMING SOON");
|
||||
@ -150,14 +152,6 @@ function initBitNodes() {
|
||||
BitNodes["BitNode22"] = new BitNode(22, "", "COMING SOON");
|
||||
BitNodes["BitNode23"] = new BitNode(23, "", "COMING SOON");
|
||||
BitNodes["BitNode24"] = new BitNode(24, "", "COMING SOON");
|
||||
BitNodes["BitNode25"] = new BitNode(25, "", "COMING SOON");
|
||||
BitNodes["BitNode26"] = new BitNode(26, "", "COMING SOON");
|
||||
BitNodes["BitNode27"] = new BitNode(27, "", "COMING SOON");
|
||||
BitNodes["BitNode28"] = new BitNode(28, "", "COMING SOON");
|
||||
BitNodes["BitNode29"] = new BitNode(29, "", "COMING SOON");
|
||||
BitNodes["BitNode30"] = new BitNode(30, "", "COMING SOON");
|
||||
BitNodes["BitNode31"] = new BitNode(31, "", "COMING SOON");
|
||||
BitNodes["BitNode32"] = new BitNode(32, "", "COMING SOON");
|
||||
}
|
||||
|
||||
let BitNodeMultipliers = {
|
||||
@ -188,6 +182,8 @@ let BitNodeMultipliers = {
|
||||
|
||||
InfiltrationMoney: 1,
|
||||
InfiltrationRep: 1,
|
||||
|
||||
CorporationValuation: 1,
|
||||
}
|
||||
|
||||
function initBitNodeMultipliers() {
|
||||
@ -215,8 +211,8 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.RepToDonateToFaction = 0.5;
|
||||
BitNodeMultipliers.AugmentationRepCost = 3;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 3;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.50;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.50;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.25;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.25;
|
||||
BitNodeMultipliers.ServerGrowthRate = 0.20;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.25;
|
||||
BitNodeMultipliers.CompanyWorkMoney = 0.25;
|
||||
@ -241,13 +237,14 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.ServerMaxMoney = 2;
|
||||
BitNodeMultipliers.ServerStartingSecurity = 2;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.5;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.2;
|
||||
BitNodeMultipliers.ScriptHackMoney = 0.15;
|
||||
BitNodeMultipliers.HacknetNodeMoney = 0.2;
|
||||
BitNodeMultipliers.CrimeMoney = 0.5;
|
||||
BitNodeMultipliers.InfiltrationRep = 1.5;
|
||||
BitNodeMultipliers.InfiltrationMoney = 1.5;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 2;
|
||||
BitNodeMultipliers.HackExpGain = 0.5;
|
||||
BitNodeMultipliers.CorporationValuation = 0.5;
|
||||
break;
|
||||
case 8: //Ghost of Wall Street
|
||||
BitNodeMultipliers.ScriptHackMoney = 0;
|
||||
@ -256,7 +253,8 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.CrimeMoney = 0;
|
||||
BitNodeMultipliers.HacknetNodeMoney = 0;
|
||||
BitNodeMultipliers.InfiltrationMoney = 0;
|
||||
BitNodeMultipliers.RepToDonateToFaction = 0
|
||||
BitNodeMultipliers.RepToDonateToFaction = 0;
|
||||
BitNodeMultipliers.CorporationValuation = 0;
|
||||
break;
|
||||
case 11: //The Big Crash
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.1;
|
||||
@ -269,6 +267,7 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 2;
|
||||
BitNodeMultipliers.InfiltrationMoney = 2.5;
|
||||
BitNodeMultipliers.InfiltrationRep = 2.5;
|
||||
BitNodeMultipliers.CorporationValuation = 0.01;
|
||||
break;
|
||||
default:
|
||||
console.log("WARNING: Player.bitNodeN invalid");
|
||||
|
@ -1,3 +1,4 @@
|
||||
import {BitNodeMultipliers} from "./BitNode.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {showLiterature} from "./Literature.js";
|
||||
import {Locations} from "./Location.js";
|
||||
@ -64,6 +65,9 @@ var OfficeInitialCost = 4e9;
|
||||
var OfficeInitialSize = 3;
|
||||
var OfficeUpgradeBaseCost = 1e9;
|
||||
|
||||
var BribeThreshold = 100e12; //Money needed to be able to bribe for faction rep
|
||||
var BribeToRepRatio = 1e9; //Bribe Value divided by this = rep gain
|
||||
|
||||
function Material(params={}) {
|
||||
this.name = params.name ? params.name : "";
|
||||
this.qty = 0; //Quantity
|
||||
@ -101,67 +105,67 @@ Material.prototype.init = function(mats={}) {
|
||||
this.dmd = 75; this.dmdR = [65, 85];
|
||||
this.cmp = 50; this.cmpR = [40, 60];
|
||||
this.bCost = 1000; this.mv = 0.2;
|
||||
this.mku = 12;
|
||||
this.mku = 6;
|
||||
break;
|
||||
case "Energy":
|
||||
this.dmd = 90; this.dmdR = [80, 100];
|
||||
this.cmp = 80; this.cmpR = [65, 95];
|
||||
this.bCost = 1500; this.mv = 0.2;
|
||||
this.mku = 12;
|
||||
this.mku = 6;
|
||||
break;
|
||||
case "Food":
|
||||
this.dmd = 80; this.dmdR = [70, 90];
|
||||
this.cmp = 60; this.cmpR = [35, 85];
|
||||
this.bCost = 5000; this.mv = 1;
|
||||
this.mku = 7.5;
|
||||
this.mku = 3;
|
||||
break;
|
||||
case "Plants":
|
||||
this.dmd = 70; this.dmdR = [20, 90];
|
||||
this.cmp = 50; this.cmpR = [30, 70];
|
||||
this.bCost = 3000; this.mv = 0.6;
|
||||
this.mku = 10;
|
||||
this.mku = 3.75;
|
||||
break;
|
||||
case "Metal":
|
||||
this.dmd = 80; this.dmdR = [75, 85];
|
||||
this.cmp = 70; this.cmpR = [60, 80];
|
||||
this.bCost = 2650; this.mv = 1;
|
||||
this.mku = 12;
|
||||
this.mku = 6;
|
||||
break;
|
||||
case "Hardware":
|
||||
this.dmd = 85; this.dmdR = [80, 90];
|
||||
this.cmp = 80; this.cmpR = [65, 95];
|
||||
this.bCost = 4000; this.mv = 0.5; //Less mv bc its processed twice
|
||||
this.mku = 5.5;
|
||||
this.mku = 1;
|
||||
break;
|
||||
case "Chemicals":
|
||||
this.dmd = 55; this.dmdR = [40, 70];
|
||||
this.cmp = 60; this.cmpR = [40, 80];
|
||||
this.bCost = 6750; this.mv = 1.2;
|
||||
this.mku = 6.5;
|
||||
this.mku = 2;
|
||||
break;
|
||||
case "Real Estate":
|
||||
this.dmd = 50; this.dmdR = [5, 100];
|
||||
this.cmp = 50; this.cmpR = [25, 75];
|
||||
this.bCost = 16e3; this.mv = 1.5; //Less mv bc its processed twice
|
||||
this.mku = 5;
|
||||
this.mku = 1.5;
|
||||
break;
|
||||
case "Drugs":
|
||||
this.dmd = 60; this.dmdR = [45, 75];
|
||||
this.cmp = 70; this.cmpR = [40, 100];
|
||||
this.bCost = 8e3; this.mv = 1.6;
|
||||
this.mku = 4;
|
||||
this.mku = 1;
|
||||
break;
|
||||
case "Robots":
|
||||
this.dmd = 90; this.dmdR = [80, 100];
|
||||
this.cmp = 90; this.cmpR = [80, 100];
|
||||
this.bCost = 20e3; this.mv = 0.5; //Less mv bc its processed twice
|
||||
this.mku = 2.5;
|
||||
this.mku = 1;
|
||||
break;
|
||||
case "AI Cores":
|
||||
this.dmd = 90; this.dmdR = [80, 100];
|
||||
this.cmp = 90; this.cmpR = [80, 100];
|
||||
this.bCost = 27e3; this.mv = 0.8; //Less mv bc its processed twice
|
||||
this.mku = 1.8;
|
||||
this.mku = 0.5;
|
||||
break;
|
||||
case "Scientific Research":
|
||||
break;
|
||||
@ -352,8 +356,7 @@ Product.prototype.finishProduct = function(employeeProd, industry) {
|
||||
(0.05 * employeeProd[EmployeePositions.Business]));
|
||||
this.calculateRating(industry);
|
||||
var advMult = 1 + (Math.pow(this.advCost, 0.1) / 100);
|
||||
console.log("advMult: " + advMult);
|
||||
this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.9) * (busRatio + mgmtRatio));
|
||||
this.mku = 100 / (advMult * Math.pow((this.qlt + 0.001), 0.75) * (busRatio + mgmtRatio));
|
||||
this.dmd = industry.awareness === 0 ? 20 : Math.min(100, advMult * (100 * (industry.popularity / industry.awareness)));
|
||||
this.cmp = getRandomInt(0, 70);
|
||||
|
||||
@ -548,11 +551,11 @@ var ProductRatingWeights = {
|
||||
var IndustryUpgrades = {
|
||||
"0": [0, 500e3, 1, 1.05,
|
||||
"Coffee", "Provide your employees with coffee, increasing their energy by 5%."],
|
||||
"1": [1, 1e9, 1.02, 1.01,
|
||||
"1": [1, 1e9, 1.03, 1.03,
|
||||
"AdVert.Inc", "Hire AdVert.Inc to advertise your company. Each level of " +
|
||||
"this upgrade grants your company a static increase of 4 and 1 to its awareness and " +
|
||||
"popularity, respectively. It will then increase your company's awareness by 1%, and its popularity " +
|
||||
"by a random percentage between 5% and 10%. These effects are increased by other upgrades " +
|
||||
"by a random percentage between 3% and 6%. These effects are increased by other upgrades " +
|
||||
"that increase the power of your advertising."]
|
||||
}
|
||||
|
||||
@ -626,6 +629,7 @@ function Industry(params={}) {
|
||||
this.upgrades = Array(numUpgrades).fill(0);
|
||||
|
||||
this.state = "START";
|
||||
this.newInd = true;
|
||||
|
||||
this.init();
|
||||
}
|
||||
@ -915,6 +919,10 @@ Industry.prototype.process = function(marketCycles=1, state, company) {
|
||||
this.thisCycleRevenue = new Decimal(0);
|
||||
this.thisCycleExpenses = new Decimal(0);
|
||||
|
||||
//Once you start making revenue, the player should no longer be
|
||||
//considered new, and therefore no longer needs the 'tutorial' UI elements
|
||||
if (this.lastCycleRevenue.gt(0)) {this.newInd = false;}
|
||||
|
||||
//Process offices (and the employees in them)
|
||||
var employeeSalary = 0;
|
||||
for (var officeLoc in this.offices) {
|
||||
@ -1256,7 +1264,9 @@ Industry.prototype.processProducts = function(marketCycles=1, corporation) {
|
||||
var prod = this.products[prodName];
|
||||
if (!prod.fin) {
|
||||
var city = prod.createCity, office = this.offices[city];
|
||||
var total = office.employeeProd["total"], ratio;
|
||||
var total = office.employeeProd[EmployeePositions.Operations] +
|
||||
office.employeeProd[EmployeePositions.Engineer] +
|
||||
office.employeeProd[EmployeePositions.Management], ratio;
|
||||
if (total === 0) {
|
||||
ratio = 0;
|
||||
} else {
|
||||
@ -1437,7 +1447,7 @@ Industry.prototype.upgrade = function(upgrade, refs) {
|
||||
this.awareness += (4 * advMult);
|
||||
this.popularity += (1 * advMult);
|
||||
this.awareness *= (1.01 * advMult);
|
||||
this.popularity *= ((1 + getRandomInt(5, 10) / 100) * advMult);
|
||||
this.popularity *= ((1 + getRandomInt(3, 6) / 100) * advMult);
|
||||
break;
|
||||
default:
|
||||
console.log("ERROR: Un-implemented function index: " + upgN);
|
||||
@ -2121,7 +2131,6 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
class:"cmpy-mgmt-warehouse-material-div",
|
||||
});
|
||||
|
||||
//Storage size
|
||||
var totalExport = 0;
|
||||
for (var i = 0; i < mat.exp.length; ++i) {
|
||||
totalExport += mat.exp[i].amt;
|
||||
@ -2160,17 +2169,27 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
div.appendChild(buttonPanel);
|
||||
|
||||
//Button to set purchase amount
|
||||
buttonPanel.appendChild(createElement("a", {
|
||||
innerText: "Buy (" + formatNumber(mat.buy, 3) + ")", display:"inline-block", class:"a-link-button",
|
||||
var tutorial = industry.newInd && Object.keys(industry.reqMats).includes(mat.name) &&
|
||||
mat.buy === 0 && mat.imp === 0;
|
||||
var buyButtonParams = {
|
||||
innerText: "Buy (" + formatNumber(mat.buy, 3) + ")", display:"inline-block",
|
||||
class: tutorial ? "a-link-button flashing-button" : "a-link-button",
|
||||
clickListener:()=>{
|
||||
var txt = createElement("p", {
|
||||
innerHTML: "Enter the amount of " + mat.name + " you would like " +
|
||||
"to purchase per second. This material's cost changes constantly"
|
||||
});
|
||||
var confirmBtn;
|
||||
var input = createElement("input", {
|
||||
type:"number", value:mat.buy ? mat.buy : null, placeholder: "Purchase amount"
|
||||
type:"number", value:mat.buy ? mat.buy : null, placeholder: "Purchase amount",
|
||||
onkeyup:(e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === 13) {
|
||||
confirmBtn.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
var confirmBtn = createElement("a", {
|
||||
confirmBtn = createElement("a", {
|
||||
innerText:"Confirm", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
if (isNaN(input.value)) {
|
||||
@ -2184,16 +2203,29 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
}
|
||||
}
|
||||
});
|
||||
var clearButton = createElement("a", {
|
||||
innerText:"Clear Purchase", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
mat.buy = 0;
|
||||
removeElementById(purchasePopupId);
|
||||
this.createUI(parentRefs);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
var cancelBtn = createElement("a", {
|
||||
innerText:"Cancel", class:"a-link-button",
|
||||
clickListener:()=>{
|
||||
removeElementById(purchasePopupId);
|
||||
}
|
||||
});
|
||||
createPopup(purchasePopupId, [txt, input, confirmBtn, cancelBtn]);
|
||||
createPopup(purchasePopupId, [txt, input, confirmBtn, clearButton, cancelBtn]);
|
||||
input.focus();
|
||||
}
|
||||
}));
|
||||
};
|
||||
if (tutorial) {
|
||||
buyButtonParams.tooltip = "Purchase your required materials to get production started!";
|
||||
}
|
||||
buttonPanel.appendChild(createElement("a", buyButtonParams));
|
||||
|
||||
//Button to manage exports
|
||||
if (company.unlockUpgrades[0] === 1) { //Export unlock upgrade
|
||||
@ -2366,15 +2398,24 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
|
||||
"to 'MP+10' then it will always be sold at $10 above the market price.",
|
||||
});
|
||||
var br = createElement("br", {});
|
||||
var confirmBtn;
|
||||
var inputQty = createElement("input", {
|
||||
type:"text", marginTop:"4px",
|
||||
value: mat.sllman[1] ? mat.sllman[1] : null, placeholder: "Sell amount"
|
||||
value: mat.sllman[1] ? mat.sllman[1] : null, placeholder: "Sell amount",
|
||||
onkeyup:(e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === 13) {confirmBtn.click();}
|
||||
}
|
||||
});
|
||||
var inputPx = createElement("input", {
|
||||
type:"text", marginTop:"4px",
|
||||
value: mat.sCost ? mat.sCost : null, placeholder: "Sell price"
|
||||
value: mat.sCost ? mat.sCost : null, placeholder: "Sell price",
|
||||
onkeyup:(e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === 13) {confirmBtn.click();}
|
||||
}
|
||||
});
|
||||
var confirmBtn = createElement("a", {
|
||||
confirmBtn = createElement("a", {
|
||||
innerText:"Confirm", class:"a-link-button", margin:"6px",
|
||||
clickListener:()=>{
|
||||
//Parse price
|
||||
@ -2501,13 +2542,22 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
"Setting the sell amount to 'MAX' will result in you always selling the " +
|
||||
"maximum possible amount of the material.<br><br>",
|
||||
});
|
||||
var confirmBtn;
|
||||
var inputQty = createElement("input", {
|
||||
type:"text", value:product.sllman[city][1] ? product.sllman[city][1] : null, placeholder: "Sell amount"
|
||||
type:"text", value:product.sllman[city][1] ? product.sllman[city][1] : null, placeholder: "Sell amount",
|
||||
onkeyup:(e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === 13) {confirmBtn.click();}
|
||||
}
|
||||
});
|
||||
var inputPx = createElement("input", {
|
||||
type:"text", value: product.sCost ? product.sCost : null, placeholder: "Sell price"
|
||||
type:"text", value: product.sCost ? product.sCost : null, placeholder: "Sell price",
|
||||
onkeyup:(e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === 13) {confirmBtn.click();}
|
||||
}
|
||||
});
|
||||
var confirmBtn = createElement("a", {
|
||||
confirmBtn = createElement("a", {
|
||||
class:"a-link-button", innerText:"Confirm",
|
||||
clickListener:()=>{
|
||||
//Parse price
|
||||
@ -2566,10 +2616,15 @@ Warehouse.prototype.createProductUI = function(product, parentRefs) {
|
||||
innerText:"Enter a limit to the amount of this product you would " +
|
||||
"like to product per second. Leave the box empty to set no limit."
|
||||
});
|
||||
var confirmBtn;
|
||||
var input = createElement("input", {
|
||||
type:"number", placeholder:"Limit"
|
||||
type:"number", placeholder:"Limit",
|
||||
onkeyup:(e)=>{
|
||||
e.preventDefault();
|
||||
if (e.keyCode === 13) {confirmBtn.click();}
|
||||
}
|
||||
});
|
||||
var confirmBtn = createElement("a", {
|
||||
confirmBtn = createElement("a", {
|
||||
class:"a-link-button", display:"inline-block", innerText:"Limit production", margin:'6px',
|
||||
clickListener:()=>{
|
||||
if (input.value === "") {
|
||||
@ -2698,10 +2753,10 @@ var CorporationUpgrades = {
|
||||
"20 seconds."],
|
||||
|
||||
//Makes advertising more effective
|
||||
"3": [3, 4e9, 1.11, 0.1,
|
||||
"3": [3, 4e9, 1.12, 0.01,
|
||||
"Wilson Analytics", "Purchase data and analysis from Wilson, a marketing research " +
|
||||
"firm. Each level of this upgrades increases the effectiveness of your " +
|
||||
"advertising by 10% (additive)."],
|
||||
"advertising by 1% (additive)."],
|
||||
|
||||
//Augmentation for employees, increases cre
|
||||
"4": [4, 1e9, 1.06, 0.1,
|
||||
@ -2776,11 +2831,32 @@ Corporation.prototype.process = function(numCycles=1) {
|
||||
if (this.storedCycles >= CyclesPerIndustryStateCycle) {
|
||||
var state = this.getState();
|
||||
|
||||
//At the start of a new cycle, calculate profits from previous cycle
|
||||
if (state === "START") {
|
||||
this.revenue = new Decimal(0);
|
||||
this.expenses = new Decimal(0);
|
||||
this.divisions.forEach((ind)=>{
|
||||
this.revenue = this.revenue.plus(ind.lastCycleRevenue);
|
||||
this.expenses = this.expenses.plus(ind.lastCycleExpenses);
|
||||
});
|
||||
var profit = this.revenue.minus(this.expenses);
|
||||
var cycleProfit = profit.times(numMarketCyclesPersist * SecsPerMarketCycle);
|
||||
if (isNaN(this.funds)) {
|
||||
dialogBoxCreate("There was an error calculating your Corporations funds and they got reset to 0. " +
|
||||
"This is a bug. Please report to game developer.<br><br>" +
|
||||
"(Your funds have been set to $150b for the inconvenience)");
|
||||
this.funds = new Decimal(150e9);
|
||||
}
|
||||
this.funds = this.funds.plus(cycleProfit);
|
||||
this.updateSharePrice();
|
||||
}
|
||||
|
||||
//Determine number of market cycles at the START state
|
||||
if (state === "START") {
|
||||
if (this.storedCycles >= 2*CyclesPerMarketCycle) {
|
||||
//Enough cycles stored for 2+ market cycles
|
||||
numMarketCyclesPersist = Math.floor(this.storedCycles / CyclesPerMarketCycle);
|
||||
//Capped out at 3 to prevent weird behavior
|
||||
numMarketCyclesPersist = Math.max(3, Math.floor(this.storedCycles / CyclesPerMarketCycle));
|
||||
} else {
|
||||
numMarketCyclesPersist = 1;
|
||||
}
|
||||
@ -2792,25 +2868,7 @@ Corporation.prototype.process = function(numCycles=1) {
|
||||
ind.process(marketCycles, state, corp);
|
||||
});
|
||||
|
||||
//At the start of a new cycle, calculate profits from previous cycle
|
||||
if (state === "START") {
|
||||
this.revenue = new Decimal(0);
|
||||
this.expenses = new Decimal(0);
|
||||
this.divisions.forEach((ind)=>{
|
||||
this.revenue = this.revenue.plus(ind.lastCycleRevenue);
|
||||
this.expenses = this.expenses.plus(ind.lastCycleExpenses);
|
||||
});
|
||||
var profit = this.revenue.minus(this.expenses);
|
||||
var cycleProfit = profit.times(marketCycles * SecsPerMarketCycle);
|
||||
if (isNaN(this.funds)) {
|
||||
dialogBoxCreate("There was an error calculating your Corporations funds and they got reset to 0. " +
|
||||
"This is a bug. Please report to game developer.<br><br>" +
|
||||
"(Your funds have been set to $150b for the inconvenience)");
|
||||
this.funds = new Decimal(150e9);
|
||||
}
|
||||
this.funds = this.funds.plus(cycleProfit);
|
||||
this.updateSharePrice();
|
||||
}
|
||||
|
||||
this.state.nextState();
|
||||
|
||||
if (Engine.currentPage === Engine.Page.Corporation) {this.updateUIContent();}
|
||||
@ -2833,7 +2891,7 @@ Corporation.prototype.determineValuation = function() {
|
||||
}
|
||||
val -= (val % 1e6); //Round down to nearest millionth
|
||||
}
|
||||
return val;
|
||||
return val * BitNodeMultipliers.CorporationValuation;
|
||||
}
|
||||
|
||||
Corporation.prototype.getInvestment = function() {
|
||||
@ -2882,8 +2940,9 @@ Corporation.prototype.goPublic = function() {
|
||||
var txt = createElement("p", {
|
||||
innerHTML: "Enter the number of shares you would like to issue " +
|
||||
"for your IPO. These shares will be publicly sold " +
|
||||
"and you will no longer own them. You will receive " +
|
||||
numeral(initialSharePrice).format('$0.000a') + " per share.<br><br>" +
|
||||
"and you will no longer own them. Your Corporation will receive " +
|
||||
numeral(initialSharePrice).format('$0.000a') + " per share " +
|
||||
"(the IPO money will be deposited directly into your Corporation's funds).<br><br>" +
|
||||
"Furthermore, issuing more shares now will help drive up " +
|
||||
"your company's stock price in the future.<br><br>" +
|
||||
"You have a total of " + numeral(this.numShares).format("0.000a") + " of shares that you can issue.",
|
||||
@ -3166,13 +3225,22 @@ Corporation.prototype.updateUIHeaderTabs = function() {
|
||||
}
|
||||
});
|
||||
|
||||
//Make an object to keep track of what industries you're already in
|
||||
var ownedIndustries = {}
|
||||
for (var i = 0; i < this.divisions.length; ++i) {
|
||||
ownedIndustries[this.divisions[i].type] = true;
|
||||
}
|
||||
|
||||
//Add industry types to selector
|
||||
//Have Agriculture be first as recommended option
|
||||
if (!ownedIndustries["Agriculture"]) {
|
||||
selector.add(createElement("option", {
|
||||
text:Industries["Agriculture"], value:"Agriculture"
|
||||
}))
|
||||
}));
|
||||
}
|
||||
|
||||
for (var key in Industries) {
|
||||
if (key !== "Agriculture" && Industries.hasOwnProperty(key)) {
|
||||
if (key !== "Agriculture" && Industries.hasOwnProperty(key) && !ownedIndustries[key]) {
|
||||
var ind = Industries[key];
|
||||
selector.add(createElement("option", {
|
||||
text: ind,value:key,
|
||||
@ -3300,7 +3368,9 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
var popupId = "cmpy-mgmt-sell-shares-popup";
|
||||
var currentStockPrice = this.sharePrice;
|
||||
var txt = createElement("p", {
|
||||
innerHTML: "Enter the number of shares you would like to sell. The current price of your " +
|
||||
innerHTML: "Enter the number of shares you would like to sell. The money from " +
|
||||
"selling your shares will go directly to you (NOT your Corporation). " +
|
||||
"The current price of your " +
|
||||
"company's stock is " + numeral(currentStockPrice).format("$0.000a"),
|
||||
});
|
||||
var profitIndicator = createElement("p", {});
|
||||
@ -3308,7 +3378,7 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
type:"number", placeholder:"Shares to sell", margin:"5px",
|
||||
inputListener: ()=> {
|
||||
var numShares = Math.round(input.value);
|
||||
if (isNaN(numShares) || shares <= 0) {
|
||||
if (isNaN(numShares) || numShares <= 0) {
|
||||
profitIndicator.innerText = "ERROR: Invalid value entered for number of shares to sell"
|
||||
} else if (numShares > this.numShares) {
|
||||
profitIndicator.innerText = "You don't have this many shares to sell!";
|
||||
@ -3365,7 +3435,9 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
var popupId = "cmpy-mgmt-buyback-shares-popup";
|
||||
var currentStockPrice = this.sharePrice;
|
||||
var txt = createElement("p", {
|
||||
innerHTML: "Enter the number of shares you would like to buy back at market price. The current price of your " +
|
||||
innerHTML: "Enter the number of shares you would like to buy back at market price. To purchase " +
|
||||
"these shares, you must use your own money (NOT your Corporation's funds). " +
|
||||
"The current price of your " +
|
||||
"company's stock is " + numeral(currentStockPrice).format("$0.000a") +
|
||||
". Your company currently has " + formatNumber(this.issuedShares, 3) + " outstanding stock shares",
|
||||
});
|
||||
@ -3375,12 +3447,13 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
inputListener: ()=> {
|
||||
var numShares = Math.round(input.value);
|
||||
//TODO add conditional for if player doesn't have enough money
|
||||
if (isNaN(numShares) || shares <= 0) {
|
||||
if (isNaN(numShares) || numShares <= 0) {
|
||||
costIndicator.innerText = "ERROR: Invalid value entered for number of shares to buyback"
|
||||
} else if (numShares > this.issuedShares) {
|
||||
costIndicator.innerText = "There are not this many shares available to buy back. " +
|
||||
"There are only " + this.issuedShares + " outstanding shares.";
|
||||
} else {
|
||||
console.log("here");
|
||||
costIndicator.innerText = "Purchase " + numShares + " shares for a total of " +
|
||||
numeral(numShares * currentStockPrice).format('$0.000a');
|
||||
}
|
||||
@ -3434,6 +3507,114 @@ Corporation.prototype.displayCorporationOverviewContent = function() {
|
||||
|
||||
companyManagementPanel.appendChild(sellShares);
|
||||
companyManagementPanel.appendChild(buybackShares);
|
||||
|
||||
//If your Corporation is big enough, buy faction influence through bribes
|
||||
var canBribe = this.determineValuation() >= BribeThreshold;
|
||||
var bribeFactions = createElement("a", {
|
||||
class: canBribe ? "a-link-button" : "a-link-button-inactive",
|
||||
innerText:"Bribe Factions", display:"inline-block",
|
||||
tooltip:canBribe
|
||||
? "Use your Corporations power and influence to bribe Faction leaders in exchange for reputation"
|
||||
: "Your Corporation is not powerful enough to bribe Faction leaders",
|
||||
clickListener:()=>{
|
||||
var popupId = "cmpy-mgmt-bribe-factions-popup";
|
||||
var txt = createElement("p", {
|
||||
innerText:"You can use Corporation funds or stock shares to bribe Faction Leaders in exchange for faction reputation"
|
||||
});
|
||||
var factionSelector = createElement("select", {margin:"3px"});
|
||||
for (var facName in Player.factions) {
|
||||
if (Player.factions.hasOwnProperty(facName)) {
|
||||
factionSelector.add(createElement("option"), {
|
||||
text:facName, value:facName
|
||||
});
|
||||
}
|
||||
}
|
||||
var repGainText = createElement("p");
|
||||
var stockSharesInput;
|
||||
var moneyInput = createElement("input", {
|
||||
type:"number", placeholder:"Corporation funds", margin:"5px",
|
||||
inputListener:()=>{
|
||||
var money = moneyInput.value == null ? 0 : moneyInput.value;
|
||||
var stockPrice = this.sharePrice;
|
||||
var stockShares = stockSharesInput.value == null ? 0 : Math.round(stockSharesInput.value);
|
||||
if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
|
||||
repGainText.innerText = "ERROR: Invalid value(s) entered";
|
||||
} else if (this.funds.lt(money)) {
|
||||
repGainText.innerText = "ERROR: You do not have this much money to bribe with";
|
||||
} else if (this.stockShares > this.numShares) {
|
||||
repGainText.innerText = "ERROR: You do not have this many shares to bribe with";
|
||||
} else {
|
||||
var totalAmount = money + (stockShares * stockPrice);
|
||||
var repGain = totalAmount / BribeToRepRatio;
|
||||
repGainText.innerText = "You will gain " + formatNumber(repGain, 0) +
|
||||
" reputation with " +
|
||||
factionSelector.options[factionSelector.selectedIndex].value +
|
||||
" with this bribe";
|
||||
}
|
||||
}
|
||||
});
|
||||
stockSharesInput = createElement("input", {
|
||||
type:"number", placeholder:"Stock Shares", margin: "5px",
|
||||
inputListener:()=>{
|
||||
var money = moneyInput.value == null ? 0 : moneyInput.value;
|
||||
var stockPrice = this.sharePrice;
|
||||
var stockShares = stockSharesInput.value == null ? 0 : Math.round(stockSharesInput.value);
|
||||
if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
|
||||
repGainText.innerText = "ERROR: Invalid value(s) entered";
|
||||
} else if (this.funds.lt(money)) {
|
||||
repGainText.innerText = "ERROR: You do not have this much money to bribe with";
|
||||
} else if (this.stockShares > this.numShares) {
|
||||
repGainText.innerText = "ERROR: You do not have this many shares to bribe with";
|
||||
} else {
|
||||
var totalAmount = money + (stockShares * stockPrice);
|
||||
var repGain = totalAmount / BribeToRepRatio;
|
||||
repGainText.innerText = "You will gain " + formatNumber(repGain, 0) +
|
||||
" reputation with " +
|
||||
factionSelector.options[factionSelector.selectedIndex].value +
|
||||
" with this bribe";
|
||||
}
|
||||
}
|
||||
});
|
||||
var confirmButton = createElement("a", {
|
||||
class:"a-link-button", innerText:"Bribe", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
var money = moneyInput.value == null ? 0 : moneyInput.value;
|
||||
var stockPrice = this.sharePrice;
|
||||
var stockShares = stockSharesInput.value == null ? 0 : Math.round(stockSharesInput.value);
|
||||
var fac = Factions[factionSelector.options[factionSelector.selectedIndex].value];
|
||||
if (fac == null) {
|
||||
dialogBoxCreate("ERROR: You must select a faction to bribe");
|
||||
return false;
|
||||
}
|
||||
if (isNaN(money) || isNaN(stockShares) || money < 0 || stockShares < 0) {
|
||||
dialogBoxCreate("ERROR: Invalid value(s) entered");
|
||||
} else if (this.funds.lt(money)) {
|
||||
dialogBoxCreate("ERROR: You do not have this much money to bribe with");
|
||||
} else if (this.stockShares > this.numShares) {
|
||||
dialogBoxCreate("ERROR: You do not have this many shares to bribe with");
|
||||
} else {
|
||||
var totalAmount = money + (stockShares * stockPrice);
|
||||
var repGain = totalAmount / BribeToRepRatio;
|
||||
dialogBoxCreate("You gained " + formatNumber(repGain, 0) +
|
||||
" reputation with " + fac.name + " by bribing them.");
|
||||
fac.playerReputation += repGain;
|
||||
this.funds = this.funds.lt(money);
|
||||
this.numShares -= stockShares;
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
var cancelButton = createElement("a", {
|
||||
class:"a-link-button", innerText:"Cancel", display:"inline-block",
|
||||
clickListener:()=>{
|
||||
removeElementById(popupId);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
companyManagementPanel.appendChild(bribeFactions);
|
||||
} else {
|
||||
var findInvestors = createElement("a", {
|
||||
class: this.fundingRound >= 4 ? "a-link-button-inactive" : "a-link-button tooltip",
|
||||
@ -3899,6 +4080,19 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
|
||||
industryEmployeePanel.appendChild(industryEmployeeText);
|
||||
|
||||
//Hire Employee button
|
||||
if (office.employees.length === 0) {
|
||||
industryEmployeeHireButton = createElement("a", {
|
||||
class:"a-link-button",display:"inline-block",
|
||||
innerText:"Hire Employee", fontSize:"13px",
|
||||
tooltip:"You'll need to hire some employees to get your operations started! " +
|
||||
"It's recommended to have at least one employee in every position",
|
||||
clickListener:()=>{
|
||||
office.findEmployees({corporation:this, division:division});
|
||||
return false;
|
||||
}
|
||||
});
|
||||
//industryEmployeeHireButton.classList.add("flashing-button");
|
||||
} else {
|
||||
industryEmployeeHireButton = createElement("a", {
|
||||
class:"a-link-button",display:"inline-block",
|
||||
innerText:"Hire Employee", fontSize:"13px",
|
||||
@ -3907,6 +4101,7 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
industryEmployeePanel.appendChild(industryEmployeeHireButton);
|
||||
|
||||
//Autohire Employee button
|
||||
@ -4240,6 +4435,9 @@ Corporation.prototype.updateDivisionContent = function(division) {
|
||||
if (office.employees.length >= office.size) {
|
||||
industryEmployeeHireButton.className = "a-link-button-inactive";
|
||||
industryEmployeeAutohireButton.className = "a-link-button-inactive tooltip";
|
||||
} else if (office.employees.length === 0) {
|
||||
industryEmployeeHireButton.className = "a-link-button tooltip flashing-button";
|
||||
industryEmployeeAutohireButton.className = "a-link-button tooltip";
|
||||
} else {
|
||||
industryEmployeeHireButton.className = "a-link-button";
|
||||
industryEmployeeAutohireButton.className = "a-link-button tooltip";
|
||||
|
@ -38,6 +38,7 @@ let CONSTANTS = {
|
||||
//NeuroFlux Governor cost multiplier as you level up
|
||||
NeuroFluxGovernorLevelMult: 1.14,
|
||||
|
||||
/* Netscript Constants */
|
||||
//RAM Costs for different commands
|
||||
ScriptWhileRamCost: 0.2,
|
||||
ScriptForRamCost: 0.2,
|
||||
@ -79,6 +80,8 @@ let CONSTANTS = {
|
||||
|
||||
MultithreadingRAMCost: 1,
|
||||
|
||||
NumNetscriptPorts: 20,
|
||||
|
||||
//Server constants
|
||||
ServerBaseGrowthRate: 1.03, //Unadjusted Growth rate
|
||||
ServerMaxGrowthRate: 1.0035, //Maximum possible growth rate (max rate accounting for server security)
|
||||
@ -1135,38 +1138,39 @@ let CONSTANTS = {
|
||||
"World Stock Exchange account and TIX API Access<br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.34.5<br>" +
|
||||
"v0.35.0<br>" +
|
||||
"-Minor rebalancing of BitNodes due to the fact that Corporations provide a (relatively) new method of " +
|
||||
"progressing<br>" +
|
||||
"-Corporation Management Changes:<br>" +
|
||||
"---Market Research unlocks are now cheaper<br>" +
|
||||
"---New 'VeChain' upgrade: displays useful statistics about Corporation<br>" +
|
||||
"---Corporation cycles are processed 25% faster<br>" +
|
||||
"---Corporation valuation was lowered by ~10% (this affects stock price and investments)<br>" +
|
||||
"---Rebalanced the effects of advertising. Should now be more effective for every Industry<br>" +
|
||||
"---Fixed several bugs/exploits involving selling and buying back stock shares<br>" +
|
||||
"---You will now receive a Corporation Handbook (.lit file) when starting out BitNode-3. It contains a brief guide to help you get started. " +
|
||||
"This same handbook can be viewed from the Corporation management screen<br>" +
|
||||
"---Slightly decreased the amount by which a Product's sell price can be marked up<br>" +
|
||||
"---Employees can now be assigned to a 'Training' task, during which they will slowly increase several of their stats<br>" +
|
||||
"-Hopefully fixed an exploit with Array.forEach(). If there are any issues with using forEach, let me know<br>" +
|
||||
"-Arguments passed into a script are now passed by value. This means modifying the 'args' array in a script " +
|
||||
"should no longer cause issues<br>" +
|
||||
"-Scripts executed programatically (via run(), exec(), etc.) will now fail if null/undefined is passed in " +
|
||||
"as an argument<br>" +
|
||||
"-Added peek() Netscript function<br>" +
|
||||
"-killall() Netscript function now returns true if any scripts were killed, and false otherwise.<br>" +
|
||||
"-hack() Netscript function now returns the amount of money gained for successful hacks, and 0 for failed hacks<br>" +
|
||||
"-scp Terminal command and Netscript function now work for txt files<br>" +
|
||||
"-Changes courtesy of Wraithan:<br>" +
|
||||
"---Text files are now displayed using 'pre' rather than 'p' elements when using the 'cat' Terminal command. " +
|
||||
"This means tabs are retained and lines don't automatically wrap<br>" +
|
||||
"---ls() Netscript function now returns text files as well<br>" +
|
||||
"-Removed round() Netscript function, since you can just use Math.round() instead<br>" +
|
||||
"-Added disableLog() and enableLog() Netscript functions<br>" +
|
||||
"-Removed the 'log' argument from sleep(), since you can now use the new disableLog function<br>" +
|
||||
"-'Netscript Documentation' button on script editor now points to new readthedocs documentation rather than wiki<br>" +
|
||||
"-When working for a faction, your current faction reputation is now displayed<br>" +
|
||||
"-Bug Fix: Hacking Missions should no longer break when dragging an existing connection to another Node<br>" +
|
||||
"-Bug Fix: Fixed RAM usage of getNextHacknetNodeCost() (is not 1.5GB instead of 4GB)<br>"
|
||||
"---Once your Corporation gets big/powerful enough, you can now bribe Factions for reputation using company funds an/or stock shares<br>" +
|
||||
"---You can now only create one Division for every Industry type<br>" +
|
||||
"---Added several new UI/UX elements<br>" +
|
||||
"---Wilson Analytics multiplier was significantly reduced to 1% per level (additive).<br>" +
|
||||
"---Reduced the effect of Advert Inc upgrade. Advert Inc. upgrade price increases faster<br>" +
|
||||
"---Materials can now be marked up at higher prices<br>" +
|
||||
"-Added Javascript's built-in Number object to Netscript<br>" +
|
||||
"-Added getCharacterInformation(), getCompanyFavor(), and getFactionFavor() Netscript Singularity functions<br>" +
|
||||
"-Rebalanced Singularity Function RAM Costs. They now cost x8 as much when outside of BN-4 (rather than x10). Also, " +
|
||||
"many of the functions now use significantly less RAM<br>" +
|
||||
"-Refactored Netscript Ports. You can now get a handle for a Netscript port using the " +
|
||||
"getPortHandle() Netscript function. This allows you to access a port's underlying queue (which is just an array) and also " +
|
||||
"makes several new functions available such as tryWrite(), full(), and empty().<br>" +
|
||||
"-Number of Netscript Ports increased from 10 to 20<br>" +
|
||||
"-Netscript assignments should now return proper values. i.e. i = 5 should return 5.<br>" +
|
||||
"-Added throw statements to Netscript. It's not super useful since 'catch' isn't implemented, but it can be used " +
|
||||
"to generate custom runtime error messages.<br>" +
|
||||
"-Added import declaration to Netscript. With this, you are able to import functions (and only functions) from " +
|
||||
"other files. Using export declarations is not necessary<br>" +
|
||||
"-Most Netscript Runtime errors (the ones that cause your script to crash) should now include the line number where the error occured<br>" +
|
||||
"-When working for a company, your current company reputation is now displayed<br>" +
|
||||
"-Whenever you get a Faction Invite it will be immediately appended to your 'invited factions' list. " +
|
||||
"Therefore the checkFactionInvitations() Singularity Function should now be properly useable since you no longer " +
|
||||
"need to decline a Faction Invitation before it shows up in the result.<br>" +
|
||||
"-Bug Fix: When purchasing servers, whitespace should now automatically be removed from the hostname<br>" +
|
||||
"-Bug Fix: Can no longer have whitespace in the filename of text files created using write()<br>" +
|
||||
"-Bug Fix: In Netscript, you can no longer assign a Hacknet Node handle (hacknetnodes[i]) to another value <br>" +
|
||||
"-Bug Fix: If you are in the Factions tab when you accept an invitation from a Faction, the page will now properly 'refresh'<br>" +
|
||||
"-Bug Fix: Scripts that run recursive functions should now be killed properly<br>"
|
||||
}
|
||||
|
||||
export {CONSTANTS};
|
||||
|
@ -14,6 +14,7 @@ import {factionInvitationBoxCreate} from "../utils/FactionInvitation
|
||||
import {clearEventListeners} from "../utils/HelperFunctions.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import {formatNumber, isPositiveNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoBoxGetYesButton,
|
||||
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
|
||||
@ -831,11 +832,13 @@ function displayFactionAugmentations(factionName) {
|
||||
for (var j = 0; j < Player.queuedAugmentations.length; ++j) {
|
||||
if (Player.queuedAugmentations[j].name == aug.name) {
|
||||
owned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (var j = 0; j < Player.augmentations.length; ++j) {
|
||||
if (Player.augmentations[j].name == aug.name) {
|
||||
owned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -844,7 +847,6 @@ function displayFactionAugmentations(factionName) {
|
||||
var aDiv = document.createElement("div");
|
||||
var aElem = document.createElement("a");
|
||||
var pElem = document.createElement("p");
|
||||
aElem.setAttribute("href", "#");
|
||||
var req = aug.baseRepRequirement * faction.augmentationRepRequirementMult;
|
||||
var hasPrereqs = hasAugmentationPrereqs(aug);
|
||||
if (!hasPrereqs) {
|
||||
@ -856,10 +858,11 @@ function displayFactionAugmentations(factionName) {
|
||||
pElem.innerHTML = "ALREADY OWNED";
|
||||
} else if (faction.playerReputation >= req) {
|
||||
aElem.setAttribute("class", "a-link-button");
|
||||
pElem.innerHTML = "UNLOCKED - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2);
|
||||
//pElem.innerHTML = "UNLOCKED - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2);
|
||||
pElem.innerHTML = "UNLOCKED - " + numeral(aug.baseCost * faction.augmentationPriceMult).format("$0.000a");
|
||||
} else {
|
||||
aElem.setAttribute("class", "a-link-button-inactive");
|
||||
pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - $" + formatNumber(aug.baseCost * faction.augmentationPriceMult, 2);
|
||||
pElem.innerHTML = "LOCKED (Requires " + formatNumber(req, 1) + " faction reputation) - " + numeral(aug.baseCost * faction.augmentationPriceMult).format("$0.000a");
|
||||
pElem.style.color = "red";
|
||||
}
|
||||
aElem.style.display = "inline";
|
||||
|
@ -1,4 +1,7 @@
|
||||
import {HacknetNode} from "./HacknetNode.js";
|
||||
import {NetscriptFunctions} from "./NetscriptFunctions.js";
|
||||
import {NetscriptPort} from "./NetscriptPort.js";
|
||||
|
||||
/* Environment
|
||||
* NetScript program environment
|
||||
*/
|
||||
@ -73,6 +76,14 @@ Environment.prototype = {
|
||||
}
|
||||
res = res[i];
|
||||
}
|
||||
|
||||
//Cant assign to ports or HacknetNodes
|
||||
if (res[idx[idx.length-1]] instanceof HacknetNode) {
|
||||
throw new Error("Cannot assign a Hacknet Node handle to a new value");
|
||||
}
|
||||
if (res[idx[idx.length-1]] instanceof NetscriptPort) {
|
||||
throw new Error("Cannot assign a Netscript Port handle to a new value");
|
||||
}
|
||||
return res[idx[idx.length-1]] = value;
|
||||
},
|
||||
|
||||
|
@ -3,12 +3,12 @@ import {CONSTANTS} from "./Constants.js";
|
||||
import {Player} from "./Player.js";
|
||||
import {Environment} from "./NetscriptEnvironment.js";
|
||||
import {WorkerScript, addWorkerScript} from "./NetscriptWorker.js";
|
||||
import {Server} from "./Server.js";
|
||||
import {Server, getServer} from "./Server.js";
|
||||
import {Settings} from "./Settings.js";
|
||||
import {Script, findRunningScript,
|
||||
RunningScript} from "./Script.js";
|
||||
|
||||
import {Node} from "../utils/acorn.js";
|
||||
import {parse, Node} from "../utils/acorn.js";
|
||||
import {printArray} from "../utils/HelperFunctions.js";
|
||||
import {isValidIPAddress} from "../utils/IPAddress.js";
|
||||
import {isString} from "../utils/StringHelperFunctions.js";
|
||||
@ -31,7 +31,7 @@ function evaluate(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (exp == null) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Error: NULL expression"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Error: NULL expression", exp));
|
||||
}
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
switch (exp.type) {
|
||||
@ -59,11 +59,11 @@ function evaluate(exp, workerScript) {
|
||||
case "Identifier":
|
||||
//Javascript constructor() method can be used as an exploit to run arbitrary code
|
||||
if (exp.name == "constructor") {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Illegal usage of constructor() method. If you have your own function named 'constructor', you must re-name it."));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Illegal usage of constructor() method. If you have your own function named 'constructor', you must re-name it.", exp));
|
||||
}
|
||||
|
||||
if (!(exp.name in env.vars)){
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.name + " not defined"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.name + " not defined", exp));
|
||||
}
|
||||
return Promise.resolve(env.get(exp.name))
|
||||
break;
|
||||
@ -135,7 +135,7 @@ function evaluate(exp, workerScript) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, e.toString()));
|
||||
}
|
||||
});
|
||||
} else if (exp.callee.type == "MemberExpression"){
|
||||
} else if (exp.callee.type === "MemberExpression"){
|
||||
return evaluate(exp.callee.object, workerScript).then(function(object) {
|
||||
try {
|
||||
if (func === "NETSCRIPTFOREACH") {
|
||||
@ -148,7 +148,7 @@ function evaluate(exp, workerScript) {
|
||||
var res = func.apply(object,args);
|
||||
return Promise.resolve(res);
|
||||
} catch (e) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, e));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, e, exp));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -158,6 +158,11 @@ function evaluate(exp, workerScript) {
|
||||
return out.then(function(res) {
|
||||
return Promise.resolve(res)
|
||||
}).catch(function(e) {
|
||||
if (isScriptErrorMessage(e)) {
|
||||
//Functions don't have line number appended in error message, so add it
|
||||
var num = getErrorLineNumber(exp, workerScript);
|
||||
e += " (Line " + num + ")";
|
||||
}
|
||||
return Promise.reject(e);
|
||||
});
|
||||
} else {
|
||||
@ -165,9 +170,14 @@ function evaluate(exp, workerScript) {
|
||||
}
|
||||
} catch (e) {
|
||||
if (isScriptErrorMessage(e)) {
|
||||
if (isScriptErrorMessage(e)) {
|
||||
//Functions don't have line number appended in error message, so add it
|
||||
var num = getErrorLineNumber(exp, workerScript);
|
||||
e += " (Line " + num + ")";
|
||||
}
|
||||
return Promise.reject(e);
|
||||
} else {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, e));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, e, exp));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,19 +189,19 @@ function evaluate(exp, workerScript) {
|
||||
if (exp.computed){
|
||||
return evaluate(exp.property, workerScript).then(function(index) {
|
||||
if (index >= object.length) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid index for arrays"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid index for arrays", exp));
|
||||
}
|
||||
return Promise.resolve(object[index]);
|
||||
}).catch(function(e) {
|
||||
if (e instanceof WorkerScript || isScriptErrorMessage(e)) {
|
||||
return Promise.reject(e);
|
||||
} else {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid MemberExpression"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid MemberExpression", exp));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (exp.property.name === "constructor") {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Illegal usage of constructor() method. If you have your own function named 'constructor', you must re-name it."));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Illegal usage of constructor() method. If you have your own function named 'constructor', you must re-name it.", exp));
|
||||
}
|
||||
if (object != null && object instanceof Array && exp.property.name === "forEach") {
|
||||
return "NETSCRIPTFOREACH";
|
||||
@ -199,7 +209,7 @@ function evaluate(exp, workerScript) {
|
||||
try {
|
||||
return Promise.resolve(object[exp.property.name])
|
||||
} catch (e) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Failed to get property: " + e.toString()));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Failed to get property: " + e.toString(), exp));
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -235,14 +245,14 @@ function evaluate(exp, workerScript) {
|
||||
}
|
||||
switch (exp.operator){
|
||||
default:
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". You are trying to use code that is currently unsupported"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". You are trying to use code that is currently unsupported", exp));
|
||||
}
|
||||
return Promise.resolve(env.get(exp.argument.name))
|
||||
} else {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.argument.name + " not defined"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.argument.name + " not defined", exp));
|
||||
}
|
||||
} else {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "argument must be an identifier"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "argument must be an identifier", exp));
|
||||
}
|
||||
break;
|
||||
case "EmptyStatement":
|
||||
@ -263,8 +273,7 @@ function evaluate(exp, workerScript) {
|
||||
return evaluateIf(exp, workerScript);
|
||||
break;
|
||||
case "SwitchStatement":
|
||||
var lineNum = getErrorLineNumber(exp, workerScript);
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Switch statements are not yet implemented in Netscript (line " + (lineNum+1) + ")"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Switch statements are not yet implemented in Netscript", exp));
|
||||
break;
|
||||
case "WhileStatement":
|
||||
return evaluateWhile(exp, workerScript).then(function(res) {
|
||||
@ -297,13 +306,24 @@ function evaluate(exp, workerScript) {
|
||||
env.set(exp.id.name, exp);
|
||||
return Promise.resolve(true);
|
||||
} else {
|
||||
var lineNum = getErrorLineNumber(exp, workerScript);
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid function declaration at line " + lineNum+1));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid function declaration", exp));
|
||||
}
|
||||
break;
|
||||
case "ImportDeclaration":
|
||||
return evaluateImport(exp, workerScript).then(function(res) {
|
||||
return Promise.resolve(res);
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
});
|
||||
break;
|
||||
case "ThrowStatement":
|
||||
//return Promise.reject(makeRuntimeRejectMsg(workerScript))
|
||||
return evaluate(exp.argument, workerScript).then(function(res) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, res));
|
||||
});
|
||||
break;
|
||||
default:
|
||||
var lineNum = getErrorLineNumber(exp, workerScript);
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + " (line " + (lineNum+1) + "). This is currently unsupported in Netscript"));
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". This is currently unsupported in Netscript", exp));
|
||||
break;
|
||||
} //End switch
|
||||
}).catch(function(e) {
|
||||
@ -438,6 +458,9 @@ function evalAssignment(exp, workerScript) {
|
||||
|
||||
return evaluate(exp.right, workerScript).then(function(expRight) {
|
||||
if (exp.left.type == "MemberExpression") {
|
||||
if (!exp.left.computed) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Cannot assign to an object's property. This is currently unsupported in Netscript", exp));
|
||||
}
|
||||
//Assign to array element
|
||||
//Array object designed by exp.left.object.name
|
||||
//Index designated by exp.left.property
|
||||
@ -450,37 +473,38 @@ function evalAssignment(exp, workerScript) {
|
||||
var arrName = res.splice(1, 1);
|
||||
arrName = arrName[0];
|
||||
|
||||
env.setArrayElement(arrName, res, expRight);
|
||||
return Promise.resolve(false);
|
||||
var res;
|
||||
try {
|
||||
res = env.setArrayElement(arrName, res, expRight);
|
||||
} catch (e) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, e));
|
||||
}
|
||||
return Promise.resolve(res);
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
});
|
||||
} else {
|
||||
//Other assignments
|
||||
try {
|
||||
var assign;
|
||||
switch (exp.operator) {
|
||||
case "=":
|
||||
env.set(exp.left.name,expRight);
|
||||
break;
|
||||
assign = expRight; break;
|
||||
case "+=":
|
||||
env.set(exp.left.name,env.get(exp.left.name) + expRight);
|
||||
break;
|
||||
assign = env.get(exp.left.name) + expRight; break;
|
||||
case "-=":
|
||||
env.set(exp.left.name,env.get(exp.left.name) - expRight);
|
||||
break;
|
||||
assign = env.get(exp.left.name) - expRight; break;
|
||||
case "*=":
|
||||
env.set(exp.left.name,env.get(exp.left.name) * expRight);
|
||||
break;
|
||||
assign = env.get(exp.left.name) * expRight; break;
|
||||
case "/=":
|
||||
env.set(exp.left.name,env.get(exp.left.name) / expRight);
|
||||
break;
|
||||
assign = env.get(exp.left.name) / expRight; break;
|
||||
case "%=":
|
||||
env.set(exp.left.name,env.get(exp.left.name) % expRight);
|
||||
break;
|
||||
assign = env.get(exp.left.name) % expRight; break;
|
||||
default:
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Bitwise assignment is not implemented"));
|
||||
}
|
||||
return Promise.resolve(false);
|
||||
env.set(exp.left.name, assign);
|
||||
return Promise.resolve(assign);
|
||||
} catch (e) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Failed to set environment variable: " + e.toString()));
|
||||
}
|
||||
@ -637,14 +661,117 @@ function evaluateProg(exp, workerScript, index) {
|
||||
}
|
||||
}
|
||||
|
||||
function evaluateImport(exp, workerScript, checkingRam=false) {
|
||||
//When its checking RAM, it exports an array of nodes for each imported function
|
||||
var ramCheckRes = [];
|
||||
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {
|
||||
if (checkingRam) {return ramCheckRes;}
|
||||
return Promise.reject(workerScript);
|
||||
}
|
||||
|
||||
//Get source script and name of all functions to import
|
||||
var scriptName = exp.source.value;
|
||||
var namespace, namespaceObj, allFns = false, fnNames = [];
|
||||
if (exp.specifiers.length === 1 && exp.specifiers[0].type === "ImportNamespaceSpecifier") {
|
||||
allFns = true;
|
||||
namespace = exp.specifiers[0].local.name;
|
||||
} else {
|
||||
for (var i = 0; i < exp.specifiers.length; ++i) {
|
||||
fnNames.push(exp.specifiers[i].local.name);
|
||||
}
|
||||
}
|
||||
|
||||
//Get the code
|
||||
var server = getServer(workerScript.serverIp), code = "";
|
||||
if (server == null) {
|
||||
if (checkingRam) {return ramCheckRes;}
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Failed to identify server. This is a bug please report to dev", exp));
|
||||
}
|
||||
for (var i = 0; i < server.scripts.length; ++i) {
|
||||
if (server.scripts[i].filename === scriptName) {
|
||||
code = server.scripts[i].code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code === "") {
|
||||
if (checkingRam) {return ramCheckRes;}
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Could not find script " + scriptName + " to import", exp));
|
||||
}
|
||||
|
||||
//Create the AST
|
||||
try {
|
||||
var ast = parse(code, {sourceType:"module"});
|
||||
} catch(e) {
|
||||
console.log("Failed to parse import script");
|
||||
if (checkingRam) {return ramCheckRes;}
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Failed to import functions from " + scriptName +
|
||||
" This is most likely due to a syntax error in the imported script", exp));
|
||||
}
|
||||
|
||||
if (allFns) {
|
||||
//A namespace is implemented as a JS obj
|
||||
env.set(namespace, {});
|
||||
namespaceObj = env.get(namespace);
|
||||
}
|
||||
|
||||
//Search through the AST for all imported functions
|
||||
var queue = [ast];
|
||||
while (queue.length != 0) {
|
||||
var node = queue.shift();
|
||||
switch (node.type) {
|
||||
case "BlockStatement":
|
||||
case "Program":
|
||||
for (var i = 0; i < node.body.length; ++i) {
|
||||
if (node.body[i] instanceof Node) {
|
||||
queue.push(node.body[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "FunctionDeclaration":
|
||||
if (node.id && node.id.name) {
|
||||
if (allFns) {
|
||||
//Import all functions under this namespace
|
||||
if (checkingRam) {
|
||||
ramCheckRes.push(node);
|
||||
} else {
|
||||
namespaceObj[node.id.name] = node;
|
||||
}
|
||||
} else {
|
||||
//Only import specified functions
|
||||
if (fnNames.includes(node.id.name)) {
|
||||
if (checkingRam) {
|
||||
ramCheckRes.push(node);
|
||||
} else {
|
||||
env.set(node.id.name, node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (checkingRam) {return ramCheckRes;}
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid function declaration in imported script " + scriptName, exp));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (var prop in node) {
|
||||
if (node.hasOwnProperty(prop)) {
|
||||
if (node[prop] instanceof Node) {
|
||||
queue.push(node[prop]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!checkingRam) {workerScript.scriptRef.log("Imported functions from " + scriptName);}
|
||||
if (checkingRam) {return ramCheckRes;}
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
function killNetscriptDelay(workerScript) {
|
||||
/*
|
||||
if (workerScript instanceof WorkerScript) {
|
||||
if (workerScript.delay) {
|
||||
workerScript.delay.cancel();
|
||||
}
|
||||
}
|
||||
*/
|
||||
if (workerScript instanceof WorkerScript) {
|
||||
if (workerScript.delay) {
|
||||
clearTimeout(workerScript.delay);
|
||||
@ -654,19 +781,6 @@ function killNetscriptDelay(workerScript) {
|
||||
}
|
||||
|
||||
function netscriptDelay(time, workerScript) {
|
||||
/*
|
||||
workerScript.delay = new Promise(function(resolve, reject, onCancel) {
|
||||
Promise.delay(time).then(function() {
|
||||
resolve();
|
||||
workerScript.delay = null;
|
||||
});
|
||||
onCancel(function() {
|
||||
console.log("Cancelling and rejecting this Promise");
|
||||
reject(workerScript);
|
||||
})
|
||||
});
|
||||
return workerScript.delay;
|
||||
*/
|
||||
return new Promise(function(resolve, reject) {
|
||||
workerScript.delay = setTimeout(()=>{
|
||||
workerScript.delay = null;
|
||||
@ -676,40 +790,14 @@ function netscriptDelay(time, workerScript) {
|
||||
});
|
||||
}
|
||||
|
||||
function makeRuntimeRejectMsg(workerScript, msg) {
|
||||
return "|"+workerScript.serverIp+"|"+workerScript.name+"|" + msg;
|
||||
function makeRuntimeRejectMsg(workerScript, msg, exp=null) {
|
||||
var lineNum = "";
|
||||
if (exp != null) {
|
||||
var num = getErrorLineNumber(exp, workerScript);
|
||||
lineNum = " (Line " + num + ")"
|
||||
}
|
||||
|
||||
/*
|
||||
function apply_op(op, a, b) {
|
||||
function num(x) {
|
||||
if (typeof x != "number")
|
||||
throw new Error("Expected number but got " + x);
|
||||
return x;
|
||||
return "|"+workerScript.serverIp+"|"+workerScript.name+"|" + msg + lineNum;
|
||||
}
|
||||
function div(x) {
|
||||
if (num(x) == 0)
|
||||
throw new Error("Divide by zero");
|
||||
return x;
|
||||
}
|
||||
switch (op) {
|
||||
case "+": return a + b;
|
||||
case "-": return num(a) - num(b);
|
||||
case "*": return num(a) * num(b);
|
||||
case "/": return num(a) / div(b);
|
||||
case "%": return num(a) % div(b);
|
||||
case "&&": return a !== false && b;
|
||||
case "||": return a !== false ? a : b;
|
||||
case "<": return num(a) < num(b);
|
||||
case ">": return num(a) > num(b);
|
||||
case "<=": return num(a) <= num(b);
|
||||
case ">=": return num(a) >= num(b);
|
||||
case "==": return a === b;
|
||||
case "!=": return a !== b;
|
||||
}
|
||||
throw new Error("Can't apply operator " + op);
|
||||
}
|
||||
*/
|
||||
|
||||
//Run a script from inside a script using run() command
|
||||
function runScriptFromScript(server, scriptname, args, workerScript, threads=1) {
|
||||
@ -759,13 +847,16 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
//Takes in a
|
||||
function getErrorLineNumber(exp, workerScript) {
|
||||
var code = workerScript.scriptRef.scriptRef.code;
|
||||
|
||||
//Split code up to the start of the node
|
||||
try {
|
||||
code = code.substring(0, exp.start);
|
||||
return (code.match(/\n/g) || []).length;
|
||||
return (code.match(/\n/g) || []).length + 1;
|
||||
} catch(e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
function isScriptErrorMessage(msg) {
|
||||
@ -838,4 +929,4 @@ export {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
|
||||
scriptCalculateHackingChance, scriptCalculateHackingTime,
|
||||
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
|
||||
scriptCalculateGrowTime, scriptCalculateWeakenTime, evaluate,
|
||||
isScriptErrorMessage, killNetscriptDelay};
|
||||
isScriptErrorMessage, killNetscriptDelay, evaluateImport};
|
||||
|
@ -54,6 +54,7 @@ import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
|
||||
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
|
||||
scriptCalculateGrowTime, scriptCalculateWeakenTime} from "./NetscriptEvaluator.js";
|
||||
import {Environment} from "./NetscriptEnvironment.js";
|
||||
import {NetscriptPort} from "./NetscriptPort.js";
|
||||
|
||||
import Decimal from '../utils/decimal.js';
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
@ -99,6 +100,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return {
|
||||
Math : Math,
|
||||
Date : Date,
|
||||
Number : Number,
|
||||
hacknetnodes : Player.hacknetNodes,
|
||||
sprintf : sprintf,
|
||||
vsprintf: vsprintf,
|
||||
@ -614,7 +616,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return CONSTANTS.ScriptSpawnRamCost;
|
||||
}
|
||||
}
|
||||
if (scriptname == null || threads == 1) {
|
||||
if (scriptname == null || threads == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid scriptname or numThreads argument passed to spawn()");
|
||||
}
|
||||
setTimeout(()=>{
|
||||
@ -665,7 +667,7 @@ function NetscriptFunctions(workerScript) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
killall : function(ip){
|
||||
killall : function(ip=workerScript.serverIp){
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.killall) {
|
||||
return 0;
|
||||
@ -1601,7 +1603,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
}
|
||||
var hostnameStr = String(hostname);
|
||||
hostnameStr = hostnameStr.replace(/\s\s+/g, '');
|
||||
hostnameStr = hostnameStr.replace(/\s+/g, '');
|
||||
if (hostnameStr == "") {
|
||||
workerScript.scriptRef.log("Error: Passed empty string for hostname argument of purchaseServer()");
|
||||
return "";
|
||||
@ -1744,20 +1746,15 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
if (!isNaN(port)) { //Write to port
|
||||
//Port 1-10
|
||||
if (port < 1 || port > 10) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Trying to write to invalid port: " + port + ". Only ports 1-10 are valid.");
|
||||
port = Math.round(port);
|
||||
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Trying to write to invalid port: " + port + ". Only ports 1-" + CONSTANTS.NumNetscriptPorts + " are valid.");
|
||||
}
|
||||
var portName = "Port" + String(port);
|
||||
var port = NetscriptPorts[portName];
|
||||
if (port == null) {
|
||||
var port = NetscriptPorts[port-1];
|
||||
if (port == null || !(port instanceof NetscriptPort)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Could not find port: " + port + ". This is a bug contact the game developer");
|
||||
}
|
||||
port.push(data);
|
||||
if (port.length > Settings.MaxPortCapacity) {
|
||||
port.shift();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return port.write(data);
|
||||
} else if (isString(port)) { //Write to text file
|
||||
var fn = port;
|
||||
var server = getServer(workerScript.serverIp);
|
||||
@ -1790,19 +1787,15 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
if (!isNaN(port)) { //Read from port
|
||||
//Port 1-10
|
||||
if (port < 1 || port > 10) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Trying to read from invalid port: " + port + ". Only ports 1-10 are valid.");
|
||||
port = Math.round(port);
|
||||
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Trying to read from invalid port: " + port + ". Only ports 1-" + CONSTANTS.NumNetscriptPorts + " are valid.");
|
||||
}
|
||||
var portName = "Port" + String(port);
|
||||
var port = NetscriptPorts[portName];
|
||||
if (port == null) {
|
||||
var port = NetscriptPorts[port-1];
|
||||
if (port == null || !(port instanceof NetscriptPort)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Could not find port: " + port + ". This is a bug contact the game developer");
|
||||
}
|
||||
if (port.length === 0) {
|
||||
return "NULL PORT DATA";
|
||||
} else {
|
||||
return port.shift();
|
||||
}
|
||||
return port.read();
|
||||
} else if (isString(port)) { //Read from text file
|
||||
var fn = port;
|
||||
var server = getServer(workerScript.serverIp);
|
||||
@ -1828,20 +1821,18 @@ function NetscriptFunctions(workerScript) {
|
||||
return CONSTANTS.ScriptReadWriteRamCost;
|
||||
}
|
||||
}
|
||||
if (isNaN(port) || port < 1 || port > 10) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: peek() called with invalid argument. Must be a port number between 1 and 10");
|
||||
if (isNaN(port)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: peek() called with invalid argument. Must be a port number between 1 and " + CONSTANTS.NumNetscriptPorts);
|
||||
}
|
||||
var portName = "Port" + String(port);
|
||||
var port = NetscriptPorts[portName];
|
||||
if (port == null) {
|
||||
port = Math.round(port);
|
||||
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: peek() called with invalid argument. Must be a port number between 1 and " + CONSTANTS.NumNetscriptPorts);
|
||||
}
|
||||
var port = NetscriptPorts[port-1];
|
||||
if (port == null || !(port instanceof NetscriptPort)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Could not find port: " + port + ". This is a bug contact the game developer");
|
||||
}
|
||||
if (port.length === 0) {
|
||||
return "NULL PORT DATA";
|
||||
} else {
|
||||
var foo = port.slice();
|
||||
return foo[0];
|
||||
}
|
||||
return port.peek();
|
||||
},
|
||||
clear : function(port) {
|
||||
if (workerScript.checkingRam) {
|
||||
@ -1853,15 +1844,15 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
}
|
||||
if (!isNaN(port)) { //Clear port
|
||||
if (port < 1 || port > 10) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Trying to read from invalid port: " + port + ". Only ports 1-10 are valid");
|
||||
port = Math.round(port);
|
||||
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Trying to clear invalid port: " + port + ". Only ports 1-" + CONSTANTS.NumNetscriptPorts + " are valid");
|
||||
}
|
||||
var portName = "Port" + String(port);
|
||||
var port = NetscriptPorts[portName];
|
||||
if (port == null) {
|
||||
var port = NetscriptPorts[port-1];
|
||||
if (port == null || !(port instanceof NetscriptPort)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Could not find port: " + port + ". This is a bug contact the game developer");
|
||||
}
|
||||
port.length = 0;
|
||||
return port.clear();
|
||||
} else if (isString(port)) { //Clear text file
|
||||
var fn = port;
|
||||
var server = getServer(workerScript.serverIp);
|
||||
@ -1877,6 +1868,28 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
getPortHandle : function(port) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getPortHandle) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getPortHandle = true;
|
||||
return CONSTANTS.ScriptReadWriteRamCost * 10;
|
||||
}
|
||||
}
|
||||
if (isNaN(port)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Invalid argument passed into getPortHandle(). Must be an integer between 1 and " + CONSTANTS.NumNetscriptPorts);
|
||||
}
|
||||
port = Math.round(port);
|
||||
if (port < 1 || port > CONSTANTS.NumNetscriptPorts) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: getPortHandle() called with invalid port number: " + port + ". Only ports 1-" + CONSTANTS.NumNetscriptPorts + " are valid");
|
||||
}
|
||||
var port = NetscriptPorts[port-1];
|
||||
if (port == null || !(port instanceof NetscriptPort)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERR: Could not find port: " + port + ". This is a bug contact the game developer");
|
||||
}
|
||||
return port;
|
||||
},
|
||||
rm : function(fn) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.rm) {
|
||||
@ -2153,7 +2166,7 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
workerScript.loadedFns.universityCourse = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2246,7 +2259,7 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
workerScript.loadedFns.gymWorkout = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2351,8 +2364,8 @@ function NetscriptFunctions(workerScript) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.travelToCity = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 2;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2390,7 +2403,7 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
workerScript.loadedFns.purchaseTor = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2433,7 +2446,7 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
workerScript.loadedFns.purchaseProgram = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2553,8 +2566,8 @@ function NetscriptFunctions(workerScript) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getStats = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2575,14 +2588,55 @@ function NetscriptFunctions(workerScript) {
|
||||
intelligence: Player.intelligence
|
||||
}
|
||||
},
|
||||
getCharacterInformation : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getCharacterInformation) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getCharacterInformation = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
|
||||
if (Player.bitNodeN != 4) {
|
||||
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot run getCharacterInformation(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
var companyPositionTitle = "";
|
||||
if (Player.companyPosition instanceof CompanyPosition) {
|
||||
companyPositionTitle = Player.companyPosition.positionName;
|
||||
}
|
||||
return {
|
||||
bitnode: Player.bitNodeN,
|
||||
company: Player.companyName,
|
||||
jobTitle: companyPositionTitle,
|
||||
city: Player.city,
|
||||
factions: Player.factions.slice(),
|
||||
tor: SpecialServerIps.hasOwnProperty("Darkweb Server"),
|
||||
timeWorked: Player.timeWorked,
|
||||
workHackExpGain: Player.workHackExpGained,
|
||||
workStrExpGain: Player.workStrExpGained,
|
||||
workDefExpGain: Player.workDefExpGained,
|
||||
workDexExpGain: Player.workDexExpGained,
|
||||
workAgiExpGain: Player.workAgiExpGained,
|
||||
workChaExpGain: Player.workChaExpGained,
|
||||
workRepGain: Player.workRepGained,
|
||||
workMoneyGain: Player.workMoneyGained,
|
||||
};
|
||||
},
|
||||
isBusy : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.isBusy) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.isBusy = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2600,11 +2654,17 @@ function NetscriptFunctions(workerScript) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.stopAction = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn1RamCost / 2;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
if (Player.bitNodeN != 4) {
|
||||
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot run stopAction(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Player.isWorking) {
|
||||
var txt = Player.singularityStopWork();
|
||||
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.stopAction == null) {
|
||||
@ -2614,14 +2674,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return false;
|
||||
},
|
||||
upgradeHomeRam() {
|
||||
upgradeHomeRam : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.upgradeHomeRam) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.upgradeHomeRam = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2658,14 +2718,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getUpgradeHomeRamCost() {
|
||||
getUpgradeHomeRamCost : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getUpgradeHomeRamCost) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getUpgradeHomeRamCost = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 2;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2686,14 +2746,14 @@ function NetscriptFunctions(workerScript) {
|
||||
var mult = Math.pow(1.55, numUpgrades);
|
||||
return cost * mult;
|
||||
},
|
||||
workForCompany() {
|
||||
workForCompany : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.workForCompany) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.workForCompany = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2731,14 +2791,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
applyToCompany(companyName, field) {
|
||||
applyToCompany : function(companyName, field) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.applyToCompany) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.applyToCompany = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2816,14 +2876,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getCompanyRep(companyName) {
|
||||
getCompanyRep : function(companyName) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getCompanyRep) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getCompanyRep = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2841,14 +2901,39 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return company.playerReputation;
|
||||
},
|
||||
checkFactionInvitations() {
|
||||
getCompanyFavor : function(companyName) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getCompanyFavor) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getCompanyFavor = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
if (Player.bitNodeN != 4) {
|
||||
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot run getCompanyFavor(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var company = Companies[companyName];
|
||||
if (company == null || !(company instanceof Company)) {
|
||||
workerScript.scriptRef.log("ERROR: Invalid companyName passed into getCompanyFavor(): " + companyName);
|
||||
return -1;
|
||||
}
|
||||
return company.favor;
|
||||
},
|
||||
checkFactionInvitations : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.checkFactionInvitations) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.checkFactionInvitations = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2861,14 +2946,14 @@ function NetscriptFunctions(workerScript) {
|
||||
//Make a copy of Player.factionInvitations
|
||||
return Player.factionInvitations.slice();
|
||||
},
|
||||
joinFaction(name) {
|
||||
joinFaction : function(name) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.joinFaction) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.joinFaction = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -2904,14 +2989,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
workForFaction(name, type) {
|
||||
workForFaction : function(name, type) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.workForFaction) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.workForFaction = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3002,14 +3087,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getFactionRep(name) {
|
||||
getFactionRep : function(name) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getFactionRep) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getFactionRep = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3027,14 +3112,39 @@ function NetscriptFunctions(workerScript) {
|
||||
|
||||
return Factions[name].playerReputation;
|
||||
},
|
||||
createProgram(name) {
|
||||
getFactionFavor : function(name) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getFactionFavor) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getFactionFavor = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn2RamCost / 4;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
if (Player.bitNodeN != 4) {
|
||||
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot run getFactionFavor(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!factionExists(name)) {
|
||||
workerScript.scriptRef.log("ERROR: Faction specified in getFactionFavor() does not exist.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return Factions[name].favor;
|
||||
},
|
||||
createProgram : function(name) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.createProgram) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.createProgram = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3136,7 +3246,7 @@ function NetscriptFunctions(workerScript) {
|
||||
} else {
|
||||
workerScript.loadedFns.commitCrime = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3222,14 +3332,14 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid crime passed into commitCrime(): " + crime);
|
||||
}
|
||||
},
|
||||
getCrimeChance(crime) {
|
||||
getCrimeChance : function(crime) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getCrimeChance) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getCrimeChance = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3269,14 +3379,14 @@ function NetscriptFunctions(workerScript) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid crime passed into getCrimeChance(): " + crime);
|
||||
}
|
||||
},
|
||||
getOwnedAugmentations(purchased=false) {
|
||||
getOwnedAugmentations : function(purchased=false) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getOwnedAugmentations) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getOwnedAugmentations = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3297,14 +3407,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getAugmentationsFromFaction(facname) {
|
||||
getAugmentationsFromFaction : function(facname) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getAugmentationsFromFaction) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getAugmentationsFromFaction = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3327,14 +3437,14 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return res;
|
||||
},
|
||||
getAugmentationCost(name) {
|
||||
getAugmentationCost : function(name) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.getAugmentationCost) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.getAugmentationCost = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3353,14 +3463,14 @@ function NetscriptFunctions(workerScript) {
|
||||
var aug = Augmentations[name];
|
||||
return [aug.baseRepRequirement, aug.baseCost];
|
||||
},
|
||||
purchaseAugmentation(faction, name) {
|
||||
purchaseAugmentation : function(faction, name) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.purchaseAugmentation) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.purchaseAugmentation = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
@ -3422,14 +3532,14 @@ function NetscriptFunctions(workerScript) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
installAugmentations(cbScript) {
|
||||
installAugmentations : function(cbScript) {
|
||||
if (workerScript.checkingRam) {
|
||||
if (workerScript.loadedFns.installAugmentations) {
|
||||
return 0;
|
||||
} else {
|
||||
workerScript.loadedFns.installAugmentations = true;
|
||||
var ramCost = CONSTANTS.ScriptSingularityFn3RamCost;
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 10;}
|
||||
if (Player.bitNodeN !== 4) {ramCost *= 8;}
|
||||
return ramCost;
|
||||
}
|
||||
}
|
||||
|
51
src/NetscriptPort.js
Normal file
51
src/NetscriptPort.js
Normal file
@ -0,0 +1,51 @@
|
||||
import {Settings} from "./Settings.js";
|
||||
|
||||
function NetscriptPort() {
|
||||
this.data = [];
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.write = function(data) {
|
||||
this.data.push(data);
|
||||
if (this.data.length > Settings.MaxPortCapacity) {
|
||||
return this.data.shift();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.tryWrite = function(data) {
|
||||
if (this.data.length >= Settings.MaxPortCapacity) {
|
||||
return false;
|
||||
}
|
||||
this.data.push(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.read = function() {
|
||||
if (this.data.length === 0) {
|
||||
return "NULL PORT DATA";
|
||||
}
|
||||
return this.data.shift();
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.peek = function() {
|
||||
if (this.data.length === 0) {
|
||||
return "NULL PORT DATA";
|
||||
} else {
|
||||
var foo = this.data.slice();
|
||||
return foo[0];
|
||||
}
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.full = function() {
|
||||
return this.data.length == Settings.MaxPortCapacity;
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.empty = function() {
|
||||
return this.data.length === 0;
|
||||
}
|
||||
|
||||
NetscriptPort.prototype.clear = function() {
|
||||
this.data.length = 0;
|
||||
}
|
||||
|
||||
export {NetscriptPort};
|
@ -6,6 +6,7 @@ import {Engine} from "./engine.js";
|
||||
import {Environment} from "./NetscriptEnvironment.js";
|
||||
import {evaluate, isScriptErrorMessage,
|
||||
killNetscriptDelay} from "./NetscriptEvaluator.js";
|
||||
import {NetscriptPort} from "./NetscriptPort.js";
|
||||
import {AllServers} from "./Server.js";
|
||||
import {Settings} from "./Settings.js";
|
||||
|
||||
@ -40,17 +41,9 @@ WorkerScript.prototype.getServer = function() {
|
||||
//Array containing all scripts that are running across all servers, to easily run them all
|
||||
let workerScripts = [];
|
||||
|
||||
let NetscriptPorts = {
|
||||
Port1: [],
|
||||
Port2: [],
|
||||
Port3: [],
|
||||
Port4: [],
|
||||
Port5: [],
|
||||
Port6: [],
|
||||
Port7: [],
|
||||
Port8: [],
|
||||
Port9: [],
|
||||
Port10: [],
|
||||
var NetscriptPorts = [];
|
||||
for (var i = 0; i < CONSTANTS.NumNetscriptPorts; ++i) {
|
||||
NetscriptPorts.push(new NetscriptPort());
|
||||
}
|
||||
|
||||
function prestigeWorkerScripts() {
|
||||
@ -95,8 +88,8 @@ function runScriptsLoop() {
|
||||
//If it isn't running, start the script
|
||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
|
||||
try {
|
||||
var ast = parse(workerScripts[i].code);
|
||||
//console.log(ast);
|
||||
var ast = parse(workerScripts[i].code, {sourceType:"module"});
|
||||
console.log(ast);
|
||||
} catch (e) {
|
||||
console.log("Error parsing script: " + workerScripts[i].name);
|
||||
dialogBoxCreate("Syntax ERROR in " + workerScripts[i].name + ":<br>" + e);
|
||||
@ -168,9 +161,12 @@ function killWorkerScript(runningScriptObj, serverIp) {
|
||||
compareArrays(workerScripts[i].args, runningScriptObj.args)) {
|
||||
workerScripts[i].env.stopFlag = true;
|
||||
killNetscriptDelay(workerScripts[i]);
|
||||
if (workerScripts[i].fnWorker) {
|
||||
workerScripts[i].fnWorker.env.stopFlag = true;
|
||||
killNetscriptDelay(workerScripts[i].fnWorker);
|
||||
//Recursively kill all functions
|
||||
var curr = workerScripts[i];
|
||||
while (curr.fnWorker) {
|
||||
curr.fnWorker.env.stopFlag = true;
|
||||
killNetscriptDelay(curr.fnWorker);
|
||||
curr = curr.fnWorker;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -48,9 +48,9 @@ function PlayerObject() {
|
||||
this.intelligence = 0;
|
||||
|
||||
//Hacking multipliers
|
||||
this.hacking_chance_mult = 1; //Increase through ascensions/augmentations
|
||||
this.hacking_speed_mult = 1; //Decrease through ascensions/augmentations
|
||||
this.hacking_money_mult = 1; //Increase through ascensions/augmentations. Can't go above 1
|
||||
this.hacking_chance_mult = 1;
|
||||
this.hacking_speed_mult = 1;
|
||||
this.hacking_money_mult = 1;
|
||||
this.hacking_grow_mult = 1;
|
||||
|
||||
//Experience and multipliers
|
||||
@ -692,11 +692,10 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
this.isWorking = false;
|
||||
//Engine.loadTerminalContent();
|
||||
Engine.loadLocationContent();
|
||||
|
||||
if (sing) {
|
||||
return "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
|
||||
var res = "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
|
||||
"earned $" + formatNumber(this.workMoneyGained, 2) + ", " +
|
||||
formatNumber(this.workRepGained, 4) + " reputation, " +
|
||||
formatNumber(this.workHackExpGained, 4) + " hacking exp, " +
|
||||
@ -705,7 +704,10 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
|
||||
formatNumber(this.workDexExpGained, 4) + " dexterity exp, " +
|
||||
formatNumber(this.workAgiExpGained, 4) + " agility exp, and " +
|
||||
formatNumber(this.workChaExpGained, 4) + " charisma exp.";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
this.resetWorkStatus();
|
||||
}
|
||||
|
||||
PlayerObject.prototype.startWork = function() {
|
||||
@ -767,9 +769,17 @@ PlayerObject.prototype.work = function(numCycles) {
|
||||
return;
|
||||
}
|
||||
|
||||
var comp = Companies[this.companyName], companyRep = "0";
|
||||
if (comp == null || !(comp instanceof Company)) {
|
||||
console.log("ERROR: Could not find Company: " + this.companyName);
|
||||
} else {
|
||||
companyRep = comp.playerReputation;
|
||||
}
|
||||
|
||||
var txt = document.getElementById("work-in-progress-text");
|
||||
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
|
||||
" at " + this.companyName + "<br><br>" +
|
||||
" at " + this.companyName + " (Current Company Reputation: " +
|
||||
formatNumber(companyRep, 0) + ")<br><br>" +
|
||||
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
|
||||
"You have earned: <br><br>" +
|
||||
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * cyclesPerSec, 2) + " / sec) <br><br>" +
|
||||
@ -886,10 +896,9 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
this.isWorking = false;
|
||||
//Engine.loadTerminalContent();
|
||||
Engine.loadLocationContent();
|
||||
if (sing) {
|
||||
return "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
|
||||
var res = "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
|
||||
"earned a total of " +
|
||||
"$" + formatNumber(this.workMoneyGained, 2) + ", " +
|
||||
formatNumber(this.workRepGained, 4) + " reputation, " +
|
||||
@ -899,7 +908,10 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
|
||||
formatNumber(this.workDexExpGained, 4) + " dexterity exp, " +
|
||||
formatNumber(this.workAgiExpGained, 4) + " agility exp, and " +
|
||||
formatNumber(this.workChaExpGained, 4) + " charisma exp";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
this.resetWorkStatus();
|
||||
}
|
||||
|
||||
/* Working for Faction */
|
||||
@ -930,11 +942,10 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
|
||||
|
||||
this.isWorking = false;
|
||||
|
||||
//Engine.loadTerminalContent();
|
||||
Engine.loadFactionContent();
|
||||
displayFactionContent(faction.name);
|
||||
if (sing) {
|
||||
return "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
|
||||
var res="You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
|
||||
"You earned " +
|
||||
formatNumber(this.workRepGained, 4) + " rep, " +
|
||||
formatNumber(this.workHackExpGained, 4) + " hacking exp, " +
|
||||
@ -943,7 +954,10 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
|
||||
formatNumber(this.workDexExpGained, 4) + " dex exp, " +
|
||||
formatNumber(this.workAgiExpGained, 4) + " agi exp, and " +
|
||||
formatNumber(this.workChaExpGained, 4) + " cha exp.";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
this.resetWorkStatus();
|
||||
}
|
||||
|
||||
PlayerObject.prototype.startFactionWork = function(faction) {
|
||||
@ -1261,6 +1275,7 @@ PlayerObject.prototype.finishCreateProgramWork = function(cancelled, sing=false)
|
||||
this.isWorking = false;
|
||||
|
||||
Engine.loadTerminalContent();
|
||||
this.resetWorkStatus();
|
||||
}
|
||||
|
||||
/* Studying/Taking Classes */
|
||||
@ -1415,8 +1430,8 @@ PlayerObject.prototype.finishClass = function(sing=false) {
|
||||
this.isWorking = false;
|
||||
|
||||
Engine.loadLocationContent();
|
||||
|
||||
if (sing) {return "After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", " +
|
||||
if (sing) {
|
||||
var res="After " + this.className + " for " + convertTimeMsToTimeElapsedString(this.timeWorked) + ", " +
|
||||
"you spent a total of $" + formatNumber(this.workMoneyGained * -1, 2) + ". " +
|
||||
"You earned a total of: " +
|
||||
formatNumber(this.workHackExpGained, 3) + " hacking exp, " +
|
||||
@ -1424,7 +1439,11 @@ PlayerObject.prototype.finishClass = function(sing=false) {
|
||||
formatNumber(this.workDefExpGained, 3) + " defense exp, " +
|
||||
formatNumber(this.workDexExpGained, 3) + " dexterity exp, " +
|
||||
formatNumber(this.workAgiExpGained, 3) + " agility exp, and " +
|
||||
formatNumber(this.workChaExpGained, 3) + " charisma exp";}
|
||||
formatNumber(this.workChaExpGained, 3) + " charisma exp";
|
||||
this.resetWorkStatus();
|
||||
return res;
|
||||
}
|
||||
this.resetWorkStatus();
|
||||
}
|
||||
|
||||
//The EXP and $ gains are hardcoded. Time is in ms
|
||||
@ -1598,6 +1617,7 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
this.isWorking = false;
|
||||
this.resetWorkStatus();
|
||||
Engine.loadLocationContent();
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@ import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {iTutorialSteps, iTutorialNextStep,
|
||||
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
|
||||
import {evaluateImport} from "./NetscriptEvaluator.js";
|
||||
import {NetscriptFunctions} from "./NetscriptFunctions.js";
|
||||
import {addWorkerScript, killWorkerScript,
|
||||
WorkerScript} from "./NetscriptWorker.js";
|
||||
@ -96,19 +97,47 @@ function scriptEditorInit() {
|
||||
/* Script editor options */
|
||||
//Theme
|
||||
var themeDropdown = document.getElementById("script-editor-option-theme");
|
||||
if (Settings.EditorTheme) {
|
||||
var initialIndex = 2;
|
||||
for (var i = 0; i < themeDropdown.options.length; ++i) {
|
||||
if (themeDropdown.options[i].value === Settings.EditorTheme) {
|
||||
initialIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
themeDropdown.selectedIndex = initialIndex;
|
||||
} else {
|
||||
themeDropdown.selectedIndex = 2;
|
||||
}
|
||||
|
||||
themeDropdown.onchange = function() {
|
||||
var val = themeDropdown.value;
|
||||
Settings.EditorTheme = val;
|
||||
var themePath = "ace/theme/" + val.toLowerCase();
|
||||
editor.setTheme(themePath);
|
||||
};
|
||||
themeDropdown.onchange();
|
||||
|
||||
//Keybinding
|
||||
var keybindingDropdown = document.getElementById("script-editor-option-keybinding");
|
||||
if (Settings.EditorKeybinding) {
|
||||
var initialIndex = 0;
|
||||
for (var i = 0; i < keybindingDropdown.options.length; ++i) {
|
||||
if (keybindingDropdown.options[i].value === Settings.EditorKeybinding) {
|
||||
initialIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
keybindingDropdown.selectedIndex = initialIndex;
|
||||
} else {
|
||||
keybindingDropdown.selectedIndex = 0;
|
||||
}
|
||||
keybindingDropdown.onchange = function() {
|
||||
var val = keybindingDropdown.value;
|
||||
Settings.EditorKeybinding = val;
|
||||
editor.setKeyboardHandler(keybindings[val.toLowerCase()]);
|
||||
};
|
||||
keybindingDropdown.onchange();
|
||||
|
||||
//Highlight Active line
|
||||
var highlightActiveChkBox = document.getElementById("script-editor-option-highlightactiveline");
|
||||
@ -174,7 +203,6 @@ function scriptEditorInit() {
|
||||
}
|
||||
editor.completers = [autocompleter];
|
||||
}
|
||||
document.addEventListener("DOMContentLoaded", scriptEditorInit, false);
|
||||
|
||||
//Updates RAM usage in script
|
||||
function updateScriptEditorContent() {
|
||||
@ -188,6 +216,8 @@ function updateScriptEditorContent() {
|
||||
var ramUsage = calculateRamUsage(codeCopy);
|
||||
if (ramUsage !== -1) {
|
||||
scriptEditorRamText.innerText = "RAM: " + formatNumber(ramUsage, 2).toString() + "GB";
|
||||
} else {
|
||||
scriptEditorRamText.innerText = "RAM: Syntax Error";
|
||||
}
|
||||
}
|
||||
|
||||
@ -295,15 +325,17 @@ Script.prototype.updateRamUsage = function() {
|
||||
|
||||
function calculateRamUsage(codeCopy) {
|
||||
//Create a temporary/mock WorkerScript and an AST from the code
|
||||
var currServ = Player.getCurrentServer();
|
||||
var workerScript = new WorkerScript({
|
||||
filename:"foo",
|
||||
scriptRef: {code:""},
|
||||
args:[]
|
||||
});
|
||||
workerScript.checkingRam = true; //Netscript functions will return RAM usage
|
||||
workerScript.serverIp = currServ.ip;
|
||||
|
||||
try {
|
||||
var ast = parse(codeCopy);
|
||||
var ast = parse(codeCopy, {sourceType:"module"});
|
||||
} catch(e) {
|
||||
return -1;
|
||||
}
|
||||
@ -315,6 +347,14 @@ function calculateRamUsage(codeCopy) {
|
||||
while (queue.length != 0) {
|
||||
var exp = queue.shift();
|
||||
switch (exp.type) {
|
||||
case "ImportDeclaration":
|
||||
//Gets an array of all imported functions as AST expressions
|
||||
//and pushes them on the queue.
|
||||
var res = evaluateImport(exp, workerScript, true);
|
||||
for (var i = 0; i < res.length; ++i) {
|
||||
queue.push(res[i]);
|
||||
}
|
||||
break;
|
||||
case "BlockStatement":
|
||||
case "Program":
|
||||
for (var i = 0; i < exp.body.length; ++i) {
|
||||
@ -659,4 +699,4 @@ AllServersMap.fromJSON = function(value) {
|
||||
Reviver.constructors.AllServersMap = AllServersMap;
|
||||
|
||||
export {updateScriptEditorContent, loadAllRunningScripts, findRunningScript,
|
||||
RunningScript, Script, AllServersMap};
|
||||
RunningScript, Script, AllServersMap, scriptEditorInit};
|
||||
|
@ -75,7 +75,7 @@ function Server(ip=createRandomIp(), hostname="", organizationName="",
|
||||
Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvailable, hackDifficulty, serverGrowth) {
|
||||
this.requiredHackingSkill = requiredHackingSkill;
|
||||
if (isNaN(moneyAvailable)) {
|
||||
this.moneyAvailable = 1000000;
|
||||
this.moneyAvailable = 1e6;
|
||||
} else {
|
||||
this.moneyAvailable = moneyAvailable * BitNodeMultipliers.ServerStartingMoney;
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ let Settings = {
|
||||
ThemeHighlightColor: "#ffffff",
|
||||
ThemeFontColor: "#66ff33",
|
||||
ThemeBackgroundColor: "#000000",
|
||||
EditorTheme: "Monokai",
|
||||
EditorKeybinding: "ace",
|
||||
}
|
||||
|
||||
function loadSettings(saveString) {
|
||||
|
@ -434,9 +434,9 @@ let Terminal = {
|
||||
'<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
|
||||
var hdr = document.getElementById("terminal-input-header");
|
||||
hdr.style.display = "inline";
|
||||
var lineWidth = document.getElementById("terminal-input-td").offsetWidth;
|
||||
var width = lineWidth - hdr.offsetWidth - 10;
|
||||
document.getElementById("terminal-input-text-box").style.width = width + "px";
|
||||
//var lineWidth = document.getElementById("terminal-input-td").offsetWidth;
|
||||
//var width = lineWidth - hdr.offsetWidth - 10;
|
||||
//document.getElementById("terminal-input-text-box").style.width = width + "px";
|
||||
},
|
||||
|
||||
//Complete the hack/analyze command
|
||||
|
@ -5,6 +5,7 @@ import {Reviver, Generic_toJSON,
|
||||
|
||||
function TextFile(fn="", txt="") {
|
||||
this.fn = fn.endsWith(".txt") ? fn : fn + ".txt";
|
||||
this.fn = this.fn.replace(/\s+/g, '');
|
||||
this.text = String(txt);
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ import {prestigeAugmentation,
|
||||
prestigeSourceFile} from "./Prestige.js";
|
||||
import {redPillFlag} from "./RedPill.js";
|
||||
import {saveObject, loadGame} from "./SaveObject.js";
|
||||
import {loadAllRunningScripts,
|
||||
import {loadAllRunningScripts, scriptEditorInit,
|
||||
updateScriptEditorContent} from "./Script.js";
|
||||
import {AllServers, Server, initForeignServers} from "./Server.js";
|
||||
import {Settings, setSettingsLabels} from "./Settings.js";
|
||||
@ -605,7 +605,7 @@ let Engine = {
|
||||
Engine.sector12LocationsList.style.display = "inline";
|
||||
|
||||
//City hall only in BitNode-3/with Source-File 3
|
||||
if (Player.bitNodeN === 3 || hasCorporationSF) {
|
||||
if ((Player.bitNodeN === 3 || hasCorporationSF) && Player.bitNodeN !== 8) {
|
||||
document.getElementById("sector12-cityhall-li").style.display = "block";
|
||||
} else {
|
||||
document.getElementById("sector12-cityhall-li").style.display = "none";
|
||||
@ -1319,6 +1319,7 @@ let Engine = {
|
||||
}
|
||||
//Initialize labels on game settings
|
||||
setSettingsLabels();
|
||||
scriptEditorInit();
|
||||
Terminal.resetTerminalInput();
|
||||
},
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {Faction, joinFaction} from "../src/Faction.js";
|
||||
import {Engine} from "../src/engine.js";
|
||||
import {Player} from "../src/Player.js";
|
||||
import {clearEventListeners} from "./HelperFunctions.js";
|
||||
|
||||
@ -26,20 +27,33 @@ function factionInvitationSetMessage(msg) {
|
||||
//ram argument is in GB
|
||||
function factionInvitationBoxCreate(faction) {
|
||||
factionInvitationSetText("You have received a faction invitation from " + faction.name);
|
||||
//TODO Faction invitation message
|
||||
faction.alreadyInvited = true;
|
||||
Player.factionInvitations.push(faction.name);
|
||||
|
||||
if (Engine.currentPage === Engine.Page.Factions) {
|
||||
Engine.loadFactionsContent();
|
||||
}
|
||||
|
||||
var newYesButton = clearEventListeners("faction-invitation-box-yes");
|
||||
newYesButton.addEventListener("click", function() {
|
||||
//Remove from invited factions
|
||||
var i = Player.factionInvitations.findIndex((facName)=>{return facName === faction.name});
|
||||
if (i === -1) {
|
||||
console.log("ERROR: Could not find faction in Player.factionInvitations");
|
||||
} else {
|
||||
Player.factionInvitations.splice(i, 1);
|
||||
}
|
||||
joinFaction(faction);
|
||||
factionInvitationBoxClose();
|
||||
if (Engine.currentPage === Engine.Page.Factions) {
|
||||
Engine.loadFactionsContent();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
var noButton = clearEventListeners("faction-invitation-box-no");
|
||||
noButton.addEventListener("click", function() {
|
||||
factionInvitationBoxClose();
|
||||
faction.alreadyInvited = true;
|
||||
Player.factionInvitations.push(faction.name);
|
||||
return false;
|
||||
});
|
||||
|
||||
|
@ -65,7 +65,7 @@ function removeChildrenFromElement(el) {
|
||||
}
|
||||
}
|
||||
|
||||
function createElement(type, params) {
|
||||
function createElement(type, params={}) {
|
||||
var el = document.createElement(type);
|
||||
if (params.id) {el.id = params.id;}
|
||||
if (params.class) {el.className = params.class;}
|
||||
|
Loading…
Reference in New Issue
Block a user