Merge pull request #336 from danielyxie/dev

v0.39.0
This commit is contained in:
danielyxie 2018-06-25 14:11:18 -05:00 committed by GitHub
commit dcb3fafc81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 12478 additions and 5689 deletions

@ -22,12 +22,6 @@
background-color: #777;
}
/* Select industry type when creating a new division */
.cmpy-mgmt-industry-select {
color:white;
background-color:black;
}
/* Switch between Cities */
.cmpy-mgmt-city-tab {
display:inline-block;

@ -501,18 +501,6 @@
width: 50%;
}
.dev-text-input {
color: var(--my-font-color);
border: 1px solid white;
background-color:black;
}
.dev-dropdown-input {
color: var(--my-font-color);
border: 1px solid white;
background-color:black;
}
/* Location */
#location-container {
position: fixed;

@ -197,6 +197,16 @@ a:link, a:visited {
pointer-events: none;
}
.dropdown {
color:white;
background-color:black;
}
.text-input {
color:white;
background-color:black;
}
/* Notification icon (for create program right now only) */
#create-program-tab {
position:relative;

BIN
dist/android-chrome-192x192.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
dist/android-chrome-512x512.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
dist/apple-touch-icon.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

9
dist/browserconfig.xml vendored Normal file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square70x70logo src="dist/mstile-70x70.png"/>
<TileColor>#000000</TileColor>
</tile>
</msapplication>
</browserconfig>

12980
dist/engine.bundle.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/favicon-16x16.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

BIN
dist/favicon-32x32.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

BIN
dist/mstile-70x70.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

1
dist/safari-pinned-tab.svg vendored Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 8.2 KiB

19
dist/site.webmanifest vendored Normal file

@ -0,0 +1,19 @@
{
"name": "Bitburner",
"short_name": "Bitburner",
"icons": [
{
"src": "android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -3,6 +3,36 @@
Changelog
=========
v0.39.0 - 6/25/2018
-------------------
* Added BitNode-7: Bladeburner 2079
* Infiltration base difficulty decreased by 10% for most locations
* Experience gains from Infiltration slightly increased
* Money gained from Infiltration increased by 20%
* Added 'var' declarations in Netscript 1.0 (only works with 'var', not 'let' or 'const')
* Script base RAM cost is now 1.6 GB (increased from 1.4 GB)
* While/for loops and if statements no longer cost RAM in scripts
* Made short-circuit evaluation logic more consistent in Netscript 1.0 (see https://github.com/danielyxie/bitburner/issues/308)
* Changelog button in the Options menu now links to the new Changelog URL (by Github user thePalindrome)
* Skill level calculation is now 'smoother' (by Github user hydroflame)
* Added a button to 'beautify' scripts in the text editor (by Github user hydroflame)
* Added favicon (by Github user kopelli)
v0.38.1 - 6/15/2018
-------------------
* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS
* Implemented by Github user hydroflame:
* Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)
* Added game option to suppress travel confirmation
* Text on buttons can no longer be highlighted
* Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations
* Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)
* Added ps() Netscript function
* Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money
* Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips
* Bug Fix: Sever's security level should now properly increase when its money is grown to max value
v0.38.0 - 6/12/2018
-------------------
* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame

@ -24,4 +24,5 @@ to reach out to the developer!
Hacknet Node API <netscripthacknetnodeapi>
Trade Information eXchange (TIX) API <netscriptixapi>
Singularity Functions <netscriptsingularityfunctions>
Bladeburner API <netscriptbladeburnerapi>
Miscellaneous <netscriptmisc>

@ -0,0 +1,446 @@
Netscript Bladeburner API
=========================
Netscript provides the following API for interacting with the game's Bladeburner mechanic.
The Bladeburner API is **not** immediately available to the palyer and must be unlocked
later in the game
**WARNING: This page contains spoilers for the game**
The Bladeburner API is unlocked in BitNode-7. If you are in BitNode-7, you will
automatically gain access to this API. Otherwise, you must have Source-File 7 in
order to use this API in other BitNodes
**Bladeburner API functions must be accessed through the bladeburner namespace**
In Netscript 1.0::
bladeburner.getContractNames();
bladeburner.startAction("general", "Training");
In :ref:`netscriptjs`::
ns.bladeburner.getContractNames();
ns.bladeburner.startAction("general", "Training");
.. _bladeburner_action_types:
Bladeburner Action Types
------------------------
Several functions in the Bladeburner API require you to specify an action using
its type and name. The following are valid values when specifying the action's type:
**Contracts**
* contract
* contracts
* contr
**Operations**
* operation
* operations
* op
* ops
**Black Ops**
* blackoperation
* black operation
* black operations
* black op
* black ops
* blackop
* blackops
**General Actions (Training, Field Analysis, Recruitment)**
* general
* general action
* gen
getContractNames
----------------
.. js:function:: getContractNames()
Returns an array of strings containing the names of all Bladeburner contracts
getOperationNames
-----------------
.. js:function:: getOperationNames()
Returns an array of strings containing the names of all Bladeburner operations
getBlackOpNames
---------------
.. js:function:: getBlackOpNames()
Returns an array of strings containing the names of all Bladeburner Black Ops
getGeneralActionNames
---------------------
.. js:function:: getGeneralActionNames()
Returns an array of strings containing the names of all general Bladeburner actions
getSkillNames
-------------
.. js:function:: getSkillNames()
Returns an array of strings containing the names of all Bladeburner skills
startAction
-----------
.. js:function:: startAction(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Attempts to start the specified Bladeburner action. Returns true if the action
was started successfully, and false otherwise.
stopBladeburnerAction
---------------------
.. js:function:: stopBladeburnerAction()
Stops the current Bladeburner action
getActionTime
-------------
.. js:function:: getActionTime(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the number of seconds it takes to complete the specified action
getActionEstimatedSuccessChance
-------------------------------
.. js:function:: getActionEstimatedSuccessChance(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the estimated success chance for the specified action
getActionCountRemaining
-----------------------
.. js:function:: getActionCountRemaining(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the remaining count of the specified action.
Note that this is meant to be used for Contracts and Operations.
This function will return 'Infinity' for actions such as Training and Field Analysis.
getRank
-------
.. js:function:: getRank()
Returns the player's Bladeburner Rank
getSkillPoints
--------------
.. js:function:: getSkillPoints()
Returns the number of Bladeburner skill points you have
getSkillLevel
-------------
.. js:function:: getSkillLevel(skillName="")
:param string skillName: Optional name of Skill. Empty string by default
If no argument or an empty string is passed in, this function returns
an object with your level for all Bladeburner Skills (only for skills that
have at least one level). In the object, the name of the Bladeburner Skills
are the keys and your skill levels are the values. For example::
{
"Blade's Intuition": 10,
"Cloak": 5,
"Evasive System": 6
}
If the name of a skill is passed in as an argument, then this function
returns your level in the specified skill.
The function returns -1 if an invalid skill name is passed in
upgradeSkill
------------
.. js:function:: upgradeSkill(skillName)
:param string skillName: Name of Skill to be upgraded. Must be an exact match
Attempts to upgrade the specified Bladeburner skill. Returns true if the
skill is successfully upgraded, and false otherwise
getTeamSize
-----------
.. js:function:: getTeamSize(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the number of Bladeburner team members you have assigned to the
specified action.
Setting a team is only applicable for Operations and BlackOps. This function
will return 0 for other action types.
setTeamSize
-----------
.. js:function:: setTeamSize(type, name, size)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
:param int size: Number of team members to set. Will be converted using Math.round()
Set the team size for the specified Bladeburner action.
Returns the team size that was set, or -1 if the function failed.
getCityEstimatedPopulation
--------------------------
.. js:function:: getCityEstimatedPopulation(cityName)
:param string cityName: Name of city. Case-sensitive
Returns the estimated number of Synthoids in the specified city, or -1
if an invalid city was specified.
getCityEstimatedCommunities
---------------------------
.. js:function:: getCityEstimatedCommunities(cityName)
:param string cityName: Name of city. Case-sensitive
Returns the estimated number of Synthoid communities in the specified city,
or -1 if an invalid city was specified.
getCityChaos
------------
.. js:function:: getCityChaos(cityName)
:param string cityName: Name of city. Case-sensitive
Returns the chaos in the specified city, or -1 if an invalid city was specified
switchCity
----------
.. js:function:: switchCity(cityName)
:param string cityName: Name of city
Attempts to switch to the specified city (for Bladeburner only).
Returns true if successful, and false otherwise
getStamina
----------
.. js:function:: getStamina()
Returns an array with two elements:
[Current stamina, Max stamina]
Example usage::
function getStaminaPercentage() {
let res = bladeburner.getStamina();
return res[0] / res[1];
}
joinBladeburnerFaction
----------------------
.. js:function:: joinBladeburnerFaction()
Attempts to join the Bladeburner faction.
Returns true if you successfully join the Bladeburner faction, or if
you are already a member.
Returns false otherwise.
Examples
--------
**Basic example usage**::
tprint(bladeburner.getContractNames());
tprint(bladeburner.getOperationNames());
tprint(bladeburner.getBlackOpNames());
tprint(bladeburner.getGeneralActionNames());
tprint(bladeburner.getSkillNames());
tprint(bladeburner.getActionTime("contract", "Tracking"));
tprint("Rank: " + bladeburner.getRank());
tprint("Skill Points: " + bladeburner.getSkillPoints());
tprint("Cloak Skill Level: " + bladeburner.getSkillLevel("Cloak"));
tprint("Trying to upgradeSkill: " + bladeburner.upgradeSkill("Cloak"));
tprint("Skill Points remaining: " + bladeburner.getSkillPoints());
tprint("Trying to switch to a nonexistent city: " + bladeburner.switchCity("lskgns"));
var chongqing = "Chongqing";
tprint("Trying to switch to Chongqing: " + bladeburner.switchCity(chongqing));
tprint("Chongqing chaos: " + bladeburner.getCityChaos(chongqing));
tprint("Chongqing estimated pop: " + bladeburner.getCityEstimatedPopulation(chongqing));
tprint("Chonqging estimated communities: " + bladeburner.getCityEstimatedCommunities(chongqing));
**Bladeburner handler example**. Note that this avoids the need of using the *bladeburner* namespace
identifier by attaching the Bladeburner API functions to an object::
const FIELD_ANALYSIS_INTERVAL = 10; //Number of minutes between field analysis states
const FIELD_ANALYSIS_DURATION = 5; //Duration in minutes
function BladeburnerHandler(ns, params) {
//Netscript environment becomes part of the instance
this.ns = ns;
//Netscript bladeburner API becomes part of this instance
for (var bladeburnerFn in ns.bladeburner) {
this[bladeburnerFn] = ns.bladeburner[bladeburnerFn];
}
this.fieldAnalysis = {
inProgress: params.startFieldAnalysis ? true : false,
cyclesRemaining: FIELD_ANALYSIS_DURATION,
cyclesSince: FIELD_ANALYSIS_INTERVAL
}
}
BladeburnerHandler.prototype.getStaminaPercentage = function() {
var res = this.getStamina();
return 100 * (res[0] / res[1]);
}
BladeburnerHandler.prototype.hasSimulacrum = function() {
var augs = this.ns.getOwnedAugmentations();
return augs.includes("The Blade's Simulacrum");
}
BladeburnerHandler.prototype.handle = function() {
//If we're doing something else manually (without Simlacrum),
//it overrides Bladeburner stuff
if (!this.hasSimulacrum() && this.ns.isBusy()) {
this.ns.print("Idling bc player is busy with some other action");
return;
}
if (this.fieldAnalysis.inProgress) {
--(this.fieldAnalysis.cyclesRemaining);
if (this.fieldAnalysis.cyclesRemaining < 0) {
this.fieldAnalysis.inProgress = false;
this.fieldAnalysis.cyclesSince = 0;
return this.handle();
} else {
this.startAction("general", "Field Analysis");
this.ns.print("handler is doing field analyis for " +
(this.fieldAnalysis.cyclesRemaining+1) + " more mins");
return;
}
} else {
++(this.fieldAnalysis.cyclesSince);
if (this.fieldAnalysis.cyclesSince > FIELD_ANALYSIS_INTERVAL) {
this.fieldAnalysis.inProgress = true;
this.fieldAnalysis.cyclesRemaining = FIELD_ANALYSIS_DURATION;
return this.handle();
}
}
this.stopBladeburnerAction();
var staminaPerc = this.getStaminaPercentage();
if (staminaPerc < 55) {
this.ns.print("handler is starting training due to low stamina percentage");
this.startAction("general", "Training");
} else {
var action = this.chooseAction();
this.ns.print("handler chose " + action.name + " " + action.type + " through chooseAction()");
this.startAction(action.type, action.name);
}
}
BladeburnerHandler.prototype.chooseAction = function() {
//Array of all Operations
var ops = this.getOperationNames();
//Sort Operations in order of increasing success chance
ops.sort((a, b)=>{
return this.getActionEstimatedSuccessChance("operation", a) -
this.getActionEstimatedSuccessChance("operation", b);
});
//Loop through until you find one with 99+% success chance
for (let i = 0; i < ops.length; ++i) {
let successChance = this.getActionEstimatedSuccessChance("operation", ops[i]);
let count = this.getActionCountRemaining("operation", ops[i]);
if (successChance >= 0.99 && count > 10) {
return {type: "operation", name: ops[i]};
}
}
//Repeat for Contracts
var contracts = this.getContractNames();
contracts.sort((a, b)=>{
return this.getActionEstimatedSuccessChance("contract", a) -
this.getActionEstimatedSuccessChance("contract", b);
});
for (let i = 0; i < contracts.length; ++i) {
let successChance = this.getActionEstimatedSuccessChance("contract", contracts[i]);
let count = this.getActionCountRemaining("contract", contracts[i]);
if (successChance >= 0.80 && count > 10) {
return {type: "contract", name: contracts[i]};
}
}
return {type:"general", name:"Training"};
}
BladeburnerHandler.prototype.process = async function() {
this.handle();
await this.ns.sleep(60000);
}
export async function main(ns) {
ns.disableLog("sleep");
//Check if Bladeburner is available. This'll throw a runtime error if it's not
ns.bladeburner.getContractNames();
var startFieldAnalysis = true;
if (ns.args.length >= 1 && ns.args[0] == "false") {
startFieldAnalysis = false;
}
var handler = new BladeburnerHandler(ns, {
startFieldAnalysis: startFieldAnalysis
});
while(true) {
await handler.process();
}
}

@ -942,7 +942,11 @@ prompt
Defining your own Functions
---------------------------
You can define your own functions in Netscript using the following syntax::
Note that the following information is only applicable for Netscript 1.0.
:doc:`netscriptjs` allows you to define your functions using native Javascript
techniques.
You can define your own functions in Netscript 1.0 using the following syntax::
function name(args...) {
function code here...

@ -50,6 +50,45 @@
<div class="section" id="changelog">
<span id="id1"></span><h1>Changelog<a class="headerlink" href="#changelog" title="Permalink to this headline"></a></h1>
<div class="section" id="v0-39-0-6-25-2018">
<h2>v0.39.0 - 6/25/2018<a class="headerlink" href="#v0-39-0-6-25-2018" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>Added BitNode-7: Bladeburner 2079</li>
<li>Infiltration base difficulty decreased by 10% for most locations</li>
<li>Experience gains from Infiltration slightly increased</li>
<li>Money gained from Infiltration increased by 20%</li>
<li>Added 'var' declarations in Netscript 1.0 (only works with 'var', not 'let' or 'const')</li>
<li>Script base RAM cost is now 1.6 GB (increased from 1.4 GB)</li>
<li>While/for loops and if statements no longer cost RAM in scripts</li>
<li>Made short-circuit evaluation logic more consistent in Netscript 1.0 (see <a class="reference external" href="https://github.com/danielyxie/bitburner/issues/308">https://github.com/danielyxie/bitburner/issues/308</a>)</li>
<li>Changelog button in the Options menu now links to the new Changelog URL (by Github user thePalindrome)</li>
<li>Skill level calculation is now 'smoother' (by Github user hydroflame)</li>
<li>Added a button to 'beautify' scripts in the text editor (by Github user hydroflame)</li>
<li>Added favicon (by Github user kopelli)</li>
</ul>
</div>
<div class="section" id="v0-38-1-6-15-2018">
<h2>v0.38.1 - 6/15/2018<a class="headerlink" href="#v0-38-1-6-15-2018" title="Permalink to this headline"></a></h2>
<ul class="simple">
<li>Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS</li>
<li><dl class="first docutils">
<dt>Implemented by Github user hydroflame:</dt>
<dd><ul class="first last">
<li>Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)</li>
<li>Added game option to suppress travel confirmation</li>
<li>Text on buttons can no longer be highlighted</li>
<li>Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations</li>
<li>Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)</li>
<li>Added ps() Netscript function</li>
<li>Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money</li>
<li>Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips</li>
<li>Bug Fix: Sever's security level should now properly increase when its money is grown to max value</li>
</ul>
</dd>
</dl>
</li>
</ul>
</div>
<div class="section" id="v0-38-0-6-12-2018">
<h2>v0.38.0 - 6/12/2018<a class="headerlink" href="#v0-38-0-6-12-2018" title="Permalink to this headline"></a></h2>
<ul class="simple">
@ -1006,6 +1045,8 @@ on the difficulty of the contract.</li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#"> Changelog</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#v0-39-0-6-25-2018">v0.39.0 - 6/25/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="#v0-38-1-6-15-2018">v0.38.1 - 6/15/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="#v0-38-0-6-12-2018">v0.38.0 - 6/12/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="#v0-37-2-6-2-2018">v0.37.2 - 6/2/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="#v0-37-1-5-22-2018">v0.37.1 - 5/22/2018</a></li>

@ -153,21 +153,39 @@
<h2 id="G">G</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptbladeburnerapi.html#getActionCountRemaining">getActionCountRemaining() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getActionEstimatedSuccessChance">getActionEstimatedSuccessChance() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getActionTime">getActionTime() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getAugmentationCost">getAugmentationCost() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getAugmentationsFromFaction">getAugmentationsFromFaction() (built-in function)</a>
</li>
<li><a href="netscriptadvancedfunctions.html#getBitNodeMultipliers">getBitNodeMultipliers() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getBlackOpNames">getBlackOpNames() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getCityChaos">getCityChaos() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getCityEstimatedCommunities">getCityEstimatedCommunities() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getCityEstimatedPopulation">getCityEstimatedPopulation() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getCompanyFavor">getCompanyFavor() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getCompanyRep">getCompanyRep() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getContractNames">getContractNames() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getCrimeChance">getCrimeChance() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getFactionFavor">getFactionFavor() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getFactionRep">getFactionRep() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getGeneralActionNames">getGeneralActionNames() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getGrowTime">getGrowTime() (built-in function)</a>
</li>
@ -182,17 +200,21 @@
<li><a href="netscriptfunctions.html#getHostname">getHostname() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getNextHacknetNodeCost">getNextHacknetNodeCost() (built-in function)</a>, <a href="netscripthacknetnodeapi.html#getNextHacknetNodeCost">[1]</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getOperationNames">getOperationNames() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getOwnedAugmentations">getOwnedAugmentations() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getPurchasedServers">getPurchasedServers() (built-in function)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptbladeburnerapi.html#getRank">getRank() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getScriptExpGain">getScriptExpGain() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getScriptIncome">getScriptIncome() (built-in function)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptfunctions.html#getScriptName">getScriptName() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getScriptRam">getScriptRam() (built-in function)</a>
@ -214,12 +236,22 @@
<li><a href="netscriptfunctions.html#getServerRequiredHackingLevel">getServerRequiredHackingLevel() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getServerSecurityLevel">getServerSecurityLevel() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getSkillLevel">getSkillLevel() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getSkillNames">getSkillNames() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getSkillPoints">getSkillPoints() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getStamina">getStamina() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#getStats">getStats() (built-in function)</a>
</li>
<li><a href="netscriptixapi.html#getStockPosition">getStockPosition() (built-in function)</a>
</li>
<li><a href="netscriptixapi.html#getStockPrice">getStockPrice() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#getTeamSize">getTeamSize() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#getTimeSinceLastAug">getTimeSinceLastAug() (built-in function)</a>
</li>
@ -278,6 +310,10 @@
<h2 id="J">J</h2>
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptbladeburnerapi.html#joinBladeburnerFaction">joinBladeburnerFaction() (built-in function)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptsingularityfunctions.html#joinFaction">joinFaction() (built-in function)</a>
</li>
@ -375,10 +411,12 @@
</li>
<li><a href="netscriptixapi.html#sellStock">sellStock() (built-in function)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptfunctions.html#serverExists">serverExists() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#setTeamSize">setTeamSize() (built-in function)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptixapi.html#shortStock">shortStock() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#sleep">sleep() (built-in function)</a>
@ -388,8 +426,14 @@
<li><a href="netscriptfunctions.html#sprintf">sprintf() (built-in function)</a>
</li>
<li><a href="netscriptfunctions.html#sqlinject">sqlinject() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#startAction">startAction() (built-in function)</a>
</li>
<li><a href="netscriptsingularityfunctions.html#stopAction">stopAction() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#stopBladeburnerAction">stopBladeburnerAction() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#switchCity">switchCity() (built-in function)</a>
</li>
</ul></td>
</tr></table>
@ -414,6 +458,8 @@
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="netscriptsingularityfunctions.html#upgradeHomeRam">upgradeHomeRam() (built-in function)</a>
</li>
<li><a href="netscriptbladeburnerapi.html#upgradeSkill">upgradeSkill() (built-in function)</a>
</li>
</ul></td>
</tr></table>

@ -211,6 +211,33 @@ secrets that you've been searching for.</p>
<li class="toctree-l3"><a class="reference internal" href="netscriptsingularityfunctions.html#installaugmentations">installAugmentations</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html"> Bladeburner API</a><ul>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#bladeburner-action-types">Bladeburner Action Types</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getcontractnames">getContractNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getoperationnames">getOperationNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getblackopnames">getBlackOpNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getgeneralactionnames">getGeneralActionNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getskillnames">getSkillNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#startaction">startAction</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#stopbladeburneraction">stopBladeburnerAction</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getactiontime">getActionTime</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getactionestimatedsuccesschance">getActionEstimatedSuccessChance</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getactioncountremaining">getActionCountRemaining</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getrank">getRank</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getskillpoints">getSkillPoints</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getskilllevel">getSkillLevel</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#upgradeskill">upgradeSkill</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getteamsize">getTeamSize</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#setteamsize">setTeamSize</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getcityestimatedpopulation">getCityEstimatedPopulation</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getcityestimatedcommunities">getCityEstimatedCommunities</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getcitychaos">getCityChaos</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#switchcity">switchCity</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#getstamina">getStamina</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#joinbladeburnerfaction">joinBladeburnerFaction</a></li>
<li class="toctree-l3"><a class="reference internal" href="netscriptbladeburnerapi.html#examples">Examples</a></li>
</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>
@ -269,6 +296,8 @@ secrets that you've been searching for.</p>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a><ul>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-39-0-6-25-2018">v0.39.0 - 6/25/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-38-1-6-15-2018">v0.38.1 - 6/15/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-38-0-6-12-2018">v0.38.0 - 6/12/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-2-6-2-2018">v0.37.2 - 6/2/2018</a></li>
<li class="toctree-l2"><a class="reference internal" href="changelog.html#v0-37-1-5-22-2018">v0.37.1 - 5/22/2018</a></li>

@ -212,6 +212,33 @@ to reach out to the developer!</p>
<li class="toctree-l2"><a class="reference internal" href="netscriptsingularityfunctions.html#installaugmentations">installAugmentations</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="netscriptbladeburnerapi.html"> Bladeburner API</a><ul>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#bladeburner-action-types">Bladeburner Action Types</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getcontractnames">getContractNames</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getoperationnames">getOperationNames</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getblackopnames">getBlackOpNames</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getgeneralactionnames">getGeneralActionNames</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getskillnames">getSkillNames</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#startaction">startAction</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#stopbladeburneraction">stopBladeburnerAction</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getactiontime">getActionTime</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getactionestimatedsuccesschance">getActionEstimatedSuccessChance</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getactioncountremaining">getActionCountRemaining</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getrank">getRank</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getskillpoints">getSkillPoints</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getskilllevel">getSkillLevel</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#upgradeskill">upgradeSkill</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getteamsize">getTeamSize</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#setteamsize">setTeamSize</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getcityestimatedpopulation">getCityEstimatedPopulation</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getcityestimatedcommunities">getCityEstimatedCommunities</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getcitychaos">getCityChaos</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#switchcity">switchCity</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#getstamina">getStamina</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#joinbladeburnerfaction">joinBladeburnerFaction</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptbladeburnerapi.html#examples">Examples</a></li>
</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>
@ -245,6 +272,7 @@ to reach out to the developer!</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="netscriptbladeburnerapi.html"> Bladeburner API</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
</ul>
</li>

@ -0,0 +1,748 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="English">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Netscript Bladeburner API &#8212; Bitburner 1.0 documentation</title>
<link rel="stylesheet" href="_static/agogo.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<script type="text/javascript">
var DOCUMENTATION_OPTIONS = {
URL_ROOT: './',
VERSION: '1.0',
COLLAPSE_INDEX: false,
FILE_SUFFIX: '.html',
HAS_SOURCE: true,
SOURCELINK_SUFFIX: '.txt'
};
</script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Netscript Miscellaneous" href="netscriptmisc.html" />
<link rel="prev" title="Netscript Singularity Functions" href="netscriptsingularityfunctions.html" />
</head>
<body>
<div class="header-wrapper" role="banner">
<div class="header">
<div class="headertitle"><a
href="index.html">Bitburner 1.0 documentation</a></div>
<div class="rel" role="navigation" aria-label="related navigation">
<a href="netscriptsingularityfunctions.html" title="Netscript Singularity Functions"
accesskey="P">previous</a> |
<a href="netscriptmisc.html" title="Netscript Miscellaneous"
accesskey="N">next</a> |
<a href="genindex.html" title="General Index"
accesskey="I">index</a>
</div>
</div>
</div>
<div class="content-wrapper">
<div class="content">
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<div class="section" id="netscript-bladeburner-api">
<h1>Netscript Bladeburner API<a class="headerlink" href="#netscript-bladeburner-api" title="Permalink to this headline"></a></h1>
<p>Netscript provides the following API for interacting with the game's Bladeburner mechanic.</p>
<p>The Bladeburner API is <strong>not</strong> immediately available to the palyer and must be unlocked
later in the game</p>
<p><strong>WARNING: This page contains spoilers for the game</strong></p>
<p>The Bladeburner API is unlocked in BitNode-7. If you are in BitNode-7, you will
automatically gain access to this API. Otherwise, you must have Source-File 7 in
order to use this API in other BitNodes</p>
<p><strong>Bladeburner API functions must be accessed through the bladeburner namespace</strong></p>
<p>In Netscript 1.0:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getContractNames</span><span class="p">();</span>
<span class="n">bladeburner</span><span class="o">.</span><span class="n">startAction</span><span class="p">(</span><span class="s2">&quot;general&quot;</span><span class="p">,</span> <span class="s2">&quot;Training&quot;</span><span class="p">);</span>
</pre></div>
</div>
<p>In <a class="reference internal" href="netscriptjs.html#netscriptjs"><span class="std std-ref">NetscriptJS (Netscript 2.0)</span></a>:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">ns</span><span class="o">.</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getContractNames</span><span class="p">();</span>
<span class="n">ns</span><span class="o">.</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">startAction</span><span class="p">(</span><span class="s2">&quot;general&quot;</span><span class="p">,</span> <span class="s2">&quot;Training&quot;</span><span class="p">);</span>
</pre></div>
</div>
<div class="section" id="bladeburner-action-types">
<span id="id1"></span><h2>Bladeburner Action Types<a class="headerlink" href="#bladeburner-action-types" title="Permalink to this headline"></a></h2>
<p>Several functions in the Bladeburner API require you to specify an action using
its type and name. The following are valid values when specifying the action's type:</p>
<dl class="docutils">
<dt><strong>Contracts</strong></dt>
<dd><ul class="first last simple">
<li>contract</li>
<li>contracts</li>
<li>contr</li>
</ul>
</dd>
<dt><strong>Operations</strong></dt>
<dd><ul class="first last simple">
<li>operation</li>
<li>operations</li>
<li>op</li>
<li>ops</li>
</ul>
</dd>
<dt><strong>Black Ops</strong></dt>
<dd><ul class="first last simple">
<li>blackoperation</li>
<li>black operation</li>
<li>black operations</li>
<li>black op</li>
<li>black ops</li>
<li>blackop</li>
<li>blackops</li>
</ul>
</dd>
<dt><strong>General Actions (Training, Field Analysis, Recruitment)</strong></dt>
<dd><ul class="first last simple">
<li>general</li>
<li>general action</li>
<li>gen</li>
</ul>
</dd>
</dl>
</div>
<div class="section" id="getcontractnames">
<h2>getContractNames<a class="headerlink" href="#getcontractnames" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getContractNames">
<code class="descname">getContractNames</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getContractNames" title="Permalink to this definition"></a></dt>
<dd><p>Returns an array of strings containing the names of all Bladeburner contracts</p>
</dd></dl>
</div>
<div class="section" id="getoperationnames">
<h2>getOperationNames<a class="headerlink" href="#getoperationnames" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getOperationNames">
<code class="descname">getOperationNames</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getOperationNames" title="Permalink to this definition"></a></dt>
<dd><p>Returns an array of strings containing the names of all Bladeburner operations</p>
</dd></dl>
</div>
<div class="section" id="getblackopnames">
<h2>getBlackOpNames<a class="headerlink" href="#getblackopnames" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getBlackOpNames">
<code class="descname">getBlackOpNames</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getBlackOpNames" title="Permalink to this definition"></a></dt>
<dd><p>Returns an array of strings containing the names of all Bladeburner Black Ops</p>
</dd></dl>
</div>
<div class="section" id="getgeneralactionnames">
<h2>getGeneralActionNames<a class="headerlink" href="#getgeneralactionnames" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getGeneralActionNames">
<code class="descname">getGeneralActionNames</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getGeneralActionNames" title="Permalink to this definition"></a></dt>
<dd><p>Returns an array of strings containing the names of all general Bladeburner actions</p>
</dd></dl>
</div>
<div class="section" id="getskillnames">
<h2>getSkillNames<a class="headerlink" href="#getskillnames" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getSkillNames">
<code class="descname">getSkillNames</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getSkillNames" title="Permalink to this definition"></a></dt>
<dd><p>Returns an array of strings containing the names of all Bladeburner skills</p>
</dd></dl>
</div>
<div class="section" id="startaction">
<h2>startAction<a class="headerlink" href="#startaction" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="startAction">
<code class="descname">startAction</code><span class="sig-paren">(</span><em>type</em>, <em>name</em><span class="sig-paren">)</span><a class="headerlink" href="#startAction" 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 last simple">
<li><strong>type</strong> (<em>string</em>) -- Type of action. See <a class="reference internal" href="#bladeburner-action-types"><span class="std std-ref">Bladeburner Action Types</span></a></li>
<li><strong>name</strong> (<em>string</em>) -- Name of action. Must be an exact match</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Attempts to start the specified Bladeburner action. Returns true if the action
was started successfully, and false otherwise.</p>
</dd></dl>
</div>
<div class="section" id="stopbladeburneraction">
<h2>stopBladeburnerAction<a class="headerlink" href="#stopbladeburneraction" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="stopBladeburnerAction">
<code class="descname">stopBladeburnerAction</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#stopBladeburnerAction" title="Permalink to this definition"></a></dt>
<dd><p>Stops the current Bladeburner action</p>
</dd></dl>
</div>
<div class="section" id="getactiontime">
<h2>getActionTime<a class="headerlink" href="#getactiontime" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getActionTime">
<code class="descname">getActionTime</code><span class="sig-paren">(</span><em>type</em>, <em>name</em><span class="sig-paren">)</span><a class="headerlink" href="#getActionTime" 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 last simple">
<li><strong>type</strong> (<em>string</em>) -- Type of action. See <a class="reference internal" href="#bladeburner-action-types"><span class="std std-ref">Bladeburner Action Types</span></a></li>
<li><strong>name</strong> (<em>string</em>) -- Name of action. Must be an exact match</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the number of seconds it takes to complete the specified action</p>
</dd></dl>
</div>
<div class="section" id="getactionestimatedsuccesschance">
<h2>getActionEstimatedSuccessChance<a class="headerlink" href="#getactionestimatedsuccesschance" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getActionEstimatedSuccessChance">
<code class="descname">getActionEstimatedSuccessChance</code><span class="sig-paren">(</span><em>type</em>, <em>name</em><span class="sig-paren">)</span><a class="headerlink" href="#getActionEstimatedSuccessChance" 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 last simple">
<li><strong>type</strong> (<em>string</em>) -- Type of action. See <a class="reference internal" href="#bladeburner-action-types"><span class="std std-ref">Bladeburner Action Types</span></a></li>
<li><strong>name</strong> (<em>string</em>) -- Name of action. Must be an exact match</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the estimated success chance for the specified action</p>
</dd></dl>
</div>
<div class="section" id="getactioncountremaining">
<h2>getActionCountRemaining<a class="headerlink" href="#getactioncountremaining" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getActionCountRemaining">
<code class="descname">getActionCountRemaining</code><span class="sig-paren">(</span><em>type</em>, <em>name</em><span class="sig-paren">)</span><a class="headerlink" href="#getActionCountRemaining" 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 last simple">
<li><strong>type</strong> (<em>string</em>) -- Type of action. See <a class="reference internal" href="#bladeburner-action-types"><span class="std std-ref">Bladeburner Action Types</span></a></li>
<li><strong>name</strong> (<em>string</em>) -- Name of action. Must be an exact match</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the remaining count of the specified action.</p>
<p>Note that this is meant to be used for Contracts and Operations.
This function will return 'Infinity' for actions such as Training and Field Analysis.</p>
</dd></dl>
</div>
<div class="section" id="getrank">
<h2>getRank<a class="headerlink" href="#getrank" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getRank">
<code class="descname">getRank</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getRank" title="Permalink to this definition"></a></dt>
<dd><p>Returns the player's Bladeburner Rank</p>
</dd></dl>
</div>
<div class="section" id="getskillpoints">
<h2>getSkillPoints<a class="headerlink" href="#getskillpoints" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getSkillPoints">
<code class="descname">getSkillPoints</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getSkillPoints" title="Permalink to this definition"></a></dt>
<dd><p>Returns the number of Bladeburner skill points you have</p>
</dd></dl>
</div>
<div class="section" id="getskilllevel">
<h2>getSkillLevel<a class="headerlink" href="#getskilllevel" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getSkillLevel">
<code class="descname">getSkillLevel</code><span class="sig-paren">(</span><em>skillName=&quot;&quot;</em><span class="sig-paren">)</span><a class="headerlink" href="#getSkillLevel" 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 last simple">
<li><strong>skillName</strong> (<em>string</em>) -- Optional name of Skill. Empty string by default</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>If no argument or an empty string is passed in, this function returns
an object with your level for all Bladeburner Skills (only for skills that
have at least one level). In the object, the name of the Bladeburner Skills
are the keys and your skill levels are the values. For example:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="p">{</span>
<span class="s2">&quot;Blade&#39;s Intuition&quot;</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span>
<span class="s2">&quot;Cloak&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span>
<span class="s2">&quot;Evasive System&quot;</span><span class="p">:</span> <span class="mi">6</span>
<span class="p">}</span>
</pre></div>
</div>
<p>If the name of a skill is passed in as an argument, then this function
returns your level in the specified skill.</p>
<p>The function returns -1 if an invalid skill name is passed in</p>
</dd></dl>
</div>
<div class="section" id="upgradeskill">
<h2>upgradeSkill<a class="headerlink" href="#upgradeskill" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="upgradeSkill">
<code class="descname">upgradeSkill</code><span class="sig-paren">(</span><em>skillName</em><span class="sig-paren">)</span><a class="headerlink" href="#upgradeSkill" 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 last simple">
<li><strong>skillName</strong> (<em>string</em>) -- Name of Skill to be upgraded. Must be an exact match</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Attempts to upgrade the specified Bladeburner skill. Returns true if the
skill is successfully upgraded, and false otherwise</p>
</dd></dl>
</div>
<div class="section" id="getteamsize">
<h2>getTeamSize<a class="headerlink" href="#getteamsize" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getTeamSize">
<code class="descname">getTeamSize</code><span class="sig-paren">(</span><em>type</em>, <em>name</em><span class="sig-paren">)</span><a class="headerlink" href="#getTeamSize" 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 last simple">
<li><strong>type</strong> (<em>string</em>) -- Type of action. See <a class="reference internal" href="#bladeburner-action-types"><span class="std std-ref">Bladeburner Action Types</span></a></li>
<li><strong>name</strong> (<em>string</em>) -- Name of action. Must be an exact match</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the number of Bladeburner team members you have assigned to the
specified action.</p>
<p>Setting a team is only applicable for Operations and BlackOps. This function
will return 0 for other action types.</p>
</dd></dl>
</div>
<div class="section" id="setteamsize">
<h2>setTeamSize<a class="headerlink" href="#setteamsize" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="setTeamSize">
<code class="descname">setTeamSize</code><span class="sig-paren">(</span><em>type</em>, <em>name</em>, <em>size</em><span class="sig-paren">)</span><a class="headerlink" href="#setTeamSize" 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 last simple">
<li><strong>type</strong> (<em>string</em>) -- Type of action. See <a class="reference internal" href="#bladeburner-action-types"><span class="std std-ref">Bladeburner Action Types</span></a></li>
<li><strong>name</strong> (<em>string</em>) -- Name of action. Must be an exact match</li>
<li><strong>size</strong> (<em>int</em>) -- Number of team members to set. Will be converted using Math.round()</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Set the team size for the specified Bladeburner action.</p>
<p>Returns the team size that was set, or -1 if the function failed.</p>
</dd></dl>
</div>
<div class="section" id="getcityestimatedpopulation">
<h2>getCityEstimatedPopulation<a class="headerlink" href="#getcityestimatedpopulation" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getCityEstimatedPopulation">
<code class="descname">getCityEstimatedPopulation</code><span class="sig-paren">(</span><em>cityName</em><span class="sig-paren">)</span><a class="headerlink" href="#getCityEstimatedPopulation" 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 last simple">
<li><strong>cityName</strong> (<em>string</em>) -- Name of city. Case-sensitive</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the estimated number of Synthoids in the specified city, or -1
if an invalid city was specified.</p>
</dd></dl>
</div>
<div class="section" id="getcityestimatedcommunities">
<h2>getCityEstimatedCommunities<a class="headerlink" href="#getcityestimatedcommunities" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getCityEstimatedCommunities">
<code class="descname">getCityEstimatedCommunities</code><span class="sig-paren">(</span><em>cityName</em><span class="sig-paren">)</span><a class="headerlink" href="#getCityEstimatedCommunities" 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 last simple">
<li><strong>cityName</strong> (<em>string</em>) -- Name of city. Case-sensitive</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the estimated number of Synthoid communities in the specified city,
or -1 if an invalid city was specified.</p>
</dd></dl>
</div>
<div class="section" id="getcitychaos">
<h2>getCityChaos<a class="headerlink" href="#getcitychaos" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getCityChaos">
<code class="descname">getCityChaos</code><span class="sig-paren">(</span><em>cityName</em><span class="sig-paren">)</span><a class="headerlink" href="#getCityChaos" 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 last simple">
<li><strong>cityName</strong> (<em>string</em>) -- Name of city. Case-sensitive</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Returns the chaos in the specified city, or -1 if an invalid city was specified</p>
</dd></dl>
</div>
<div class="section" id="switchcity">
<h2>switchCity<a class="headerlink" href="#switchcity" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="switchCity">
<code class="descname">switchCity</code><span class="sig-paren">(</span><em>cityName</em><span class="sig-paren">)</span><a class="headerlink" href="#switchCity" 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 last simple">
<li><strong>cityName</strong> (<em>string</em>) -- Name of city</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>Attempts to switch to the specified city (for Bladeburner only).</p>
<p>Returns true if successful, and false otherwise</p>
</dd></dl>
</div>
<div class="section" id="getstamina">
<h2>getStamina<a class="headerlink" href="#getstamina" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="getStamina">
<code class="descname">getStamina</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#getStamina" title="Permalink to this definition"></a></dt>
<dd><p>Returns an array with two elements:</p>
<blockquote>
<div>[Current stamina, Max stamina]</div></blockquote>
<p>Example usage:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">function</span> <span class="n">getStaminaPercentage</span><span class="p">()</span> <span class="p">{</span>
<span class="n">let</span> <span class="n">res</span> <span class="o">=</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getStamina</span><span class="p">();</span>
<span class="k">return</span> <span class="n">res</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">/</span> <span class="n">res</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
<span class="p">}</span>
</pre></div>
</div>
</dd></dl>
</div>
<div class="section" id="joinbladeburnerfaction">
<h2>joinBladeburnerFaction<a class="headerlink" href="#joinbladeburnerfaction" title="Permalink to this headline"></a></h2>
<dl class="function">
<dt id="joinBladeburnerFaction">
<code class="descname">joinBladeburnerFaction</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#joinBladeburnerFaction" title="Permalink to this definition"></a></dt>
<dd><p>Attempts to join the Bladeburner faction.</p>
<p>Returns true if you successfully join the Bladeburner faction, or if
you are already a member.</p>
<p>Returns false otherwise.</p>
</dd></dl>
</div>
<div class="section" id="examples">
<h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline"></a></h2>
<p><strong>Basic example usage</strong>:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">tprint</span><span class="p">(</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getContractNames</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getOperationNames</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getBlackOpNames</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getGeneralActionNames</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getSkillNames</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="n">bladeburner</span><span class="o">.</span><span class="n">getActionTime</span><span class="p">(</span><span class="s2">&quot;contract&quot;</span><span class="p">,</span> <span class="s2">&quot;Tracking&quot;</span><span class="p">));</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Rank: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getRank</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Skill Points: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getSkillPoints</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Cloak Skill Level: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getSkillLevel</span><span class="p">(</span><span class="s2">&quot;Cloak&quot;</span><span class="p">));</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Trying to upgradeSkill: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">upgradeSkill</span><span class="p">(</span><span class="s2">&quot;Cloak&quot;</span><span class="p">));</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Skill Points remaining: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getSkillPoints</span><span class="p">());</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Trying to switch to a nonexistent city: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">switchCity</span><span class="p">(</span><span class="s2">&quot;lskgns&quot;</span><span class="p">));</span>
<span class="n">var</span> <span class="n">chongqing</span> <span class="o">=</span> <span class="s2">&quot;Chongqing&quot;</span><span class="p">;</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Trying to switch to Chongqing: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">switchCity</span><span class="p">(</span><span class="n">chongqing</span><span class="p">));</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Chongqing chaos: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getCityChaos</span><span class="p">(</span><span class="n">chongqing</span><span class="p">));</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Chongqing estimated pop: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getCityEstimatedPopulation</span><span class="p">(</span><span class="n">chongqing</span><span class="p">));</span>
<span class="n">tprint</span><span class="p">(</span><span class="s2">&quot;Chonqging estimated communities: &quot;</span> <span class="o">+</span> <span class="n">bladeburner</span><span class="o">.</span><span class="n">getCityEstimatedCommunities</span><span class="p">(</span><span class="n">chongqing</span><span class="p">));</span>
</pre></div>
</div>
<p><strong>Bladeburner handler example</strong>. Note that this avoids the need of using the <em>bladeburner</em> namespace
identifier by attaching the Bladeburner API functions to an object:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span>const FIELD_ANALYSIS_INTERVAL = 10; //Number of minutes between field analysis states
const FIELD_ANALYSIS_DURATION = 5; //Duration in minutes
function BladeburnerHandler(ns, params) {
//Netscript environment becomes part of the instance
this.ns = ns;
//Netscript bladeburner API becomes part of this instance
for (var bladeburnerFn in ns.bladeburner) {
this[bladeburnerFn] = ns.bladeburner[bladeburnerFn];
}
this.fieldAnalysis = {
inProgress: params.startFieldAnalysis ? true : false,
cyclesRemaining: FIELD_ANALYSIS_DURATION,
cyclesSince: FIELD_ANALYSIS_INTERVAL
}
}
BladeburnerHandler.prototype.getStaminaPercentage = function() {
var res = this.getStamina();
return 100 * (res[0] / res[1]);
}
BladeburnerHandler.prototype.hasSimulacrum = function() {
var augs = this.ns.getOwnedAugmentations();
return augs.includes(&quot;The Blade&#39;s Simulacrum&quot;);
}
BladeburnerHandler.prototype.handle = function() {
//If we&#39;re doing something else manually (without Simlacrum),
//it overrides Bladeburner stuff
if (!this.hasSimulacrum() &amp;&amp; this.ns.isBusy()) {
this.ns.print(&quot;Idling bc player is busy with some other action&quot;);
return;
}
if (this.fieldAnalysis.inProgress) {
--(this.fieldAnalysis.cyclesRemaining);
if (this.fieldAnalysis.cyclesRemaining &lt; 0) {
this.fieldAnalysis.inProgress = false;
this.fieldAnalysis.cyclesSince = 0;
return this.handle();
} else {
this.startAction(&quot;general&quot;, &quot;Field Analysis&quot;);
this.ns.print(&quot;handler is doing field analyis for &quot; +
(this.fieldAnalysis.cyclesRemaining+1) + &quot; more mins&quot;);
return;
}
} else {
++(this.fieldAnalysis.cyclesSince);
if (this.fieldAnalysis.cyclesSince &gt; FIELD_ANALYSIS_INTERVAL) {
this.fieldAnalysis.inProgress = true;
this.fieldAnalysis.cyclesRemaining = FIELD_ANALYSIS_DURATION;
return this.handle();
}
}
this.stopBladeburnerAction();
var staminaPerc = this.getStaminaPercentage();
if (staminaPerc &lt; 55) {
this.ns.print(&quot;handler is starting training due to low stamina percentage&quot;);
this.startAction(&quot;general&quot;, &quot;Training&quot;);
} else {
var action = this.chooseAction();
this.ns.print(&quot;handler chose &quot; + action.name + &quot; &quot; + action.type + &quot; through chooseAction()&quot;);
this.startAction(action.type, action.name);
}
}
BladeburnerHandler.prototype.chooseAction = function() {
//Array of all Operations
var ops = this.getOperationNames();
//Sort Operations in order of increasing success chance
ops.sort((a, b)=&gt;{
return this.getActionEstimatedSuccessChance(&quot;operation&quot;, a) -
this.getActionEstimatedSuccessChance(&quot;operation&quot;, b);
});
//Loop through until you find one with 99+% success chance
for (let i = 0; i &lt; ops.length; ++i) {
let successChance = this.getActionEstimatedSuccessChance(&quot;operation&quot;, ops[i]);
let count = this.getActionCountRemaining(&quot;operation&quot;, ops[i]);
if (successChance &gt;= 0.99 &amp;&amp; count &gt; 10) {
return {type: &quot;operation&quot;, name: ops[i]};
}
}
//Repeat for Contracts
var contracts = this.getContractNames();
contracts.sort((a, b)=&gt;{
return this.getActionEstimatedSuccessChance(&quot;contract&quot;, a) -
this.getActionEstimatedSuccessChance(&quot;contract&quot;, b);
});
for (let i = 0; i &lt; contracts.length; ++i) {
let successChance = this.getActionEstimatedSuccessChance(&quot;contract&quot;, contracts[i]);
let count = this.getActionCountRemaining(&quot;contract&quot;, contracts[i]);
if (successChance &gt;= 0.80 &amp;&amp; count &gt; 10) {
return {type: &quot;contract&quot;, name: contracts[i]};
}
}
return {type:&quot;general&quot;, name:&quot;Training&quot;};
}
BladeburnerHandler.prototype.process = async function() {
this.handle();
await this.ns.sleep(60000);
}
export async function main(ns) {
ns.disableLog(&quot;sleep&quot;);
//Check if Bladeburner is available. This&#39;ll throw a runtime error if it&#39;s not
ns.bladeburner.getContractNames();
var startFieldAnalysis = true;
if (ns.args.length &gt;= 1 &amp;&amp; ns.args[0] == &quot;false&quot;) {
startFieldAnalysis = false;
}
var handler = new BladeburnerHandler(ns, {
startFieldAnalysis: startFieldAnalysis
});
while(true) {
await handler.process();
}
}
</pre></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sidebar">
<h3>Table Of Contents</h3>
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="netscript.html"> Netscript</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="netscriptjs.html"> NetscriptJS (Netscript 2.0)</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptdatatypes.html"> Data Types and Variables</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptoperators.html"> Operators</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptloopsandconditionals.html"> Loops and Conditionals</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptscriptarguments.html"> Script Arguments</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptfunctions.html"> Basic Functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptadvancedfunctions.html"> Advanced Functions</a></li>
<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 current"><a class="current reference internal" href="#"> Bladeburner API</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#bladeburner-action-types">Bladeburner Action Types</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getcontractnames">getContractNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getoperationnames">getOperationNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getblackopnames">getBlackOpNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getgeneralactionnames">getGeneralActionNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getskillnames">getSkillNames</a></li>
<li class="toctree-l3"><a class="reference internal" href="#startaction">startAction</a></li>
<li class="toctree-l3"><a class="reference internal" href="#stopbladeburneraction">stopBladeburnerAction</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getactiontime">getActionTime</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getactionestimatedsuccesschance">getActionEstimatedSuccessChance</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getactioncountremaining">getActionCountRemaining</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getrank">getRank</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getskillpoints">getSkillPoints</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getskilllevel">getSkillLevel</a></li>
<li class="toctree-l3"><a class="reference internal" href="#upgradeskill">upgradeSkill</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getteamsize">getTeamSize</a></li>
<li class="toctree-l3"><a class="reference internal" href="#setteamsize">setTeamSize</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getcityestimatedpopulation">getCityEstimatedPopulation</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getcityestimatedcommunities">getCityEstimatedCommunities</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getcitychaos">getCityChaos</a></li>
<li class="toctree-l3"><a class="reference internal" href="#switchcity">switchCity</a></li>
<li class="toctree-l3"><a class="reference internal" href="#getstamina">getStamina</a></li>
<li class="toctree-l3"><a class="reference internal" href="#joinbladeburnerfaction">joinBladeburnerFaction</a></li>
<li class="toctree-l3"><a class="reference internal" href="#examples">Examples</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="terminal.html"> Terminal</a></li>
<li class="toctree-l1"><a class="reference internal" href="shortcuts.html"> Keyboard Shortcuts</a></li>
<li class="toctree-l1"><a class="reference internal" href="changelog.html"> Changelog</a></li>
</ul>
<div role="search">
<h3 style="margin-top: 1.5em;">Search</h3>
<form class="search" action="search.html" method="get">
<input type="text" name="q" />
<input type="submit" value="Go" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="clearer"></div>
</div>
</div>
<div class="footer-wrapper">
<div class="footer">
<div class="left">
<div role="navigation" aria-label="related navigaton">
<a href="netscriptsingularityfunctions.html" title="Netscript Singularity Functions"
>previous</a> |
<a href="netscriptmisc.html" title="Netscript Miscellaneous"
>next</a> |
<a href="genindex.html" title="General Index"
>index</a>
</div>
<div role="note" aria-label="source link">
<br/>
<a href="_sources/netscriptbladeburnerapi.rst.txt"
rel="nofollow">Show Source</a>
</div>
</div>
<div class="right">
<div class="footer" role="contentinfo">
&#169; Copyright 2017, Bitburner.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.6.4.
</div>
</div>
<div class="clearer"></div>
</div>
</div>
</body>
</html>

@ -1567,7 +1567,10 @@ false if the player clicks &quot;No&quot;. The script's execution is halted unti
<div class="section" id="defining-your-own-functions">
<h3>Defining your own Functions<a class="headerlink" href="#defining-your-own-functions" title="Permalink to this headline"></a></h3>
<p>You can define your own functions in Netscript using the following syntax:</p>
<p>Note that the following information is only applicable for Netscript 1.0.
<a class="reference internal" href="netscriptjs.html"><span class="doc">NetscriptJS (Netscript 2.0)</span></a> allows you to define your functions using native Javascript
techniques.</p>
<p>You can define your own functions in Netscript 1.0 using the following syntax:</p>
<div class="highlight-default"><div class="highlight"><pre><span></span><span class="n">function</span> <span class="n">name</span><span class="p">(</span><span class="n">args</span><span class="o">...</span><span class="p">)</span> <span class="p">{</span>
<span class="n">function</span> <span class="n">code</span> <span class="n">here</span><span class="o">...</span>
<span class="k">return</span> <span class="n">some_value</span>
@ -1738,6 +1741,7 @@ you create in functions such as <a class="reference external" href="https://deve
<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="netscriptbladeburnerapi.html"> Bladeburner API</a></li>
<li class="toctree-l2"><a class="reference internal" href="netscriptmisc.html"> Miscellaneous</a></li>
</ul>
</li>

Binary file not shown.

File diff suppressed because one or more lines are too long

@ -3,6 +3,22 @@
Changelog
=========
v0.39.0 - 6/25/2018
-------------------
* Added BitNode-7: Bladeburner 2079
* Infiltration base difficulty decreased by 10% for most locations
* Experience gains from Infiltration slightly increased
* Money gained from Infiltration increased by 20%
* Added 'var' declarations in Netscript 1.0 (only works with 'var', not 'let' or 'const')
* Script base RAM cost is now 1.6 GB (increased from 1.4 GB)
* While/for loops and if statements no longer cost RAM in scripts
* Made short-circuit evaluation logic more consistent in Netscript 1.0 (see https://github.com/danielyxie/bitburner/issues/308)
* Changelog button in the Options menu now links to the new Changelog URL (by Github user thePalindrome)
* Skill level calculation is now 'smoother' (by Github user hydroflame)
* Added a button to 'beautify' scripts in the text editor (by Github user hydroflame)
* Added favicon (by Github user kopelli)
v0.38.1 - 6/15/2018
-------------------
* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS
@ -17,7 +33,6 @@ v0.38.1 - 6/15/2018
* Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips
* Bug Fix: Sever's security level should now properly increase when its money is grown to max value
v0.38.0 - 6/12/2018
-------------------
* New BitNode: BN-12 The Recursion - Implemented by Github user hydroflame

@ -24,4 +24,5 @@ to reach out to the developer!
Hacknet Node API <netscripthacknetnodeapi>
Trade Information eXchange (TIX) API <netscriptixapi>
Singularity Functions <netscriptsingularityfunctions>
Bladeburner API <netscriptbladeburnerapi>
Miscellaneous <netscriptmisc>

@ -0,0 +1,446 @@
Netscript Bladeburner API
=========================
Netscript provides the following API for interacting with the game's Bladeburner mechanic.
The Bladeburner API is **not** immediately available to the palyer and must be unlocked
later in the game
**WARNING: This page contains spoilers for the game**
The Bladeburner API is unlocked in BitNode-7. If you are in BitNode-7, you will
automatically gain access to this API. Otherwise, you must have Source-File 7 in
order to use this API in other BitNodes
**Bladeburner API functions must be accessed through the bladeburner namespace**
In Netscript 1.0::
bladeburner.getContractNames();
bladeburner.startAction("general", "Training");
In :ref:`netscriptjs`::
ns.bladeburner.getContractNames();
ns.bladeburner.startAction("general", "Training");
.. _bladeburner_action_types:
Bladeburner Action Types
------------------------
Several functions in the Bladeburner API require you to specify an action using
its type and name. The following are valid values when specifying the action's type:
**Contracts**
* contract
* contracts
* contr
**Operations**
* operation
* operations
* op
* ops
**Black Ops**
* blackoperation
* black operation
* black operations
* black op
* black ops
* blackop
* blackops
**General Actions (Training, Field Analysis, Recruitment)**
* general
* general action
* gen
getContractNames
----------------
.. js:function:: getContractNames()
Returns an array of strings containing the names of all Bladeburner contracts
getOperationNames
-----------------
.. js:function:: getOperationNames()
Returns an array of strings containing the names of all Bladeburner operations
getBlackOpNames
---------------
.. js:function:: getBlackOpNames()
Returns an array of strings containing the names of all Bladeburner Black Ops
getGeneralActionNames
---------------------
.. js:function:: getGeneralActionNames()
Returns an array of strings containing the names of all general Bladeburner actions
getSkillNames
-------------
.. js:function:: getSkillNames()
Returns an array of strings containing the names of all Bladeburner skills
startAction
-----------
.. js:function:: startAction(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Attempts to start the specified Bladeburner action. Returns true if the action
was started successfully, and false otherwise.
stopBladeburnerAction
---------------------
.. js:function:: stopBladeburnerAction()
Stops the current Bladeburner action
getActionTime
-------------
.. js:function:: getActionTime(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the number of seconds it takes to complete the specified action
getActionEstimatedSuccessChance
-------------------------------
.. js:function:: getActionEstimatedSuccessChance(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the estimated success chance for the specified action
getActionCountRemaining
-----------------------
.. js:function:: getActionCountRemaining(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the remaining count of the specified action.
Note that this is meant to be used for Contracts and Operations.
This function will return 'Infinity' for actions such as Training and Field Analysis.
getRank
-------
.. js:function:: getRank()
Returns the player's Bladeburner Rank
getSkillPoints
--------------
.. js:function:: getSkillPoints()
Returns the number of Bladeburner skill points you have
getSkillLevel
-------------
.. js:function:: getSkillLevel(skillName="")
:param string skillName: Optional name of Skill. Empty string by default
If no argument or an empty string is passed in, this function returns
an object with your level for all Bladeburner Skills (only for skills that
have at least one level). In the object, the name of the Bladeburner Skills
are the keys and your skill levels are the values. For example::
{
"Blade's Intuition": 10,
"Cloak": 5,
"Evasive System": 6
}
If the name of a skill is passed in as an argument, then this function
returns your level in the specified skill.
The function returns -1 if an invalid skill name is passed in
upgradeSkill
------------
.. js:function:: upgradeSkill(skillName)
:param string skillName: Name of Skill to be upgraded. Must be an exact match
Attempts to upgrade the specified Bladeburner skill. Returns true if the
skill is successfully upgraded, and false otherwise
getTeamSize
-----------
.. js:function:: getTeamSize(type, name)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
Returns the number of Bladeburner team members you have assigned to the
specified action.
Setting a team is only applicable for Operations and BlackOps. This function
will return 0 for other action types.
setTeamSize
-----------
.. js:function:: setTeamSize(type, name, size)
:param string type: Type of action. See :ref:`bladeburner_action_types`
:param string name: Name of action. Must be an exact match
:param int size: Number of team members to set. Will be converted using Math.round()
Set the team size for the specified Bladeburner action.
Returns the team size that was set, or -1 if the function failed.
getCityEstimatedPopulation
--------------------------
.. js:function:: getCityEstimatedPopulation(cityName)
:param string cityName: Name of city. Case-sensitive
Returns the estimated number of Synthoids in the specified city, or -1
if an invalid city was specified.
getCityEstimatedCommunities
---------------------------
.. js:function:: getCityEstimatedCommunities(cityName)
:param string cityName: Name of city. Case-sensitive
Returns the estimated number of Synthoid communities in the specified city,
or -1 if an invalid city was specified.
getCityChaos
------------
.. js:function:: getCityChaos(cityName)
:param string cityName: Name of city. Case-sensitive
Returns the chaos in the specified city, or -1 if an invalid city was specified
switchCity
----------
.. js:function:: switchCity(cityName)
:param string cityName: Name of city
Attempts to switch to the specified city (for Bladeburner only).
Returns true if successful, and false otherwise
getStamina
----------
.. js:function:: getStamina()
Returns an array with two elements:
[Current stamina, Max stamina]
Example usage::
function getStaminaPercentage() {
let res = bladeburner.getStamina();
return res[0] / res[1];
}
joinBladeburnerFaction
----------------------
.. js:function:: joinBladeburnerFaction()
Attempts to join the Bladeburner faction.
Returns true if you successfully join the Bladeburner faction, or if
you are already a member.
Returns false otherwise.
Examples
--------
**Basic example usage**::
tprint(bladeburner.getContractNames());
tprint(bladeburner.getOperationNames());
tprint(bladeburner.getBlackOpNames());
tprint(bladeburner.getGeneralActionNames());
tprint(bladeburner.getSkillNames());
tprint(bladeburner.getActionTime("contract", "Tracking"));
tprint("Rank: " + bladeburner.getRank());
tprint("Skill Points: " + bladeburner.getSkillPoints());
tprint("Cloak Skill Level: " + bladeburner.getSkillLevel("Cloak"));
tprint("Trying to upgradeSkill: " + bladeburner.upgradeSkill("Cloak"));
tprint("Skill Points remaining: " + bladeburner.getSkillPoints());
tprint("Trying to switch to a nonexistent city: " + bladeburner.switchCity("lskgns"));
var chongqing = "Chongqing";
tprint("Trying to switch to Chongqing: " + bladeburner.switchCity(chongqing));
tprint("Chongqing chaos: " + bladeburner.getCityChaos(chongqing));
tprint("Chongqing estimated pop: " + bladeburner.getCityEstimatedPopulation(chongqing));
tprint("Chonqging estimated communities: " + bladeburner.getCityEstimatedCommunities(chongqing));
**Bladeburner handler example**. Note that this avoids the need of using the *bladeburner* namespace
identifier by attaching the Bladeburner API functions to an object::
const FIELD_ANALYSIS_INTERVAL = 10; //Number of minutes between field analysis states
const FIELD_ANALYSIS_DURATION = 5; //Duration in minutes
function BladeburnerHandler(ns, params) {
//Netscript environment becomes part of the instance
this.ns = ns;
//Netscript bladeburner API becomes part of this instance
for (var bladeburnerFn in ns.bladeburner) {
this[bladeburnerFn] = ns.bladeburner[bladeburnerFn];
}
this.fieldAnalysis = {
inProgress: params.startFieldAnalysis ? true : false,
cyclesRemaining: FIELD_ANALYSIS_DURATION,
cyclesSince: FIELD_ANALYSIS_INTERVAL
}
}
BladeburnerHandler.prototype.getStaminaPercentage = function() {
var res = this.getStamina();
return 100 * (res[0] / res[1]);
}
BladeburnerHandler.prototype.hasSimulacrum = function() {
var augs = this.ns.getOwnedAugmentations();
return augs.includes("The Blade's Simulacrum");
}
BladeburnerHandler.prototype.handle = function() {
//If we're doing something else manually (without Simlacrum),
//it overrides Bladeburner stuff
if (!this.hasSimulacrum() && this.ns.isBusy()) {
this.ns.print("Idling bc player is busy with some other action");
return;
}
if (this.fieldAnalysis.inProgress) {
--(this.fieldAnalysis.cyclesRemaining);
if (this.fieldAnalysis.cyclesRemaining < 0) {
this.fieldAnalysis.inProgress = false;
this.fieldAnalysis.cyclesSince = 0;
return this.handle();
} else {
this.startAction("general", "Field Analysis");
this.ns.print("handler is doing field analyis for " +
(this.fieldAnalysis.cyclesRemaining+1) + " more mins");
return;
}
} else {
++(this.fieldAnalysis.cyclesSince);
if (this.fieldAnalysis.cyclesSince > FIELD_ANALYSIS_INTERVAL) {
this.fieldAnalysis.inProgress = true;
this.fieldAnalysis.cyclesRemaining = FIELD_ANALYSIS_DURATION;
return this.handle();
}
}
this.stopBladeburnerAction();
var staminaPerc = this.getStaminaPercentage();
if (staminaPerc < 55) {
this.ns.print("handler is starting training due to low stamina percentage");
this.startAction("general", "Training");
} else {
var action = this.chooseAction();
this.ns.print("handler chose " + action.name + " " + action.type + " through chooseAction()");
this.startAction(action.type, action.name);
}
}
BladeburnerHandler.prototype.chooseAction = function() {
//Array of all Operations
var ops = this.getOperationNames();
//Sort Operations in order of increasing success chance
ops.sort((a, b)=>{
return this.getActionEstimatedSuccessChance("operation", a) -
this.getActionEstimatedSuccessChance("operation", b);
});
//Loop through until you find one with 99+% success chance
for (let i = 0; i < ops.length; ++i) {
let successChance = this.getActionEstimatedSuccessChance("operation", ops[i]);
let count = this.getActionCountRemaining("operation", ops[i]);
if (successChance >= 0.99 && count > 10) {
return {type: "operation", name: ops[i]};
}
}
//Repeat for Contracts
var contracts = this.getContractNames();
contracts.sort((a, b)=>{
return this.getActionEstimatedSuccessChance("contract", a) -
this.getActionEstimatedSuccessChance("contract", b);
});
for (let i = 0; i < contracts.length; ++i) {
let successChance = this.getActionEstimatedSuccessChance("contract", contracts[i]);
let count = this.getActionCountRemaining("contract", contracts[i]);
if (successChance >= 0.80 && count > 10) {
return {type: "contract", name: contracts[i]};
}
}
return {type:"general", name:"Training"};
}
BladeburnerHandler.prototype.process = async function() {
this.handle();
await this.ns.sleep(60000);
}
export async function main(ns) {
ns.disableLog("sleep");
//Check if Bladeburner is available. This'll throw a runtime error if it's not
ns.bladeburner.getContractNames();
var startFieldAnalysis = true;
if (ns.args.length >= 1 && ns.args[0] == "false") {
startFieldAnalysis = false;
}
var handler = new BladeburnerHandler(ns, {
startFieldAnalysis: startFieldAnalysis
});
while(true) {
await handler.process();
}
}

@ -942,7 +942,11 @@ prompt
Defining your own Functions
---------------------------
You can define your own functions in Netscript using the following syntax::
Note that the following information is only applicable for Netscript 1.0.
:doc:`netscriptjs` allows you to define your functions using native Javascript
techniques.
You can define your own functions in Netscript 1.0 using the following syntax::
function name(args...) {
function code here...

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

@ -3,6 +3,17 @@
<head>
<meta charset="utf-8">
<title>Bitburner</title>
<link rel="apple-touch-icon" sizes="180x180" href="dist/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="dist/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="dist/favicon-16x16.png">
<link rel="manifest" href="dist/site.webmanifest">
<link rel="mask-icon" href="dist/safari-pinned-tab.svg" color="#000000">
<link rel="shortcut icon" href="favicon.ico">
<meta name="apple-mobile-web-app-title" content="Bitburner">
<meta name="application-name" content="Bitburner">
<meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-config" content="dist/browserconfig.xml">
<meta name="theme-color" content="#ffffff">
<link rel="stylesheet" type="text/css" href="css/styles.css" />
<link rel="stylesheet" type="text/css" href="css/terminal.css" />
<link rel="stylesheet" type="text/css" href="css/menupages.css" />
@ -99,7 +110,7 @@
<div id="script-editor-filename-wrapper">
<p id="script-editor-filename-tag"> <strong style="background-color:#555;">Script name: </strong></p>
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1"> </input>
<input id="script-editor-filename" type="text" maxlength="30" tabindex="1" />
</div>
<div id="javascript-editor"></div>
@ -149,9 +160,7 @@
<fieldset>
<label for="script-editor-option-maxerr" class="tooltip">Max Error Count</label>
<input type="range" max="1000" min="50" value="200"
step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr"
</input>
<input type="range" max="1000" min="50" value="200" step="1" name="script-editor-option-maxerr" id="script-editor-option-maxerr" />
<em id="script-editor-option-maxerror-value-label" style="font-style: normal;"></em>
</fieldset>
</div> <!-- End script editor options panel -->
@ -162,8 +171,7 @@
<table id="terminal">
<tr id="terminal-input">
<td id="terminal-input-td" tabindex="2">$
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"
onfocus="this.value = this.value;"/>
<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1" onfocus="this.value = this.value;"/>
</td>
</tr>
</table>
@ -488,20 +496,20 @@
<p id='dev-menu-text'>Augmentation related: </p>
<!-- gets populated with the list of all augments -->
<select id="dev-menu-aug-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-aug-dropdown" class="dropdown"></select>
<a id="dev-add-aug" class="a-link-button tooltip">Queue Augmentation<span class="tooltiptext">May require save + reload</span></a>
<input id="dev-sf-n" type="number" class="dev-text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="dev-text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<input id="dev-sf-n" type="number" class="text-input" placeholder="SourceFile-N"><input id="dev-sf-lvl" type="number" class="text-input" placeholder="SourceFile-Lvl"><a id="dev-add-source-file" class="a-link-button tooltip"> Add/Remove source file <span class="tooltiptext">If Lvl == 0 the sf will be removed, calling it with another level will replace your current source file. You CAN set a source file higher than it's maximum level.</span></a>
<p id='dev-menu-text'>Faction related: </p>
<select id="dev-menu-faction-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-faction-dropdown" class="dropdown"></select>
<a id="dev-add-faction" class="a-link-button tooltip">Receive invite<span class="tooltiptext">May require save + reload</span></a>
<p id='dev-menu-text'>Program related: </p>
<select id="dev-menu-connect-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-connect-dropdown" class="dropdown"></select>
<a id="dev-connect" class="a-link-button tooltip">Connect<span class="tooltiptext">Connect to the target server.</span></a>
<select id="dev-menu-add-program-dropdown" class="dev-dropdown-input"></select>
<select id="dev-menu-add-program-dropdown" class="dropdown"></select>
<a id="dev-add-program" class="a-link-button tooltip">Add Program<span class="tooltiptext">Add this program to the player home server, won't add the same program twice.</span></a>
<a id="dev-bit-flume" class="a-link-button tooltip">Trigger BitFlume<span class="tooltiptext">Quick escape to change BN, does not give SFs</span></a>
@ -512,19 +520,19 @@
<a id="dev-max-money" class="a-link-button tooltip">maximize all servers money<span class="tooltiptext">Set all servers available money to maximum for that server</span></a>
<p id='dev-menu-text'>Exp/stats related: </p>
<input id="dev-hacking-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-hacking-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-hacking" class="a-link-button tooltip">add hacking exp<span class="tooltiptext">Add that many hacking experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-strength-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-strength-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-strength" class="a-link-button tooltip">add strength exp<span class="tooltiptext">Add that many strength experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-defense-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-defense-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-defense" class="a-link-button tooltip">add defense exp<span class="tooltiptext">Add that many defense experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-dexterity-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-dexterity-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-dexterity" class="a-link-button tooltip">add dexterity exp<span class="tooltiptext">Add that many dexterity experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-agility-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-agility-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-agility" class="a-link-button tooltip">add agility exp<span class="tooltiptext">Add that many agility experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-charisma-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-charisma-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-charisma" class="a-link-button tooltip">add charisma exp<span class="tooltiptext">Add that many charisma experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<input id="dev-intelligence-exp" type="number" class="dev-text-input" placeholder="+exp/-exp (int)">
<input id="dev-intelligence-exp" type="number" class="text-input" placeholder="+exp/-exp (int)">
<a id="dev-add-intelligence" class="a-link-button tooltip">add intelligence exp<span class="tooltiptext">Add that many intelligence experience point, use negative numbers to remove, don't worry about going under 0 exp</span></a>
<a id="dev-enable-intelligence" class="a-link-button tooltip"> enable intelligence<span class="tooltiptext">Enables the intelligence stat</span></a>
<a id="dev-disable-intelligence" class="a-link-button tooltip"> disable intelligence<span class="tooltiptext">Disables the intelligence stat</span></a>
@ -711,7 +719,7 @@
<div id="yes-no-text-input-box-container" class="popup-box-container">
<div id="yes-no-text-input-box-content" class="popup-box-content">
<p id="yes-no-text-input-box-text"> </p>
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"> </input>
<input type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30" />
<span id="yes-no-text-input-box-yes" class="popup-box-button"> Yes </span>
<span id="yes-no-text-input-box-no" class="popup-box-button"> No </span>
</div>
@ -801,9 +809,7 @@
</span>
</label>
<input type ="range" max="250" min="15"
step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100">
</input>
<input type ="range" max="250" min="15" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100" />
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
</fieldset>
@ -817,9 +823,7 @@
</span>
</label>
<input type="range" max="100" min="20"
step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50">
</input>
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50" />
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em>
</fieldset>
@ -833,9 +837,7 @@
</span>
</label>
<input type="range" max="100" min="20"
step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50">
</input>
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50" />
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
</fieldset>
@ -847,9 +849,7 @@
</span>
</label>
<input type="range" max="600" min="0"
step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60">
</input>
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60" />
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em>
</fieldset>
@ -910,7 +910,7 @@
<div id="game-options-right-panel">
<a class="a-link-button" style="display:block;" href="https://bitburner.readthedocs.io/en/latest/changelog.html" target="_blank"> Changelog </a>
<a class="a-link-button" style="display:block;" href="https://bitburner.wikia.com" target="_blank">Wiki</a>
<a class="a-link-button" style="display:block;", href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
<a class="a-link-button" style="display:block;" href="https://www.reddit.com/r/bitburner" target="_blank">Subreddit</a>
<a id="save-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Save Game </a>
<a id="delete-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Delete Game </a>
<a id="export-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Export Game </a>
@ -939,6 +939,6 @@
<div class="loaderspinner"></div>
<div class="loaderlabel">Loading Bitburner...</div>
</div>
</body>
<script src="dist/engine.bundle.js"></script>
</body>
</html>

@ -86,7 +86,16 @@ let NetscriptFunctions =
"installAugmentations|hacknetnodes|upgradeLevel|upgradeRam|upgradeCore|" +
"getLevelUpgradeCost|getRamUpgradeCost|getCoreUpgradeCost|" +
"getStockPrice|getStockPosition|buyStock|sellStock|shortStock|sellShort|" +
"placeOrder|cancelOrder";
"placeOrder|cancelOrder|" +
//Bladeburner functions
"bladeburner|getContractNames|getOperationNames|getBlackOpNames|" +
"getGeneralActionNames|getSkillNames|startAction|stopBladeburnerAction|" +
"getActionTime|getActionEstimatedSuccessChance|getActionCountRemaining|" +
"getRank|getSkillPoints|getSkillLevel|upgradeSkill|getTeamSize|" +
"setTeamSize|getCityEstimatedPopulation|getCityEstimatedCommunities|" +
"getCityChaos|switchCity|getStamina|joinBladeburnerFaction"
;
var NetscriptHighlightRules = function(options) {
var keywordMapper = this.createKeywordMapper({

1495
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -62,6 +62,9 @@
"sinon": "^2.3.2",
"source-map": "^0.7.3",
"style-loader": "^0.21.0",
"ts-loader": "^4.4.1",
"tslint": "^5.10.0",
"typescript": "^2.9.2",
"url-loader": "^1.0.1",
"watchpack": "^1.6.0",
"webpack": "^4.12.0",
@ -84,6 +87,7 @@
"start:dev": "webpack-dev-server",
"build": "webpack --mode production",
"build:dev": "webpack --mode development",
"lint:typescript": "tslint --project . --exclude **/*.d.ts --format stylish src/**/*.ts utils/**/*.ts",
"watch": "webpack --watch --mode production",
"watch:dev": "webpack --watch --mode development"
},

@ -115,7 +115,29 @@ function initBitNodes() {
"Level 1: 8%<br>" +
"Level 2: 12%<br>" +
"Level 3: 14%");
BitNodes["BitNode7"] = new BitNode(7, "Hacktocracy", "COMING SOON"); //Healthy Hacknet balancing mechanic
BitNodes["BitNode7"] = new BitNode(7, "Bladeburners 2079", "More human than humans",
"In the middle of the 21st century, you were doing cutting-edge work at OmniTek Incorporated as part of the AI design team " +
"for advanced synthetic androids, or Synthoids for short. You helped achieve a major technological " +
"breakthrough in the sixth generation of the company's Synthoid design, called MK-VI, by developing a hyperintelligent AI. " +
"Many argue that this was the first sentient AI ever created. This resulted in Synthoid models that were stronger, faster, " +
"and more intelligent than the humans that had created them.<br><br>" +
"In this BitNode you will be able to access the Bladeburner API, which allows you to access Bladeburner " +
"functionality through Netscript. Furthermore: <br><br>" +
"The rank you gain from Bladeburner contracts/operations is reduced by 50%<br>" +
"Bladeburner skills cost twice as many skill points<br>" +
"Augmentations are 3x more expensive<br>" +
"Hacking and Hacknet Nodes will be significantly less profitable<br>" +
"Your hacking level is reduced by 50%<br>" +
"Hacking experience gain from scripts is reduced by 75%<br>" +
"Corporations have 80% lower valuations and are therefore less profitable<br>" +
"Working for companies is 50% less profitable<br>" +
"Crimes and Infiltration are 50% less profitable<br><br>" +
"Destroying this BitNode will give you Source-File 7, or if you already have this Source-File it will upgrade " +
"its level up to a maximum of 3. This Source-File allows you to access the Bladeburner Netscript API in other " +
"BitNodes. In addition, this Source-File will increase all of your Bladeburner multipliers by:<br><br>" +
"Level 1: 8%<br>" +
"Level 2: 12%<br>" +
"Level 3: 14%");
BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "Money never sleeps",
"You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.<br><br>" +
"In this BitNode:<br><br>" +
@ -208,6 +230,9 @@ let BitNodeMultipliers = {
InfiltrationRep: 1,
CorporationValuation: 1,
BladeburnerRank: 1,
BladeburnerSkillCost: 1,
}
function initBitNodeMultipliers() {
@ -284,6 +309,23 @@ function initBitNodeMultipliers() {
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.HackExpGain = 0.25;
break;
case 7: //Bladeburner 2079
BitNodeMultipliers.BladeburnerRank = 0.5;
BitNodeMultipliers.BladeburnerSkillCost = 2;
BitNodeMultipliers.AugmentationMoneyCost = 3;
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
BitNodeMultipliers.ServerMaxMoney = 0.5;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ServerStartingSecurity = 1.5;
BitNodeMultipliers.ScriptHackMoney = 0.5;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.InfiltrationMoney = 0.5;
BitNodeMultipliers.CorporationValuation = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.FactionPassiveRepGain = 0;
BitNodeMultipliers.HackExpGain = 0.25;
break;
case 8: //Ghost of Wall Street
BitNodeMultipliers.ScriptHackMoney = 0;
BitNodeMultipliers.ManualHackMoney = 0;

@ -1,4 +1,5 @@
import {Augmentations, AugmentationNames} from "./Augmentations.js";
import {BitNodeMultipliers} from "./BitNode.js";
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {Faction, Factions, factionExists,
@ -349,6 +350,10 @@ function Skill(params={name:"foo", desc:"foo"}) {
if (params.weaponAbility) {this.weaponAbility = params.weaponAbility;}
if (params.gunAbility) {this.gunAbility = params.gunAbility;}
}
Skill.prototype.calculateCost = function(currentLevel) {
return (this.baseCost + (currentLevel * this.costInc)) * BitNodeMultipliers.BladeburnerSkillCost;
}
var Skills = {};
var SkillNames = {
BladesIntuition: "Blade's Intuition",
@ -1168,7 +1173,7 @@ Bladeburner.prototype.completeAction = function() {
action.setMaxLevel(ContractSuccessesPerLevel);
}
if (action.rankGain) {
var gain = addOffset(action.rankGain * rewardMultiplier, 10);
var gain = addOffset(action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank, 10);
this.changeRank(gain);
if (isOperation && this.logging.ops) {
this.log(action.name + " successfully completed! Gained " + formatNumber(gain, 3) + " rank");
@ -1233,7 +1238,7 @@ Bladeburner.prototype.completeAction = function() {
this.blackops[action.name] = true;
var rankGain = 0;
if (action.rankGain) {
rankGain = addOffset(action.rankGain, 10);
rankGain = addOffset(action.rankGain * BitNodeMultipliers.BladeburnerRank, 10);
this.changeRank(rankGain);
}
teamLossMax = Math.ceil(teamCount/2);
@ -2671,7 +2676,7 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
if (this.skills[skillName] && !isNaN(this.skills[skillName])) {
currentLevel = this.skills[skillName];
}
var pointCost = skill.baseCost + (currentLevel * skill.costInc);
var pointCost = skill.calculateCost(currentLevel);
el.appendChild(createElement("h2", { //Header
innerText:skill.name + " (Lvl " + currentLevel + ")", display:"inline-block"
@ -3110,7 +3115,7 @@ Bladeburner.prototype.executeSkillConsoleCommand = function(args) {
if (this.skills[skillName] && !isNaN(this.skills[skillName])) {
currentLevel = this.skills[skillName];
}
var pointCost = skill.baseCost + (currentLevel * skill.costInc);
var pointCost = skill.calculateCost(currentLevel);
if (this.skillPoints >= pointCost) {
this.skillPoints -= pointCost;
this.upgradeSkill(skill);
@ -3203,6 +3208,7 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
switch (convertedType) {
case "contract":
case "contracts":
case "contr":
action.type = ActionTypes["Contract"];
if (this.contracts.hasOwnProperty(name)) {
action.name = name;
@ -3263,24 +3269,24 @@ Bladeburner.prototype.getActionIdFromTypeAndName = function(type="", name="") {
}
}
Bladeburner.prototype.isContractNameNetscriptFn = function(name) {
return this.contracts.hasOwnProperty(name);
Bladeburner.prototype.getContractNamesNetscriptFn = function() {
return Object.keys(this.contracts);
}
Bladeburner.prototype.isOperationNameNetscriptFn = function(name) {
return this.operations.hasOwnProperty(name);
Bladeburner.prototype.getOperationNamesNetscriptFn = function() {
return Object.keys(this.operations);
}
Bladeburner.prototype.isBlackOpNameNetscriptFn = function(name) {
return BlackOperations.hasOwnProperty(name);
Bladeburner.prototype.getBlackOpNamesNetscriptFn = function() {
return Object.keys(BlackOperations);
}
Bladeburner.prototype.isGeneralActionNameNetscriptFn = function(name) {
return GeneralActions.hasOwnProperty(name);
Bladeburner.prototype.getGeneralActionNamesNetscriptFn = function() {
return Object.keys(GeneralActions);
}
Bladeburner.prototype.isSkillNameNetscriptFn = function(name) {
return Skills.hasOwnProperty(name);
Bladeburner.prototype.getSkillNamesNetscriptFn = function() {
return Object.keys(Skills);
}
Bladeburner.prototype.startActionNetscriptFn = function(type, name, workerScript) {
@ -3362,7 +3368,7 @@ Bladeburner.prototype.getActionEstimatedSuccessChanceNetscriptFn = function(type
case ActionTypes["Operation"]:
case ActionTypes["BlackOp"]:
case ActionTypes["BlackOperation"]:
return actionObj.getSuccessChance(this);
return actionObj.getSuccessChance(this, {est:true});
case ActionTypes["Training"]:
case ActionTypes["Field Analysis"]:
case ActionTypes["FieldAnalysis"]:
@ -3422,7 +3428,11 @@ Bladeburner.prototype.getSkillLevelNetscriptFn = function(skillName, workerScrip
return -1;
}
return Skills[skillName];
if (this.skills[skillName] == null) {
return 0;
} else {
return this.skills[skillName];
}
}
Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript) {
@ -3438,7 +3448,7 @@ Bladeburner.prototype.upgradeSkillNetscriptFn = function(skillName, workerScript
if (this.skills[skillName] && !isNaN(this.skills[skillName])) {
currentLevel = this.skills[skillName];
}
var cost = skill.baseCost + (currentLevel * skill.costInc);
var cost = skill.calculateCost(currentLevel);
if (this.skillPoints < cost) {
if (workerScript.shouldLog("upgradeSkill")) {
@ -3500,8 +3510,8 @@ Bladeburner.prototype.setTeamSizeNetscriptFn = function(type, name, size, worker
return -1;
}
if (actionId.type !== ActionTypes["Operation"] ||
actionId.type !== ActionTypes["BlackOp"] ||
if (actionId.type !== ActionTypes["Operation"] &&
actionId.type !== ActionTypes["BlackOp"] &&
actionId.type !== ActionTypes["BlackOperation"]) {
workerScript.log("ERROR: Bladeburner.setTeamSize() failed. This function " +
"only works for Operations and BlackOps");

@ -2431,8 +2431,9 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
});
//Select industry and city to export to
var citySelector = createElement("select");
var citySelector = createElement("select", {class: "dropdown"});
var industrySelector = createElement("select", {
class: "dropdown",
changeListener:()=>{
var industryName = industrySelector.options[industrySelector.selectedIndex].value;
for (var foo = 0; foo < company.divisions.length; ++foo) {
@ -2475,6 +2476,7 @@ Warehouse.prototype.createMaterialUI = function(mat, matName, parentRefs) {
//Select amount to export
var exportAmount = createElement("input", {
class: "text-input",
placeholder:"Export amount / s"
});
@ -3423,15 +3425,14 @@ Corporation.prototype.updateUIHeaderTabs = function() {
innerHTML: "Create a new division to expand into a new industry:",
});
var selector = createElement("select", {
class:"cmpy-mgmt-industry-select"
class:"dropdown"
});
var industryDescription = createElement("p", {});
var yesBtn;
var nameInput = createElement("input", {
type:"text",
id:"cmpy-mgmt-expand-industry-name-input",
color:"white",
backgroundColor:"black",
class: "text-input",
display:"block",
maxLength: 30,
pattern:"[a-zA-Z0-9-_]",
@ -4069,7 +4070,7 @@ Corporation.prototype.displayDivisionContent = function(division, city) {
innerText: "Would you like to expand into a new city by opening an office? " +
"This would cost " + numeral(OfficeInitialCost).format('$0.000a'),
});
var citySelector = createElement("select", {margin:"5px"});
var citySelector = createElement("select", {class: "dropdown", margin:"5px"});
for (var cityName in division.offices) {
if (division.offices.hasOwnProperty(cityName)) {
if (!(division.offices[cityName] instanceof OfficeSpace)) {

@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.38.1",
Version: "0.39.0",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -42,11 +42,11 @@ let CONSTANTS = {
/* Netscript Constants */
//RAM Costs for different commands
ScriptBaseRamCost: 1.4,
ScriptBaseRamCost: 1.6,
ScriptDomRamCost: 100,
ScriptWhileRamCost: 0.2,
ScriptForRamCost: 0.2,
ScriptIfRamCost: 0.15,
ScriptWhileRamCost: 0,
ScriptForRamCost: 0,
ScriptIfRamCost: 0,
ScriptHackRamCost: 0.1,
ScriptGrowRamCost: 0.15,
ScriptWeakenRamCost: 0.15,
@ -106,8 +106,8 @@ let CONSTANTS = {
TorRouterCost: 200000,
//Infiltration constants
InfiltrationBribeBaseAmount: 100000, //Amount per clearance level
InfiltrationMoneyValue: 2500, //Convert "secret" value to money
InfiltrationBribeBaseAmount: 100e3, //Amount per clearance level
InfiltrationMoneyValue: 3e3, //Convert "secret" value to money
InfiltrationRepValue: 1.4, //Convert "secret" value to faction reputation
//Stock market constants
@ -489,18 +489,20 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.38.1<br>" +
"* Bug Fix: Using 'Object.prototype' functions like toLocaleString() or toString() should no longer cause errors in NetscriptJS<br>" +
"* Implemented by Github user hydroflame:<br>" +
"*** Accessing the 'window' and 'document' objects in Netscript JS now requires a large amount of RAM (100 GB)<br>" +
"*** Added game option to suppress travel confirmation<br>" +
"*** Text on buttons can no longer be highlighted<br>" +
"*** Bug Fix: Fixed an issue that caused NaN values when exporting Real Estate in Corporations<br>" +
"*** Bug Fix: Competition and Demand displays in Corporation are now correct (were reversed before)<br>" +
"*** Added ps() Netscript function<br>" +
"*** Bug Fix: grow() should no longer return/log a negative value when it runs on a server that's already at max money<br>" +
"*** Bug Fix: serverExists() Netscript function should now properly return false for non-existent hostname/ips<br>" +
"*** Bug Fix: Sever's security level should now properly increase when its money is grown to max value"
"v0.39.0<br>" +
"* Added BitNode-7: Bladeburner 2079<br>" +
"* Infiltration base difficulty decreased by 10% for most locations<br>" +
"* Experience gains from Infiltration slightly increased<br>" +
"* Money gained from Infiltration increased by 20%<br>" +
"* Added 'var' declarations in Netscript 1.0 (only works with 'var', not 'let' or 'const')<br>" +
"* Script base RAM cost is now 1.6 GB (increased from 1.4 GB)<br>" +
"* While/for loops and if statements no longer cost RAM in scripts<br>" +
"* Made short-circuit evaluation logic more consistent in Netscript 1.0 (see https://github.com/danielyxie/bitburner/issues/308)<br>" +
"* Changelog button in the Options menu now links to the new Changelog URL (by Github user thePalindrome)<br>" +
"* Skill level calculation is now 'smoother' (by Github user hydroflame)<br>" +
"* Added a button to 'beautify' scripts in the text editor (by Github user hydroflame)<br>" +
"* Added favicon (by Github user kopelli)"
}

@ -19,7 +19,6 @@ function checkIfConnectedToDarkweb() {
"to purchase an item");
}
}
}
//Handler for dark web commands. The terminal's executeCommand() function will pass
@ -49,150 +48,69 @@ function executeDarkwebTerminalCommand(commandArray) {
}
function listAllDarkwebItems() {
for (var item in DarkWebItems) {
if (DarkWebItems.hasOwnProperty(item)) {
var item = DarkWebItems[item];
//Convert string using toLocaleString
var split = item.split(" - ");
if (split.length == 3 && split[1].charAt(0) == '$') {
split[1] = split[1].slice(1);
split[1] = split[1].replace(/,/g, '');
var price = parseFloat(split[1]);
if (isNaN(price)) {
post(item);
return;
for(const key in DarkWebItems) {
const item = DarkWebItems[key];
post(item.toString());
}
price = formatNumber(price, 0);
split[1] = "$" + price.toString();
post(split.join(" - "));
} else {
post(item);
}
}
}
var priceString = split[1];
//Check for errors
if (priceString.length == 0 || priceString.charAt(0) != '$') {
return -1;
}
//Remove dollar sign and commas
priceString = priceString.slice(1);
priceString = priceString.replace(/,/g, '');
//Convert string to numeric
var price = parseFloat(priceString);
if (isNaN(price)) {return -1;}
else {return price;}
}
function buyDarkwebItem(itemName) {
if (itemName.toLowerCase() == Programs.BruteSSHProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.BruteSSHProgram);
post("You have purchased the BruteSSH.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.FTPCrackProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.FTPCrackProgram);
post("You have purchased the FTPCrack.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.RelaySMTPProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram);
post("You have purchased the relaySMTP.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.HTTPWormProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.HTTPWormProgram);
post("You have purchased the HTTPWorm.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.SQLInjectProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.SQLInjectProgram);
post("You have purchased the SQLInject.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.DeepscanV1.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV1);
post("You have purchased the DeepscanV1.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else if (itemName.toLowerCase() == Programs.DeepscanV2.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV2);
post("You have purchased the DeepscanV2.exe program. The new program " +
"can be found on your home computer.");
} else {
post("Not enough money to purchase " + itemName);
}
} else {
post("Unrecognized item");
itemName = itemName.toLowerCase();
// find the program that matches, if any
let item = null;
for(const key in DarkWebItems) {
const i = DarkWebItems[key];
if(i.program.toLowerCase() == itemName) {
item = i;
}
}
function parseDarkwebItemPrice(itemDesc) {
var split = itemDesc.split(" - ");
if (split.length == 3) {
var priceString = split[1];
//Check for errors
if (priceString.length == 0 || priceString.charAt(0) != '$') {
return -1;
}
//Remove dollar sign and commas
priceString = priceString.slice(1);
priceString = priceString.replace(/,/g, '');
//Convert string to numeric
var price = parseFloat(priceString);
if (isNaN(price)) {return -1;}
else {return price;}
} else {
return -1;
}
// return if invalid
if(item === null) {
post("Unrecognized item: "+itemName);
return;
}
let DarkWebItems = {
BruteSSHProgram: "BruteSSH.exe - $500,000 - Opens up SSH Ports",
FTPCrackProgram: "FTPCrack.exe - $1,500,000 - Opens up FTP Ports",
RelaySMTPProgram: "relaySMTP.exe - $5,000,000 - Opens up SMTP Ports",
HTTPWormProgram: "HTTPWorm.exe - $30,000,000 - Opens up HTTP Ports",
SQLInjectProgram: "SQLInject.exe - $250,000,000 - Opens up SQL Ports",
DeepScanV1Program: "DeepscanV1.exe - $500,000 - Enables 'scan-analyze' with a depth up to 5",
DeepScanV2Program: "DeepscanV2.exe - $25,000,000 - Enables 'scan-analyze' with a depth up to 10",
// return if the player already has it.
if(Player.hasProgram(item.program)) {
post('You already have the '+item.program+' program');
return;
}
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand,
listAllDarkwebItems, buyDarkwebItem, parseDarkwebItemPrice,
DarkWebItems};
// return if the player doesn't have enough money
if(Player.money.lt(item.price)) {
post("Not enough money to purchase " + item.program);
return;
}
// buy and push
Player.loseMoney(item.price);
Player.getHomeComputer().programs.push(item.program);
post('You have purchased the '+item.program+' program. The new program can be found on your home computer.');
}
function DarkWebItem(program, price, description) {
this.program = program;
this.price = price;
this.description = description;
}
// formats the item for the terminal (eg. "BruteSSH.exe - $500,000 - Opens up SSH Ports")
DarkWebItem.prototype.toString = function() {
return [this.program, "$"+formatNumber(this.price), this.description].join(' - ');
}
const DarkWebItems = {
BruteSSHProgram: new DarkWebItem(Programs.BruteSSHProgram, 500000, "Opens up SSH Ports"),
FTPCrackProgram: new DarkWebItem(Programs.FTPCrackProgram, 1500000, "Opens up FTP Ports"),
RelaySMTPProgram: new DarkWebItem(Programs.RelaySMTPProgram, 5000000, "Opens up SMTP Ports"),
HTTPWormProgram: new DarkWebItem(Programs.HTTPWormProgram, 30000000, "Opens up HTTP Ports"),
SQLInjectProgram: new DarkWebItem(Programs.SQLInjectProgram, 250000000, "Opens up SQL Ports"),
DeepscanV1: new DarkWebItem(Programs.DeepscanV1, 500000, "Enables 'scan-analyze' with a depth up to 5"),
DeepscanV2: new DarkWebItem(Programs.DeepscanV2, 25000000, "Enables 'scan-analyze' with a depth up to 10"),
AutolinkProgram: new DarkWebItem(Programs.AutoLink, 1000000, "Enables direct connect via 'scan-analyze'"),
};
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand, DarkWebItems};

@ -1,5 +1,5 @@
/* HelpText.js */
let TerminalHelpText =
/* tslint:disable:max-line-length completed-docs variable-name*/
export const TerminalHelpText: string =
"Type 'help name' to learn more about the command 'name'<br><br>" +
'alias [-g] [name="value"] Create or display Terminal aliases<br>' +
"analyze Get information about the current machine <br>" +
@ -34,7 +34,10 @@ let TerminalHelpText =
"top Displays all running scripts and their RAM usage<br>" +
'unalias "[alias name]" Deletes the specified alias<br>';
let HelpTexts = {
interface IMap<T> {
[key: string]: T;
}
export const HelpTexts: IMap<string> = {
alias: 'alias [-g] [name="value"] <br>' +
"Create or display aliases. An alias enables a replacement of a word with another string. " +
"It can be used to abbreviate a commonly used command, or commonly used parts of a command. The NAME " +
@ -212,6 +215,4 @@ let HelpTexts = {
'unalias "r"<br><br>' +
"It is not necessary to differentiate between global and non-global aliases when using 'unalias'",
}
export {TerminalHelpText, HelpTexts};
};

@ -594,10 +594,10 @@ let intWgt = CONSTANTS.IntelligenceInfiltrationWeight;
//Success: 5%, Failure 10%, -Karma
function attemptInfiltrationKill(inst) {
var chance = getInfiltrationKillChance(inst);
inst.gainStrengthExp(inst.securityLevel / 85) * Player.strength_exp_mult;
inst.gainDefenseExp(inst.securityLevel / 85) * Player.defense_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 85) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 85) * Player.agility_exp_mult;
inst.gainStrengthExp(inst.securityLevel / 75) * Player.strength_exp_mult;
inst.gainDefenseExp(inst.securityLevel / 75) * Player.defense_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
if (Math.random() <= chance) {
inst.securityLevel *= 1.05;
return [true, 1.05];
@ -620,10 +620,10 @@ function getInfiltrationKillChance(inst) {
//Success: 3%, Failure: 10%
function attemptInfiltrationKnockout(inst) {
var chance = getInfiltrationKnockoutChance(inst);
inst.gainStrengthExp(inst.securityLevel / 80) * Player.strength_exp_mult;
inst.gainDefenseExp(inst.securityLevel / 80) * Player.defense_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 80) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 80) * Player.agility_exp_mult;
inst.gainStrengthExp(inst.securityLevel / 70) * Player.strength_exp_mult;
inst.gainDefenseExp(inst.securityLevel / 70) * Player.defense_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 70) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 70) * Player.agility_exp_mult;
if (Math.random() <= chance) {
inst.securityLevel *= 1.03;
return [true, 1.03];
@ -645,9 +645,9 @@ function getInfiltrationKnockoutChance(inst) {
//Success: 0%, Failure: 10%
function attemptInfiltrationStealthKnockout(inst) {
var chance = getInfiltrationStealthKnockoutChance(inst);
inst.gainStrengthExp(inst.securityLevel / 85) * Player.strength_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 65) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 65) * Player.agility_exp_mult;
inst.gainStrengthExp(inst.securityLevel / 75) * Player.strength_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 60) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 60) * Player.agility_exp_mult;
if (Math.random() <= chance) {
return [true, 1];
} else {
@ -669,9 +669,9 @@ function getInfiltrationStealthKnockoutChance(inst) {
//Success: 0%, Failure: 5%, -Karma
function attemptInfiltrationAssassinate(inst) {
var chance = getInfiltrationAssassinateChance(inst);
inst.gainStrengthExp(inst.securityLevel / 85) * Player.strength_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 65) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 65) * Player.agility_exp_mult;
inst.gainStrengthExp(inst.securityLevel / 75) * Player.strength_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 55) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 55) * Player.agility_exp_mult;
if (Math.random() <= chance) {
return [true, 1];
} else {
@ -693,10 +693,10 @@ function getInfiltrationAssassinateChance(inst) {
//Success: 5%, Failure: 10%
function attemptInfiltrationDestroySecurity(inst) {
var chance = getInfiltrationDestroySecurityChance(inst);
inst.gainStrengthExp(inst.securityLevel / 85) * Player.strength_exp_mult;
inst.gainDefenseExp(inst.securityLevel / 85) * Player.defense_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 85) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 85) * Player.agility_exp_mult;
inst.gainStrengthExp(inst.securityLevel / 75) * Player.strength_exp_mult;
inst.gainDefenseExp(inst.securityLevel / 75) * Player.defense_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
if (Math.random() <= chance) {
inst.securityLevel *= 1.05;
return [true, 1.05];
@ -720,8 +720,8 @@ function getInfiltrationDestroySecurityChance(inst) {
//Success: 3%, Failure: 5%
function attemptInfiltrationHack(inst) {
var chance = getInfiltrationHackChance(inst);
inst.gainHackingExp(inst.securityLevel / 40) * Player.hacking_exp_mult;
inst.gainIntelligenceExp(inst.securityLevel / 690);
inst.gainHackingExp(inst.securityLevel / 30) * Player.hacking_exp_mult;
inst.gainIntelligenceExp(inst.securityLevel / 680);
if (Math.random() <= chance) {
inst.securityLevel *= 1.03;
return [true, 1.03];
@ -743,7 +743,7 @@ function getInfiltrationHackChance(inst) {
//Success: 0%, Failure: 8%
function attemptInfiltrationSneak(inst) {
var chance = getInfiltrationSneakChance(inst);
inst.gainAgilityExp(inst.securityLevel / 40) * Player.agility_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 30) * Player.agility_exp_mult;
if (Math.random() <= chance) {
return [true, 1];
} else {
@ -764,7 +764,7 @@ function getInfiltrationSneakChance(inst) {
//Success: 1%, Failure: 3%
function attemptInfiltrationPickLockedDoor(inst) {
var chance = getInfiltrationPickLockedDoorChance(inst);
inst.gainDexterityExp(inst.securityLevel / 30) * Player.dexterity_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 25) * Player.dexterity_exp_mult;
if (Math.random() <= chance) {
inst.securityLevel *= 1.01;
return [true, 1.01];
@ -785,7 +785,7 @@ function getInfiltrationPickLockedDoorChance(inst) {
//Success: 0%, Failure: 15%,
function attemptInfiltrationBribe(inst) {
var chance = getInfiltrationBribeChance(inst);
inst.gainCharismaExp(inst.securityLevel / 10) * Player.charisma_exp_mult;
inst.gainCharismaExp(inst.securityLevel / 8) * Player.charisma_exp_mult;
if (Math.random() <= chance) {
return [true, 1];
} else {
@ -804,8 +804,8 @@ function getInfiltrationBribeChance(inst) {
//Failure: 5%
function attemptInfiltrationEscape(inst) {
var chance = getInfiltrationEscapeChance(inst);
inst.gainAgilityExp(inst.securityLevel / 35) * Player.agility_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 35) * Player.dexterity_exp_mult;
inst.gainAgilityExp(inst.securityLevel / 30) * Player.agility_exp_mult;
inst.gainDexterityExp(inst.securityLevel / 30) * Player.dexterity_exp_mult;
if (Math.random() <= chance) {
return [true, 1];
} else {

@ -432,7 +432,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumECorp,
6000, 116, 150, 8.5);
5400, 116, 150, 6);
break;
case Locations.AevumBachmanAndAssociates:
@ -445,7 +445,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumBachmanAndAssociates,
1500, 42, 60, 5.75);
1500, 42, 60, 4.1);
break;
case Locations.AevumClarkeIncorporated:
@ -458,7 +458,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumClarkeIncorporated,
2400, 34, 75, 5.4);
2000, 34, 75, 3.6);
break;
case Locations.AevumFulcrumTechnologies:
@ -478,7 +478,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumFulcrumTechnologies,
6000, 96, 100, 9);
4600, 96, 100, 6.2);
break;
case Locations.AevumAeroCorp:
@ -490,7 +490,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumAeroCorp,
2000, 32, 50, 6.3);
1500, 32, 50, 4.4);
break;
case Locations.AevumGalacticCybersystems:
@ -503,7 +503,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumGalacticCybersystems,
1400, 30, 50, 5.3);
1400, 30, 50, 3.95);
break;
case Locations.AevumWatchdogSecurity:
@ -517,7 +517,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumWatchdogSecurity,
850, 16, 30, 4.5);
765, 20, 30, 3);
break;
case Locations.AevumRhoConstruction:
@ -526,7 +526,7 @@ function displayLocationContent() {
softwareJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumRhoConstruction,
600, 12, 20, 2.7);
540, 16, 20, 1.9);
break;
case Locations.AevumPolice:
@ -535,7 +535,7 @@ function displayLocationContent() {
softwareJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumPolice,
700, 14, 25, 3.2);
630, 18, 25, 2.2);
break;
case Locations.AevumNetLinkTechnologies:
@ -554,7 +554,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumNetLinkTechnologies,
160, 10, 15, 1.8);
144, 10, 15, 1.4);
break;
case Locations.AevumCrushFitnessGym:
@ -588,7 +588,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.ChongqingKuaiGongInternational,
5500, 48, 100, 9);
4950, 100, 100, 6.1);
break;
case Locations.ChongqingSolarisSpaceSystems:
@ -600,7 +600,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.ChongqingSolarisSpaceSystems,
3600, 26, 75, 8.6);
3240, 52, 75, 6);
break;
@ -629,7 +629,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12MegaCorp,
6000, 114, 125, 9.8);
5000, 114, 125, 6.75);
break;
case Locations.Sector12BladeIndustries:
@ -642,7 +642,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12BladeIndustries,
3000, 46, 100, 6.7);
2400, 46, 100, 4.2);
break;
case Locations.Sector12FourSigma:
@ -655,7 +655,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12FourSigma,
1500, 58, 100, 10.2);
1500, 58, 100, 7);
break;
case Locations.Sector12IcarusMicrosystems:
@ -668,7 +668,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12IcarusMicrosystems,
900, 32, 70, 7.8);
810, 32, 70, 5.4);
break;
case Locations.Sector12UniversalEnergy:
@ -681,7 +681,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12UniversalEnergy,
775, 24, 50, 6.3);
775, 24, 50, 4.3);
break;
case Locations.Sector12DeltaOne:
@ -693,7 +693,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12DeltaOne,
1200, 38, 75, 6.3);
1080, 38, 75, 4.5);
break;
case Locations.Sector12CIA:
@ -706,7 +706,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12CIA,
1450, 44, 80, 7.6);
1305, 44, 80, 4.6);
break;
case Locations.Sector12NSA:
@ -725,13 +725,13 @@ function displayLocationContent() {
nsaBladeburner.innerText = "Enter Bladeburner Headquarters";
} else {
setInfiltrateButton(infiltrate, Locations.Sector12NSA,
1400, 40, 80, 7.2);
1260, 40, 80, 5);
nsaBladeburner.innerText = "Apply to Bladeburner Division";
}
nsaBladeburner.style.display = "block";
} else {
setInfiltrateButton(infiltrate, Locations.Sector12NSA,
1400, 40, 80, 7.2);
1260, 40, 80, 5);
}
break;
@ -747,7 +747,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12AlphaEnterprises,
250, 14, 40, 2.7);
225, 14, 40, 2.25);
break;
case Locations.Sector12CarmichaelSecurity:
@ -761,7 +761,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12CarmichaelSecurity,
500, 18, 60, 2.7);
450, 18, 60, 2.5);
break;
case Locations.Sector12FoodNStuff:
@ -777,7 +777,7 @@ function displayLocationContent() {
employeeJob.style.display = "block";
employeePartTimeJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12JoesGuns,
120, 8, 20, 2.2);
120, 8, 20, 1.8);
break;
case Locations.Sector12IronGym:
@ -819,7 +819,7 @@ function displayLocationContent() {
securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoDefComm,
1300, 28, 70, 5.4);
1170, 28, 70, 4);
break;
case Locations.NewTokyoVitaLife:
@ -832,7 +832,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoVitaLife,
750, 22, 100, 5);
675, 22, 100, 3.5);
break;
case Locations.NewTokyoGlobalPharmaceuticals:
@ -846,7 +846,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoGlobalPharmaceuticals,
900, 24, 80, 5.4);
775, 24, 80, 3.8);
break;
case Locations.NewTokyoNoodleBar:
@ -886,7 +886,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaStormTechnologies,
700, 24, 100, 5.9);
630, 24, 100, 4.1);
break;
case Locations.IshimaNovaMedical:
@ -899,7 +899,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaNovaMedical,
600, 20, 50, 4.5);
540, 20, 50, 3.2);
break;
case Locations.IshimaOmegaSoftware:
@ -918,7 +918,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaOmegaSoftware,
200, 10, 40, 2.3);
130, 10, 40, 1.6);
break;
case Locations.VolhavenTravelAgency:
@ -951,7 +951,7 @@ function displayLocationContent() {
purchase512gb.style.display = "block";
purchase1tb.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenOmniTekIncorporated,
1500, 44, 100, 6.3);
1350, 44, 100, 4.4);
break;
case Locations.VolhavenNWO:
@ -964,7 +964,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenNWO,
1800, 56, 200, 7.2);
1620, 56, 200, 6.8);
break;
case Locations.VolhavenHeliosLabs:
@ -976,7 +976,7 @@ function displayLocationContent() {
securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenHeliosLabs,
1200, 28, 75, 5.4);
1200, 28, 75, 3);
break;
case Locations.VolhavenOmniaCybersystems:
@ -988,7 +988,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenOmniaCybersystems,
900, 28, 90, 5.8);
810, 28, 90, 4.9);
break;
case Locations.VolhavenLexoCorp:
@ -1002,7 +1002,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenLexoCorp,
500, 14, 40, 3.1);
375, 14, 60, 2);
break;
case Locations.VolhavenSysCoreSecurities:
@ -1013,7 +1013,7 @@ function displayLocationContent() {
securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenSysCoreSecurities,
600, 16, 50, 3.6);
480, 18, 75, 2.4);
break;
case Locations.VolhavenCompuTek:
@ -1035,7 +1035,7 @@ function displayLocationContent() {
purchaseHomeRam.style.display = "block";
purchaseHomeCores.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenCompuTek,
300, 12, 35, 3.1);
215, 12, 60, 2.1);
break;
case Locations.VolhavenMilleniumFitnessGym:

@ -224,6 +224,9 @@ function evaluate(exp, workerScript) {
case "AssignmentExpression":
return evalAssignment(exp, workerScript);
break;
case "VariableDeclaration":
return evalVariableDeclaration(exp, workerScript);
break;
case "UpdateExpression":
if (exp.argument.type==="Identifier"){
if (exp.argument.name in env.vars){
@ -333,11 +336,11 @@ function evaluate(exp, workerScript) {
function evalBinary(exp, workerScript){
return evaluate(exp.left, workerScript).then(function(expLeft) {
//Short circuiting
if (expLeft == true && exp.operator === "||") {
return Promise.resolve(true);
if (expLeft && exp.operator === "||") {
return Promise.resolve(expLeft);
}
if (expLeft == false && exp.operator === "&&") {
return Promise.resolve(false);
if (!expLeft && exp.operator === "&&") {
return Promise.resolve(expLeft);
}
return evaluate(exp.right, workerScript).then(function(expRight) {
switch (exp.operator){
@ -511,6 +514,41 @@ function evalAssignment(exp, workerScript) {
});
}
function evalVariableDeclaration(exp, workerScript) {
var env = workerScript.env;
if (env.stopFlag) {return Promise.reject(workerScript);}
if (!(exp.declarations instanceof Array)) {
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Variable declarations parsed incorrectly. This may be a syntax error"));
}
if (exp.kind !== "var") {
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Only 'var' declarations are currently allowed (let, const, etc. are not allowed)"));
}
return Promise.all(exp.declarations.map((decl)=>{
evalVariableDeclarator(decl, workerScript);
})).then(function(res) {
return Promise.resolve(res);
});
}
//A Variable Declaration contains an array of Variable Declarators
function evalVariableDeclarator(exp, workerScript) {
var env = workerScript.env;
if (exp.type !== "VariableDeclarator") {
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid AST Node passed into evalVariableDeclarator: " + exp.type));
}
if (exp.init == null) {
env.set(exp.id.name, null);
return Promise.resolve(null);
} else {
return evaluate(exp.init, workerScript).then(function(initValue) {
env.set(exp.id.name, initValue);
});
}
}
function evaluateIf(exp, workerScript, i) {
var env = workerScript.env;
return evaluate(exp.test, workerScript).then(function(condRes) {

@ -12,7 +12,7 @@ import {Companies, Company, CompanyPosition,
CompanyPositions, companyExists} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {parseDarkwebItemPrice, DarkWebItems} from "./DarkWeb.js";
import {DarkWebItems} from "./DarkWeb.js";
import {Engine} from "./engine.js";
import {AllGangs} from "./Gang.js";
import {Factions, Faction, joinFaction,
@ -36,7 +36,7 @@ import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
Stock, shortStock, sellShort, OrderTypes,
PositionTypes, placeOrder, cancelOrder} from "./StockMarket.js";
import {post} from "./Terminal.js";
import {TextFile, getTextFile, createTextFile} from "./TextFile.js";
import {TextFile, getTextFile, createTextFile} from "./TextFile";
import {WorkerScript, workerScripts,
killWorkerScript, NetscriptPorts} from "./NetscriptWorker.js";
@ -148,8 +148,8 @@ function NetscriptFunctions(workerScript) {
workerScript.dynamicRamUsage += ramCost;
if (workerScript.dynamicRamUsage > 1.01 * workerScript.ramUsage) {
throw makeRuntimeRejectMsg(workerScript,
"Dynamic RAM usage calculated to be greater than initial RAM usage. " +
"This is probably because you somehow circumvented the static RAM " +
"Dynamic RAM usage calculated to be greater than initial RAM usage on fn: " + fnName +
". This is probably because you somehow circumvented the static RAM " +
"calculation.<br><br>Please don't do that :(");
}
};
@ -2333,105 +2333,40 @@ function NetscriptFunctions(workerScript) {
}
if (SpecialServerIps["Darkweb Server"] == null) {
workerScript.scriptRef.log("ERROR: You do not have TOR router. purchaseProgram() failed.");
workerScript.scriptRef.log("ERROR: You do not have the TOR router. purchaseProgram() failed.");
return false;
}
switch(programName.toLowerCase()) {
case Programs.BruteSSHProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.BruteSSHProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the BruteSSH.exe program. The new program can be found on your home computer.");
programName = programName.toLowerCase();
let item = null;
for(const key in DarkWebItems) {
const i = DarkWebItems[key];
if(i.program.toLowerCase() == programName) {
item = i;
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
}
if(item == null) {
workerScript.scriptRef.log("ERROR: Invalid program name passed into purchaseProgram().");
return false;
}
if(Player.money.lt(item.price)) {
workerScript.scriptRef.log("Not enough money to purchase " + item.program);
return false;
}
if(Player.hasProgram(item.program)) {
workerScript.scriptRef.log('You already have the '+item.program+' program');
return true;
case Programs.FTPCrackProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.FTPCrackProgram);
}
Player.loseMoney(item.price);
Player.getHomeComputer().programs.push(item.program);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the FTPCrack.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.RelaySMTPProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the relaySMTP.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.HTTPWormProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.HTTPWormProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the HTTPWorm.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.SQLInjectProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.SQLInjectProgram);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the SQLInject.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.DeepscanV1.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV1);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the DeepscanV1.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.DeepscanV2.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV2);
if (workerScript.disableLogs.ALL == null && workerScript.disableLogs.purchaseProgram == null) {
workerScript.scriptRef.log("You have purchased the DeepscanV2.exe program. The new program can be found on your home computer.");
}
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
default:
workerScript.scriptRef.log("ERROR: Invalid program passed into purchaseProgram().");
return false;
workerScript.scriptRef.log("You have purchased the "+item.program+" program. The new program can be found on your home computer.");
}
return true;
},
@ -3280,59 +3215,59 @@ function NetscriptFunctions(workerScript) {
//Bladeburner API
bladeburner : {
isContractName : function(name) {
getContractNames : function() {
if (workerScript.checkingRam) {
return updateStaticRam("isContractName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
return updateStaticRam("getContractNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
}
updateDynamicRam("isContractName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
updateDynamicRam("getContractNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.isContractNameNetscriptFn(name);
return Player.bladeburner.getContractNamesNetscriptFn();
}
throw makeRuntimeRejectMsg(workerScript, "isContractName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
throw makeRuntimeRejectMsg(workerScript, "getContractNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isOperationName : function(name) {
getOperationNames : function() {
if (workerScript.checkingRam) {
return updateStaticRam("isOperationName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
return updateStaticRam("getOperationNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
}
updateDynamicRam("isOperationName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
updateDynamicRam("getOperationNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.isOperationNameNetscriptFn(name);
return Player.bladeburner.getOperationNamesNetscriptFn();
}
throw makeRuntimeRejectMsg(workerScript, "isOperationName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
throw makeRuntimeRejectMsg(workerScript, "getOperationNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isBlackOpName : function(name) {
getBlackOpNames : function() {
if (workerScript.checkingRam) {
return updateStaticRam("isBlackOpName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
return updateStaticRam("getBlackOpNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
}
updateDynamicRam("isBlackOpName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
updateDynamicRam("getBlackOpNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.isBlackOpNameNetscriptFn(name);
return Player.bladeburner.getBlackOpNamesNetscriptFn();
}
throw makeRuntimeRejectMsg(workerScript, "isBlackOpName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
throw makeRuntimeRejectMsg(workerScript, "getBlackOpNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isGeneralActionName : function(name) {
getGeneralActionNames : function() {
if (workerScript.checkingRam) {
return updateStaticRam("isGeneralActionName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
return updateStaticRam("getGeneralActionNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
}
updateDynamicRam("isGeneralActionName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
updateDynamicRam("getGeneralActionNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.isGeneralActionNameNetscriptFn(name);
return Player.bladeburner.getGeneralActionNamesNetscriptFn();
}
throw makeRuntimeRejectMsg(workerScript, "isGeneralActionName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
throw makeRuntimeRejectMsg(workerScript, "getGeneralActionNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
isSkillName : function(name) {
getSkillNames : function() {
if (workerScript.checkingRam) {
return updateStaticRam("isSkillName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
return updateStaticRam("getSkillNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
}
updateDynamicRam("isSkillName", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
updateDynamicRam("getSkillNames", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 10);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.isSkillNameNetscriptFn(name);
return Player.bladeburner.getSkillNamesNetscriptFn();
}
throw makeRuntimeRejectMsg(workerScript, "isSkillName() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
throw makeRuntimeRejectMsg(workerScript, "getSkillNames() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
startAction : function(type="", name="") {
@ -3350,15 +3285,15 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeRejectMsg(workerScript, "startAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
stopAction : function() {
stopBladeburnerAction : function() {
if (workerScript.checkingRam) {
return updateStaticRam("stopAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 2);
return updateStaticRam("stopBladeburnerAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 2);
}
updateDynamicRam("stopAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 2);
updateDynamicRam("stopBladeburnerAction", CONSTANTS.ScriptBladeburnerApiBaseRamCost / 2);
if (Player.bladeburner instanceof Bladeburner && (Player.bitNodeN === 7 || hasBladeburner2079SF)) {
return Player.bladeburner.resetAction();
}
throw makeRuntimeRejectMsg(workerScript, "stopAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
throw makeRuntimeRejectMsg(workerScript, "stopBladeburnerAction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
},
getActionTime : function(type="", name="") {
@ -3569,7 +3504,7 @@ function NetscriptFunctions(workerScript) {
}
throw makeRuntimeRejectMsg(workerScript, "joinBladeburnerFaction() failed because you do not currently have access to the Bladeburner API. This is either because you are not currently employed " +
"at the Bladeburner division or because you do not have Source-File 7");
}
},
}
} //End return
} //End NetscriptFunction()

@ -201,6 +201,7 @@ function PlayerObject() {
this.lastUpdate = 0;
this.totalPlaytime = 0;
this.playtimeSinceLastAug = 0;
this.playtimeSinceLastBitnode = 0;
//Production since last Augmentation installation
this.scriptProdSinceLastAug = 0;
@ -390,6 +391,7 @@ PlayerObject.prototype.prestigeSourceFile = function() {
this.corporation = 0;
this.playtimeSinceLastAug = 0;
this.playtimeSinceLastBitnode = 0;
this.scriptProdSinceLastAug = 0;
}

@ -208,7 +208,8 @@ function loadBitVerse(destroyedBitNodeNum, flume=false) {
var elemId = "bitnode-" + i.toString();
var elem = clearEventListeners(elemId);
if (elem == null) {return;}
if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 || i === 6 || i === 8 || i === 11 || i === 12) {
if (i === 1 || i === 2 || i === 3 || i === 4 || i === 5 ||
i === 6 || i === 7 || i === 8 || i === 11 || i === 12) {
elem.addEventListener("click", function() {
var bitNodeKey = "BitNode" + i;
var bitNode = BitNodes[bitNodeKey];

@ -503,8 +503,10 @@ function loadImportedGame(saveObj, saveString) {
var time = numCyclesOffline * Engine._idleSpeed;
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
if (Player.playtimeSinceLastAug == null) {Player.playtimeSinceLastAug = 0;}
if (Player.playtimeSinceLastBitnode == null) {Player.playtimeSinceLastBitnode = 0;}
Player.totalPlaytime += time;
Player.playtimeSinceLastAug += time;
Player.playtimeSinceLastBitnode += time;
//Re-apply augmentations
Player.reapplyAllAugmentations();

@ -1,4 +1,5 @@
var ace = require('brace');
var beautify = require('js-beautify').js_beautify;
require('brace/mode/javascript');
require('../netscript');
require('brace/theme/chaos');
@ -29,7 +30,7 @@ import {Player} from "./Player.js";
import {AllServers, processSingleServerGrowth} from "./Server.js";
import {Settings} from "./Settings.js";
import {post, Terminal} from "./Terminal.js";
import {TextFile} from "./TextFile.js";
import {TextFile} from "./TextFile";
import {parse, Node} from "../utils/acorn.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
@ -57,6 +58,15 @@ function scriptEditorInit() {
console.log("Error finding 'script-editor-buttons-wrapper'");
return;
}
var beautifyButton = createElement("a", {
class:"a-link-button", display:"inline-block",
innerText:"Beautify",
clickListener:()=>{
beautifyScript();
return false;
}
});
var closeButton = createElement("a", {
class:"a-link-button", display:"inline-block",
innerText:"Save & Close (Ctrl/Cmd + b)",
@ -90,6 +100,7 @@ function scriptEditorInit() {
target:"_blank"
});
wrapper.appendChild(beautifyButton);
wrapper.appendChild(closeButton);
wrapper.appendChild(scriptEditorRamText);
wrapper.appendChild(scriptEditorRamCheck);
@ -243,6 +254,13 @@ $(document).keydown(function(e) {
}
});
function beautifyScript() {
var editor = ace.edit('javascript-editor');
var code = editor.getValue();
code = beautify(code, { indent_size: 4 })
editor.setValue(code);
}
function saveAndCloseScriptEditor() {
var filename = document.getElementById("script-editor-filename").value;
var editor = ace.edit('javascript-editor');
@ -456,19 +474,32 @@ function parseOnlyRamCalculate(server, code, workerScript) {
//
// TODO it would be simpler to just reference a dictionary.
try {
var func = workerScript.env.get(ref);
function applyFuncRam(func) {
if (typeof func === "function") {
try {
var res = func.apply(null, []);
let res = func.apply(null, []);
if (typeof res === "number") {
ram += res;
return res;
}
return 0;
} catch(e) {
console.log("ERROR applying function: " + e);
return 0;
}
} else {
return 0;
}
}
} catch (error) { continue; }
//Special logic for Bladeburner
var func;
if (ref in workerScript.env.vars.bladeburner) {
func = workerScript.env.vars.bladeburner[ref];
} else {
func = workerScript.env.get(ref);
}
ram += applyFuncRam(func);
} catch (error) {continue;}
}
return ram;

@ -164,6 +164,17 @@ function applySourceFile(srcFile) {
Player.dexterity_exp_mult *= incMult;
Player.agility_exp_mult *= incMult;
break;
case 7: //Bladeburner 2079
var mult = 0;
for (var i = 0; i < srcFile.lvl; ++i) {
mult += (8 / (Math.pow(2, i)));
}
var incMult = 1 + (mult / 100);
Player.bladeburner_max_stamina_mult *= incMult;
Player.bladeburner_stamina_gain_mult *= incMult;
Player.bladeburner_analysis_mult *= incMult;
Player.bladeburner_success_chance_mult *= incMult;
break;
case 8: //Ghost of Wall Street
var mult = 0;
for (var i = 0; i < srcFile.lvl; ++i) {

@ -5,11 +5,12 @@ import {substituteAliases, printAliases,
import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {executeDarkwebTerminalCommand,
checkIfConnectedToDarkweb} from "./DarkWeb.js";
checkIfConnectedToDarkweb,
DarkWebItems} from "./DarkWeb.js";
import {Engine} from "./engine.js";
import {FconfSettings, parseFconfSettings,
createFconf} from "./Fconf.js";
import {TerminalHelpText, HelpTexts} from "./HelpText.js";
import {TerminalHelpText, HelpTexts} from "./HelpText";
import {iTutorialNextStep, iTutorialSteps,
iTutorialIsRunning,
currITutorialStep} from "./InteractiveTutorial.js";
@ -19,6 +20,7 @@ import {scriptCalculateHackingTime,
scriptCalculateGrowTime,
scriptCalculateWeakenTime} from "./NetscriptEvaluator.js";
import {killWorkerScript, addWorkerScript} from "./NetscriptWorker.js";
import numeral from "numeral/min/numeral.min";
import {Player} from "./Player.js";
import {hackWorldDaemon} from "./RedPill.js";
import {findRunningScript, RunningScript,
@ -29,8 +31,7 @@ import {AllServers, GetServerByHostname,
import {Settings} from "./Settings.js";
import {SpecialServerIps,
SpecialServerNames} from "./SpecialServerIps.js";
import {TextFile, getTextFile,
createTextFile} from "./TextFile.js";
import {TextFile, getTextFile} from "./TextFile";
import {containsAllStrings, longestCommonStart,
formatNumber, isString} from "../utils/StringHelperFunctions.js";
@ -409,9 +410,12 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
}
if (input.startsWith ("buy ")) {
return [Programs.BruteSSHProgram, Programs.FTPCrackProgram, Programs.RelaySMTPProgram,
Programs.HTTPWormProgram, Programs.SQLInjectProgram, Programs.DeepscanV1,
Programs.DeepscanV2].concat(Object.keys(GlobalAliases));
let options = [];
for(const i in DarkWebItems) {
const item = DarkWebItems[i]
options.push(item.program);
}
return options.concat(Object.keys(GlobalAliases));
}
if (input.startsWith("scp ") && index == 1) {
@ -1913,7 +1917,8 @@ let Terminal = {
break;
case Programs.Flight:
post("Augmentations: " + Player.augmentations.length + " / 30");
post("Money: $" + formatNumber(Player.money.toNumber(), 2) + " / $" + formatNumber(100000000000, 2));
post("Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + " / " + numeral(1e11).format('($0.000a)'));
post("One path below must be fulfilled...");
post("----------HACKING PATH----------");
post("Hacking skill: " + Player.hacking_skill + " / 2500");

@ -1,90 +0,0 @@
import {Server} from "./Server.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
function TextFile(fn="", txt="") {
this.fn = fn.endsWith(".txt") ? fn : fn + ".txt";
this.fn = this.fn.replace(/\s+/g, '');
this.text = String(txt);
}
TextFile.prototype.append = function(txt) {
this.text += String(txt);
}
TextFile.prototype.write = function(txt) {
this.text = String(txt);
}
TextFile.prototype.read = function() {
return this.txt;
}
TextFile.prototype.show = function() {
dialogBoxCreate(this.fn + "<br><br>" + this.text, true);
}
TextFile.prototype.download = function() {
var filename = this.fn;
var file = new Blob([this.text], {type: 'text/plain'});
if (window.navigator.msSaveOrOpenBlob) {// IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
} else { // Others
var a = document.createElement("a"),
url = URL.createObjectURL(file);
a.href = url;
a.download = this.fn;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
}
TextFile.prototype.toJSON = function() {
return Generic_toJSON("TextFile", this);
}
TextFile.fromJSON = function(value) {
return Generic_fromJSON(TextFile, value.data);
}
Reviver.constructors.TextFile = TextFile;
function getTextFile(fn, server) {
if (!fn.endsWith(".txt")) {fn += ".txt";}
for (var i = 0; i < server.textFiles.length; ++i) {
if (server.textFiles[i].fn === fn) {
return server.textFiles[i];
}
}
return null;
}
//Returns the TextFile object that was just created
function createTextFile(fn, txt, server) {
if (getTextFile(fn, server) !== null) {
console.log("ERROR: createTextFile failed because the specified " +
"server already has a text file with the same fn");
return;
}
var file = new TextFile(fn, txt);
server.textFiles.push(file);
return file;
}
function deleteTextFile(fn, server) {
if (!fn.endsWith(".txt")) {fn += ".txt";}
for (var i = 0; i < server.textFiles.length; ++i) {
if (server.textFiles[i].fn === fn) {
server.textFiles.splice(i, 1);
return true;
}
}
return false;
}
export {TextFile, getTextFile, createTextFile};

147
src/TextFile.ts Normal file

@ -0,0 +1,147 @@
import { dialogBoxCreate } from "../utils/DialogBox";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
/**
* Represents a plain text file that is typically stored on a server.
*/
export class TextFile {
/**
* Initiatizes a TextFile from a JSON save state.
*/
static fromJSON(value: any): TextFile {
return Generic_fromJSON(TextFile, value.data);
}
/**
* The full file name.
*/
fn: string;
/**
* The content of the file.
*/
text: string;
constructor(fn: string = "", txt: string = "") {
this.fn = (fn.endsWith(".txt") ? fn : `${fn}.txt`).replace(/\s+/g, "");
this.text = txt;
}
/**
* Concatenates the raw values to the end of current content.
*/
append(txt: string): void {
this.text += txt;
}
/**
* Serves the file to the user as a downloadable resource through the browser.
*/
download(): void {
const filename: string = this.fn;
const file: Blob = new Blob([ this.text ], { type: "text/plain" });
/* tslint:disable-next-line:strict-boolean-expressions */
if (window.navigator.msSaveOrOpenBlob) {
// IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
} else {
// Others
const a: HTMLAnchorElement = document.createElement("a");
const url: string = URL.createObjectURL(file);
a.href = url;
a.download = this.fn;
document.body.appendChild(a);
a.click();
setTimeout(
() => {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
},
0);
}
}
/**
* Retrieve the content of the file.
*/
read(): string {
return this.text;
}
/**
* Shows the content to the user via the game's dialog box.
*/
show(): void {
dialogBoxCreate(`${this.fn}<br /><br />${this.text}`, true);
}
/**
* Serialize the current file to a JSON save state.
*/
toJSON(): any {
return Generic_toJSON("TextFile", this);
}
/**
* Replaces the current content with the text provided.
*/
write(txt: string): void {
this.text = txt;
}
}
Reviver.constructors.TextFile = TextFile;
/**
* Retrieve the file object for the filename on the specified server.
* @param fn The file name to look for
* @param server The server object to look in
* @returns The file object, or null if it couldn't find it.
*/
export function getTextFile(fn: string, server: any): TextFile | null {
const filename: string = !fn.endsWith(".txt") ? `${fn}.txt` : fn;
for (const file of (server.textFiles as TextFile[])) {
if (file.fn === filename) {
return file;
}
}
return null;
}
/**
* Creates a TextFile on the target server.
* @param fn The file name to create.
* @param txt The contents of the file.
* @param server The server that the file should be created on.
* @returns The instance of the file.
*/
export function createTextFile(fn: string, txt: string, server: any): TextFile | undefined {
if (getTextFile(fn, server) !== null) {
// This should probably be a `throw`...
/* tslint:disable-next-line:no-console */
console.error(`A file named "${fn}" already exists on server ${server.hostname}.`);
return undefined;
}
const file: TextFile = new TextFile(fn, txt);
server.textFiles.push(file);
return file;
}
/* tslint:disable-next-line:no-unused-variable */
function deleteTextFile(fn: string, server: any): boolean {
const filename: string = !fn.endsWith(".txt") ? `${fn}.txt` : fn;
/* tslint:disable-next-line:typedef */
for (let i = 0; i < server.textFiles.length; ++i) {
if (server.textFiles[i].fn === filename) {
server.textFiles.splice(i, 1);
return true;
}
}
return false;
}

@ -576,6 +576,11 @@ let Engine = {
intText = 'Intelligence: ' + (Player.intelligence).toLocaleString() + "<br><br><br>";
}
let bitNodeTimeText = "";
if(Player.sourceFiles.length > 0) {
bitNodeTimeText = 'Time played since last Bitnode destroyed: ' + convertTimeMsToTimeElapsedString(Player.playtimeSinceLastBitnode) + '<br>';
}
Engine.Display.characterInfo.appendChild(createElement("pre", {
innerHTML:
'<b>General</b><br><br>' +
@ -629,6 +634,7 @@ let Engine = {
'Hacknet Nodes owned: ' + Player.hacknetNodes.length + '<br>' +
'Augmentations installed: ' + Player.augmentations.length + '<br>' +
'Time played since last Augmentation: ' + convertTimeMsToTimeElapsedString(Player.playtimeSinceLastAug) + '<br>' +
bitNodeTimeText +
'Time played: ' + convertTimeMsToTimeElapsedString(Player.totalPlaytime),
}));
@ -914,8 +920,10 @@ let Engine = {
var time = numCycles * Engine._idleSpeed;
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
if (Player.playtimeSinceLastAug == null) {Player.playtimeSinceLastAug = 0;}
if (Player.playtimeSinceLastBitnode == null) {Player.playtimeSinceLastBitnode = 0;}
Player.totalPlaytime += time;
Player.playtimeSinceLastAug += time;
Player.playtimeSinceLastBitnode += time;
//Start Manual hack
if (Player.startAction == true) {
@ -1335,8 +1343,10 @@ let Engine = {
var time = numCyclesOffline * Engine._idleSpeed;
if (Player.totalPlaytime == null) {Player.totalPlaytime = 0;}
if (Player.playtimeSinceLastAug == null) {Player.playtimeSinceLastAug = 0;}
if (Player.playtimeSinceLastBitnode == null) {Player.playtimeSinceLastBitnode = 0;}
Player.totalPlaytime += time;
Player.playtimeSinceLastAug += time;
Player.playtimeSinceLastBitnode += time;
Player.lastUpdate = Engine._lastUpdate;
Engine.start(); //Run main game loop and Scripts loop

11
tsconfig.json Normal file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"sourceMap": true,
"strict": true
},
"exclude": [
"node_modules"
]
}

76
tslint.json Normal file

@ -0,0 +1,76 @@
{
"defaultSeverity": "error",
"extends": [
"tslint:all"
],
"jsRules": {},
"linterOptions": {
"exclude": [
"node_modules/"
]
},
"rules": {
"completed-docs": [
true,
{
"classes": true,
"enums": true,
"enum-members": true,
"functions": {
"visibilities": [
"exported"
]
},
"interfaces": true,
"methods": {
"privacies": [
"public"
]
},
"namespaces": true,
"properties": true,
"types": true,
"variables": {
"visibilities": [
"exported"
]
}
}
],
"linebreak-style": false,
"member-access": [
true,
"no-public"
],
"no-any": false,
"no-inferrable-types": [
false,
"ignore-params",
"ignore-properties"
],
"no-null-keyword": false,
"no-unsafe-any": false,
"object-literal-key-quotes": [
true,
"as-needed"
],
"only-arrow-functions": [
true,
"allow-declarations",
"allow-named-functions"
],
"typedef": [
true,
"call-signatures",
"arrow-call-signatures",
"parameter",
"arrow-parameter",
"property-declaration",
"variable-declaration",
"member-variable-declaration",
"object-destructuring",
"array-destructuring"
]
},
"rulesDirectory": []
}

2
utils/DialogBox.d.ts vendored Normal file

@ -0,0 +1,2 @@
export function dialogBoxCreate(txt: string, preformatted: boolean): void;
export var dialogBoxOpened: boolean;

10
utils/JSONReviver.d.ts vendored Normal file

@ -0,0 +1,10 @@
interface IReviverValue {
ctor: string;
data: object
}
export function Generic_fromJSON<T>(ctor: new () => T, data: any): T;
export function Generic_toJSON(ctorName: string, obj: object, keys?: string[]): string;
export function Reviver(key, value: IReviverValue);
export namespace Reviver {
export var constructors: any;
}

@ -2,7 +2,6 @@ var path = require('path');
var webpack = require('webpack');
module.exports = (env, argv) => ({
//mode: "development",
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': argv.mode === 'development' ? "\"development\"" : "\"production\""
@ -28,7 +27,13 @@ module.exports = (env, argv) => ({
filename: "[name].bundle.js"
},
module: {
rules: []
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
exclude: /node_modules/
}
]
},
optimization: {
removeAvailableModules: true,
@ -47,5 +52,12 @@ module.exports = (env, argv) => ({
},
devServer: {
publicPath: "/dist",
},
resolve: {
extensions: [
".tsx",
".ts",
".js"
]
}
});