mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 22:52:29 +01:00
Merge branch 'dev' of https://github.com/danielyxie/bitburner into dev
This commit is contained in:
commit
8fbf673719
89
css/characteroverview.scss
Normal file
89
css/characteroverview.scss
Normal file
@ -0,0 +1,89 @@
|
||||
@import "mixins";
|
||||
@import "theme";
|
||||
|
||||
/**
|
||||
* Styling for the Character Overview Panel (top-right)
|
||||
*/
|
||||
|
||||
#character-overview-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#character-overview-container {
|
||||
display: none;
|
||||
position: absolute; /* Stay in place */
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: auto; /* Full height */
|
||||
padding: 10px 2px;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
width: auto;
|
||||
max-width: 280px;
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#character-overview-text {
|
||||
color: $my-stat-physical;
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.character-stat-text {
|
||||
color: #fff;
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.character-stat-cell {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#character-hack-wrapper td,
|
||||
#character-agi-wrapper td {
|
||||
border-bottom: 1px #aaa solid;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#character-str-wrapper td,
|
||||
#character-cha-wrapper td {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#character-hp-wrapper { color: $my-stat-hp-color; }
|
||||
#character-money-wrapper { color: $my-stat-money-color; }
|
||||
#character-hack-wrapper { color: $my-stat-hack-color; }
|
||||
#character-cha-wrapper { color: $my-stat-cha-color; }
|
||||
#character-int-wrapper { color: $my-stat-int-color; }
|
||||
|
||||
.character-overview-btn {
|
||||
@include borderRadius(12px);
|
||||
@include boxShadow(1px 1px 3px #000);
|
||||
color: #cecece;
|
||||
display: inline-block;
|
||||
font-size: $defaultFontSize * 0.875;
|
||||
font-weight: bold;
|
||||
height: 25px;
|
||||
background-color: #000;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.character-quick-options {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.character-overview-btn:hover,
|
||||
.character-overview-btn:focus {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
@ -296,93 +296,6 @@ a:visited {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
/* Character Overview */
|
||||
#character-overview-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#character-overview-container {
|
||||
display: none;
|
||||
position: absolute; /* Stay in place */
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: auto; /* Full height */
|
||||
padding: 10px 2px;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
width: auto;
|
||||
max-width: 280px;
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
background-color: rgba(57, 54, 54, 0.9); /* Fallback color */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#character-overview-text {
|
||||
color: $my-stat-physical;
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.character-stat-text {
|
||||
color: #fff;
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.character-stat-cell {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#character-hack-wrapper td,
|
||||
#character-agi-wrapper td {
|
||||
border-bottom: 1px #aaa solid;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
#character-str-wrapper td,
|
||||
#character-cha-wrapper td {
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
#character-hp-wrapper { color: $my-stat-hp-color; }
|
||||
#character-money-wrapper { color: $my-stat-money-color; }
|
||||
#character-hack-wrapper { color: $my-stat-hack-color; }
|
||||
#character-cha-wrapper { color: $my-stat-cha-color; }
|
||||
#character-int-wrapper { color: $my-stat-int-color; }
|
||||
|
||||
#character-overview-save-button,
|
||||
#character-overview-options-button {
|
||||
@include borderRadius(12px);
|
||||
@include boxShadow(1px 1px 3px #000);
|
||||
color: #cecece;
|
||||
display: inline-block;
|
||||
font-size: $defaultFontSize * 0.875;
|
||||
font-weight: bold;
|
||||
height: 25px;
|
||||
background-color: #000;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
.character-quick-options {
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#character-overview-save-button:hover,
|
||||
#character-overview-save-button:focus,
|
||||
#character-overview-options-button:hover,
|
||||
#character-overview-options-button:focus {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Scan analyze links from AutoLink */
|
||||
.scan-analyze-link {
|
||||
cursor: pointer;
|
||||
|
56961
dist/engine.bundle.js
vendored
56961
dist/engine.bundle.js
vendored
File diff suppressed because one or more lines are too long
181
dist/engine.css
vendored
181
dist/engine.css
vendored
@ -305,96 +305,6 @@ a:visited {
|
||||
top: 0;
|
||||
width: auto; }
|
||||
|
||||
/* Character Overview */
|
||||
#character-overview-wrapper {
|
||||
position: relative; }
|
||||
|
||||
#character-overview-container {
|
||||
display: none;
|
||||
position: absolute;
|
||||
/* Stay in place */
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: auto;
|
||||
/* Full height */
|
||||
padding: 10px 2px;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
width: auto;
|
||||
max-width: 280px;
|
||||
overflow: auto;
|
||||
/* Enable scroll if needed */
|
||||
background-color: rgba(57, 54, 54, 0.9);
|
||||
/* Fallback color */
|
||||
z-index: 1; }
|
||||
|
||||
#character-overview-text {
|
||||
color: #faffdf; }
|
||||
#character-overview-text table {
|
||||
border-collapse: collapse;
|
||||
margin: auto; }
|
||||
#character-overview-text td {
|
||||
padding: 2px;
|
||||
vertical-align: middle; }
|
||||
|
||||
.character-stat-text {
|
||||
color: #fff;
|
||||
background-color: #444; }
|
||||
|
||||
.character-stat-cell {
|
||||
text-align: right; }
|
||||
|
||||
#character-hack-wrapper td,
|
||||
#character-agi-wrapper td {
|
||||
border-bottom: 1px #aaa solid;
|
||||
padding-bottom: 10px; }
|
||||
|
||||
#character-str-wrapper td,
|
||||
#character-cha-wrapper td {
|
||||
padding-top: 10px; }
|
||||
|
||||
#character-hp-wrapper {
|
||||
color: #dd3434; }
|
||||
|
||||
#character-money-wrapper {
|
||||
color: #ffd700; }
|
||||
|
||||
#character-hack-wrapper {
|
||||
color: #adff2f; }
|
||||
|
||||
#character-cha-wrapper {
|
||||
color: #a671d1; }
|
||||
|
||||
#character-int-wrapper {
|
||||
color: #6495ed; }
|
||||
|
||||
#character-overview-save-button,
|
||||
#character-overview-options-button {
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
-webkit-box-shadow: 1px 1px 3px #000;
|
||||
-moz-box-shadow: 1px 1px 3px #000;
|
||||
box-shadow: 1px 1px 3px #000;
|
||||
color: #cecece;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
height: 25px;
|
||||
background-color: #000;
|
||||
padding: 5px 8px; }
|
||||
|
||||
.character-quick-options {
|
||||
margin-top: 10px;
|
||||
text-align: center; }
|
||||
|
||||
#character-overview-save-button:hover,
|
||||
#character-overview-save-button:focus,
|
||||
#character-overview-options-button:hover,
|
||||
#character-overview-options-button:focus {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
cursor: pointer; }
|
||||
|
||||
/* Scan analyze links from AutoLink */
|
||||
.scan-analyze-link {
|
||||
cursor: pointer;
|
||||
@ -678,6 +588,97 @@ button {
|
||||
opacity: 1;
|
||||
transition: max-height 0.2s ease-out; }
|
||||
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
/**
|
||||
* Styling for the Character Overview Panel (top-right)
|
||||
*/
|
||||
#character-overview-wrapper {
|
||||
position: relative; }
|
||||
|
||||
#character-overview-container {
|
||||
display: none;
|
||||
position: absolute;
|
||||
/* Stay in place */
|
||||
right: 0;
|
||||
top: 0;
|
||||
height: auto;
|
||||
/* Full height */
|
||||
padding: 10px 2px;
|
||||
border: 2px solid var(--my-highlight-color);
|
||||
width: auto;
|
||||
max-width: 280px;
|
||||
overflow: auto;
|
||||
/* Enable scroll if needed */
|
||||
background-color: rgba(57, 54, 54, 0.9);
|
||||
/* Fallback color */
|
||||
z-index: 1; }
|
||||
|
||||
#character-overview-text {
|
||||
color: #faffdf; }
|
||||
#character-overview-text table {
|
||||
border-collapse: collapse;
|
||||
margin: auto; }
|
||||
#character-overview-text td {
|
||||
padding: 2px;
|
||||
vertical-align: middle; }
|
||||
|
||||
.character-stat-text {
|
||||
color: #fff;
|
||||
background-color: #444; }
|
||||
|
||||
.character-stat-cell {
|
||||
text-align: right; }
|
||||
|
||||
#character-hack-wrapper td,
|
||||
#character-agi-wrapper td {
|
||||
border-bottom: 1px #aaa solid;
|
||||
padding-bottom: 10px; }
|
||||
|
||||
#character-str-wrapper td,
|
||||
#character-cha-wrapper td {
|
||||
padding-top: 10px; }
|
||||
|
||||
#character-hp-wrapper {
|
||||
color: #dd3434; }
|
||||
|
||||
#character-money-wrapper {
|
||||
color: #ffd700; }
|
||||
|
||||
#character-hack-wrapper {
|
||||
color: #adff2f; }
|
||||
|
||||
#character-cha-wrapper {
|
||||
color: #a671d1; }
|
||||
|
||||
#character-int-wrapper {
|
||||
color: #6495ed; }
|
||||
|
||||
.character-overview-btn {
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
-webkit-box-shadow: 1px 1px 3px #000;
|
||||
-moz-box-shadow: 1px 1px 3px #000;
|
||||
box-shadow: 1px 1px 3px #000;
|
||||
color: #cecece;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
height: 25px;
|
||||
background-color: #000;
|
||||
padding: 5px 8px; }
|
||||
|
||||
.character-quick-options {
|
||||
margin-top: 10px;
|
||||
text-align: center; }
|
||||
|
||||
.character-overview-btn:hover,
|
||||
.character-overview-btn:focus {
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
cursor: pointer; }
|
||||
|
||||
/* COLORS */
|
||||
/* Attributes */
|
||||
#terminal-container {
|
||||
|
111046
dist/vendor.bundle.js
vendored
111046
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -3,6 +3,66 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
v0.41.1 - 11/5/2018
|
||||
-------------------
|
||||
* IMPORTANT - Netscript Changes:
|
||||
* purchaseTor() now returns true if you already have a TOR router (it used to return false)
|
||||
* getPurchasedServerCost() now returns Infinity if the specified RAM is an invalid amount or is greater than the max amount of RAM (2 ^ 20 GB)
|
||||
* Added purchase4SMarketData() and purchase4SMarketDataTixApi() functions
|
||||
* getScriptLogs() now takes in optional arguments that let you get the logs of another script
|
||||
|
||||
* Stock Market changes:
|
||||
* Stocks now have "maximum prices". These are hidden from the player
|
||||
* If a stock reaches its "maximum price", it will most likely drop in value (although it might still rise)
|
||||
* Each stock has its own, unique maximum price
|
||||
* Maximum price for each stock are randomly generated and change during each 'reset'
|
||||
* Stock Market cycles are now accumulated/stored, much like it is for Gangs and Bladeburners
|
||||
* Accumulated/stored cycles cause stock prices to update up to 50% faster (from every 6 seconds to 4 seconds)
|
||||
* This means that after coming back from being offline, stock prices will update faster to make up for offline time
|
||||
|
||||
* Decreased the Hacking Level multiplier for BitNodes 6 and 7 to 0.4 (from 0.5)
|
||||
* Bladeburner console history is now saved and persists when switching screens or closing/reopening the game
|
||||
* In Bladeburner, if your stamina reaches 0 your current action will be cancelled
|
||||
* b1t_flum3.exe is no longer removed from your home computer upon reset
|
||||
* Added main menu link for the Stock Market (once you've purchased an account)
|
||||
* Job main menu link only appears if you actually have a job
|
||||
* Bug Fix: After installing Augs, the "Portfolio Mode" button on the Stock Market page should be properly reset
|
||||
* Bug Fix: bladeburner.getActionCountRemaining()'s return value is now rounded down (by Kline-)
|
||||
|
||||
v0.41.0 - 10/29/2018
|
||||
--------------------
|
||||
* WARNING: In NetscriptJS, defining a function called print() is no longer possible
|
||||
* Gang Mechanic Changes (BitNode-2):
|
||||
* Added a Gang Netscript API
|
||||
* Added new 'ascension' mechanic for Gang Members
|
||||
* The first three gang members are now 'free' (can be recruited instantly)
|
||||
* Maximum number of increased Gang Members increased from 20 to 30
|
||||
* Changed the formula for calculating respect needed to recruit the next gang member
|
||||
* Added a new category of upgrades for Gang Members: Augmentations
|
||||
* Non-Augmentation Gang member upgrades are now significantly weaker
|
||||
* Reputation for your Gang faction can no longer be gained through Infiltration
|
||||
* Re-worked the territory 'warfare' mechanic so that player can choose when to engage in it
|
||||
* Gang Members can now be killed during territory 'warfare'
|
||||
* Changed BitNode-2 Multipliers to make hacking slightly less profitable
|
||||
* Gang Member Equipment + Upgrades now get cheaper as your gang grows in power and respect
|
||||
* The effects of Source-File 2 are now slightly more powerful
|
||||
* RAM Cost of accessing the global document object lowered from 100 GB to 25 GB
|
||||
* RAM Cost to use Singularity Functions outside of BitNode-4 lowered by 75%. They now only cost twice as much as they do in BitNode-4
|
||||
* b1t_flum3.exe now takes significantly less time to create
|
||||
* Crimes commited through Singularity function no longer give half money/exp (there is now no penalty)
|
||||
* Improved number formatting for Player 'work' actions (including crimes, etc.). These numbers should also adhere to locale settings now (by Kline-)
|
||||
* The order that Augmentations are listed in (when purchasing from Faction and viewing your Augmentations) is now saved and persists when choosing different orders
|
||||
* getCharacterInformation() Singularity function now returns multiplier information (from Augmentations/Source Files)
|
||||
* Bug Fix: Calling print() in NetscriptJS no longer brings up the print dialog
|
||||
* Bug Fix: Fixed a bug that sometimes caused a blank black screen when destroying/resetting/switching BitNodes
|
||||
* Bug Fix: Netscript calls that throw errors will now no longer cause the 'concurrent calls' error if they are caught in the script. i.e. try/catch should now work properly in scripts
|
||||
* Bug Fix: Fixed a bug where sometimes the NeuroFlux Governor Augmentation level would be incorrectly calculated when the game was loaded
|
||||
* Bug Fix: Fixed a bug where calling the scp() Netscript function with invalid hostname/ips would throw an unclear error message
|
||||
* Bug Fix: Bladeburner API function getActionCountRemaining() should now work properly for BlackOps
|
||||
* Bug Fix: Black Ops can no longer be attempted out-of-order or without the required rank via Bladeburner API
|
||||
* Bug Fix: Dynamic RAM Calculation now properly accounts for number of threads
|
||||
* RAM cost for basic Netscript functions added to documentation (by CBJamo)
|
||||
|
||||
v0.40.5 - 10/09/2018
|
||||
--------------------
|
||||
* Added codingcontract.getContractType() Netscript function
|
||||
|
@ -153,17 +153,37 @@ isLogEnabled
|
||||
getScriptLogs
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
.. js:function:: getScriptLogs()
|
||||
.. js:function:: getScriptLogs([fn], [hostname/ip=current ip], [args...])
|
||||
|
||||
:param string fn: Optional. Filename of script to get logs from.
|
||||
:param string ip: Optional. IP or hostname of the server that the script is on
|
||||
:param args...: Arguments to identify which scripts to get logs for
|
||||
:RAM cost: 0 GB
|
||||
|
||||
Returns the script's logs. The logs are returned as an array, where each
|
||||
Returns a script's logs. The logs are returned as an array, where each
|
||||
line is an element in the array. The most recently logged line is at the
|
||||
end of the array.
|
||||
|
||||
Note that there is a maximum number of lines that a script stores in its logs.
|
||||
This is configurable in the game's options.
|
||||
|
||||
If the function is called with no arguments, it will return the current script's logs.
|
||||
|
||||
Otherwise, the `fn`, `hostname/ip,` and `args...` arguments can be used to get the logs
|
||||
from another script. Remember that scripts are uniquely identified by both
|
||||
their names and arguments.
|
||||
|
||||
Examples::
|
||||
|
||||
// Get logs from foo.script on the current server that was run with no args
|
||||
getScriptLogs("foo.script");
|
||||
|
||||
// Get logs from foo.script on the foodnstuff server that was run with no args
|
||||
getScriptLogs("foo.script", "foodnstuff");
|
||||
|
||||
// Get logs from foo.script on the foodnstuff server that was run with the arguments [1, "test"]
|
||||
getScriptLogs("foo.script", "foodnstuff", 1, "test");
|
||||
|
||||
scan
|
||||
^^^^
|
||||
|
||||
|
@ -2,7 +2,7 @@ Netscript Trade Information eXchange (TIX) API
|
||||
==============================================
|
||||
|
||||
The Trade Information eXchange (TIX) is the communications protocol supported by the World Stock Exchange (WSE).
|
||||
The WESE provides an API that allows you to automatically communicate with the
|
||||
The WSE provides an API that allows you to automatically communicate with the
|
||||
`Stock Market <http://bitburner.wikia.com/wiki/Stock_Market>`_. This API lets you write code using Netscript
|
||||
to build automated trading systems and create your own algorithmic trading strategies. Access to this
|
||||
TIX API can be purchased by visiting the World Stock Exchange in-game.
|
||||
@ -11,7 +11,7 @@ Access to the TIX API currently costs $5 billion. After you purchase it, you wil
|
||||
access even after you 'reset' by installing Augmentations
|
||||
|
||||
getStockSymbols
|
||||
-------------
|
||||
---------------
|
||||
|
||||
.. js:function:: getStockSymbols()
|
||||
|
||||
@ -214,3 +214,23 @@ getStockForecast
|
||||
In other words, if this function returned 0.30 for a stock, then this means
|
||||
that the stock's price has a 30% chance of increasing and a 70% chance of
|
||||
decreasing during the next tick.
|
||||
|
||||
purchase4SMarketData
|
||||
--------------------
|
||||
|
||||
.. js:function:: purchase4SMarketData()
|
||||
|
||||
Purchase 4S Market Data Access.
|
||||
|
||||
Returns true if you successfully purchased it or if you already have access.
|
||||
Returns false otherwise.
|
||||
|
||||
purchase4SMarketDataTixApi
|
||||
--------------------------
|
||||
|
||||
.. js:function:: purchase4SMarketDataTixApi()
|
||||
|
||||
Purchase 4S Market Data TIX API Access.
|
||||
|
||||
Returns true if you successfully purchased it or if you already have access.
|
||||
Returns false otherwise.
|
||||
|
@ -500,8 +500,6 @@ commitCrime
|
||||
This function is used to automatically attempt to commit crimes. If you are already in the middle of some 'working' action
|
||||
(such as working for a company or training at a gym), then running this function will automatically cancel that action and give you your earnings.
|
||||
|
||||
Note that crimes committed using this function will have all of their earnings halved (this applied for both money and experience!)
|
||||
|
||||
This function returns the number of seconds it takes to attempt the specified crime (e.g It takes 60 seconds to attempt the 'Rob Store' crime,
|
||||
so running *commitCrime('rob store')* will return 60).
|
||||
|
||||
|
61
index.html
61
index.html
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bitburner - development</title>
|
||||
<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">
|
||||
@ -79,6 +79,9 @@
|
||||
<li id="job-tab" class="mainmenu-accordion-panel">
|
||||
<button id="job-menu-link"> Job </button>
|
||||
</li>
|
||||
<li id="stock-market-tab" class="mainmenu-accordion-panel">
|
||||
<button id="stock-market-menu-link"> Stock Market </button>
|
||||
</li>
|
||||
<li id="bladeburner-tab" class="mainmenu-accordion-panel">
|
||||
<button id="bladeburner-menu-link"> Bladeburner </button>
|
||||
</li>
|
||||
@ -109,7 +112,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 id="script-editor-filename" type="text" maxlength="30" tabindex="1"/>
|
||||
</div>
|
||||
|
||||
<div id="javascript-editor"></div>
|
||||
@ -159,7 +162,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 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 -->
|
||||
@ -170,7 +173,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>
|
||||
@ -187,7 +190,7 @@
|
||||
provides information about each script's production. The scripts are categorized by the hostname of the servers on which
|
||||
they are running. </p>
|
||||
<p id="active-scripts-total-prod">Total online production of
|
||||
Active scripts: <span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br />
|
||||
Active scripts: <span class="money-gold"><span id="active-scripts-total-production-active">$0.000</span> / sec</span><br/>
|
||||
Total online production since last Aug installation: <span id="active-scripts-total-prod-aug-total" class="money-gold">$0.000</span>
|
||||
(<span class="money-gold"><span id="active-scripts-total-prod-aug-avg" class="money-gold">$0.000</span> / sec</span>)</p>
|
||||
<ul class="active-scripts-list" id="active-scripts-list" style="list-style: none;">
|
||||
@ -201,19 +204,19 @@
|
||||
The Hacknet is a global, decentralized network of machines. It is used by hackers all around
|
||||
the world to anonymously share computing power and perform distributed cyberattacks without the
|
||||
fear of being traced.
|
||||
<br /><br />
|
||||
<br/><br/>
|
||||
Here, you can purchase a Hacknet Node, a specialized machine that can connect and contribute its
|
||||
resources to the Hacknet network. This allows you to take a small percentage of profits
|
||||
from hacks performed on the network. Essentially, you are renting out your Node's computing power.
|
||||
<br /><br />
|
||||
<br/><br/>
|
||||
Each Hacknet Node you purchase will passively earn you money. Each Hacknet Node can be upgraded
|
||||
in order to increase its computing power and thereby increase the profit you earn from it.
|
||||
</p>
|
||||
<a id="hacknet-nodes-purchase-button" class="a-link-button"> Purchase Hacknet Node </a>
|
||||
<br />
|
||||
<br/>
|
||||
<div id="hacknet-nodes-money-multipliers-div">
|
||||
<p id="hacknet-nodes-money">
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" class="money-gold"></span><br />
|
||||
<span>Money:</span><span id="hacknet-nodes-player-money" class="money-gold"></span><br/>
|
||||
<span>Total Hacknet Node Production:</span><span id="hacknet-nodes-total-production" class="money-gold"></span>
|
||||
</p>
|
||||
<span id="hacknet-nodes-multipliers">
|
||||
@ -471,8 +474,7 @@
|
||||
|
||||
<!-- Tutorial content -->
|
||||
<div id="tutorial-container" class="generic-menupage-container">
|
||||
<a id="tutorial-getting-started-link" class="a-link-button"
|
||||
href="http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner" target="_blank"> Getting Started </a>
|
||||
<a id="tutorial-getting-started-link" class="a-link-button" href="http://bitburner.wikia.com/wiki/Chapt3rs_Guide_to_Getting_Started_with_Bitburner" target="_blank"> Getting Started </a>
|
||||
<a id="tutorial-networking-link" class="a-link-button"> Servers & Networking </a>
|
||||
<a id="tutorial-hacking-link" class="a-link-button"> Hacking </a>
|
||||
<a id="tutorial-scripts-link" class="a-link-button"> Scripts </a>
|
||||
@ -481,8 +483,7 @@
|
||||
<a id="tutorial-jobs-link" class="a-link-button"> Companies and Infiltration </a>
|
||||
<a id="tutorial-factions-link" class="a-link-button"> Factions </a>
|
||||
<a id="tutorial-augmentations-link" class="a-link-button"> Augmentations </a>
|
||||
<a id="tutorial-shortcuts-link" class="a-link-button"
|
||||
href="https://bitburner.wikia.com/wiki/Shortcuts" target="_blank"> Keyboard Shortcuts </a>
|
||||
<a id="tutorial-shortcuts-link" class="a-link-button" href="https://bitburner.wikia.com/wiki/Shortcuts" target="_blank"> Keyboard Shortcuts </a>
|
||||
|
||||
<a id="tutorial-back-button" class="a-link-button"> Back </a>
|
||||
<p id="tutorial-text"> </p>
|
||||
@ -573,7 +574,7 @@
|
||||
<p id="location-slums-description">
|
||||
You have entered the Slums, a poverty-ridden district filled with gangs, criminals, and
|
||||
other shadowy entities. The city's government and police have neglected this area for years...
|
||||
<br /><br /><br />
|
||||
<br/><br/><br/>
|
||||
In the Slums, you can commit crimes to earn money and experience. Crime attempts are not always
|
||||
successful. Your chance at successfully committing a crime is determined by your stats.
|
||||
</p>
|
||||
@ -620,7 +621,7 @@
|
||||
|
||||
<div id="stock-market-container" class="generic-menupage-container">
|
||||
<p>
|
||||
Welcome to the World Stock Exchange (WSE)! <br /><br />
|
||||
Welcome to the World Stock Exchange (WSE)! <br/><br/>
|
||||
|
||||
To begin trading, you must first purchase an account. WSE accounts will persist
|
||||
after you 'reset' by installing Augmentations.
|
||||
@ -633,7 +634,7 @@
|
||||
TIX, short for Trade Information eXchange, is the communications protocol supported by the WSE.
|
||||
Purchasing access to the TIX API lets you write code to create your own algorithmic/automated
|
||||
trading strategies.
|
||||
<br /><br />
|
||||
<br/><br/>
|
||||
If you purchase access to the TIX API, you will retain that access even after
|
||||
you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
@ -643,7 +644,7 @@
|
||||
<p>
|
||||
Four Sigma's (4S) Market Data Feed provides information about stocks
|
||||
that will help your trading strategies.
|
||||
<br /><br />
|
||||
<br/><br/>
|
||||
If you purchase access to 4S Market Data and/or the 4S TIX API, you will
|
||||
retain that access even after you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
@ -661,7 +662,7 @@
|
||||
<a id="stock-market-mode" class="a-link-button tooltip"></a>
|
||||
<a id="stock-market-expand-tickers" class="a-link-button tooltip">Expand tickers</a>
|
||||
<a id="stock-market-collapse-tickers" class="a-link-button tooltip">Collapse tickers</a>
|
||||
<br /><br />
|
||||
<br/><br/>
|
||||
<input id="stock-market-watchlist-filter" type="text" placeholder="Filter Stocks by symbol (comma-separated list)"/>
|
||||
<a id="stock-market-watchlist-filter-update" class="a-link-button"> Update Watchlist </a>
|
||||
<ul id="stock-market-list" style="list-style:none;">
|
||||
@ -691,7 +692,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 type="text" id="yes-no-text-input-box-input" pattern="[a-zA-Z0-9-_]" maxlength="30"/>
|
||||
<button id="yes-no-text-input-box-yes" class="popup-box-button"> Yes </button>
|
||||
<button id="yes-no-text-input-box-no" class="popup-box-button"> No </button>
|
||||
</div>
|
||||
@ -703,7 +704,7 @@
|
||||
<p id="faction-invitation-box-text"> </p>
|
||||
<p id="faction-invitation-box-message"> </p>
|
||||
<p id="faction-invitation-box-warning">
|
||||
Would you like to join? <br /> <br />
|
||||
Would you like to join? <br/> <br/>
|
||||
Warning: Joining this faction may prevent you from joining other factions during this run!
|
||||
</p>
|
||||
<button id="faction-invitation-box-yes" class="popup-box-button"> Yes </button>
|
||||
@ -716,8 +717,8 @@
|
||||
<div id="infiltration-box-content" class="popup-box-content">
|
||||
<p id="infiltration-box-text"> </p>
|
||||
|
||||
<button id="infiltration-box-sell" class="a-link-button"> Sell on Black Market </button> <br /><br />
|
||||
<select id="infiltration-faction-select"> </select> <br />
|
||||
<button id="infiltration-box-sell" class="a-link-button"> Sell on Black Market </button> <br/><br/>
|
||||
<select id="infiltration-faction-select"> </select> <br/>
|
||||
<button id="infiltration-box-faction" class="a-link-button"> Give to Faction for Reputation </button>
|
||||
|
||||
</div>
|
||||
@ -787,8 +788,8 @@
|
||||
</table>
|
||||
</div>
|
||||
<div class="character-quick-options">
|
||||
<button id="character-overview-save-button">Save Game</button>
|
||||
<button id="character-overview-options-button">Options</button>
|
||||
<button id="character-overview-save-button" class="character-overview-btn">Save Game</button>
|
||||
<button id="character-overview-options-button" class="character-overview-btn">Options</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -803,7 +804,7 @@
|
||||
<div id="game-options-content" class="game-options-box">
|
||||
<button id="game-options-close-button">×</button>
|
||||
<h1> Game Options </h1>
|
||||
<br />
|
||||
<br/>
|
||||
<div id="game-options-left-panel">
|
||||
<!-- Netscript execution time -->
|
||||
<fieldset>
|
||||
@ -815,7 +816,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type ="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25" />
|
||||
<input type="range" max="100" min="10" step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="25"/>
|
||||
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -829,7 +830,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50" />
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"/>
|
||||
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -843,7 +844,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50" />
|
||||
<input type="range" max="100" min="20" step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"/>
|
||||
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -855,7 +856,7 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60" />
|
||||
<input type="range" max="600" min="0" step="1" name="settingsAutosaveIntervalVal" id="settingsAutosaveIntervalVal" value="60"/>
|
||||
<em id="settingsAutosaveIntervalValLabel" style="font-style: normal;"></em>
|
||||
</fieldset>
|
||||
|
||||
@ -967,7 +968,7 @@
|
||||
<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>
|
||||
<input type="file" id="import-game-file-selector" name="file" />
|
||||
<input type="file" id="import-game-file-selector" name="file"/>
|
||||
<a id="import-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Import Game </a>
|
||||
<a id="debug-delete-scripts-link" class="a-link-button tooltip" style="display:block;width:46%;">
|
||||
(DEBUG) Delete Active Scripts
|
||||
|
@ -62,7 +62,7 @@ let NetscriptFunctions =
|
||||
"hack|sleep|grow|weaken|print|tprint|scan|nuke|brutessh|ftpcrack|" + //Netscript functions
|
||||
"clearLog|disableLog|enableLog|isLogEnabled|getScriptLogs|" +
|
||||
"relaysmtp|httpworm|sqlinject|run|exec|spawn|kill|killall|exit|" +
|
||||
"scp|ls|hasRootAccess|" +
|
||||
"scp|ls|ps|hasRootAccess|" +
|
||||
"getIp|getHackingMultipliers|getBitNodeMultipliers|getStats|isBusy|" +
|
||||
"getHacknetMultipliers|" +
|
||||
"getHostname|getHackingLevel|getServerMoneyAvailable|getServerMaxMoney|" +
|
||||
@ -95,6 +95,7 @@ let NetscriptFunctions =
|
||||
"getStockPrice|getStockPosition|getStockSymbols|buyStock|sellStock|" +
|
||||
"shortStock|sellShort|" +
|
||||
"placeOrder|cancelOrder|getStockVolatility|getStockForecast|" +
|
||||
"purchase4SMarketData|purchase4SMarketDataTixApi|" +
|
||||
|
||||
// Hacknet Node API
|
||||
"hacknet|numNodes|purchaseNode|getPurchaseNodeCost|getNodeStats|" +
|
||||
|
@ -265,7 +265,7 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.CorporationValuation = 0.5;
|
||||
break;
|
||||
case 6: //Bladeburner
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.5;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.5;
|
||||
BitNodeMultipliers.ServerStartingSecurity = 1.5;
|
||||
@ -282,7 +282,7 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.BladeburnerRank = 0.6;
|
||||
BitNodeMultipliers.BladeburnerSkillCost = 2;
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 3;
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.5;
|
||||
BitNodeMultipliers.HackingLevelMultiplier = 0.4;
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.5;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.5;
|
||||
BitNodeMultipliers.ServerStartingSecurity = 1.5;
|
||||
|
@ -74,7 +74,6 @@ var ContractBaseMoneyGain = 50e3; //Base Money Gained per contract
|
||||
var ActiveActionCssClass = "bladeburner-active-action";
|
||||
|
||||
//Console related stuff
|
||||
var consoleHistory = []; //Console command history
|
||||
var consoleHistoryIndex = 0;
|
||||
var consoleHelpText = {
|
||||
helpList:"Use 'help [command]' to get more information about a particular Bladeburner console command.<br><br>" +
|
||||
@ -153,6 +152,7 @@ $(document).keydown(function(event) {
|
||||
//}
|
||||
|
||||
if (!(Player.bladeburner instanceof Bladeburner)) {return;}
|
||||
let consoleHistory = Player.bladeburner.consoleHistory;
|
||||
|
||||
//NOTE: Keycodes imported from Terminal.js
|
||||
if (event.keyCode === KEY.ENTER) {
|
||||
@ -712,6 +712,10 @@ function Bladeburner(params={}) {
|
||||
this.automateActionLow = 0;
|
||||
this.automateThreshLow = 0; //Stamina Threshold
|
||||
|
||||
//Console command history
|
||||
this.consoleHistory = [];
|
||||
this.consoleLogs = [];
|
||||
|
||||
//Initialization
|
||||
initBladeburner();
|
||||
this.initializeDomElementRefs();
|
||||
@ -864,6 +868,12 @@ Bladeburner.prototype.process = function() {
|
||||
this.resetAction();
|
||||
}
|
||||
|
||||
// If the Player has no Stamina, set action to idle
|
||||
if (this.stamina <= 0) {
|
||||
this.log("Your Bladeburner action was cancelled because your stamina hit 0");
|
||||
this.resetAction();
|
||||
}
|
||||
|
||||
//A 'tick' for this mechanic is one second (= 5 game cycles)
|
||||
if (this.storedCycles >= CyclesPerSecond) {
|
||||
var seconds = Math.floor(this.storedCycles / CyclesPerSecond);
|
||||
@ -1345,7 +1355,6 @@ Bladeburner.prototype.completeAction = function() {
|
||||
Player.gainIntelligenceExp(BaseIntGain);
|
||||
Player.gainCharismaExp(charismaExpGain);
|
||||
this.changeRank(0.1 * BitNodeMultipliers.BladeburnerRank);
|
||||
console.log("DEBUG: Field Analysis effectiveness is " + (eff * this.skillMultipliers.successChanceEstimate));
|
||||
this.getCurrentCity().improvePopulationEstimateByPercentage(eff * this.skillMultipliers.successChanceEstimate);
|
||||
if (this.logging.general) {
|
||||
this.log("Field analysis completed. Gained 0.1 rank, " + formatNumber(hackingExpGain, 1) + " hacking exp, and " + formatNumber(charismaExpGain, 1) + " charisma exp");
|
||||
@ -1738,8 +1747,15 @@ Bladeburner.prototype.createContent = function() {
|
||||
|
||||
document.getElementById("entire-game-container").appendChild(DomElems.bladeburnerDiv);
|
||||
|
||||
this.postToConsole("Bladeburner Console BETA");
|
||||
this.postToConsole("Type 'help' to see console commands");
|
||||
if (this.consoleLogs.length === 0) {
|
||||
this.postToConsole("Bladeburner Console BETA");
|
||||
this.postToConsole("Type 'help' to see console commands");
|
||||
} else {
|
||||
for (let i = 0; i < this.consoleLogs.length; ++i) {
|
||||
this.postToConsole(this.consoleLogs[i], false);
|
||||
}
|
||||
}
|
||||
|
||||
DomElems.consoleInput.focus();
|
||||
}
|
||||
|
||||
@ -2732,12 +2748,22 @@ Bladeburner.prototype.updateSkillsUIElement = function(el, skill) {
|
||||
}
|
||||
|
||||
//Bladeburner Console Window
|
||||
Bladeburner.prototype.postToConsole = function(input) {
|
||||
Bladeburner.prototype.postToConsole = function(input, saveToLogs=true) {
|
||||
const MaxConsoleEntries = 100;
|
||||
if (saveToLogs === true) {
|
||||
this.consoleLogs.push(input);
|
||||
if (this.consoleLogs.length > MaxConsoleEntries) {
|
||||
this.consoleLogs.shift();
|
||||
}
|
||||
}
|
||||
|
||||
if (input == null || DomElems.consoleDiv == null) {return;}
|
||||
$("#bladeubrner-console-input-row").before('<tr><td class="bladeburner-console-line" style="color: var(--my-font-color); white-space:pre-wrap;">' + input + '</td></tr>');
|
||||
if (DomElems.consoleTable.childNodes.length > 200) {
|
||||
|
||||
if (DomElems.consoleTable.childNodes.length > MaxConsoleEntries) {
|
||||
DomElems.consoleTable.removeChild(DomElems.consoleTable.firstChild);
|
||||
}
|
||||
|
||||
this.updateConsoleScroll();
|
||||
}
|
||||
|
||||
@ -2753,6 +2779,8 @@ Bladeburner.prototype.clearConsole = function() {
|
||||
while (DomElems.consoleTable.childNodes.length > 1) {
|
||||
DomElems.consoleTable.removeChild(DomElems.consoleTable.firstChild);
|
||||
}
|
||||
|
||||
this.consoleLogs.length = 0;
|
||||
}
|
||||
|
||||
Bladeburner.prototype.log = function(input) {
|
||||
@ -2764,13 +2792,13 @@ Bladeburner.prototype.log = function(input) {
|
||||
Bladeburner.prototype.executeConsoleCommands = function(commands) {
|
||||
try {
|
||||
//Console History
|
||||
if (consoleHistory[consoleHistory.length-1] != commands) {
|
||||
consoleHistory.push(commands);
|
||||
if (consoleHistory.length > 50) {
|
||||
consoleHistory.splice(0, 1);
|
||||
if (this.consoleHistory[this.consoleHistory.length-1] != commands) {
|
||||
this.consoleHistory.push(commands);
|
||||
if (this.consoleHistory.length > 50) {
|
||||
this.consoleHistory.splice(0, 1);
|
||||
}
|
||||
}
|
||||
consoleHistoryIndex = consoleHistory.length;
|
||||
consoleHistoryIndex = this.consoleHistory.length;
|
||||
|
||||
var arrayOfCommands = commands.split(";");
|
||||
for (var i = 0; i < arrayOfCommands.length; ++i) {
|
||||
@ -3469,7 +3497,7 @@ Bladeburner.prototype.getActionCountRemainingNetscriptFn = function(type, name,
|
||||
switch (actionId.type) {
|
||||
case ActionTypes["Contract"]:
|
||||
case ActionTypes["Operation"]:
|
||||
return actionObj.count;
|
||||
return Math.floor( actionObj.count );
|
||||
case ActionTypes["BlackOp"]:
|
||||
case ActionTypes["BlackOperation"]:
|
||||
if (this.blackops[name] != null) {
|
||||
|
158
src/CodingContractGenerator.js
Normal file
158
src/CodingContractGenerator.js
Normal file
@ -0,0 +1,158 @@
|
||||
import {CodingContract,
|
||||
CodingContractRewardType,
|
||||
CodingContractTypes} from "./CodingContracts";
|
||||
import {Factions} from "./Faction";
|
||||
import {Player} from "./Player";
|
||||
import {GetServerByHostname,
|
||||
AllServers} from "./Server";
|
||||
|
||||
import {getRandomInt} from "../utils/helpers/getRandomInt";
|
||||
|
||||
export function generateRandomContract() {
|
||||
// First select a random problem type
|
||||
const problemTypes = Object.keys(CodingContractTypes);
|
||||
let randIndex = getRandomInt(0, problemTypes.length - 1);
|
||||
let problemType = problemTypes[randIndex];
|
||||
|
||||
// Then select a random reward type. 'Money' will always be the last reward type
|
||||
const reward = getRandomReward();
|
||||
|
||||
// Choose random server
|
||||
const randServer = getRandomServer();
|
||||
|
||||
let contractFn = getRandomFilename(randServer, reward);
|
||||
let contract = new CodingContract(contractFn, problemType, reward);
|
||||
|
||||
randServer.addContract(contract);
|
||||
}
|
||||
|
||||
export function generateContract(params) {
|
||||
// Problem Type
|
||||
let problemType;
|
||||
const problemTypes = Object.keys(CodingContractTypes);
|
||||
if (params.problemType != null && problemTypes.includes(params.problemType)) {
|
||||
problemType = params.problemType;
|
||||
} else {
|
||||
let randIndex = getRandomInt(0, problemTypes.length - 1);
|
||||
problemType = problemTypes[randIndex];
|
||||
}
|
||||
|
||||
// Reward Type - This is always random for now
|
||||
const reward = getRandomReward();
|
||||
|
||||
// Server
|
||||
let server;
|
||||
if (params.server != null) {
|
||||
server = GetServerByHostname(params.server);
|
||||
if (server == null) {
|
||||
server = AllServers[param.server];
|
||||
}
|
||||
if (server == null) {
|
||||
server = getRandomServer();
|
||||
}
|
||||
} else {
|
||||
server = getRandomServer();
|
||||
}
|
||||
|
||||
// Filename
|
||||
let fn;
|
||||
if (params.fn != null) {
|
||||
fn = params.fn;
|
||||
} else {
|
||||
fn = getRandomFilename(server, reward);
|
||||
}
|
||||
|
||||
let contract = new CodingContract(fn, problemType, reward);
|
||||
server.addContract(contract);
|
||||
}
|
||||
|
||||
// Ensures that a contract's reward type is valid
|
||||
function sanitizeRewardType(rewardType) {
|
||||
let type = rewardType; // Create copy
|
||||
|
||||
const factionsThatAllowHacking = Player.factions.filter((fac) => {
|
||||
try {
|
||||
return Factions[fac].getInfo().offerHackingWork;
|
||||
} catch (e) {
|
||||
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) {
|
||||
type = CodingContractRewardType.CompanyReputation;
|
||||
}
|
||||
if (type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) {
|
||||
type = CodingContractRewardType.CompanyReputation;
|
||||
}
|
||||
if (type === CodingContractRewardType.CompanyReputation && Player.companyName === "") {
|
||||
type = CodingContractRewardType.Money;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
function getRandomReward() {
|
||||
let reward = {};
|
||||
reward.type = getRandomInt(0, CodingContractRewardType.Money);
|
||||
reward.type = sanitizeRewardType(reward.type);
|
||||
|
||||
// Add additional information based on the reward type
|
||||
const factionsThatAllowHacking = Player.factions.filter((fac) => {
|
||||
try {
|
||||
return Factions[fac].getInfo().offerHackingWork;
|
||||
} catch (e) {
|
||||
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
switch (reward.type) {
|
||||
case CodingContractRewardType.FactionReputation:
|
||||
// Get a random faction that player is a part of. That
|
||||
// faction must allow hacking contracts
|
||||
var numFactions = factionsThatAllowHacking.length;
|
||||
var randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)];
|
||||
reward.name = randFaction;
|
||||
break;
|
||||
case CodingContractRewardType.CompanyReputation:
|
||||
if (Player.companyName !== "") {
|
||||
reward.name = Player.companyName;
|
||||
} else {
|
||||
reward.type = CodingContractRewardType.Money;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return reward;
|
||||
}
|
||||
|
||||
function getRandomServer() {
|
||||
const servers = Object.keys(AllServers);
|
||||
let randIndex = getRandomInt(0, servers.length - 1);
|
||||
let randServer = AllServers[servers[randIndex]];
|
||||
|
||||
// An infinite loop shouldn't ever happen, but to be safe we'll use
|
||||
// a for loop with a limited number of tries
|
||||
for (let i = 0; i < 200; ++i) {
|
||||
if (randServer.purchasedByPlayer === false) { break; }
|
||||
randIndex = getRandomInt(0, servers.length - 1);
|
||||
randServer = AllServers[servers[randIndex]];
|
||||
}
|
||||
|
||||
return randServer;
|
||||
}
|
||||
|
||||
function getRandomFilename(server, reward) {
|
||||
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||
|
||||
for (let i = 0; i < 1000; ++i) {
|
||||
if (server.contracts.filter((c) => {return c.fn === contractFn}).length <= 0) { break; }
|
||||
contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||
}
|
||||
|
||||
if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; }
|
||||
|
||||
return contractFn;
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
let CONSTANTS = {
|
||||
Version: "0.40.5",
|
||||
Version: "0.41.1",
|
||||
|
||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||
@ -502,38 +502,30 @@ let CONSTANTS = {
|
||||
|
||||
LatestUpdate:
|
||||
`
|
||||
v0.41.0
|
||||
* WARNING: In NetscriptJS, defining a function called print() is no longer possible
|
||||
* Gang Mechanic Changes (BitNode-2):
|
||||
*** Added a Gang Netscript API
|
||||
*** Added new 'ascension' mechanic for Gang Members
|
||||
*** The first three gang members are now 'free' (can be recruited instantly)
|
||||
*** Maximum number of increased Gang Members increased from 20 to 30
|
||||
*** Changed the formula for calculating respect needed to recruit the next gang member
|
||||
*** Added a new category of upgrades for Gang Members: Augmentations
|
||||
*** Non-Augmentation Gang member upgrades are now significantly weaker
|
||||
*** Reputation for your Gang faction can no longer be gained through Infiltration
|
||||
*** Re-worked the territory 'warfare' mechanic so that player can choose when to engage in it
|
||||
*** Gang Members can now be killed during territory 'warfare'
|
||||
*** Changed BitNode-2 Multipliers to make hacking slightly less profitable
|
||||
*** Gang Member Equipment + Upgrades now get cheaper as your gang grows in power and respect
|
||||
*** The effects of Source-File 2 are now slightly more powerful
|
||||
* RAM Cost of accessing the global document object lowered from 100 GB to 25 GB
|
||||
* RAM Cost to use Singularity Functions outside of BitNode-4 lowered by 75%. They now only cost twice as much as they do in BitNode-4
|
||||
* b1t_flum3.exe now takes significantly less time to create
|
||||
* Crimes commited through Singularity function no longer give half money/exp
|
||||
* Improved number formatting for Player 'work' actions (including crimes, etc.). These numbers should also adhere to locale settings now (by Kline-)
|
||||
* The order that Augmentations are listed in (when purchasing from Faction and viewing your Augmentations) is now saved and persists when choosing different orders
|
||||
* getCharacterInformation() Singularity function now returns multiplier information (from Augmentations/Source Files)
|
||||
* Bug Fix: Calling print() in NetscriptJS no longer brings up the print dialog
|
||||
* Bug Fix: Fixed a bug that sometimes caused a blank black screen when destroying/resetting/switching BitNodes
|
||||
* Bug Fix: Netscript calls that throw errors will now no longer cause the 'concurrent calls' error if they are caught in the script. i.e. try/catch should now work properly in scripts
|
||||
* Bug Fix: Fixed a bug where sometimes the NeuroFlux Governor Augmentation level would be incorrectly calculated when the game was loaded
|
||||
* Bug Fix: Fixed a bug where calling the scp() Netscript function with invalid hostname/ips would throw an unclear error message
|
||||
* Bug Fix: Bladeburner API function getActionCountRemaining() should now work properly for BlackOps
|
||||
* Bug Fix: Black Ops can no longer be attempted out-of-order or without the required rank via Bladeburner API
|
||||
* Bug Fix: Dynamic RAM Calculation now properly accounts for number of threads
|
||||
* RAM cost for basic Netscript functions added to documentation (by CBJamo)
|
||||
v0.41.1
|
||||
* IMPORTANT - Netscript Changes:
|
||||
** purchaseTor() now returns true if you already have a TOR router (it used to return false)
|
||||
** getPurchasedServerCost() now returns Infinity if the specified RAM is an invalid amount or is greater than the max amount of RAM (2 ^ 20 GB)
|
||||
** Added purchase4SMarketData() and purchase4SMarketDataTixApi() functions
|
||||
** getScriptLogs() now takes in optional arguments that let you get the logs of another script
|
||||
|
||||
* Stock Market changes:
|
||||
** Stocks now have "maximum prices". These are hidden from the player
|
||||
** If a stock reaches its "maximum price", it will most likely drop in value (although it might still rise)
|
||||
** Each stock has its own, unique maximum price
|
||||
** Maximum price for each stock are randomly generated and change during each 'reset'
|
||||
** Stock Market cycles are now accumulated/stored, much like it is for Gangs and Bladeburners
|
||||
** Accumulated/stored cycles cause stock prices to update up to 50% faster (from every 6 seconds to 4 seconds)
|
||||
*** This means that after coming back from being offline, stock prices will update faster to make up for offline time
|
||||
|
||||
* Decreased the Hacking Level multiplier for BitNodes 6 and 7 to 0.4 (from 0.5)
|
||||
* Bladeburner console history is now saved and persists when switching screens or closing/reopening the game
|
||||
* In Bladeburner, if your stamina reaches 0 your current action will be cancelled
|
||||
* b1t_flum3.exe is no longer removed from your home computer upon reset
|
||||
* Added main menu link for the Stock Market (once you've purchased an account)
|
||||
* Job main menu link only appears if you actually have a job
|
||||
* Bug Fix: After installing Augs, the "Portfolio Mode" button on the Stock Market page should be properly reset
|
||||
* Bug Fix: bladeburner.getActionCountRemaining()'s return value is now rounded down (by Kline-)
|
||||
`
|
||||
|
||||
}
|
||||
|
118
src/DevMenu.js
118
src/DevMenu.js
@ -1,13 +1,19 @@
|
||||
import {AugmentationNames} from "./Augmentations"
|
||||
import {Programs} from "./CreateProgram"
|
||||
import {Factions} from "./Faction";
|
||||
import {Player} from "./Player";
|
||||
import {AllServers} from "./Server";
|
||||
import {hackWorldDaemon} from "./RedPill";
|
||||
import {Terminal} from "./Terminal";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
import {AugmentationNames} from "./Augmentations";
|
||||
import {generateRandomContract} from "./CodingContractGenerator";
|
||||
import {Programs} from "./CreateProgram";
|
||||
import {Factions} from "./Faction";
|
||||
import {Player} from "./Player";
|
||||
import {AllServers} from "./Server";
|
||||
import {hackWorldDaemon} from "./RedPill";
|
||||
import {StockMarket,
|
||||
SymbolToStockMap} from "./StockMarket";
|
||||
import {Stock} from "./Stock";
|
||||
import {Terminal} from "./Terminal";
|
||||
import {numeralWrapper} from "./ui/numeralFormat";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox";
|
||||
import {exceptionAlert} from "../utils/helpers/exceptionAlert";
|
||||
import {createElement} from "../utils/uiHelpers/createElement";
|
||||
import {removeElementById} from "../utils/uiHelpers/removeElementById";
|
||||
|
||||
const devMenuContainerId = "dev-menu-container";
|
||||
|
||||
@ -60,7 +66,7 @@ export function createDevMenu() {
|
||||
},
|
||||
innerText: "Destroy Current BitNode",
|
||||
tooltip: "Will grant Source-File for the BitNode",
|
||||
})
|
||||
});
|
||||
|
||||
// Experience / stats
|
||||
const statsHeader = createElement("h2", {
|
||||
@ -321,6 +327,7 @@ export function createDevMenu() {
|
||||
|
||||
const bladeburnerGainRankInput = createElement("input", {
|
||||
class: "text-input",
|
||||
margin: "5px",
|
||||
placeholder: "Rank to gain (or negative to lose rank)",
|
||||
type: "number",
|
||||
});
|
||||
@ -343,6 +350,7 @@ export function createDevMenu() {
|
||||
|
||||
const gangStoredCyclesInput = createElement("input", {
|
||||
class: "text-input",
|
||||
margin: "5px",
|
||||
placeholder: "# Cycles to add",
|
||||
type: "number",
|
||||
});
|
||||
@ -358,7 +366,85 @@ export function createDevMenu() {
|
||||
}
|
||||
},
|
||||
innerText: "Add cycles to Gang mechanic",
|
||||
})
|
||||
});
|
||||
|
||||
// Coding Contracts
|
||||
const contractsHeader = createElement("h2", {innerText: "Coding Contracts"});
|
||||
|
||||
const generateRandomContractBtn = createElement("button", {
|
||||
class: "std-button",
|
||||
clickListener: () => {
|
||||
generateRandomContract();
|
||||
},
|
||||
innerText: "Generate Random Contract",
|
||||
});
|
||||
|
||||
// Stock Market
|
||||
const stockmarketHeader = createElement("h2", {innerText: "Stock Market"});
|
||||
|
||||
const stockInput = createElement("input", {
|
||||
class: "text-input",
|
||||
display: "block",
|
||||
placeholder: "Stock symbol(s), or 'all'",
|
||||
});
|
||||
|
||||
function processStocks(cb) {
|
||||
const input = stockInput.value.toString().replace(/\s/g, '');
|
||||
|
||||
// Empty input, or "all", will process all stocks
|
||||
if (input === "" || input.toLowerCase() === "all") {
|
||||
for (const name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
const stock = StockMarket[name];
|
||||
if (stock instanceof Stock) {
|
||||
cb(stock);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const stockSymbols = input.split(",");
|
||||
for (let i = 0; i < stockSymbols.length; ++i) {
|
||||
const stock = SymbolToStockMap[stockSymbols];
|
||||
if (stock instanceof Stock) {
|
||||
cb(stock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const stockPriceChangeInput = createElement("input", {
|
||||
class: "text-input",
|
||||
margin: "5px",
|
||||
placeholder: "Price to change stock(s) to",
|
||||
type: "number",
|
||||
});
|
||||
|
||||
const stockPriceChangeBtn = createElement("button", {
|
||||
class: "std-button",
|
||||
clickListener: () => {
|
||||
const price = parseInt(stockPriceChangeInput.value);
|
||||
if (isNaN(price)) { return; }
|
||||
|
||||
processStocks((stock) => {
|
||||
stock.price = price;
|
||||
});
|
||||
dialogBoxCreate(`Stock Prices changed to ${price}`);
|
||||
},
|
||||
innerText: "Change Stock Price(s)",
|
||||
});
|
||||
|
||||
const stockViewPriceCapBtn = createElement("button", {
|
||||
class: "std-button",
|
||||
clickListener: () => {
|
||||
let text = "";
|
||||
processStocks((stock) => {
|
||||
text += `${stock.symbol}: ${numeralWrapper.format(stock.cap, '$0.000a')}<br>`;
|
||||
});
|
||||
dialogBoxCreate(text);
|
||||
},
|
||||
innerText: "View Stock Price Caps",
|
||||
});
|
||||
|
||||
// Add everything to container, then append to main menu
|
||||
const devMenuContainer = createElement("div", {
|
||||
@ -419,6 +505,14 @@ export function createDevMenu() {
|
||||
devMenuContainer.appendChild(gangStoredCyclesInput);
|
||||
devMenuContainer.appendChild(gangAddStoredCycles);
|
||||
devMenuContainer.appendChild(createElement("br"));
|
||||
devMenuContainer.appendChild(contractsHeader);
|
||||
devMenuContainer.appendChild(generateRandomContractBtn);
|
||||
devMenuContainer.appendChild(stockmarketHeader);
|
||||
devMenuContainer.appendChild(stockInput);
|
||||
devMenuContainer.appendChild(stockPriceChangeInput);
|
||||
devMenuContainer.appendChild(stockPriceChangeBtn);
|
||||
devMenuContainer.appendChild(createElement("br"));
|
||||
devMenuContainer.appendChild(stockViewPriceCapBtn);
|
||||
|
||||
const entireGameContainer = document.getElementById("entire-game-container");
|
||||
if (entireGameContainer == null) {
|
||||
|
@ -394,7 +394,6 @@ function displayFactionContent(factionName) {
|
||||
var hacking = false;
|
||||
if (factionName === "NiteSec" || factionName === "The Black Hand") {hacking = true;}
|
||||
Player.startGang(factionName, hacking);
|
||||
document.getElementById("gang-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
Engine.loadGangContent();
|
||||
|
@ -31,7 +31,7 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox";
|
||||
|
||||
// Constants
|
||||
const GangRespectToReputationRatio = 2; // Respect is divided by this to get rep gain
|
||||
const GangRespectToReputationRatio = 5; // Respect is divided by this to get rep gain
|
||||
const MaximumGangMembers = 30;
|
||||
const GangRecruitCostMultiplier = 2;
|
||||
const CyclesPerTerritoryAndPowerUpdate = 100;
|
||||
@ -273,7 +273,7 @@ Gang.prototype.processTerritoryAndPowerGains = function(numCycles=1) {
|
||||
// Multiplicative gain (50% chance)
|
||||
// This is capped per cycle, to prevent it from getting out of control
|
||||
const multiplicativeGain = AllGangs[name].power * 0.008;
|
||||
AllGangs[name].power += Math.min(1, multiplicativeGain);
|
||||
AllGangs[name].power += Math.min(0.9, multiplicativeGain);
|
||||
} else {
|
||||
// Additive gain (50% chance)
|
||||
const additiveGain = 0.5 * gainRoll * AllGangs[name].territory;
|
||||
@ -357,6 +357,7 @@ Gang.prototype.getRespectNeededToRecruitMember = function() {
|
||||
}
|
||||
|
||||
Gang.prototype.recruitMember = function(name) {
|
||||
name = String(name);
|
||||
if (name === "" || !this.canRecruitMember()) { return false; }
|
||||
|
||||
// Check for already-existing names
|
||||
@ -840,7 +841,7 @@ function GangMemberTask(name="", desc="", isHacking=false, isCombat=false,
|
||||
this.chaWeight = params.chaWeight ? params.chaWeight : 0;
|
||||
|
||||
if (Math.round(this.hackWeight + this.strWeight + this.defWeight + this.dexWeight + this.agiWeight + this.chaWeight) != 100) {
|
||||
throw new Error(`GangMemberTask ${this.name} weights do not add up to 100`);
|
||||
console.error(`GangMemberTask ${this.name} weights do not add up to 100`);
|
||||
}
|
||||
|
||||
// 1 - 100
|
||||
|
@ -1953,7 +1953,6 @@ function initLocationButtons() {
|
||||
name:companyName,
|
||||
});
|
||||
displayLocationContent();
|
||||
document.getElementById("corporation-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
dialogBoxCreate("Congratulations! You just started your own corporation. You can visit " +
|
||||
@ -1983,7 +1982,6 @@ function initLocationButtons() {
|
||||
Player.bladeburner = new Bladeburner({new:true});
|
||||
dialogBoxCreate("You have been accepted into the Bladeburner division!");
|
||||
displayLocationContent();
|
||||
document.getElementById("bladeburner-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
} else {
|
||||
|
@ -35,10 +35,9 @@ import {Server, getServer, AddToAllServers,
|
||||
import {Settings} from "./Settings";
|
||||
import {SpecialServerIps} from "./SpecialServerIps";
|
||||
import {Stock} from "./Stock";
|
||||
import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
||||
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
||||
sellStock, updateStockPrices, displayStockMarketContent,
|
||||
updateStockTicker, updateStockPlayerPosition,
|
||||
import {StockMarket, StockSymbols, SymbolToStockMap,
|
||||
initStockMarket, initSymbolToStockMap, buyStock,
|
||||
sellStock, updateStockPlayerPosition,
|
||||
shortStock, sellShort, OrderTypes,
|
||||
PositionTypes, placeOrder, cancelOrder} from "./StockMarket";
|
||||
import {post} from "./ui/postToTerminal";
|
||||
@ -107,8 +106,16 @@ var possibleLogs = {
|
||||
getServerGrowth: true,
|
||||
getServerNumPortsRequired: true,
|
||||
getServerRam: true,
|
||||
|
||||
// TIX API
|
||||
buyStock: true,
|
||||
sellStock: true,
|
||||
shortStock: true,
|
||||
sellShort: true,
|
||||
purchase4SMarketData: true,
|
||||
purchase4SMarketDataTixApi: true,
|
||||
|
||||
// Singularity Functions
|
||||
purchaseServer: true,
|
||||
deleteServer: true,
|
||||
universityCourse: true,
|
||||
@ -125,12 +132,18 @@ var possibleLogs = {
|
||||
donateToFaction: true,
|
||||
createProgram: true,
|
||||
commitCrime: true,
|
||||
shortStock: true,
|
||||
sellShort: true,
|
||||
|
||||
// Bladeburner API
|
||||
startAction: true,
|
||||
upgradeSkill: true,
|
||||
setTeamSize: true,
|
||||
joinBladeburnerFaction: true,
|
||||
|
||||
// Gang API
|
||||
recruitMember: true,
|
||||
setMemberTask: true,
|
||||
purchaseEquipment: true,
|
||||
setTerritoryWarfare: true,
|
||||
}
|
||||
|
||||
//Used to check and set flags for every Source File, despite the name of the function
|
||||
@ -535,8 +548,30 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
return workerScript.disableLogs[fn] ? false : true;
|
||||
},
|
||||
getScriptLogs : function() {
|
||||
getScriptLogs : function(fn, ip) {
|
||||
if (workerScript.checkingRam) {return 0;}
|
||||
|
||||
if (fn != null && typeof fn === 'string') {
|
||||
// Get Logs of another script
|
||||
if (ip == null) { ip = workerScript.serverIp; }
|
||||
const server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.log(`getScriptLogs() failed. Invalid IP or hostname passed in: ${ip}`);
|
||||
throw makeRuntimeRejectMsg(workerScript, `getScriptLogs() failed. Invalid IP or hostname passed in: ${ip}`);
|
||||
}
|
||||
|
||||
let argsForTarget = [];
|
||||
for (let i = 2; i < arguments.length; ++i) {
|
||||
argsForTarget.push(arguments[i]);
|
||||
}
|
||||
const runningScriptObj = findRunningScript(fn, argsForTarget, server);
|
||||
if (runningScriptObj == null) {
|
||||
workerScript.scriptRef.log(`getScriptLogs() failed. No such script ${fn} on ${server.hostname} with args: ${arrayToString(argsForTarget)}`);
|
||||
return "";
|
||||
}
|
||||
return runningScriptObj.logs.slice();
|
||||
}
|
||||
|
||||
return workerScript.scriptRef.logs.slice();
|
||||
},
|
||||
nuke : function(ip){
|
||||
@ -790,7 +825,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
NetscriptFunctions(workerScript).exit();
|
||||
},
|
||||
kill : function(filename,ip) {
|
||||
kill : function(filename, ip) {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("kill", CONSTANTS.ScriptKillRamCost);
|
||||
}
|
||||
@ -1686,6 +1721,68 @@ function NetscriptFunctions(workerScript) {
|
||||
stock.b ? forecast += stock.otlkMag : forecast -= stock.otlkMag;
|
||||
return forecast / 100; //Convert from percentage to decimal
|
||||
},
|
||||
purchase4SMarketData : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("purchase4SMarketData", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketData()");
|
||||
}
|
||||
|
||||
if (Player.has4SData) {
|
||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||
workerScript.log("Already purchased 4S Market Data");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Player.money.lt(CONSTANTS.MarketData4SCost)) {
|
||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||
workerScript.log("Failed to purchase 4S Market Data - Not enough money");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.has4SData = true;
|
||||
Player.loseMoney(CONSTANTS.MarketData4SCost);
|
||||
if (workerScript.shouldLog("purchase4SMarketData")) {
|
||||
workerScript.log("Purchased 4S Market Data");
|
||||
}
|
||||
return true;
|
||||
},
|
||||
purchase4SMarketDataTixApi : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
}
|
||||
updateDynamicRam("purchase4SMarketDataTixApi", CONSTANTS.ScriptBuySellStockRamCost);
|
||||
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use purchase4SMarketDataTixApi()");
|
||||
}
|
||||
|
||||
if (Player.has4SDataTixApi) {
|
||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||
workerScript.log("Already purchased 4S Market Data TIX API");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Player.money.lt(CONSTANTS.MarketDataTixApi4SCost)) {
|
||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||
workerScript.log("Failed to purchase 4S Market Data TIX API - Not enough money");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Player.has4SDataTixApi = true;
|
||||
Player.loseMoney(CONSTANTS.MarketDataTixApi4SCost);
|
||||
if (workerScript.shouldLog("purchase4SMarketDataTixApi")) {
|
||||
workerScript.log("Purchased 4S Market Data TIX API");
|
||||
}
|
||||
return true;
|
||||
},
|
||||
getPurchasedServerLimit : function() {
|
||||
if (workerScript.checkingRam) {
|
||||
return updateStaticRam("getPurchasedServerLimit", CONSTANTS.ScriptGetPurchasedServerLimit);
|
||||
@ -1713,7 +1810,7 @@ function NetscriptFunctions(workerScript) {
|
||||
cost = getPurchaseServerRamCostGuard(ram);
|
||||
} catch (e) {
|
||||
workerScript.scriptRef.log("ERROR: 'getPurchasedServerCost()' " + e.message);
|
||||
return "";
|
||||
return Infinity;
|
||||
}
|
||||
|
||||
return cost;
|
||||
@ -3647,7 +3744,7 @@ function NetscriptFunctions(workerScript) {
|
||||
strength: member.str,
|
||||
strengthEquipMult: member.str_mult,
|
||||
strengthAscensionMult: member.str_asc_mult,
|
||||
task: member.task.name,
|
||||
task: member.task,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3679,7 +3776,16 @@ function NetscriptFunctions(workerScript) {
|
||||
nsGang.checkGangApiAccess(workerScript, "recruitMember");
|
||||
|
||||
try {
|
||||
return Player.gang.recruitMember(name);
|
||||
const res = Player.gang.recruitMember(name);
|
||||
if (workerScript.shouldLog("recruitMember")) {
|
||||
if (res) {
|
||||
workerScript.log(`Successfully recruited Gang Member ${name}`);
|
||||
} else {
|
||||
workerScript.log(`Failed to recruit Gang Member ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
} catch(e) {
|
||||
throw makeRuntimeRejectMsg(workerScript, nsGang.unknownGangApiExceptionMessage("recruitMember", e));
|
||||
}
|
||||
@ -3709,7 +3815,16 @@ function NetscriptFunctions(workerScript) {
|
||||
try {
|
||||
for (const member of Player.gang.members) {
|
||||
if (member.name === memberName) {
|
||||
return member.assignToTask(taskName);
|
||||
const res = member.assignToTask(taskName);
|
||||
if (workerScript.shouldLog("setMemberTask")) {
|
||||
if (res) {
|
||||
workerScript.log(`Successfully assigned Gang Member ${memberName} to ${taskName} task`);
|
||||
} else {
|
||||
workerScript.log(`Failed to assign Gang Member ${memberName} to ${taskName} task. ${memberName} is now Unassigned`);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3755,7 +3870,16 @@ function NetscriptFunctions(workerScript) {
|
||||
try {
|
||||
for (const member in Player.gang.members) {
|
||||
if (member.name === memberName) {
|
||||
return member.buyUpgrade(equipName, Player, Player.gang);
|
||||
const res = member.buyUpgrade(equipName, Player, Player.gang);
|
||||
if (workerScript.shouldLog("purchaseEquipment")) {
|
||||
if (res) {
|
||||
workerScript.log(`Purchased ${equipName} for Gang member ${memberName}`);
|
||||
} else {
|
||||
workerScript.log(`Failed to purchase ${equipName} for Gang member ${memberName}`);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3779,7 +3903,7 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
}
|
||||
|
||||
workerScript.log(`Invalid argument passed to gang.ascendMember(). No gang member could be found with name ${memberName}`);
|
||||
workerScript.log(`Invalid argument passed to gang.ascendMember(). No gang member could be found with name ${name}`);
|
||||
return false;
|
||||
} catch(e) {
|
||||
throw makeRuntimeRejectMsg(workerScript, nsGang.unknownGangApiExceptionMessage("ascendMember", e));
|
||||
@ -3795,8 +3919,14 @@ function NetscriptFunctions(workerScript) {
|
||||
try {
|
||||
if (engage) {
|
||||
Player.gang.territoryWarfareEngaged = true;
|
||||
if (workerScript.shouldLog("setTerritoryWarfare")) {
|
||||
workerScript.log("Engaging in Gang Territory Warfare");
|
||||
}
|
||||
} else {
|
||||
Player.gang.territoryWarfareEngaged = false;
|
||||
if (workerScript.shouldLog("setTerritoryWarfare")) {
|
||||
workerScript.log("Disengaging in Gang Territory Warfare");
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
throw makeRuntimeRejectMsg(workerScript, nsGang.unknownGangApiExceptionMessage("setTerritoryWarfare", e));
|
||||
|
@ -73,7 +73,7 @@ export function _getScriptUrls(script, scripts, seen) {
|
||||
// import {foo} from "blob://<uuid>"
|
||||
//
|
||||
// Where the blob URL contains the script content.
|
||||
let transformedCode = script.code.replace(/((?:from|import)\s+(?:'|"))([^'"]+)('|";)/g,
|
||||
let transformedCode = script.code.replace(/((?:from|import)\s+(?:'|"))(?:\.\/)?([^'"]+)('|";)/g,
|
||||
(unmodified, prefix, filename, suffix) => {
|
||||
const isAllowedImport = scripts.some(s => s.filename == filename);
|
||||
if (!isAllowedImport) return unmodified;
|
||||
|
@ -191,7 +191,6 @@ function PlayerObject() {
|
||||
//Flags for determining whether certain "thresholds" have been achieved
|
||||
this.firstFacInvRecvd = false;
|
||||
this.firstAugPurchased = false;
|
||||
this.firstJobRecvd = false;
|
||||
this.firstTimeTraveled = false;
|
||||
this.firstProgramAvailable = false;
|
||||
|
||||
@ -1687,12 +1686,8 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
|
||||
this.companyName = company.companyName;
|
||||
this.companyPosition = pos;
|
||||
|
||||
if (this.firstJobRecvd === false) {
|
||||
this.firstJobRecvd = true;
|
||||
document.getElementById("job-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
}
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
|
||||
if (leaveCompany) {
|
||||
if (sing) {return true;}
|
||||
@ -1797,14 +1792,10 @@ PlayerObject.prototype.applyForAgentJob = function(sing=false) {
|
||||
PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
|
||||
var company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions.Employee)) {
|
||||
if (this.firstJobRecvd === false) {
|
||||
this.firstJobRecvd = true;
|
||||
document.getElementById("job-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
}
|
||||
this.companyName = company.companyName;
|
||||
this.companyPosition = CompanyPositions.Employee;
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
if (sing) {return true;}
|
||||
dialogBoxCreate("Congratulations, you are now employed at " + this.companyName);
|
||||
Engine.loadLocationContent();
|
||||
@ -1817,14 +1808,10 @@ PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
|
||||
PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
|
||||
var company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions.PartTimeEmployee)) {
|
||||
if (this.firstJobRecvd === false) {
|
||||
this.firstJobRecvd = true;
|
||||
document.getElementById("job-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
}
|
||||
this.companyName = company.companyName;
|
||||
this.companyPosition = CompanyPositions.PartTimeEmployee;
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
if (sing) {return true;}
|
||||
dialogBoxCreate("Congratulations, you are now employed part-time at " + this.companyName);
|
||||
Engine.loadLocationContent();
|
||||
@ -1837,14 +1824,10 @@ PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
|
||||
PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
|
||||
var company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions.Waiter)) {
|
||||
if (this.firstJobRecvd === false) {
|
||||
this.firstJobRecvd = true;
|
||||
document.getElementById("job-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
}
|
||||
this.companyName = company.companyName;
|
||||
this.companyPosition = CompanyPositions.Waiter;
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
if (sing) {return true;}
|
||||
dialogBoxCreate("Congratulations, you are now employed as a waiter at " + this.companyName);
|
||||
Engine.loadLocationContent();
|
||||
@ -1857,14 +1840,10 @@ PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
|
||||
PlayerObject.prototype.applyForPartTimeWaiterJob = function(sing=false) {
|
||||
var company = Companies[this.location]; //Company being applied to
|
||||
if (this.isQualified(company, CompanyPositions.PartTimeWaiter)) {
|
||||
if (this.firstJobRecvd === false) {
|
||||
this.firstJobRecvd = true;
|
||||
document.getElementById("job-tab").style.display = "list-item";
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
}
|
||||
this.companyName = company.companyName;
|
||||
this.companyPosition = CompanyPositions.PartTimeWaiter;
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
if (sing) {return true;}
|
||||
dialogBoxCreate("Congratulations, you are now employed as a part-time waiter at " + this.companyName);
|
||||
Engine.loadLocationContent();
|
||||
|
@ -148,6 +148,10 @@ function prestigeAugmentation() {
|
||||
Terminal.resetTerminalInput();
|
||||
Engine.loadTerminalContent();
|
||||
|
||||
// Refresh Main Menu (the 'World' menu, specifically)
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
|
||||
//Red Pill
|
||||
if (augmentationExists(AugmentationNames.TheRedPill) &&
|
||||
Augmentations[AugmentationNames.TheRedPill].owned) {
|
||||
@ -319,6 +323,10 @@ function prestigeSourceFile() {
|
||||
Player.corporation = null;
|
||||
Player.bladeburner = null;
|
||||
|
||||
// Refresh Main Menu (the 'World' menu, specifically)
|
||||
document.getElementById("world-menu-header").click();
|
||||
document.getElementById("world-menu-header").click();
|
||||
|
||||
//Gain int exp
|
||||
Player.gainIntelligenceExp(5);
|
||||
}
|
||||
|
@ -198,16 +198,12 @@ function loadGame(saveString) {
|
||||
//that everything should be available
|
||||
Player.firstFacInvRecvd = true;
|
||||
Player.firstAugPurchased = true;
|
||||
Player.firstJobRecvd = true;
|
||||
Player.firstTimeTraveled = true;
|
||||
Player.firstProgramAvailable = true;
|
||||
} else {
|
||||
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
|
||||
Player.firstFacInvRecvd = true;
|
||||
}
|
||||
if (Player.companyName !== "" || Player.companyPosition !== "") {
|
||||
Player.firstJobRecvd = true;
|
||||
}
|
||||
if (Player.hacking_skill >= 25) {
|
||||
Player.firstScriptAvailable = true;
|
||||
}
|
||||
@ -417,16 +413,12 @@ function loadImportedGame(saveObj, saveString) {
|
||||
//that everything should be available
|
||||
Player.firstFacInvRecvd = true;
|
||||
Player.firstAugPurchased = true;
|
||||
Player.firstJobRecvd = true;
|
||||
Player.firstTimeTraveled = true;
|
||||
Player.firstProgramAvailable = true;
|
||||
} else {
|
||||
if (Player.factions.length > 0 || Player.factionInvitations.length > 0) {
|
||||
Player.firstFacInvRecvd = true;
|
||||
}
|
||||
if (Player.companyName !== "" || Player.companyPosition !== "") {
|
||||
Player.firstJobRecvd = true;
|
||||
}
|
||||
if (Player.hacking_skill >= 25) {
|
||||
Player.firstScriptAvailable = true;
|
||||
}
|
||||
|
@ -344,12 +344,15 @@ function processSingleServerGrowth(server, numCycles) {
|
||||
}
|
||||
|
||||
function prestigeHomeComputer(homeComp) {
|
||||
const hasBitflume = homeComp.programs.includes(Programs.BitFlume.name);
|
||||
|
||||
homeComp.programs.length = 0; //Remove programs
|
||||
homeComp.runningScripts = [];
|
||||
homeComp.serversOnNetwork = [];
|
||||
homeComp.isConnectedTo = true;
|
||||
homeComp.ramUsed = 0;
|
||||
homeComp.programs.push(Programs.NukeProgram.name);
|
||||
if (hasBitflume) { homeComp.programs.push(Programs.BitFlume.name); }
|
||||
|
||||
//Update RAM usage on all scripts
|
||||
homeComp.scripts.forEach(function(script) {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
|
||||
import { getRandomInt } from "../utils/helpers/getRandomInt";
|
||||
|
||||
/**
|
||||
* Represents the valuation of a company in the World Stock Exchange.
|
||||
@ -16,6 +17,11 @@ export class Stock {
|
||||
*/
|
||||
b: boolean;
|
||||
|
||||
/**
|
||||
* Maximum price of a stock (per share)
|
||||
*/
|
||||
readonly cap: number;
|
||||
|
||||
/**
|
||||
* Maximum volatility
|
||||
*/
|
||||
@ -83,6 +89,7 @@ export class Stock {
|
||||
this.mv = mv;
|
||||
this.b = b;
|
||||
this.otlkMag = otlkMag;
|
||||
this.cap = getRandomInt(initPrice * 1e3, initPrice * 25e3);
|
||||
|
||||
this.posTxtEl = null;
|
||||
}
|
||||
|
@ -23,8 +23,6 @@ import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoTxtInpBoxGetInput, yesNoBoxClose,
|
||||
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox";
|
||||
|
||||
let StockPriceCap = 1e9; //Put a limit on how high a price can go
|
||||
|
||||
var OrderTypes = {
|
||||
LimitBuy: "Limit Buy Order",
|
||||
LimitSell: "Limit Sell Order",
|
||||
@ -227,136 +225,138 @@ function initStockMarket() {
|
||||
}
|
||||
}
|
||||
|
||||
const randInt = getRandomInt;
|
||||
|
||||
var ecorp = Locations.AevumECorp;
|
||||
var ecorpStk = new Stock(ecorp, StockSymbols[ecorp], getRandomInt(40, 50)/100, true, 19, getRandomInt(17e3, 28e3));
|
||||
var ecorpStk = new Stock(ecorp, StockSymbols[ecorp], randInt(40, 50) / 100, true, 19, randInt(17e3, 28e3));
|
||||
StockMarket[ecorp] = ecorpStk;
|
||||
|
||||
var megacorp = Locations.Sector12MegaCorp;
|
||||
var megacorpStk = new Stock(megacorp, StockSymbols[megacorp], getRandomInt(40,50)/100, true, 19, getRandomInt(24e3, 34e3));
|
||||
var megacorpStk = new Stock(megacorp, StockSymbols[megacorp], randInt(40,50)/100, true, 19, randInt(24e3, 34e3));
|
||||
StockMarket[megacorp] = megacorpStk;
|
||||
|
||||
var blade = Locations.Sector12BladeIndustries;
|
||||
var bladeStk = new Stock(blade, StockSymbols[blade], getRandomInt(70, 80)/100, true, 13, getRandomInt(12e3, 25e3));
|
||||
var bladeStk = new Stock(blade, StockSymbols[blade], randInt(70, 80)/100, true, 13, randInt(12e3, 25e3));
|
||||
StockMarket[blade] = bladeStk;
|
||||
|
||||
var clarke = Locations.AevumClarkeIncorporated;
|
||||
var clarkeStk = new Stock(clarke, StockSymbols[clarke], getRandomInt(65, 75)/100, true, 12, getRandomInt(10e3, 25e3));
|
||||
var clarkeStk = new Stock(clarke, StockSymbols[clarke], randInt(65, 75)/100, true, 12, randInt(10e3, 25e3));
|
||||
StockMarket[clarke] = clarkeStk;
|
||||
|
||||
var omnitek = Locations.VolhavenOmniTekIncorporated;
|
||||
var omnitekStk = new Stock(omnitek, StockSymbols[omnitek], getRandomInt(60, 70)/100, true, 12, getRandomInt(32e3, 43e3));
|
||||
var omnitekStk = new Stock(omnitek, StockSymbols[omnitek], randInt(60, 70)/100, true, 12, randInt(32e3, 43e3));
|
||||
StockMarket[omnitek] = omnitekStk;
|
||||
|
||||
var foursigma = Locations.Sector12FourSigma;
|
||||
var foursigmaStk = new Stock(foursigma, StockSymbols[foursigma], getRandomInt(100, 110)/100, true, 17, getRandomInt(50e3, 80e3));
|
||||
var foursigmaStk = new Stock(foursigma, StockSymbols[foursigma], randInt(100, 110)/100, true, 17, randInt(50e3, 80e3));
|
||||
StockMarket[foursigma] = foursigmaStk;
|
||||
|
||||
var kuaigong = Locations.ChongqingKuaiGongInternational;
|
||||
var kuaigongStk = new Stock(kuaigong, StockSymbols[kuaigong], getRandomInt(75, 85)/100, true, 10, getRandomInt(16e3, 28e3));
|
||||
var kuaigongStk = new Stock(kuaigong, StockSymbols[kuaigong], randInt(75, 85)/100, true, 10, randInt(16e3, 28e3));
|
||||
StockMarket[kuaigong] = kuaigongStk;
|
||||
|
||||
var fulcrum = Locations.AevumFulcrumTechnologies;
|
||||
var fulcrumStk = new Stock(fulcrum, StockSymbols[fulcrum], getRandomInt(120, 130)/100, true, 16, getRandomInt(29e3, 36e3));
|
||||
var fulcrumStk = new Stock(fulcrum, StockSymbols[fulcrum], randInt(120, 130)/100, true, 16, randInt(29e3, 36e3));
|
||||
StockMarket[fulcrum] = fulcrumStk;
|
||||
|
||||
var storm = Locations.IshimaStormTechnologies;
|
||||
var stormStk = new Stock(storm, StockSymbols[storm], getRandomInt(80, 90)/100, true, 7, getRandomInt(20e3, 25e3));
|
||||
var stormStk = new Stock(storm, StockSymbols[storm], randInt(80, 90)/100, true, 7, randInt(20e3, 25e3));
|
||||
StockMarket[storm] = stormStk;
|
||||
|
||||
var defcomm = Locations.NewTokyoDefComm;
|
||||
var defcommStk = new Stock(defcomm, StockSymbols[defcomm], getRandomInt(60, 70)/100, true, 10, getRandomInt(6e3, 19e3));
|
||||
var defcommStk = new Stock(defcomm, StockSymbols[defcomm], randInt(60, 70)/100, true, 10, randInt(6e3, 19e3));
|
||||
StockMarket[defcomm] = defcommStk;
|
||||
|
||||
var helios = Locations.VolhavenHeliosLabs;
|
||||
var heliosStk = new Stock(helios, StockSymbols[helios], getRandomInt(55, 65)/100, true, 9, getRandomInt(10e3, 18e3));
|
||||
var heliosStk = new Stock(helios, StockSymbols[helios], randInt(55, 65)/100, true, 9, randInt(10e3, 18e3));
|
||||
StockMarket[helios] = heliosStk;
|
||||
|
||||
var vitalife = Locations.NewTokyoVitaLife;
|
||||
var vitalifeStk = new Stock(vitalife, StockSymbols[vitalife], getRandomInt(70, 80)/100, true, 7, getRandomInt(8e3, 14e3));
|
||||
var vitalifeStk = new Stock(vitalife, StockSymbols[vitalife], randInt(70, 80)/100, true, 7, randInt(8e3, 14e3));
|
||||
StockMarket[vitalife] = vitalifeStk;
|
||||
|
||||
var icarus = Locations.Sector12IcarusMicrosystems;
|
||||
var icarusStk = new Stock(icarus, StockSymbols[icarus], getRandomInt(60, 70)/100, true, 7.5, getRandomInt(12e3, 24e3));
|
||||
var icarusStk = new Stock(icarus, StockSymbols[icarus], randInt(60, 70)/100, true, 7.5, randInt(12e3, 24e3));
|
||||
StockMarket[icarus] = icarusStk;
|
||||
|
||||
var universalenergy = Locations.Sector12UniversalEnergy;
|
||||
var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], getRandomInt(50, 60)/100, true, 10, getRandomInt(16e3, 29e3));
|
||||
var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], randInt(50, 60)/100, true, 10, randInt(16e3, 29e3));
|
||||
StockMarket[universalenergy] = universalenergyStk;
|
||||
|
||||
var aerocorp = Locations.AevumAeroCorp;
|
||||
var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], getRandomInt(55, 65)/100, true, 6, getRandomInt(8e3, 17e3));
|
||||
var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], randInt(55, 65)/100, true, 6, randInt(8e3, 17e3));
|
||||
StockMarket[aerocorp] = aerocorpStk;
|
||||
|
||||
var omnia = Locations.VolhavenOmniaCybersystems;
|
||||
var omniaStk = new Stock(omnia, StockSymbols[omnia], getRandomInt(65, 75)/100, true, 4.5, getRandomInt(6e3, 15e3));
|
||||
var omniaStk = new Stock(omnia, StockSymbols[omnia], randInt(65, 75)/100, true, 4.5, randInt(6e3, 15e3));
|
||||
StockMarket[omnia] = omniaStk;
|
||||
|
||||
var solaris = Locations.ChongqingSolarisSpaceSystems;
|
||||
var solarisStk = new Stock(solaris, StockSymbols[solaris], getRandomInt(70, 80)/100, true, 8.5, getRandomInt(14e3, 28e3));
|
||||
var solarisStk = new Stock(solaris, StockSymbols[solaris], randInt(70, 80)/100, true, 8.5, randInt(14e3, 28e3));
|
||||
StockMarket[solaris] = solarisStk;
|
||||
|
||||
var globalpharm = Locations.NewTokyoGlobalPharmaceuticals;
|
||||
var globalpharmStk = new Stock(globalpharm, StockSymbols[globalpharm], getRandomInt(55, 65)/100, true, 10.5, getRandomInt(12e3, 30e3));
|
||||
var globalpharmStk = new Stock(globalpharm, StockSymbols[globalpharm], randInt(55, 65)/100, true, 10.5, randInt(12e3, 30e3));
|
||||
StockMarket[globalpharm] = globalpharmStk;
|
||||
|
||||
var nova = Locations.IshimaNovaMedical;
|
||||
var novaStk = new Stock(nova, StockSymbols[nova], getRandomInt(70, 80)/100, true, 5, getRandomInt(15e3, 27e3));
|
||||
var novaStk = new Stock(nova, StockSymbols[nova], randInt(70, 80)/100, true, 5, randInt(15e3, 27e3));
|
||||
StockMarket[nova] = novaStk;
|
||||
|
||||
var watchdog = Locations.AevumWatchdogSecurity;
|
||||
var watchdogStk = new Stock(watchdog, StockSymbols[watchdog], getRandomInt(240, 260)/100, true, 1.5, getRandomInt(4e3, 8.5e3));
|
||||
var watchdogStk = new Stock(watchdog, StockSymbols[watchdog], randInt(240, 260)/100, true, 1.5, randInt(4e3, 8.5e3));
|
||||
StockMarket[watchdog] = watchdogStk;
|
||||
|
||||
var lexocorp = Locations.VolhavenLexoCorp;
|
||||
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], getRandomInt(115, 135)/100, true, 6, getRandomInt(4.5e3, 8e3));
|
||||
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], randInt(115, 135)/100, true, 6, randInt(4.5e3, 8e3));
|
||||
StockMarket[lexocorp] = lexocorpStk;
|
||||
|
||||
var rho = Locations.AevumRhoConstruction;
|
||||
var rhoStk = new Stock(rho, StockSymbols[rho], getRandomInt(50, 70)/100, true, 1, getRandomInt(2e3, 7e3));
|
||||
var rhoStk = new Stock(rho, StockSymbols[rho], randInt(50, 70)/100, true, 1, randInt(2e3, 7e3));
|
||||
StockMarket[rho] = rhoStk;
|
||||
|
||||
var alpha = Locations.Sector12AlphaEnterprises;
|
||||
var alphaStk = new Stock(alpha, StockSymbols[alpha], getRandomInt(175, 205)/100, true, 10, getRandomInt(4e3, 8.5e3));
|
||||
var alphaStk = new Stock(alpha, StockSymbols[alpha], randInt(175, 205)/100, true, 10, randInt(4e3, 8.5e3));
|
||||
StockMarket[alpha] = alphaStk;
|
||||
|
||||
var syscore = Locations.VolhavenSysCoreSecurities;
|
||||
var syscoreStk = new Stock(syscore, StockSymbols[syscore], getRandomInt(150, 170)/100, true, 3, getRandomInt(3e3, 8e3));
|
||||
var syscoreStk = new Stock(syscore, StockSymbols[syscore], randInt(150, 170)/100, true, 3, randInt(3e3, 8e3));
|
||||
StockMarket[syscore] = syscoreStk;
|
||||
|
||||
var computek = Locations.VolhavenCompuTek;
|
||||
var computekStk = new Stock(computek, StockSymbols[computek], getRandomInt(80, 100)/100, true, 4, getRandomInt(1e3, 6e3));
|
||||
var computekStk = new Stock(computek, StockSymbols[computek], randInt(80, 100)/100, true, 4, randInt(1e3, 6e3));
|
||||
StockMarket[computek] = computekStk;
|
||||
|
||||
var netlink = Locations.AevumNetLinkTechnologies;
|
||||
var netlinkStk = new Stock(netlink, StockSymbols[netlink], getRandomInt(400, 430)/100, true, 1, getRandomInt(1e3, 5e3));
|
||||
var netlinkStk = new Stock(netlink, StockSymbols[netlink], randInt(400, 430)/100, true, 1, randInt(1e3, 5e3));
|
||||
StockMarket[netlink] = netlinkStk;
|
||||
|
||||
var omega = Locations.IshimaOmegaSoftware;
|
||||
var omegaStk = new Stock(omega, StockSymbols[omega], getRandomInt(90, 110)/100, true, 0.5, getRandomInt(1e3, 8e3));
|
||||
var omegaStk = new Stock(omega, StockSymbols[omega], randInt(90, 110)/100, true, 0.5, randInt(1e3, 8e3));
|
||||
StockMarket[omega] = omegaStk;
|
||||
|
||||
var fns = Locations.Sector12FoodNStuff;
|
||||
var fnsStk = new Stock(fns, StockSymbols[fns], getRandomInt(70, 80)/100, false, 1, getRandomInt(500, 4.5e3));
|
||||
var fnsStk = new Stock(fns, StockSymbols[fns], randInt(70, 80)/100, false, 1, randInt(500, 4.5e3));
|
||||
StockMarket[fns] = fnsStk;
|
||||
|
||||
var sigmacosm = "Sigma Cosmetics";
|
||||
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], getRandomInt(260, 300)/100, true, 0, getRandomInt(1.5e3, 3.5e3));
|
||||
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], randInt(260, 300)/100, true, 0, randInt(1.5e3, 3.5e3));
|
||||
StockMarket[sigmacosm] = sigmacosmStk;
|
||||
|
||||
var joesguns = "Joes Guns";
|
||||
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], getRandomInt(360, 400)/100, true, 1, getRandomInt(250, 1.5e3));
|
||||
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], randInt(360, 400)/100, true, 1, randInt(250, 1.5e3));
|
||||
StockMarket[joesguns] = joesgunsStk;
|
||||
|
||||
var catalyst = "Catalyst Ventures";
|
||||
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], getRandomInt(120, 175)/100, true, 13.5, getRandomInt(250, 1.5e3));
|
||||
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], randInt(120, 175)/100, true, 13.5, randInt(250, 1.5e3));
|
||||
StockMarket[catalyst] = catalystStk;
|
||||
|
||||
var microdyne = "Microdyne Technologies";
|
||||
var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], getRandomInt(70, 80)/100, true, 8, getRandomInt(15e3, 30e3));
|
||||
var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], randInt(70, 80)/100, true, 8, randInt(15e3, 30e3));
|
||||
StockMarket[microdyne] = microdyneStk;
|
||||
|
||||
var titanlabs = "Titan Laboratories";
|
||||
var titanlabsStk = new Stock(titanlabs, StockSymbols[titanlabs], getRandomInt(50, 70)/100, true, 11, getRandomInt(12e3, 24e3));
|
||||
var titanlabsStk = new Stock(titanlabs, StockSymbols[titanlabs], randInt(50, 70)/100, true, 11, randInt(12e3, 24e3));
|
||||
StockMarket[titanlabs] = titanlabsStk;
|
||||
|
||||
var orders = {};
|
||||
@ -368,6 +368,9 @@ function initStockMarket() {
|
||||
}
|
||||
}
|
||||
StockMarket["Orders"] = orders;
|
||||
|
||||
StockMarket.storedCycles = 0;
|
||||
StockMarket.lastUpdate = 0;
|
||||
}
|
||||
|
||||
function initSymbolToStockMap() {
|
||||
@ -375,7 +378,7 @@ function initSymbolToStockMap() {
|
||||
if (StockSymbols.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (stock == null) {
|
||||
console.log("ERROR finding stock");
|
||||
console.error(`Could not find Stock for ${name}`);
|
||||
continue;
|
||||
}
|
||||
var symbol = StockSymbols[name];
|
||||
@ -543,25 +546,40 @@ function sellShort(stock, shares, workerScript=null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateStockPrices() {
|
||||
function processStockPrices(numCycles=1) {
|
||||
if (StockMarket.storedCycles == null || isNaN(StockMarket.storedCycles)) { StockMarket.storedCycles = 0; }
|
||||
StockMarket.storedCycles += numCycles;
|
||||
|
||||
// Stock Prices updated every 6 seconds on average. But if there are stored
|
||||
// cycles they update 50% faster, so every 4 seconds
|
||||
const msPerStockUpdate = 6e3;
|
||||
const cyclesPerStockUpdate = msPerStockUpdate / CONSTANTS.MilliPerCycle;
|
||||
if (StockMarket.storedCycles < cyclesPerStockUpdate) { return; }
|
||||
|
||||
const timeNow = new Date().getTime();
|
||||
if (timeNow - StockMarket.lastUpdate < 4e3) { return; }
|
||||
|
||||
StockMarket.lastUpdate = timeNow;
|
||||
StockMarket.storedCycles -= cyclesPerStockUpdate;
|
||||
|
||||
var v = Math.random();
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;}
|
||||
if (!(stock instanceof Stock)) { continue; }
|
||||
var av = (v * stock.mv) / 100;
|
||||
if (isNaN(av)) {av = .02;}
|
||||
|
||||
var chc = 50;
|
||||
if (stock.b) {
|
||||
chc = (chc + stock.otlkMag)/100;
|
||||
chc = (chc + stock.otlkMag) / 100;
|
||||
if (isNaN(chc)) {chc = 0.5;}
|
||||
} else {
|
||||
chc = (chc - stock.otlkMag)/100;
|
||||
chc = (chc - stock.otlkMag) / 100;
|
||||
if (isNaN(chc)) {chc = 0.5;}
|
||||
}
|
||||
if (stock.price >= StockPriceCap) {
|
||||
chc = -1; //Limit on stock price
|
||||
if (stock.price >= stock.cap) {
|
||||
chc = 0.1; // "Soft Limit" on stock price. It could still go up but its unlikely
|
||||
stock.b = false;
|
||||
}
|
||||
|
||||
@ -725,6 +743,7 @@ function displayStockMarketContent() {
|
||||
"Buy 4S Market Data Access - " + numeralWrapper.format(CONSTANTS.MarketData4SCost, '($0.000a)'),
|
||||
"4S Market Data - Purchased");
|
||||
marketDataButton.addEventListener("click", function() {
|
||||
if (Player.money.lt(CONSTANTS.MarketData4SCost)) { return false; }
|
||||
Player.has4SData = true;
|
||||
Player.loseMoney(CONSTANTS.MarketData4SCost);
|
||||
displayStockMarketContent();
|
||||
@ -764,6 +783,7 @@ function displayStockMarketContent() {
|
||||
"4S Market Data TIX API - Purchased");
|
||||
if (Player.hasTixApiAccess) {
|
||||
marketDataTixButton.addEventListener("click", function() {
|
||||
if (Player.money.lt(CONSTANTS.MarketDataTixApi4SCost)) { return false; }
|
||||
Player.has4SDataTixApi = true;
|
||||
Player.loseMoney(CONSTANTS.MarketDataTixApi4SCost);
|
||||
displayStockMarketContent();
|
||||
@ -875,6 +895,7 @@ function displayStockMarketContent() {
|
||||
|
||||
//Switch to Portfolio Mode Button
|
||||
if (modeBtn) {
|
||||
stockMarketPortfolioMode = false;
|
||||
modeBtn.innerHTML = "Switch to 'Portfolio' Mode" +
|
||||
"<span class='tooltiptext'>Displays only the stocks for which you have shares or orders</span>";
|
||||
modeBtn.addEventListener("click", switchToPortfolioMode);
|
||||
@ -1459,6 +1480,6 @@ function updateStockOrderList(stock) {
|
||||
|
||||
export {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
||||
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
||||
sellStock, shortStock, sellShort, updateStockPrices, displayStockMarketContent,
|
||||
sellStock, shortStock, sellShort, processStockPrices, displayStockMarketContent,
|
||||
updateStockTicker, updateStockPlayerPosition, loadStockMarket,
|
||||
setStockMarketContentCreated, placeOrder, cancelOrder, Order, OrderTypes, PositionTypes};
|
||||
|
@ -105,7 +105,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
" 2 + 2\n",
|
||||
" 2 + 1 + 1\n",
|
||||
" 1 + 1 + 1 + 1\n\n",
|
||||
`How many different ways can ${n} be written as a sum of at least`,
|
||||
`How many different ways can the number ${n} be written as a sum of at least`,
|
||||
"two positive integers?"].join(" ");
|
||||
},
|
||||
difficulty: 1.5,
|
||||
@ -230,8 +230,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
desc: (arr: number[]) => {
|
||||
return ["You are given the following array of integers:\n\n",
|
||||
`${arr}\n\n`,
|
||||
"Each element in the array represents your maximum jump length",
|
||||
"at that position. Assuming you are initially positioned",
|
||||
"Each element in the array represents your MAXIMUM jump length",
|
||||
"at that position. This means that if you are at position i and your",
|
||||
"maximum jump length is n, you can jump to any position from",
|
||||
"i to i+n.",
|
||||
"\n\nAssuming you are initially positioned",
|
||||
"at the start of the array, determine whether you are",
|
||||
"able to reach the last index exactly.\n\n",
|
||||
"Your answer should be submitted as 1 or 0, representing true and false respectively"].join(" ");
|
||||
@ -242,7 +245,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
const arr: number[] = [];
|
||||
arr.length = len;
|
||||
for (let i: number = 0; i < arr.length; ++i) {
|
||||
arr[i] = getRandomInt(0, 24);
|
||||
if (Math.random() < 0.2) {
|
||||
arr[i] = 0; // 20% chance of being 0
|
||||
} else {
|
||||
arr[i] = getRandomInt(0, 10);
|
||||
}
|
||||
}
|
||||
|
||||
return arr;
|
||||
@ -278,7 +285,7 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
difficulty: 3,
|
||||
gen: () => {
|
||||
const intervals: number[][] = [];
|
||||
const numIntervals: number = getRandomInt(1, 15);
|
||||
const numIntervals: number = getRandomInt(1, 20);
|
||||
for (let i: number = 0; i < numIntervals; ++i) {
|
||||
const start: number = getRandomInt(1, 25);
|
||||
const end: number = start + getRandomInt(1, 10);
|
||||
@ -322,8 +329,11 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
"an array with all possible valid IP address combinations",
|
||||
"that can be created from the string:\n\n",
|
||||
`${data}\n\n`,
|
||||
"Example:\n\n",
|
||||
"25525511135 -> [255.255.11.135, 255.255.111.35]"].join(" ");
|
||||
"Note that an octet cannot begin with a '0' unless the number",
|
||||
"itself is actually 0. For example, '192.168.010.1' is not a valid IP.\n\n",
|
||||
"Examples:\n\n",
|
||||
"25525511135 -> [255.255.11.135, 255.255.111.35]\n",
|
||||
"1938718066 -> [193.87.180.66]"].join(" ");
|
||||
},
|
||||
difficulty: 3,
|
||||
gen: () => {
|
||||
@ -377,8 +387,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
},
|
||||
{
|
||||
desc: (data: number[]) => {
|
||||
return ["You are given the following array of stock prices where the i-th element",
|
||||
"represents the stock price on day i:\n\n",
|
||||
return ["You are given the following array of stock prices (which are numbers)",
|
||||
"where the i-th element represents the stock price on day i:\n\n",
|
||||
`${data}\n\n`,
|
||||
"Determine the maximum possible profit you can earn using at most",
|
||||
"one transaction (i.e. you can only buy and sell the stock once). If no profit can be made",
|
||||
@ -411,8 +421,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
},
|
||||
{
|
||||
desc: (data: number[]) => {
|
||||
return ["You are given the following array of stock prices where the i-th element",
|
||||
"represents the stock price on day i:\n\n",
|
||||
return ["You are given the following array of stock prices (which are numbers)",
|
||||
"where the i-th element represents the stock price on day i:\n\n",
|
||||
`${data}\n\n`,
|
||||
"Determine the maximum possible profit you can earn using as many",
|
||||
"transactions as you'd like. A transaction is defined as buying",
|
||||
@ -445,8 +455,8 @@ export const codingContractTypesMetadata: ICodingContractTypeMetadata[] = [
|
||||
},
|
||||
{
|
||||
desc: (data: number[]) => {
|
||||
return ["You are given the following array of stock prices where the i-th element",
|
||||
"represents the stock price on day i:\n\n",
|
||||
return ["You are given the following array of stock prices (which are numbers)",
|
||||
"where the i-th element represents the stock price on day i:\n\n",
|
||||
`${data}\n\n`,
|
||||
"Determine the maximum possible profit you can earn using at most",
|
||||
"two transactions. A transaction is defined as buying",
|
||||
|
@ -205,7 +205,7 @@ export const gangMemberTasksMetadata: IGangMemberTaskMetadata[] = [
|
||||
isHacking: false,
|
||||
name: "Human Trafficking",
|
||||
params: {
|
||||
baseRespect: 0.005, baseWanted: 0.4, baseMoney: 120,
|
||||
baseRespect: 0.004, baseWanted: 1, baseMoney: 120,
|
||||
hackWeight: 30, strWeight: 5, defWeight: 5, dexWeight: 30, chaWeight: 30,
|
||||
difficulty: 36,
|
||||
territory: {
|
||||
@ -221,7 +221,7 @@ export const gangMemberTasksMetadata: IGangMemberTaskMetadata[] = [
|
||||
isHacking: false,
|
||||
name: "Terrorism",
|
||||
params: {
|
||||
baseRespect: 0.01, baseWanted: 1.5,
|
||||
baseRespect: 0.01, baseWanted: 5,
|
||||
hackWeight: 20, strWeight: 20, defWeight: 20, dexWeight: 20, chaWeight: 20,
|
||||
difficulty: 36,
|
||||
territory: {
|
||||
|
145
src/engine.js
145
src/engine.js
@ -24,8 +24,7 @@ import {BitNodes, initBitNodes,
|
||||
import {Bladeburner} from "./Bladeburner";
|
||||
import {CharacterOverview} from "./CharacterOverview";
|
||||
import {cinematicTextFlag} from "./CinematicText";
|
||||
import {CodingContract, CodingContractRewardType,
|
||||
CodingContractTypes} from "./CodingContracts";
|
||||
import {generateRandomContract} from "./CodingContractGenerator";
|
||||
import {CompanyPositions, initCompanies} from "./Company";
|
||||
import {Corporation} from "./CompanyManagement";
|
||||
import {CONSTANTS} from "./Constants";
|
||||
@ -67,7 +66,7 @@ import {SpecialServerIps, initSpecialServerIps} from "./SpecialServerIps
|
||||
import {StockMarket, StockSymbols,
|
||||
SymbolToStockMap, initStockSymbols,
|
||||
initSymbolToStockMap, stockMarketCycle,
|
||||
updateStockPrices,
|
||||
processStockPrices,
|
||||
displayStockMarketContent} from "./StockMarket";
|
||||
import {Terminal, postNetburnerText} from "./Terminal";
|
||||
import {KEY} from "../utils/helpers/keyCodes";
|
||||
@ -79,6 +78,7 @@ import 'normalize.css';
|
||||
import "../css/styles.scss";
|
||||
import "../css/buttons.scss";
|
||||
import "../css/mainmenu.scss";
|
||||
import "../css/characteroverview.scss";
|
||||
import "../css/terminal.scss";
|
||||
import "../css/menupages.scss";
|
||||
import "../css/workinprogress.scss";
|
||||
@ -173,6 +173,7 @@ const Engine = {
|
||||
worldMainMenuButton: null,
|
||||
travelMainMenuButton: null,
|
||||
jobMainMenuButton: null,
|
||||
stockmarketMainMenuButton: null,
|
||||
createProgramMainMenuButton: null,
|
||||
factionsMainMenuButton: null,
|
||||
augmentationsMainMenuButton: null,
|
||||
@ -886,6 +887,11 @@ const Engine = {
|
||||
}
|
||||
}
|
||||
|
||||
// Update stock prices
|
||||
if (Player.hasWseAccount) {
|
||||
processStockPrices(numCycles);
|
||||
}
|
||||
|
||||
//Gang, if applicable
|
||||
if (Player.bitNodeN == 2 && Player.inGang()) {
|
||||
Player.gang.process(numCycles, Player);
|
||||
@ -936,7 +942,6 @@ const Engine = {
|
||||
checkFactionInvitations: 100, //Check whether you qualify for any faction invitations
|
||||
passiveFactionGrowth: 600,
|
||||
messages: 150,
|
||||
stockTick: 30, //Update stock prices
|
||||
sCr: 1500,
|
||||
mechanicProcess: 5, //Processes certain mechanics (Corporation, Bladeburner)
|
||||
contractGeneration: 3000 //Generate Coding Contracts
|
||||
@ -1057,13 +1062,6 @@ const Engine = {
|
||||
}
|
||||
}
|
||||
|
||||
if (Engine.Counters.stockTick <= 0) {
|
||||
if (Player.hasWseAccount) {
|
||||
updateStockPrices();
|
||||
}
|
||||
Engine.Counters.stockTick = 30;
|
||||
}
|
||||
|
||||
if (Engine.Counters.sCr <= 0) {
|
||||
if (Player.hasWseAccount) {
|
||||
stockMarketCycle();
|
||||
@ -1089,71 +1087,7 @@ const Engine = {
|
||||
if (Engine.Counters.contractGeneration <= 0) {
|
||||
// X% chance of a contract being generated
|
||||
if (Math.random() <= 0.25) {
|
||||
// First select a random problem type
|
||||
const problemTypes = Object.keys(CodingContractTypes);
|
||||
let randIndex = getRandomInt(0, problemTypes.length - 1);
|
||||
let problemType = problemTypes[randIndex];
|
||||
|
||||
// Then select a random reward type. 'Money' will always be the last reward type
|
||||
var reward = {};
|
||||
reward.type = getRandomInt(0, CodingContractRewardType.Money);
|
||||
|
||||
// Change type based on certain conditions
|
||||
var factionsThatAllowHacking = Player.factions.filter((fac) => {
|
||||
try {
|
||||
return Factions[fac].getInfo().offerHackingWork;
|
||||
} catch (e) {
|
||||
console.error(`Error when trying to filter Hacking Factions for Coding Contract Generation: ${e}`);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (reward.type === CodingContractRewardType.FactionReputation && factionsThatAllowHacking.length === 0) {
|
||||
reward.type = CodingContractRewardType.CompanyReputation;
|
||||
}
|
||||
if (reward.type === CodingContractRewardType.FactionReputationAll && factionsThatAllowHacking.length === 0) {
|
||||
reward.type = CodingContractRewardType.CompanyReputation;
|
||||
}
|
||||
if (reward.type === CodingContractRewardType.CompanyReputation && Player.companyName === "") {
|
||||
reward.type = CodingContractRewardType.Money;
|
||||
}
|
||||
|
||||
// Add additional information based on the reward type
|
||||
switch (reward.type) {
|
||||
case CodingContractRewardType.FactionReputation:
|
||||
// Get a random faction that player is a part of. That
|
||||
// faction must allow hacking contracts
|
||||
var numFactions = factionsThatAllowHacking.length;
|
||||
var randFaction = factionsThatAllowHacking[getRandomInt(0, numFactions - 1)];
|
||||
reward.name = randFaction;
|
||||
break;
|
||||
case CodingContractRewardType.CompanyReputation:
|
||||
if (Player.companyName !== "") {
|
||||
reward.name = Player.companyName;
|
||||
} else {
|
||||
reward.type = CodingContractRewardType.Money;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Choose random server
|
||||
const servers = Object.keys(AllServers);
|
||||
randIndex = getRandomInt(0, servers.length - 1);
|
||||
var randServer = AllServers[servers[randIndex]];
|
||||
while (randServer.purchasedByPlayer === true) {
|
||||
randIndex = getRandomInt(0, servers.length - 1);
|
||||
randServer = AllServers[servers[randIndex]];
|
||||
}
|
||||
|
||||
let contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||
while (randServer.contracts.filter((c) => {return c.fn === contractFn}).length > 0) {
|
||||
contractFn = `contract-${getRandomInt(0, 1e6)}`;
|
||||
}
|
||||
if (reward.name) { contractFn += `-${reward.name.replace(/\s/g, "")}`; }
|
||||
let contract = new CodingContract(contractFn, problemType, reward);
|
||||
|
||||
randServer.addContract(contract);
|
||||
generateRandomContract();
|
||||
}
|
||||
Engine.Counters.contractGeneration = 3000;
|
||||
}
|
||||
@ -1254,6 +1188,7 @@ const Engine = {
|
||||
var city = document.getElementById("city-tab");
|
||||
var travel = document.getElementById("travel-tab");
|
||||
var job = document.getElementById("job-tab");
|
||||
var stockmarket = document.getElementById("stock-market-tab");
|
||||
var bladeburner = document.getElementById("bladeburner-tab");
|
||||
var corp = document.getElementById("corporation-tab");
|
||||
var gang = document.getElementById("gang-tab");
|
||||
@ -1311,6 +1246,11 @@ const Engine = {
|
||||
//Passive faction rep gain offline
|
||||
processPassiveFactionRepGain(numCyclesOffline);
|
||||
|
||||
// Stock Market offline progress
|
||||
if (Player.hasWseAccount) {
|
||||
processStockPrices(numCyclesOffline);
|
||||
}
|
||||
|
||||
//Gang progress for BitNode 2
|
||||
if (Player.bitNodeN != null && Player.bitNodeN === 2 && Player.inGang()) {
|
||||
Player.gang.process(numCyclesOffline, Player);
|
||||
@ -1343,12 +1283,14 @@ const Engine = {
|
||||
else {factions.style.display = "none";}
|
||||
if (Player.firstAugPurchased) {visibleMenuTabs.push(augmentations);}
|
||||
else {augmentations.style.display = "none";}
|
||||
if (Player.firstJobRecvd) {visibleMenuTabs.push(job);}
|
||||
if (Player.companyPosition !== "") {visibleMenuTabs.push(job);}
|
||||
else {job.style.display = "none";}
|
||||
if (Player.firstTimeTraveled) {visibleMenuTabs.push(travel);}
|
||||
else {travel.style.display = "none";}
|
||||
if (Player.firstProgramAvailable) {visibleMenuTabs.push(createProgram);}
|
||||
else {createProgram.style.display = "none";}
|
||||
if (Player.hasWseAccount) {visibleMenuTabs.push(stockmarket);}
|
||||
else {stockmarket.style.display = "none";}
|
||||
if(Player.bladeburner instanceof Bladeburner) {visibleMenuTabs.push(bladeburner);}
|
||||
else {bladeburner.style.display = "none";}
|
||||
if(Player.corporation instanceof Corporation) {visibleMenuTabs.push(corp);}
|
||||
@ -1392,6 +1334,7 @@ const Engine = {
|
||||
factions.style.display = "none";
|
||||
augmentations.style.display = "none";
|
||||
job.style.display = "none";
|
||||
stockmarket.style.display = "none";
|
||||
travel.style.display = "none";
|
||||
createProgram.style.display = "none";
|
||||
bladeburner.style.display = "none";
|
||||
@ -1608,28 +1551,38 @@ const Engine = {
|
||||
}
|
||||
|
||||
worldHdr.onclick = function() {
|
||||
var city = document.getElementById("city-tab");
|
||||
var cityLink = document.getElementById("city-menu-link");
|
||||
var travel = document.getElementById("travel-tab");
|
||||
var travelLink = document.getElementById("travel-menu-link");
|
||||
var job = document.getElementById("job-tab");
|
||||
var jobLink = document.getElementById("job-menu-link");
|
||||
var bladeburner = document.getElementById("bladeburner-tab");
|
||||
var bladeburnerLink = document.getElementById("bladeburner-menu-link");
|
||||
var corporation = document.getElementById("corporation-tab");
|
||||
var corporationLink = document.getElementById("corporation-menu-link");
|
||||
var gang = document.getElementById("gang-tab");
|
||||
var gangLink = document.getElementById("gang-menu-link");
|
||||
var city = document.getElementById("city-tab");
|
||||
var cityLink = document.getElementById("city-menu-link");
|
||||
var travel = document.getElementById("travel-tab");
|
||||
var travelLink = document.getElementById("travel-menu-link");
|
||||
var job = document.getElementById("job-tab");
|
||||
var jobLink = document.getElementById("job-menu-link");
|
||||
var stockmarket = document.getElementById("stock-market-tab");
|
||||
var stockmarketLink = document.getElementById("stock-market-menu-link");
|
||||
var bladeburner = document.getElementById("bladeburner-tab");
|
||||
var bladeburnerLink = document.getElementById("bladeburner-menu-link");
|
||||
var corporation = document.getElementById("corporation-tab");
|
||||
var corporationLink = document.getElementById("corporation-menu-link");
|
||||
var gang = document.getElementById("gang-tab");
|
||||
var gangLink = document.getElementById("gang-menu-link");
|
||||
|
||||
// Determine whether certain links should show up
|
||||
job.style.display = Player.companyPosition !== "" ? "list-item" : "none";
|
||||
stockmarket.style.display = Player.hasWseAccount ? "list-item" : "none";
|
||||
bladeburner.style.display = Player.bladeburner instanceof Bladeburner ? "list-item" : "none";
|
||||
corporation.style.display = Player.corporation instanceof Corporation ? "list-item" : "none";
|
||||
gang.style.display = Player.inGang() ? "list-item" : "none";
|
||||
|
||||
this.classList.toggle("opened");
|
||||
if (city.style.maxHeight) {
|
||||
Engine.toggleMainMenuHeader(false,
|
||||
[city, travel, job, bladeburner, corporation, gang],
|
||||
[cityLink, travelLink, jobLink, bladeburnerLink, corporationLink, gangLink]
|
||||
[city, travel, job, stockmarket, bladeburner, corporation, gang],
|
||||
[cityLink, travelLink, jobLink, stockmarketLink, bladeburnerLink, corporationLink, gangLink]
|
||||
);
|
||||
} else {
|
||||
Engine.toggleMainMenuHeader(true,
|
||||
[city, travel, job, bladeburner, corporation, gang],
|
||||
[cityLink, travelLink, jobLink, bladeburnerLink, corporationLink, gangLink]
|
||||
[city, travel, job, stockmarket, bladeburner, corporation, gang],
|
||||
[cityLink, travelLink, jobLink, stockmarketLink, bladeburnerLink, corporationLink, gangLink]
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1702,6 +1655,12 @@ const Engine = {
|
||||
return false;
|
||||
});
|
||||
|
||||
Engine.Clickables.stockmarketMainMenuButton = clearEventListeners("stock-market-menu-link");
|
||||
Engine.Clickables.stockmarketMainMenuButton.addEventListener("click", function() {
|
||||
Engine.loadStockMarketContent();
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
Engine.Clickables.createProgramMainMenuButton = clearEventListeners("create-program-menu-link");
|
||||
Engine.Clickables.createProgramMainMenuButton.addEventListener("click", function() {
|
||||
|
@ -81,6 +81,9 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
||||
<li id="job-tab" class="mainmenu-accordion-panel">
|
||||
<button id="job-menu-link"> Job </button>
|
||||
</li>
|
||||
<li id="stock-market-tab" class="mainmenu-accordion-panel">
|
||||
<button id="stock-market-menu-link"> Stock Market </button>
|
||||
</li>
|
||||
<li id="bladeburner-tab" class="mainmenu-accordion-panel">
|
||||
<button id="bladeburner-menu-link"> Bladeburner </button>
|
||||
</li>
|
||||
@ -789,8 +792,8 @@ if (htmlWebpackPlugin.options.googleAnalytics.trackingId) { %>
|
||||
</table>
|
||||
</div>
|
||||
<div class="character-quick-options">
|
||||
<button id="character-overview-save-button">Save Game</button>
|
||||
<button id="character-overview-options-button">Options</button>
|
||||
<button id="character-overview-save-button" class="character-overview-btn">Save Game</button>
|
||||
<button id="character-overview-options-button" class="character-overview-btn">Options</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user