mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-26 16:07:33 +01:00
commit
5d37227ea0
@ -596,28 +596,31 @@ div.faction-clear {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.stock-market-qty-input {
|
||||
border: 1px solid white;
|
||||
color: var(--my-font-color);
|
||||
.stock-market-input {
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
margin: 4px;
|
||||
background-color:black;
|
||||
}
|
||||
|
||||
.stock-market-buy-sell-button {
|
||||
color: #aaa;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
padding: 2px;
|
||||
margin: 6px;
|
||||
margin: 2px;
|
||||
background-color: black;
|
||||
border: 1px solid white;
|
||||
color: var(--my-font-color);
|
||||
}
|
||||
|
||||
.stock-market-buy-sell-button:hover,
|
||||
.stock-market-buy-sell-button:focus {
|
||||
.stock-market-position-text {
|
||||
color:white;
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
.stock-market-order-list {
|
||||
overflow-y:auto;
|
||||
max-height: 100px;
|
||||
}
|
||||
|
||||
.stock-market-order-cancel-btn {
|
||||
background-color: black;
|
||||
border: 1px solid white;
|
||||
color: var(--my-font-color);
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
margin: 2px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
/* Gang */
|
||||
|
@ -445,7 +445,8 @@ a:link, a:visited {
|
||||
margin-left: 5%;
|
||||
display: none;
|
||||
background-color: #555;
|
||||
overflow:auto;
|
||||
overflow-y:auto;
|
||||
overflow-x:none;
|
||||
}
|
||||
|
||||
.accordion-panel div,
|
||||
|
6201
dist/bundle.js
vendored
6201
dist/bundle.js
vendored
File diff suppressed because it is too large
Load Diff
@ -781,9 +781,8 @@
|
||||
If you purchase access to the TIX API, you will retain that access even after
|
||||
you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
<a id="stock-market-buy-tix-api" class="a-link-button-inactive">
|
||||
Buy Trade Information eXchange (TIX) API Access - COMING SOON
|
||||
</a>
|
||||
<a id="stock-market-buy-tix-api" class="a-link-button-inactive"> Buy Trade Information eXchange (TIX) API Access - COMING SOON</a>
|
||||
<a id="stock-market-investopedia" class='a-link-button'>Investopedia</a>
|
||||
<p id="stock-market-commission"> </p>
|
||||
|
||||
<ul id="stock-market-list" style="list-style:none;">
|
||||
|
@ -77,7 +77,21 @@ function initBitNodes() {
|
||||
"Level 3: 7%");
|
||||
BitNodes["BitNode6"] = new BitNode(6, "Do Androids Dream?", "COMING SOON"); //Build androids for automation
|
||||
BitNodes["BitNode7"] = new BitNode(7, "Waste Runner", "COMING SOON"); //Postapocalyptic wasteland + blade runner
|
||||
BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "COMING SOON"); //Trading only viable strategy
|
||||
BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "Money never sleeps",
|
||||
"You are trying to make a name for yourself as an up-and-coming hedge fund manager on Wall Street.<br><br>" +
|
||||
"In this BitNode:<br><br>" +
|
||||
"You start with $100 million<br>" +
|
||||
"The only way to earn money is by trading on the stock market<br>" +
|
||||
"You start with a WSE membership and access to the TIX API<br>" +
|
||||
"You are able to short stocks and place different types of orders (limit/stop)<br>" +
|
||||
"You can immediately donate to factions to gain reputation<br><br>" +
|
||||
"Destroying this BitNode will give you Source-File 8, or if you already have this Source-File it will " +
|
||||
"upgrade its level up to a maximum of 3. This Source-File grants the following benefits:<br><br>" +
|
||||
"Level 1: Permanent access to WSE and TIX API<br>" +
|
||||
"Level 2: Ability to short stocks in other BitNodes<br>" +
|
||||
"Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" +
|
||||
"This Source-File also increases your hacking growth multipliers by: " +
|
||||
"<br>Level 1: 8%<br>Level 2: 12%<br>Level 3: 14%");
|
||||
BitNodes["BitNode9"] = new BitNode(9, "Hacktocracy", "COMING SOON"); //Healthy Hacknet balancing mechanic
|
||||
BitNodes["BitNode10"] = new BitNode(10, "MegaCorp", "COMING SOON"); //Not sure yet
|
||||
BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.",
|
||||
@ -148,6 +162,7 @@ let BitNodeMultipliers = {
|
||||
|
||||
FactionWorkRepGain: 1,
|
||||
FactionPassiveRepGain: 1,
|
||||
RepToDonateToFaction: 1,
|
||||
|
||||
AugmentationRepCost: 1,
|
||||
AugmentationMoneyCost: 1,
|
||||
@ -203,6 +218,15 @@ function initBitNodeMultipliers() {
|
||||
BitNodeMultipliers.AugmentationMoneyCost = 2;
|
||||
BitNodeMultipliers.HackExpGain = 0.5;
|
||||
break;
|
||||
case 8: //Ghost of Wall Street
|
||||
BitNodeMultipliers.ScriptHackMoney = 0;
|
||||
BitNodeMultipliers.ManualHackMoney = 0;
|
||||
BitNodeMultipliers.CompanyWorkMoney = 0;
|
||||
BitNodeMultipliers.CrimeMoney = 0;
|
||||
BitNodeMultipliers.HacknetNodeMoney = 0;
|
||||
BitNodeMultipliers.InfiltrationMoney = 0;
|
||||
BitNodeMultipliers.RepToDonateToFaction = 0
|
||||
break;
|
||||
case 11: //The Big Crash
|
||||
BitNodeMultipliers.ServerMaxMoney = 0.1;
|
||||
BitNodeMultipliers.ServerStartingMoney = 0.1;
|
||||
|
@ -1,8 +1,156 @@
|
||||
/* CompanyManagement.js */
|
||||
|
||||
/*
|
||||
Company made up of
|
||||
Products
|
||||
For certain industries, players can created their own custom products
|
||||
Essentially, these are just things you give a certain name to.
|
||||
|
||||
Products have certain properties that affect how well they sell. These properties
|
||||
are just numbers. For each Industry, only some of these properties are applicable
|
||||
(e.g. Performance isnt applicable for food industry)
|
||||
Demand: Determined by industry. For most industries this will slowly decrease over time, meaning
|
||||
that you must create new and better products to remain successful. The speed at which this
|
||||
decreases over time is dependent on industry
|
||||
Competition: Determined by industry
|
||||
Markup : Determined by Industry
|
||||
Quality:
|
||||
Performance:
|
||||
Durability:
|
||||
Reliability:
|
||||
Aesthetics:
|
||||
Features:
|
||||
Location: Only valid for 'building' products like Restaurants, Hospitals, etc.
|
||||
Scientific Research affects the properties of products
|
||||
Materials:
|
||||
To create Products, you need materials. There are different tiers of Materials
|
||||
Materials have several properties that determine how profitable they can be:
|
||||
Quality:
|
||||
Demand:
|
||||
Competition:
|
||||
Markup: How much price markup a material can have before theres a significant dropoff in how much its bought
|
||||
|
||||
Materials Types:
|
||||
1st tier:
|
||||
Water - High Stable Demand, Medium competition, low markup
|
||||
Energy - Suuuuuuper high stable demand, High competition, low markup
|
||||
2nd Tier:
|
||||
Food - High Stable Demand, Lots of competition, medium markup
|
||||
Plants - Initially high but volatile demand. Decent competition, low markup
|
||||
Metal - Very high stable demand, lots of competition, low markup
|
||||
3rd Tier:
|
||||
Hardware - Very high stable demand, lots of competition, med markup
|
||||
Chemicals - High stable demand, good amount of competition, med markup
|
||||
Real estate - Initially high but volatile demand. Decent competition, med markup. Tied to a certain city
|
||||
4th tier:
|
||||
Drugs - High stable demand, lots of competition, medium markup
|
||||
Robots - Very high stable demand, looots of competition, high markup
|
||||
AI Cores - Very high stable demand, looooots of competition, veeery high markup
|
||||
5th tier:
|
||||
Scientific Research
|
||||
|
||||
Industries:
|
||||
- Some Industries let you create your own custom "Products", while others just produce Materials
|
||||
- Each Industry has different characteristics for things
|
||||
- List of Industries:
|
||||
Energy - Requires hardware, real estate
|
||||
Produces Energy
|
||||
Can Use Hardware/AI Cores to increase production
|
||||
More real estate = more production with very little dimishing returns
|
||||
Production increased by scientific research
|
||||
High starting cost
|
||||
Utilities - Requires hardware, Real Estate
|
||||
Produces Water
|
||||
Can use Hardware, Robotics, and AI Cores to increase production
|
||||
More real estate = more production with medium diminishing returns
|
||||
Production increased by scientific research
|
||||
High starting cost
|
||||
Agriculture - Requires Water and Energy
|
||||
Produces food and plants
|
||||
Can use Hardware/Robotics/AI Cores to increase production
|
||||
Production increased by scientific research
|
||||
More real estate = more production with very little diminishing returns
|
||||
Medium starting cost
|
||||
Fishing - Requires energy
|
||||
Produces lots of food
|
||||
Can use Hardware/Robotics/AI Cores to increase production
|
||||
Production increased by scientific research
|
||||
More real estate = slightly more production with very high diminishing returns
|
||||
Medium starting cost (higher than agriculture)
|
||||
Mining - Requires Energy
|
||||
Produces Metal
|
||||
Can use hardware/Robotics/AI Cores to increase production
|
||||
Production increased by scientific research
|
||||
More real estate = more production with medium diminishing returns
|
||||
High starting cost
|
||||
Food - Create your own "restaurant" products
|
||||
Restaurants require food, water, energy, and real estate
|
||||
Restaurants in general are high stable demand, but lots of competition, and medium markup
|
||||
Low starting cost
|
||||
Production increase from real estate diminishes greatly in city. e.g. making many restaurants
|
||||
in one city has high diminishing returns, but making a few in every city is good
|
||||
Tobacco - Create your own tobacco products
|
||||
Requires plants, water, and real estate
|
||||
High volatile demand, but not much competition. Low markup
|
||||
Low starting cost
|
||||
Product quality significantly affected by scientific research
|
||||
Chemical - Create your own chemical products.
|
||||
Requires plants, energy, water, and real estate
|
||||
High stable demand, high competition, low markup
|
||||
Medium starting cost
|
||||
Advertising does very little
|
||||
Product quality significantly affected by scientific research
|
||||
Pharmaceutical - Create your own drug products
|
||||
Requires chemicals, energy, water, and real estate
|
||||
Very high stable demand. High competition, very high markup
|
||||
High starting cost
|
||||
Requires constant creation of new and better products to be successful
|
||||
Product quality significantly affected by scientific research
|
||||
Computer - Creates 'Hardware' material
|
||||
Requires metal, energy, real estate
|
||||
Can use Robotics/AI Cores to increase production
|
||||
More real estate = more production with high diminishing returns
|
||||
Production significantly affected by scientific research
|
||||
High starting cost
|
||||
Robotics - Create 'Robots' material and create your own 'Robot' products
|
||||
Requires hardware, energy, and real estate
|
||||
Production can be improved by using AI Cores
|
||||
Extremely high stable demand, medium competition, high markup
|
||||
Extremely high starting cost
|
||||
Product quality significantly affected by scientific research
|
||||
more real estate = more production with medium diminishing returns for 'Robot' materials
|
||||
Software - Create 'AI Cores' material and create your own software products
|
||||
Requires hardware, energy, real estate
|
||||
Very high stable demand, high competition, low markup
|
||||
Low starting cost
|
||||
Product quality slightly affected by scientific research
|
||||
Healthcare - Open your own hospitals (each is its own product).
|
||||
Requires real estate, robots, AI Cores, energy, water
|
||||
Extremely high stable demand, semi-high competition, super high markup
|
||||
Extremely high starting cost
|
||||
Production increase from real estate diminishes greatly in city. e.g. making many hospitals
|
||||
in one city has high diminishing returns, but making a few in every city is goodIn
|
||||
Real Estate - Create 'Real Estate'.
|
||||
Requires metal, energy, water, hardware
|
||||
Can use Hardware/Robotics/AI Cores to increase production
|
||||
Production slightly affected by scientific research
|
||||
Heavily affected by advertising
|
||||
Biotechnology -
|
||||
Entertainment -
|
||||
Finance -
|
||||
Mass Media -
|
||||
Telecommunications -
|
||||
|
||||
Employees:
|
||||
Has morale and energy that must be managed to maintain productivity
|
||||
Stats:
|
||||
Intelligence, Charisma, Experience, Creativity, Efficiency
|
||||
|
||||
Assigned to different positions. The productivity at each position is determined by
|
||||
stats. I.e. each employe should be assigned to positions based on stats to optimize production
|
||||
|
||||
Position
|
||||
Operations -
|
||||
Engineer -
|
||||
Business -
|
||||
Accounting -
|
||||
Management -
|
||||
Research and Development -
|
||||
*/
|
||||
|
246
src/Constants.js
246
src/Constants.js
@ -1,5 +1,5 @@
|
||||
let CONSTANTS = {
|
||||
Version: "0.31.0",
|
||||
Version: "0.32.0",
|
||||
|
||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||
@ -440,18 +440,18 @@ let CONSTANTS = {
|
||||
"<u><h1> Functions </h1></u><br>" +
|
||||
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
|
||||
"you may use: <br><br> " +
|
||||
"<i>hack(hostname/ip)</i><br>Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " +
|
||||
"<i><u>hack(hostname/ip)</u></i><br>Core function that is used to try and hack servers to steal money and gain hacking experience. The argument passed in must be a string with " +
|
||||
"either the IP or hostname of the server you want to hack. The runtime for this command depends on your hacking level and the target server's security level. " +
|
||||
" A script can hack a server from anywhere. It does not need to be running on the same server to hack that server. " +
|
||||
"For example, you can create a script that hacks the 'foodnstuff' server and run that script on any server in the game. A successful hack() on " +
|
||||
"a server will raise that server's security level by 0.002. Returns true if the hack is successful and " +
|
||||
"false otherwise. <br>" +
|
||||
"Examples: hack('foodnstuff'); or hack('148.192.0.12');<br><br>" +
|
||||
"<i>sleep(n, log=true)</i><br>Suspends the script for n milliseconds. The second argument is an optional boolean that indicates " +
|
||||
"<i><u>sleep(n, log=true)</u></i><br>Suspends the script for n milliseconds. The second argument is an optional boolean that indicates " +
|
||||
"whether or not the function should log the sleep action. If this argument is true, then calling this function will write " +
|
||||
"'Sleeping for N milliseconds' to the script's logs. If it's false, then this function will not log anything. " +
|
||||
"If this argument is not specified then it will be true by default. <br>Example: sleep(5000);<br><br>" +
|
||||
"<i>grow(hostname/ip)</i><br>Use your hacking skills to increase the amount of money available on a server. The argument passed in " +
|
||||
"<i><u>grow(hostname/ip)</u></i><br>Use your hacking skills to increase the amount of money available on a server. The argument passed in " +
|
||||
"must be a string with either the IP or hostname of the target server. The runtime for this command depends on your hacking level and the target server's security level. " +
|
||||
"When grow() completes, the money available on a target server will be increased by a certain, fixed percentage. This percentage " +
|
||||
"is determined by the server's growth rate and varies between servers. Generally, higher-level servers have higher growth rates. <br><br> " +
|
||||
@ -460,28 +460,28 @@ let CONSTANTS = {
|
||||
"It also raises the security level of the target server by 0.004. " +
|
||||
"Returns the number by which the money on the server was multiplied for the growth. " +
|
||||
"Works offline at a slower rate. <br> Example: grow('foodnstuff');<br><br>" +
|
||||
"<i>weaken(hostname/ip)</i><br>Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " +
|
||||
"<i><u>weaken(hostname/ip)</u></i><br>Use your hacking skills to attack a server's security, lowering the server's security level. The argument passed " +
|
||||
"in must be a string with either the IP or hostname of the target server. The runtime for this command depends on your " +
|
||||
"hacking level and the target server's security level. This function lowers the security level of the target server by " +
|
||||
"0.05.<br><br> Like hack() and grow(), weaken() can be called on " +
|
||||
"any server, regardless of where the script is running. This command requires root access to the target server, but " +
|
||||
"there is no required hacking level to run the command. Returns " +
|
||||
"0.1. Works offline at a slower rate<br> Example: weaken('foodnstuff');<br><br>" +
|
||||
"<i>print(x)</i><br>Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br><br>" +
|
||||
"<i>tprint(x)</i><br>Prints a value or a variable to the Terminal<br><br>" +
|
||||
"<i>clearLog()</i><br>Clears the script's logs. <br><br>" +
|
||||
"<i>scan(hostname/ip, [hostnames=true])</i><br>Returns an array containing the hostnames or IPs of all servers that are one node away from the specified server. " +
|
||||
"<i><u>print(x)</u></i><br>Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br><br>" +
|
||||
"<i><u>tprint(x)</u></i><br>Prints a value or a variable to the Terminal<br><br>" +
|
||||
"<i><u>clearLog()</u></i><br>Clears the script's logs. <br><br>" +
|
||||
"<i><u>scan(hostname/ip, [hostnames=true])</u></i><br>Returns an array containing the hostnames or IPs of all servers that are one node away from the specified server. " +
|
||||
"The argument must be a string containing the IP or hostname of the target server. The second argument is a boolean that specifies whether " +
|
||||
"the hostnames or IPs of the scanned servers should be output. If it is true then hostnames will be returned, and if false then IP addresses will. " +
|
||||
"This second argument is optional and, if ommitted, the function will output " +
|
||||
"the hostnames of the scanned servers. The hostnames/IPs in the returned array are strings.<br><br>" +
|
||||
"<i>nuke(hostname/ip)</i><br>Run NUKE.exe on the target server. NUKE.exe must exist on your home computer.<br> Example: nuke('foodnstuff'); <br><br>" +
|
||||
"<i>brutessh(hostname/ip)</i><br>Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer.<br> Example: brutessh('foodnstuff');<br><br>" +
|
||||
"<i>ftpcrack(hostname/ip)</i><br>Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer.<br> Example: ftpcrack('foodnstuff');<br><br>" +
|
||||
"<i>relaysmtp(hostname/ip)</i><br>Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer.<br> Example: relaysmtp('foodnstuff');<br><br>" +
|
||||
"<i>httpworm(hostname/ip)</i><br>Run HTTPWorm.exe on the target server. HTTPWorm.exe must exist on your home computer.<br> Example: httpworm('foodnstuff');<br><br>" +
|
||||
"<i>sqlinject(hostname/ip)</i><br>Run SQLInject.exe on the target server. SQLInject.exe must exist on your home computer.<br> Example: sqlinject('foodnstuff');<br><br>" +
|
||||
"<i>run(script, [numThreads], [args...])</i> <br> Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " +
|
||||
"<i><u>nuke(hostname/ip)</u></i><br>Run NUKE.exe on the target server. NUKE.exe must exist on your home computer.<br> Example: nuke('foodnstuff'); <br><br>" +
|
||||
"<i><u>brutessh(hostname/ip)</u></i><br>Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer.<br> Example: brutessh('foodnstuff');<br><br>" +
|
||||
"<i><u>ftpcrack(hostname/ip)</u></i><br>Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer.<br> Example: ftpcrack('foodnstuff');<br><br>" +
|
||||
"<i><u>relaysmtp(hostname/ip)</u></i><br>Run relaySMTP.exe on the target server. relaySMTP.exe must exist on your home computer.<br> Example: relaysmtp('foodnstuff');<br><br>" +
|
||||
"<i><u>httpworm(hostname/ip)</u></i><br>Run HTTPWorm.exe on the target server. HTTPWorm.exe must exist on your home computer.<br> Example: httpworm('foodnstuff');<br><br>" +
|
||||
"<i><u>sqlinject(hostname/ip)</u></i><br>Run SQLInject.exe on the target server. SQLInject.exe must exist on your home computer.<br> Example: sqlinject('foodnstuff');<br><br>" +
|
||||
"<i><u>run(script, [numThreads], [args...])</u></i> <br> Run a script as a separate process. The first argument that is passed in is the name of the script as a string. This function can only " +
|
||||
"be used to run scripts located on the current server (the server running the script that calls this function). The second argument " +
|
||||
"is optional, and it specifies how many threads to run the script with. This argument must be a number greater than 0. If it is omitted, then the script will be run single-threaded. Any additional arguments will specify " +
|
||||
"arguments to pass into the new script that is being run. If arguments are specified for the new script, then the second argument numThreads argument must be filled in with a value.<br><br>" +
|
||||
@ -493,7 +493,7 @@ let CONSTANTS = {
|
||||
"run('foo.script', 5);<br><br>" +
|
||||
"The following example will run 'foo.script' single-threaded, and will pass the string 'foodnstuff' into the script as an argument:<br><br>" +
|
||||
"run('foo.script', 1, 'foodnstuff');<br><br>" +
|
||||
"<i>exec(script, hostname/ip, [numThreads], [args...])</i><br>Run a script as a separate process on another server. The first argument is the name of the script as a string. The " +
|
||||
"<i><u>exec(script, hostname/ip, [numThreads], [args...])</u></i><br>Run a script as a separate process on another server. The first argument is the name of the script as a string. The " +
|
||||
"second argument is a string with the hostname or IP of the 'target server' on which to run the script. The specified script must exist on the target server. " +
|
||||
"The third argument is optional, and it specifies how many threads to run the script with. If it is omitted, then the script will be run single-threaded. " +
|
||||
"This argument must be a number that is greater than 0. Any additional arguments will specify arguments to pass into the new script that is being run. If " +
|
||||
@ -507,7 +507,7 @@ let CONSTANTS = {
|
||||
"The following example will try to run the script 'foo.script' on the 'foodnstuff' server with 5 threads. It will also pass the number 1 and the string 'test' in as arguments " +
|
||||
"to the script.<br><br>" +
|
||||
"exec('foo.script', 'foodnstuff', 5, 1, 'test');<br><br>" +
|
||||
"<i>kill(script, hostname/ip, [args...])</i><br> Kills the script on the target server specified by the script's name and arguments. Remember that " +
|
||||
"<i><u>kill(script, hostname/ip, [args...])</u></i><br> Kills the script on the target server specified by the script's name and arguments. Remember that " +
|
||||
"scripts are uniquely identified by both their name and arguments. For example, if 'foo.script' is run with the argument 1, then this is not the " +
|
||||
"same as 'foo.script' run with the argument 2, even though they have the same code. <br><br>" +
|
||||
"The first argument must be a string with the name of the script. The name is case-sensitive. " +
|
||||
@ -522,9 +522,9 @@ let CONSTANTS = {
|
||||
"kill('foo.script', getHostname());<br><br>" +
|
||||
"If you are trying to kill a script named 'foo.script' on the current server that was ran with the arguments 1 and 'foodnstuff', use this:<br><br>" +
|
||||
"kill('foo.script', getHostname(), 1, 'foodnstuff');<br><br>" +
|
||||
"<i>killall(hostname/ip)</i><br> Kills all running scripts on the specified server. This function takes a single argument which " +
|
||||
"<i><u>killall(hostname/ip)</u></i><br> Kills all running scripts on the specified server. This function takes a single argument which " +
|
||||
"must be a string containing the hostname or IP of the target server. This function will always return true. <br><br>" +
|
||||
"<i>scp(script, [source], destination)</i><br>Copies a script or literature (.lit) file to another server. The first argument is a string with " +
|
||||
"<i><u>scp(script, [source], destination)</u></i><br>Copies a script or literature (.lit) file to another server. The first argument is a string with " +
|
||||
"the filename of the script or literature file " +
|
||||
"to be copied, or an array of filenames to be copied. The next two arguments are strings containing the hostname/IPs of the source and target server. " +
|
||||
"The source refers to the server from which the script/literature file will be copied, while the destination " +
|
||||
@ -534,15 +534,15 @@ let CONSTANTS = {
|
||||
"will return if at least one of the files in the array is successfully copied over.<br><br>" +
|
||||
"Example: scp('hack-template.script', 'foodnstuff'); //Copies hack-template.script from the current server to foodnstuff<br>" +
|
||||
"Example: scp('foo.lit', 'helios', 'home'); //Copies foo.lit from the helios server to the home computer<br><br>" +
|
||||
"<i>ls(hostname/ip)</i><br>Returns an array containing the names of all files on the specified server. The argument must be a " +
|
||||
"<i><u>ls(hostname/ip)</u></i><br>Returns an array containing the names of all files on the specified server. The argument must be a " +
|
||||
"string with the hostname or IP of the target server.<br><br>" +
|
||||
"<i>hasRootAccess(hostname/ip)</i><br> Returns a boolean (true or false) indicating whether or not the Player has root access to a server. " +
|
||||
"<i><u>hasRootAccess(hostname/ip)</u></i><br> Returns a boolean (true or false) indicating whether or not the Player has root access to a server. " +
|
||||
"The argument passed in must be a string with either the hostname or IP of the target server.<br> " +
|
||||
"Example:<br>if (hasRootAccess('foodnstuff') == false) {<br> nuke('foodnstuff');<br>}<br><br>" +
|
||||
"<i>getIp()</i><br>Returns a string with the IP Address of the server that the script is running on <br><br>" +
|
||||
"<i>getHostname()</i><br>Returns a string with the hostname of the server that the script is running on<br><br>" +
|
||||
"<i>getHackingLevel()</i><br>Returns the Player's current hacking level.<br><br> " +
|
||||
"<i>getHackingMultipliers()</i><br>Returns an object containing the Player's hacking related multipliers. " +
|
||||
"<i><u>getIp()</u></i><br>Returns a string with the IP Address of the server that the script is running on <br><br>" +
|
||||
"<i><u>getHostname()</u></i><br>Returns a string with the hostname of the server that the script is running on<br><br>" +
|
||||
"<i><u>getHackingLevel()</u></i><br>Returns the Player's current hacking level.<br><br> " +
|
||||
"<i><u>getHackingMultipliers()</u></i><br>Returns an object containing the Player's hacking related multipliers. " +
|
||||
"These multipliers are returned in integer forms, not percentages (e.g. 1.5 instead of 150%). " +
|
||||
"The object has the following structure:<br><br>" +
|
||||
"{<br>" +
|
||||
@ -554,7 +554,7 @@ let CONSTANTS = {
|
||||
"mults = getHackingMultipliers();<br>" +
|
||||
"print(mults.chance);<br>" +
|
||||
"print(mults.growth);<br><br>" +
|
||||
"<i>getBitNodeMultipliers()</i><br>Returns an object containing the current BitNode multipliers. " +
|
||||
"<i><u>getBitNodeMultipliers()</u></i><br>Returns an object containing the current BitNode multipliers. " +
|
||||
"This function requires Source-File 5 in order to run. The multipliers are returned in integer forms, not percentages " +
|
||||
"(e.g. 1.5 instead of 150%). The multipliers represent the difference between the current BitNode and the " +
|
||||
"original BitNode (BitNode-1). For example, if the 'CrimeMoney' multiplier has a value of 0.1 then that means " +
|
||||
@ -584,33 +584,33 @@ let CONSTANTS = {
|
||||
"mults = getBitNodeMultipliers();<br>" +
|
||||
"print(mults.ServerMaxMoney);<br>" +
|
||||
"print(mults.HackExpGain);<br><br>" +
|
||||
"<i>getServerMoneyAvailable(hostname/ip)</i><br> Returns the amount of money available on a server. The argument passed in must be a string with either the " +
|
||||
"<i><u>getServerMoneyAvailable(hostname/ip)</u></i><br> Returns the amount of money available on a server. The argument passed in must be a string with either the " +
|
||||
"hostname or IP of the target server.<br> Example: getServerMoneyAvailable('foodnstuff');<br><br>" +
|
||||
"<i>getServerMaxMoney(hostname/ip)</i><br>Returns the maximum amount of money that can be available on a server. The argument passed in must be a string with " +
|
||||
"<i><u>getServerMaxMoney(hostname/ip)</u></i><br>Returns the maximum amount of money that can be available on a server. The argument passed in must be a string with " +
|
||||
"the hostname or IP of the target server.<br>Example: getServerMaxMoney('foodnstuff');<br><br>" +
|
||||
"<i>getServerGrowth(hostname/ip)</i><br>Returns the server's intrinsic 'growth parameter'. This growth parameter is a number " +
|
||||
"<i><u>getServerGrowth(hostname/ip)</u></i><br>Returns the server's intrinsic 'growth parameter'. This growth parameter is a number " +
|
||||
"between 1 and 100 that represents how quickly the server's money grows. This parameter affects the percentage by which this server's " +
|
||||
"money is increased when using the grow() function. A higher growth parameter will result in a higher percentage from grow().<br><br>" +
|
||||
"The argument passed in must be a string with the hostname or IP of the target server.<br><br>" +
|
||||
"<i>getServerSecurityLevel(hostname/ip)</i><br>Returns the security level of a server. The argument passed in must be a string with either the " +
|
||||
"<i><u>getServerSecurityLevel(hostname/ip)</u></i><br>Returns the security level of a server. The argument passed in must be a string with either the " +
|
||||
"hostname or IP of the target server. A server's security is denoted by a number, typically between 1 and 100.<br><br>" +
|
||||
"<i>getServerBaseSecurityLevel(hostname/ip)</i><br>Returns the base security level of a server. This is the security level that the server starts out with. " +
|
||||
"<i><u>getServerBaseSecurityLevel(hostname/ip)</u></i><br>Returns the base security level of a server. This is the security level that the server starts out with. " +
|
||||
"This is different than getServerSecurityLevel() because getServerSecurityLevel() returns the current security level of a server, which can constantly change " +
|
||||
"due to hack(), grow(), and weaken() calls on that server. The base security level will stay the same until you reset by installing an Augmentation. <br><br>" +
|
||||
"The argument passed in must be a string with either the hostname or IP of the target server. A server's base security is denoted by a number, typically between 1 and 100. " +
|
||||
"<br><br>" +
|
||||
"<i>getServerMinSecurityLevel(hostname/ip)</i>Returns the minimum security level of a server. The argument passed in must be a string with " +
|
||||
"<i><u>getServerMinSecurityLevel(hostname/ip)</u></i>Returns the minimum security level of a server. The argument passed in must be a string with " +
|
||||
"either the hostname or IP of the target server.<br><br>" +
|
||||
"<i>getServerRequiredHackingLevel(hostname/ip)</i><br>Returns the required hacking level of a server. The argument passed in must be a string with either the " +
|
||||
"<i><u>getServerRequiredHackingLevel(hostname/ip)</u></i><br>Returns the required hacking level of a server. The argument passed in must be a string with either the " +
|
||||
"hostname or IP or the target server.<br><br>" +
|
||||
"<i>getServerNumPortsRequired(hostname/ip)</i><br>Returns the number of open ports required to successfully run NUKE.exe on a server. The argument " +
|
||||
"<i><u>getServerNumPortsRequired(hostname/ip)</u></i><br>Returns the number of open ports required to successfully run NUKE.exe on a server. The argument " +
|
||||
"passed in must be a string with either the hostname or IP of the target server.<br><br>" +
|
||||
"<i>getServerRam(hostname/ip)</i><br>Returns an array with two elements that gives information about the target server's RAM. The first " +
|
||||
"<i><u>getServerRam(hostname/ip)</u></i><br>Returns an array with two elements that gives information about the target server's RAM. The first " +
|
||||
"element in the array is the amount of RAM that the server has (in GB). The second element in the array is the amount of RAM that " +
|
||||
"is currently being used on the server.<br><br>" +
|
||||
"<i>serverExists(hostname/ip)</i><br>Returns a boolean denoting whether or not the specified server exists. The argument " +
|
||||
"<i><u>serverExists(hostname/ip)</u></i><br>Returns a boolean denoting whether or not the specified server exists. The argument " +
|
||||
"must be a string with the hostname or IP of the target server.<br><br>" +
|
||||
"<i>fileExists(filename, [hostname/ip])</i><br> Returns a boolean (true or false) indicating whether the specified file exists on a server. " +
|
||||
"<i><u>fileExists(filename, [hostname/ip])</u></i><br> Returns a boolean (true or false) indicating whether the specified file exists on a server. " +
|
||||
"The first argument must be a string with the name of the file. A file can either be a script, program, or literature file. A script name is case-sensitive, but a " +
|
||||
"program/literature file is not. For example, fileExists('brutessh.exe') will work fine, even though the actual program is named BruteSSH.exe. <br><br> " +
|
||||
"The second argument is a string with the hostname or IP of the server on which to search for the program. This second argument is optional. " +
|
||||
@ -619,7 +619,7 @@ let CONSTANTS = {
|
||||
"Example: fileExists('ftpcrack.exe');<br><br>" +
|
||||
"The first example above will return true if the script named 'foo.script' exists on the 'foodnstuff' server, and false otherwise. The second example above will " +
|
||||
"return true if the current server (the server on which this function runs) contains the FTPCrack.exe program, and false otherwise. <br><br>" +
|
||||
"<i>isRunning(filename, hostname/ip, [args...])</i><br> Returns a boolean (true or false) indicating whether the specified script is running on a server. " +
|
||||
"<i><u>isRunning(filename, hostname/ip, [args...])</u></i><br> Returns a boolean (true or false) indicating whether the specified script is running on a server. " +
|
||||
"Remember that a script is uniquely identified by both its name and its arguments. <br><br>" +
|
||||
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is a string with the " +
|
||||
"hostname or IP of the target server. Any additional arguments passed to the function will specify the arguments passed into the target script. " +
|
||||
@ -631,45 +631,45 @@ let CONSTANTS = {
|
||||
"example above will return true if there is a script named 'foo.script' with no arguments running on the current server, and false otherwise. " +
|
||||
"The third example above will return true if there is a script named 'foo.script' with the arguments 1, 5, and 'test' running on the 'joesguns' server, and " +
|
||||
"false otherwise.<br><br>" +
|
||||
"<i>getNextHacknetNodeCost()</i><br>Returns the cost of purchasing a new Hacknet Node<br><br>" +
|
||||
"<i>purchaseHacknetNode()</i><br>Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " +
|
||||
"<i><u>getNextHacknetNodeCost()</u></i><br>Returns the cost of purchasing a new Hacknet Node<br><br>" +
|
||||
"<i><u>purchaseHacknetNode()</u></i><br>Purchases a new Hacknet Node. Returns a number with the index of the Hacknet Node. This index is equivalent to the number " +
|
||||
"at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " +
|
||||
"a new Hacknet Node then the function will return false. Does NOT work offline<br><br>" +
|
||||
"<i>purchaseServer(hostname, ram)</i><br> Purchases a server with the specified hostname and amount of RAM. The first argument can be any data type, " +
|
||||
"<i><u>purchaseServer(hostname, ram)</u></i><br> Purchases a server with the specified hostname and amount of RAM. The first argument can be any data type, " +
|
||||
"but it will be converted to a string using Javascript's String function. Anything that resolves to an empty string will cause the function to fail. " +
|
||||
"The second argument specified the amount of RAM (in GB) for the server. This argument must resolve to a numeric and it must be a power of 2 " +
|
||||
"(2, 4, 8, etc...). <br><br>" +
|
||||
"This function returns the hostname of the newly purchased server as a string. If the function fails to purchase a server, then it will return " +
|
||||
"an empty string. The function will fail if the arguments passed in are invalid or if the player does not have enough money to purchase the specified server.<br><br>" +
|
||||
"<i>deleteServer(hostname)</i><br>Deletes one of the servers you've purchased with the specified hostname. The function will fail if " +
|
||||
"<i><u>deleteServer(hostname)</u></i><br>Deletes one of the servers you've purchased with the specified hostname. The function will fail if " +
|
||||
"there are any scripts running on the specified server. Returns true if successful and false otherwise<br><br>" +
|
||||
"<i>getPurchasedServers([hostname=true])</i><br>Returns an array with either the hostname or IPs of all of the servers you " +
|
||||
"<i><u>getPurchasedServers([hostname=true])</u></i><br>Returns an array with either the hostname or IPs of all of the servers you " +
|
||||
"have purchased. It takes an optional parameter specifying whether the hostname or IP addresses will be returned. If this " +
|
||||
"parameter is not specified, it is true by default and hostnames will be returned<br><br>" +
|
||||
"<i>round(n)</i><br>Rounds the number n to the nearest integer. If the argument passed in is not a number, then the function will return 0.<br><br>" +
|
||||
"<i>write(port, data)</i><br>Writes data to a port. The first argument must be a number between 1 and 10 that specifies the port. The second " +
|
||||
"<i><u>round(n)</u></i><br>Rounds the number n to the nearest integer. If the argument passed in is not a number, then the function will return 0.<br><br>" +
|
||||
"<i><u>write(port, data)</u></i><br>Writes data to a port. The first argument must be a number between 1 and 10 that specifies the port. The second " +
|
||||
"argument defines the data to write to the port. If the second argument is not specified then it will write an empty string to the port.<br><br>" +
|
||||
"<i>read(port)</i><br>Reads data from a port. The first argument must be a number between 1 and 10 that specifies the port. A port is a serialized queue. " +
|
||||
"<i><u>read(port)</u></i><br>Reads data from a port. The first argument must be a number between 1 and 10 that specifies the port. A port is a serialized queue. " +
|
||||
"This function will remove the first element from the queue and return it. If the queue is empty, then the string 'NULL PORT DATA' will be returned. <br><br>" +
|
||||
"<i>scriptRunning(scriptname, hostname/ip)</i><br>Returns a boolean indicating whether any instance of the specified script is running " +
|
||||
"<i><u>scriptRunning(scriptname, hostname/ip)</u></i><br>Returns a boolean indicating whether any instance of the specified script is running " +
|
||||
"on a server, regardless of its arguments. This is different than the isRunning() function because it does not " +
|
||||
"try to identify a specific instance of a running script by its arguments.<br><br>" +
|
||||
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " +
|
||||
"a string with the hostname or IP of the target server. Both arguments are required.<br><br>" +
|
||||
"<i>scriptKill(scriptname, hostname/ip)</i><br>Kills all scripts with the specified filename that are running on the server specified by the " +
|
||||
"<i><u>scriptKill(scriptname, hostname/ip)</u></i><br>Kills all scripts with the specified filename that are running on the server specified by the " +
|
||||
"hostname/ip, regardless of arguments. Returns true if one or more scripts were successfully killed, and false if there were none. <br><br>" +
|
||||
"The first argument must be a string with the name of the script. The script name is case sensitive. The second argument is " +
|
||||
"a string with the hostname or IP of the target server. Both arguments are required.<br><br>" +
|
||||
"<i>getScriptRam(scriptname, hostname/ip)</i><br>Returns the amount of RAM required to run the specified script on the " +
|
||||
"<i><u>getScriptRam(scriptname, hostname/ip)</u></i><br>Returns the amount of RAM required to run the specified script on the " +
|
||||
"target server. The first argument must be a string with the name of the script. The script name is case sensitive. " +
|
||||
"The second argument is a string with the hostname or IP of the server where that script is. Both arguments are required.<br><br>" +
|
||||
"<i>getHackTime(hostname/ip)</i><br>Returns the amount of time in seconds it takes to execute the hack() Netscript function " +
|
||||
"<i><u>getHackTime(hostname/ip)</u></i><br>Returns the amount of time in seconds it takes to execute the hack() Netscript function " +
|
||||
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
|
||||
"<i>getGrowTime(hostname/ip)</i><br>Returns the amount of time in seconds it takes to execute the grow() Netscript function " +
|
||||
"<i><u>getGrowTime(hostname/ip)</u></i><br>Returns the amount of time in seconds it takes to execute the grow() Netscript function " +
|
||||
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
|
||||
"<i>getWeakenTime(hostname/ip)</i><br>Returns the amount of time in seconds it takes to execute the weaken() Netscript function " +
|
||||
"<i><u>getWeakenTime(hostname/ip)</u></i><br>Returns the amount of time in seconds it takes to execute the weaken() Netscript function " +
|
||||
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
|
||||
"<i>getScriptIncome([scriptname], [hostname/ip], [args...])</i><br>" +
|
||||
"<i><u>getScriptIncome([scriptname], [hostname/ip], [args...])</u></i><br>" +
|
||||
"Returns the amount of income the specified script generates while online (when the game is open, does not apply for " +
|
||||
"offline income). This function can also be called with no arguments. If called with no arguments, then this function " +
|
||||
"will return an array of two values. The first value is the total income ($/sec) of all of your active scripts (currently running). " +
|
||||
@ -681,7 +681,7 @@ let CONSTANTS = {
|
||||
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
|
||||
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
|
||||
"the arguments passed into the target script.<br><br>" +
|
||||
"<i>getScriptExpGain([scriptname], [hostname/ip], [args...])</i><br>" +
|
||||
"<i><u>getScriptExpGain([scriptname], [hostname/ip], [args...])</u></i><br>" +
|
||||
"Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for " +
|
||||
"offline experience gains). This function can also return the total experience gain rate of all of your active scripts by running the function " +
|
||||
"with no arguments.<br><br>" +
|
||||
@ -692,26 +692,28 @@ let CONSTANTS = {
|
||||
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
|
||||
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
|
||||
"the arguments passed into the target script.<br><br>" +
|
||||
"<i>getTimeSinceLastAug()</i><br>" +
|
||||
"<i><u>getTimeSinceLastAug()</u></i><br>" +
|
||||
"Returns the amount of time in milliseconds that have passed since you last installed Augmentations (or destroyed a BitNode).<br><br>" +
|
||||
"<i><u>sprintf()/vsprintf()</u></i><br>" +
|
||||
"<a href='https://github.com/alexei/sprintf.js' target='_blank'>See this link for details</a><br><br>" +
|
||||
"<u><h1>Hacknet Nodes API</h1></u><br>" +
|
||||
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.<br><br>" +
|
||||
"<i>hacknetnodes</i><br> A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
|
||||
"<i><u>hacknetnodes</u></i><br>A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
|
||||
"indexes. These indexes correspond to the number at the end of the name of the Hacknet Node. For example, the first Hacknet Node you purchase " +
|
||||
"will have the same 'hacknet-node-0' and can be accessed with hacknetnodes[0]. The fourth Hacknet Node you purchase will have the name " +
|
||||
"'hacknet-node-3' and can be accessed with hacknetnodes[3]. <br><br>" +
|
||||
"<i>hacknetnodes.length</i><br>Returns the number of Hacknet Nodes that the player owns<br><br>" +
|
||||
"<i>hacknetnodes[i].level</i><br>Returns the level of the corresponding Hacknet Node<br><br>" +
|
||||
"<i>hacknetnodes[i].ram</i><br>Returns the amount of RAM on the corresponding Hacknet Node<br><br>" +
|
||||
"<i>hacknetnodes[i].cores</i><br>Returns the number of cores on the corresponding Hacknet Node<br><br>" +
|
||||
"<i>hacknetnodes[i].totalMoneyGenerated</i><br>Returns the total amount of money that the corresponding Hacknet Node has earned<br><br>" +
|
||||
"<i>hacknetnodes[i].onlineTimeSeconds</i><br>Returns the total amount of time that the corresponding Hacknet Node has existed<br><br>" +
|
||||
"<i>hacknetnodes[i].moneyGainRatePerSecond</i><br>Returns the income ($ / sec) that the corresponding Hacknet Node earns<br><br>" +
|
||||
"<i>hacknetnodes[i].upgradeLevel(n)</i><br>Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " +
|
||||
"<i><u>hacknetnodes.length</u></i><br>Returns the number of Hacknet Nodes that the player owns<br><br>" +
|
||||
"<i><u>hacknetnodes[i].level</u></i><br>Returns the level of the corresponding Hacknet Node<br><br>" +
|
||||
"<i><u>hacknetnodes[i].ram</u></i><br>Returns the amount of RAM on the corresponding Hacknet Node<br><br>" +
|
||||
"<i><u>hacknetnodes[i].cores</u></i><br>Returns the number of cores on the corresponding Hacknet Node<br><br>" +
|
||||
"<i><u>hacknetnodes[i].totalMoneyGenerated</u></i><br>Returns the total amount of money that the corresponding Hacknet Node has earned<br><br>" +
|
||||
"<i><u>hacknetnodes[i].onlineTimeSeconds</u></i><br>Returns the total amount of time that the corresponding Hacknet Node has existed<br><br>" +
|
||||
"<i><u>hacknetnodes[i].moneyGainRatePerSecond</u></i><br>Returns the income ($ / sec) that the corresponding Hacknet Node earns<br><br>" +
|
||||
"<i><u>hacknetnodes[i].upgradeLevel(n)</u></i><br>Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " +
|
||||
"positive integer. Returns true if the Hacknet Node's level is successfully upgraded n times or up to the max level (200), and false otherwise.<br><br>" +
|
||||
"<i>hacknetnodes[i].upgradeRam()</i><br>Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
|
||||
"<i><u>hacknetnodes[i].upgradeRam()</u></i><br>Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
|
||||
"RAM is successfully upgraded, and false otherwise. <br><br>" +
|
||||
"<i>hacknetnodes[i].upgradeCore()</i><br>Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
|
||||
"<i><u>hacknetnodes[i].upgradeCore()</u></i><br>Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
|
||||
"additional core is successfully purchase, and false otherwise. <br><br>" +
|
||||
"Example: The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. " +
|
||||
"This script purchases new Hacknet Nodes until the player has four. Then, it iteratively upgrades each of those four Hacknet Nodes " +
|
||||
@ -738,25 +740,53 @@ let CONSTANTS = {
|
||||
" }<br>" +
|
||||
"}<br><br>" +
|
||||
"<u><h1>Trade Information eXchange (TIX) API</h1></u><br>" +
|
||||
"<i>getStockPrice(sym)</i><br>Returns the price of a stock. The argument passed in must be the stock's symbol (NOT THE COMPANY NAME!). The symbol " +
|
||||
"<i><u>getStockPrice(sym)</u></i><br>Returns the price of a stock. The argument passed in must be the stock's symbol (NOT THE COMPANY NAME!). The symbol " +
|
||||
"is a sequence of two to four capital letters. The symbol argument must be a string. <br><br>" +
|
||||
"Example: getStockPrice('FSIG');<br><br>" +
|
||||
"<i>getStockPosition(sym)</i><br>Returns an array of two elements that represents the player's position in a stock. The first element " +
|
||||
"<i><u>getStockPosition(sym)</u></i><br>Returns an array of two elements that represents the player's position in a stock. The first element " +
|
||||
"in the array is the number of shares the player owns of the specified stock. The second element in the array is the average price of the player's " +
|
||||
"shares. Both elements are numbers. The argument passed in must be the stock's symbol, which is a sequence of two to four capital letters.<br><br>" +
|
||||
"Example: <br><br>pos = getStockPosition('ECP');<br>shares = pos[0];<br>avgPx = pos[1];<br><br>"+
|
||||
"<i>buyStock(sym, shares)</i><br>Attempts to purchase shares of a stock. The first argument must be a string with the stock's symbol. The second argument " +
|
||||
"<i><u>buyStock(sym, shares)</u></i><br>Attempts to purchase shares of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " +
|
||||
"must be the number of shares to purchase.<br><br>" +
|
||||
"If the player does not have enough money to purchase specified number of shares, then no shares will be purchased (it will not purchase the most you can afford). " +
|
||||
"Remember that every transaction on the stock exchange costs a certain commission fee.<br><br>" +
|
||||
"The function will return true if it successfully purchases the specified number of shares of stock, and false otherwise.<br><br>" +
|
||||
"<i>sellStock(sym, shares)</i><br>Attempts to sell shares of a stock. The first argument must be a string with the stock's symbol. The second argument " +
|
||||
"<i><u>sellStock(sym, shares)</u></i><br>Attempts to sell shares of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " +
|
||||
"must be the number of shares to sell.<br><br>" +
|
||||
"If the specified number of shares in the function exceeds the amount that the player actually owns, then this function will sell all owned shares. " +
|
||||
"Remember that every transaction on the stock exchange costs a certain commission fee.<br><br>" +
|
||||
"The net profit made from selling stocks with this function is reflected in the script's statistics. This net profit is calculated as: <br><br>" +
|
||||
"shares * (sell price - average price of purchased shares)<br><br>" +
|
||||
"This function will return true if the shares of stock are successfully sold and false otherwise.<br><br>" +
|
||||
"<i><u>shortStock(sym, shares)</u></i><br>" +
|
||||
"Attempts to purchase a short position of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument " +
|
||||
"must be the number of shares to purchase.<br><br>" +
|
||||
"In order to use this function the player must be in BitNode-8 or must have Level 2 of Source-File 8.<br><br>" +
|
||||
"If the player does not have enough money to purchase the specified number of shares, then no shares will be purchased. Remember that every " +
|
||||
"every transaction on the stock exchange costs a certain commission fee.<br><br>" +
|
||||
"Returns true if it successfully shorts the stock with the specified number of shares, and false otherwise.<br><br>" +
|
||||
"<i><u>sellShort(sym, shares)</u></i><br>" +
|
||||
"Attempts to sell a short position of a stock using a Market Order. The first argument must be a string with the stock's symbol. The second argument must be the " +
|
||||
"number of shares to sell.<br><br>" +
|
||||
"In order to use this function the player must be in BitNode-8 or must have Level 2 of Source-File 8.<br><br>" +
|
||||
"If the specified number of shares exceeds the amount that the player actually owns, then this function will sell all owned shares. " +
|
||||
"Remember that every transaction on the stock exchange costs a certain commission fee.<br><br>" +
|
||||
"This function returns true if it successfully sells any number of shares, and false otherwise.<br><br>" +
|
||||
"<i><u>placeOrder(sym, shares, price, type, pos)</u></i><br>" +
|
||||
"Places an order on the stock market. This function only works for Limit and Stop Orders. Use the buyStock/sellStock/shortStock/sellShort functions " +
|
||||
"to place Market Orders. In order to use this function the player must be in BitNode-8 or must have Level 3 of Source-File 8.<br><br>" +
|
||||
"The 'sym' argument must be a string with the symbol of the stock. The 'shares' and 'price' arguments " +
|
||||
"specify the number of shares and the execution price for the order. They must be numeric.<br><br>" +
|
||||
"The 'type' argument is a string that specifies the type of order. It must specify either 'limit' or 'stop', and must " +
|
||||
"also specify 'buy' or 'sell'. This argument is NOT case-sensitive. Here are four examples that will work: <br><br>" +
|
||||
"limitbuy, limitsell, stopbuy, stopsell<br><br>" +
|
||||
"The last argument, 'pos', is a string that specifies whether the order is a 'Long' or 'Short' position. The values 'L' and " +
|
||||
"'S' can also be used. This argument is NOT case-sensitive.<br><br>" +
|
||||
"Returns true if the order is successfully placed, and false otherwise.<br><br>" +
|
||||
"<i><u>cancelOrder(sym, shares, price, type, pos)</u></i><br>" +
|
||||
"Cancels an oustanding order on the stock market. In order to use this function the player must be in BitNode-8 or must have " +
|
||||
"Level 3 of Source-File 8. This function uses the same arguments as placeOrder()<br><br>" +
|
||||
"<u><h1>While loops </h1></u><br>" +
|
||||
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met. <br><br> " +
|
||||
"<i>while (<i>[cond]</i>) {<br> <i>[code]</i><br>}</i><br><br>" +
|
||||
@ -800,7 +830,7 @@ let CONSTANTS = {
|
||||
"then you will be able to access all of the Singularity Functions.<br><br>" +
|
||||
"Note that Singularity Functions require a lot of RAM outside of BitNode-4 (their RAM costs are multiplied by " +
|
||||
"10 if you are not in BitNode-4).<br><br>" +
|
||||
"<i>universityCourse(universityName, courseName)</i><br>" +
|
||||
"<i><u>universityCourse(universityName, courseName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically set you to start taking a course at a university. If you are already " +
|
||||
"in the middle of some 'working' action (such as working at a company, for a faction, or on a program), " +
|
||||
@ -814,7 +844,7 @@ let CONSTANTS = {
|
||||
"The cost and experience gains for all of these universities and classes are the same as if you were to manually " +
|
||||
"visit and take these classes.<br><br>" +
|
||||
"This function will return true if you successfully start taking the course, and false otherwise.<br><br>" +
|
||||
"<i>gymWorkout(gymName, stat)</i><br>" +
|
||||
"<i><u>gymWorkout(gymName, stat)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically set you to start working out at a gym to train a particular stat. If you are " +
|
||||
"already in the middle of some 'working' action (such as working at a company, for a faction, or on a program), then " +
|
||||
@ -826,18 +856,18 @@ let CONSTANTS = {
|
||||
"The valid stats are:<br><br>strength OR str<br>defense OR def<br>dexterity OR dex<br>agility OR agi<br><br>" +
|
||||
"The cost and experience gains for all of these gyms are the same as if you were to manually visit these gyms and train " +
|
||||
"This function will return true if you successfully start working out at the gym, and false otherwise.<br><br>" +
|
||||
"<i>travelToCity(cityname)</i><br>" +
|
||||
"<i><u>travelToCity(cityname)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function allows the player to travel to any city. The cost for using this function is the same as the cost for traveling through the Travel Agency.<br><br>" +
|
||||
"The argument passed into this must be a string with the name of the city to travel to. Note that this argument IS CASE SENSITIVE. The valid cities are:<br><br>" +
|
||||
"Aevum<br>Chongqing<br>Sector-12<br>New Tokyo<br>Ishima<br>Volhaven<br><br>" +
|
||||
"This function will return true if you successfully travel to the specified city and false otherwise.<br><br>" +
|
||||
"<i>purchaseTor()</i><br>" +
|
||||
"<i><u>purchaseTor()</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function allows you to automatically purchase a TOR router. The cost for purchasing a TOR router using this " +
|
||||
"function is the same as if you were to manually purchase one.<br><br>" +
|
||||
"This function will return true if it successfully purchase a TOR router and false otherwise.<br><br>" +
|
||||
"<i>purchaseProgram(programName)</i><br>" +
|
||||
"<i><u>purchaseProgram(programName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function allows you to automatically purchase programs. You MUST have a TOR router in order to use this function.<br><br>" +
|
||||
"The argument passed in must be a string with the name of the program (including the '.exe' extension). This argument is " +
|
||||
@ -846,29 +876,29 @@ let CONSTANTS = {
|
||||
"The cost of purchasing programs using this function is the same as if you were purchasing them through the Dark Web (using " +
|
||||
"the buy Terminal command).<br><br>" +
|
||||
"This function will return true if the specified program is purchased, and false otherwise.<br><br>" +
|
||||
"<i>getStats()</i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this " +
|
||||
"<i><u>getStats()</u></i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this " +
|
||||
"function.<br><br>Returns an object with the Player's stats. The object has the following properties:<br><br>" +
|
||||
"Player.hacking<br>Player.strength<br>Player.defense<br>Player.dexterity<br>Player.agility<br>Player.charisma<br>Player.intelligence<br><br>" +
|
||||
"Example: <br><br>" +
|
||||
"res = getStats();<br>print('My charisma level is: ' + res.charisma);<br><br>" +
|
||||
"<i>isBusy()</i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this " +
|
||||
"<i><u>isBusy()</u></i><br>If you are not in BitNode-4, then you must have Level 1 of Source-File 4 in order to run this " +
|
||||
"function.<br><br>Returns a boolean indicating whether or not the player is currently performing an 'action'. " +
|
||||
"These actions include working for a company/faction, studying at a univeristy, working out at a gym, " +
|
||||
"creating a program, or committing a crime.<br><br>" +
|
||||
"<i>upgradeHomeRam()</i><br>" +
|
||||
"<i><u>upgradeHomeRam()</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will upgrade amount of RAM on the player's home computer. The cost is the same as if you were to do it manually.<br><br>" +
|
||||
"This function will return true if the player's home computer RAM is successfully upgraded, and false otherwise.<br><br>" +
|
||||
"<i>getUpgradeHomeRamCost()</i><br>" +
|
||||
"<i><u>getUpgradeHomeRamCost()</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"Returns the cost of upgrading the player's home computer RAM.<br><br>" +
|
||||
"<i>workForCompany()</i><br>" +
|
||||
"<i><u>workForCompany()</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically set you to start working at the company at which you are employed. If you are already " +
|
||||
"in the middle of some 'working' action (such as working for a faction, training at a gym, or creating a program), then " +
|
||||
"running this function will automatically cancel that action and give you your earnings.<br><br>" +
|
||||
"This function will return true if the player starts working, and false otherwise.<br><br>" +
|
||||
"<i>applyToCompany(companyName, field)</i><br>" +
|
||||
"<i><u>applyToCompany(companyName, field)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically try to apply to the specified company for a position in the specified field. This " +
|
||||
"function can also be used to apply for promotions by specifying the company and field you are already employed at.<br><br>" +
|
||||
@ -879,19 +909,19 @@ let CONSTANTS = {
|
||||
"security<br>agent<br>employee<br>part-time employee<br>waiter<br>part-time waiter<br><br>" +
|
||||
"This function will return true if you successfully get a job/promotion, and false otherwise. Note " +
|
||||
"that if you are trying to use this function to apply for a promotion and you don't get one, it will return false.<br><br>" +
|
||||
"<i>getCompanyRep(companyName)</i><br>" +
|
||||
"<i><u>getCompanyRep(companyName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will return the amount of reputation you have at the specified company. If the company passed in as " +
|
||||
"an argument is invalid, -1 will be returned.<br><br>" +
|
||||
"The argument passed in must be a string with the name of the company. This argument IS CASE-SENSITIVE.<br><br>" +
|
||||
"<i>checkFactionInvitations()</i><br>" +
|
||||
"<i><u>checkFactionInvitations()</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"Returns an array with the name of all Factions you currently have oustanding invitations from.<br><br>" +
|
||||
"<i>joinFaction(name)</i><br>" +
|
||||
"<i><u>joinFaction(name)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically accept an invitation from a faction and join it.<br><br>" +
|
||||
"The argument must be a string with the name of the faction. This name IS CASE-SENSITIVE.<br><br>" +
|
||||
"<i>workForFaction(factionName, workType)</i><br>" +
|
||||
"<i><u>workForFaction(factionName, workType)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically set you to start working for the specified Faction. Obviously, you " +
|
||||
"must be a member of the Faction or else this function will fail. If you are already in the middle of " +
|
||||
@ -901,11 +931,11 @@ let CONSTANTS = {
|
||||
"must be a string with the type of work you want to perform for the faction. The valid values for this argument are:<br><br>" +
|
||||
"<br>hacking/hacking contracts/hackingcontracts<br>field/fieldwork/field work<br>security/securitywork/security work<br><br>" +
|
||||
"This function will return true if you successfully start working for the specified faction, and false otherwise.<br><br>" +
|
||||
"<i>getFactionRep(factionName)</i><br>" +
|
||||
"<i><u>getFactionRep(factionName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 2 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function returns the amount of reputation you have for the specified Faction. The argument must be a " +
|
||||
"string with the name of the Faction. The argument IS CASE-SENSITIVE.<br><br>" +
|
||||
"<i>createProgram(programName)</i><br>" +
|
||||
"<i><u>createProgram(programName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically set you to start working on creating the specified program. If you are already in " +
|
||||
"the middle of some 'working' action (such as working for a company, training at a gym, or taking a course), then " +
|
||||
@ -916,7 +946,7 @@ let CONSTANTS = {
|
||||
"BruteSSH.exe: 50<br>FTPCrack.exe: 100<br>relaySMTP.exe: 250<br>HTTPWorm.exe: 500<br>SQLInject.exe: 750<br>" +
|
||||
"DeepscanV1.exe: 75<br>DeepscanV2.exe: 400<br>ServerProfiler.exe: 75<br>AutoLink.exe: 25<br><br>" +
|
||||
"This function returns true if you successfully start working on the specified program, and false otherwise.<br><br>" +
|
||||
"<i>commitCrime(crime)</i><br>" +
|
||||
"<i><u>commitCrime(crime)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"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 " +
|
||||
@ -925,40 +955,41 @@ let CONSTANTS = {
|
||||
"lenient in terms of what inputs it accepts. Here is a list of valid inputs for all of the crimes:<br><br>" +
|
||||
"shoplift, rob store, mug, larceny, deal drugs, bond forgery, traffick arms, homicide, grand theft auto, " +
|
||||
"kidnap, assassinate, heist<br><br> " +
|
||||
"Crimes committed using this function will have all of their earnings halved (this applies for both money and experience!)<br><br>" +
|
||||
"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). Warning: I do not recommend using the time " +
|
||||
"returned from this function to try and schedule your crime attempts. Instead, I would use the isBusy() Singularity function " +
|
||||
"to check whether you have finished attempting a crime. This is because although the game sets a certain crime to be X amount of seconds, " +
|
||||
"there is no guarantee that your browser will follow that time limit.<br><br>" +
|
||||
"<i>getCrimeChance(crime)</i><br>If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to " +
|
||||
"<i><u>getCrimeChance(crime)</u></i><br>If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to " +
|
||||
"use this function.<br><br>" +
|
||||
"This function returns your chance of success at commiting the specified crime. The chance is returned as a decimal " +
|
||||
"(i.e. 60% would be returned as 0.6). The argument for this function is a string. It is not case-sensitive and is fairly " +
|
||||
"lenient in terms of what inputs it accepts. Check the documentation for the commitCrime() Singularity Function to see " +
|
||||
"examples of valid inputs.<br><br>" +
|
||||
"<i>getOwnedAugmentations(purchased=false)</i><br>" +
|
||||
"<i><u>getOwnedAugmentations(purchased=false)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function returns an array of the names of all Augmentations you own as strings. It takes a single optional " +
|
||||
"boolean argument that specifies whether the returned array should include Augmentations you have purchased " +
|
||||
"but not yet installed. If it is true, then the returned array will include these Augmentations. By default, " +
|
||||
"this argument is false.<br><br>" +
|
||||
"<i>getAugmentationsFromFaction(facName)</i><br>" +
|
||||
"<i><u>getAugmentationsFromFaction(facName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"Returns an array containing the names (as strings) of all Augmentations that are available from the specified faction. " +
|
||||
"The argument must be a string with the faction's name. This argument is case-sensitive.<br><br>" +
|
||||
"<i>getAugmentationCost(augName)</i><br>" +
|
||||
"<i><u>getAugmentationCost(augName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function returns an array with two elements that gives the cost for the specified Augmentation" +
|
||||
". The first element in the returned array is the reputation requirement of the Augmentation, and the second element " +
|
||||
"is the money cost.<br><br>" +
|
||||
"The argument passed in must be a string with the name of the Augmentation. This argument IS CASE-SENSITIVE. " +
|
||||
"If an invalid Augmentation name is passed in, this function will return the array [-1, -1].<br><br>" +
|
||||
"<i>purchaseAugmentation(factionName, augName)</i><br>" +
|
||||
"<i><u>purchaseAugmentation(factionName, augName)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will try to purchase the specified Augmentation through the given Faction.<br><br>" +
|
||||
"The two arguments must be strings specifying the name of the Faction and Augmentation, respectively. These arguments are both CASE-SENSITIVE.<br><br>" +
|
||||
"This function will return true if the Augmentation is successfully purchased, and false otherwise.<br><br>" +
|
||||
"<i>installAugmentations(cbScript)</i><br>" +
|
||||
"<i><u>installAugmentations(cbScript)</u></i><br>" +
|
||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||
"This function will automatically install your Augmentations, resetting the game as usual.<br><br>" +
|
||||
"It will return true if successful, and false otherwise.<br><br>" +
|
||||
@ -1065,27 +1096,10 @@ let CONSTANTS = {
|
||||
"World Stock Exchange account and TIX API Access<br>",
|
||||
|
||||
LatestUpdate:
|
||||
"v0.31.0<br>" +
|
||||
"-Game now saves to IndexedDb (if your browser supports it). This means you should " +
|
||||
"no longer have trouble saving the game when your save file gets too big (from running " +
|
||||
"too many scripts). " +
|
||||
"The game will still be saved to localStorage as well<br>" +
|
||||
"-New file type: text files (.txt). You can read or write to text files using the read()/write() Netscript commands. " +
|
||||
"You can view text files in Terminal using 'cat'. Eventually I will make it so you can edit them in the editor " +
|
||||
"but that's not available yet. You can also download files to your real computer using the 'download' Terminal command<br>" +
|
||||
"-Added a new Crime: Bond Forgery. This crime takes 5 minutes to attempt " +
|
||||
"and gives $4,500,000 if successful. It is meant for mid game.<br>" +
|
||||
"-Added commitCrime(), getCrimeChance(), isBusy(), and getStats() Singularity Functions.<br>" +
|
||||
"-Removed getIntelligence() Netscript function<br>" +
|
||||
"-Added sprintf and vsprintf to Netscript. See <a href='https://github.com/alexei/sprintf.js' target='_blank'>this Github page for details</a><br>" +
|
||||
"-Increased the amount of money gained from Infiltration by 20%, and the amount of faction reputation by 12%<br>" +
|
||||
"-Rebalanced BitNode-2 so that Crime and Infiltration are more profitable but hacking is less profitable. Infiltration also gives more faction rep<br>" +
|
||||
"-Rebalanced BitNode-4 so that hacking is slightly less profitable<br>" +
|
||||
"-Rebalanced BitNode-5 so that Infiltration is more profitable and gives more faction rep<br>" +
|
||||
"-Rebalanced BitNode-11 so that Crime and Infiltration are more profitable. Infiltration also gives more faction rep.<br>" +
|
||||
"-Fixed an annoying issue in Hacking Missions where sometimes you would click a Node but it wouldnt actually get selected<br>" +
|
||||
"-Made the Hacking Mission gameplay a bit slower by lowering the effect of Scan and reducing Attack damage<br>" +
|
||||
"-Slightly increased the base reputation gain rate for factions when doing Field Work and Security Work<br>"
|
||||
"v0.32.0<br>" +
|
||||
"-Released BitNode-8: Ghost of Wall Street<br>" +
|
||||
"-Re-designed Stock Market UI<br>" +
|
||||
"-Minor bugfixes<br>"
|
||||
}
|
||||
|
||||
export {CONSTANTS};
|
||||
|
@ -605,7 +605,7 @@ function displayFactionContent(factionName) {
|
||||
}
|
||||
|
||||
if (faction.isMember) {
|
||||
if (faction.favor >= 150) {
|
||||
if (faction.favor >= (150 * BitNodeMultipliers.RepToDonateToFaction)) {
|
||||
donateDiv.style.display = "inline";
|
||||
} else {
|
||||
donateDiv.style.display = "none";
|
||||
|
@ -1132,7 +1132,7 @@ function setGangMemberClickHandlers() {
|
||||
//Server panel click handlers
|
||||
var gangMemberHdrs = document.getElementsByClassName("gang-member-header");
|
||||
if (gangMemberHdrs == null) {
|
||||
console.log("ERROR: Could not find Active Scripts server panels");
|
||||
console.log("ERROR: Could not find Gang Member Headers");
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < gangMemberHdrs.length; ++i) {
|
||||
@ -1243,7 +1243,6 @@ function createGangMemberDisplayElement(memberObj) {
|
||||
taskDescP.style.display = "inline";
|
||||
taskDescDiv.appendChild(taskDescP);
|
||||
|
||||
|
||||
statsDiv.style.width = "30%";
|
||||
taskDiv.style.width = "30%";
|
||||
taskDescDiv.style.width = "30%";
|
||||
|
@ -48,6 +48,7 @@ function InfiltrationInstance(companyName, startLevel, val, maxClearance, diff)
|
||||
this.dexExpGained = 0;
|
||||
this.agiExpGained = 0;
|
||||
this.chaExpGained = 0;
|
||||
this.intExpGained = 0;
|
||||
}
|
||||
|
||||
InfiltrationInstance.prototype.gainHackingExp = function(amt) {
|
||||
@ -80,6 +81,11 @@ InfiltrationInstance.prototype.gainCharismaExp = function(amt) {
|
||||
this.chaExpGained += amt;
|
||||
}
|
||||
|
||||
InfiltrationInstance.prototype.gainIntelligenceExp = function(amt) {
|
||||
if (isNaN(amt)) {return;}
|
||||
this.intExpGained += amt;
|
||||
}
|
||||
|
||||
function beginInfiltration(companyName, startLevel, val, maxClearance, diff) {
|
||||
var inst = new InfiltrationInstance(companyName, startLevel, val, maxClearance, diff);
|
||||
clearInfiltrationStatusText();
|
||||
@ -87,9 +93,7 @@ function beginInfiltration(companyName, startLevel, val, maxClearance, diff) {
|
||||
}
|
||||
|
||||
function endInfiltration(inst, success) {
|
||||
if (success) {
|
||||
infiltrationBoxCreate(inst);
|
||||
}
|
||||
if (success) {infiltrationBoxCreate(inst);}
|
||||
|
||||
clearEventListeners("infiltration-kill");
|
||||
clearEventListeners("infiltration-knockout");
|
||||
@ -588,10 +592,10 @@ let intWgt = CONSTANTS.IntelligenceInfiltrationWeight;
|
||||
//Success: 5%, Failure 10%, -Karma
|
||||
function attemptInfiltrationKill(inst) {
|
||||
var chance = getInfiltrationKillChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 100) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 100) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 100) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 90) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 90) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 90) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 90) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.05;
|
||||
return [true, 1.05];
|
||||
@ -614,10 +618,10 @@ function getInfiltrationKillChance(inst) {
|
||||
//Success: 3%, Failure: 10%
|
||||
function attemptInfiltrationKnockout(inst) {
|
||||
var chance = getInfiltrationKnockoutChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 100) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 100) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 100) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 85) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 85) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 85) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 85) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.03;
|
||||
return [true, 1.03];
|
||||
@ -639,9 +643,9 @@ function getInfiltrationKnockoutChance(inst) {
|
||||
//Success: 0%, Failure: 10%
|
||||
function attemptInfiltrationStealthKnockout(inst) {
|
||||
var chance = getInfiltrationStealthKnockoutChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 90) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 70) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 70) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -663,9 +667,9 @@ function getInfiltrationStealthKnockoutChance(inst) {
|
||||
//Success: 0%, Failure: 5%, -Karma
|
||||
function attemptInfiltrationAssassinate(inst) {
|
||||
var chance = getInfiltrationAssassinateChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 90) * Player.strength_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 70) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 70) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -687,10 +691,10 @@ function getInfiltrationAssassinateChance(inst) {
|
||||
//Success: 5%, Failure: 10%
|
||||
function attemptInfiltrationDestroySecurity(inst) {
|
||||
var chance = getInfiltrationDestroySecurityChance(inst);
|
||||
inst.gainStrengthExp(inst.securityLevel / 100) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 100) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 100) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 100) * Player.agility_exp_mult;
|
||||
inst.gainStrengthExp(inst.securityLevel / 90) * Player.strength_exp_mult;
|
||||
inst.gainDefenseExp(inst.securityLevel / 90) * Player.defense_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 90) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 90) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.05;
|
||||
return [true, 1.05];
|
||||
@ -714,7 +718,8 @@ function getInfiltrationDestroySecurityChance(inst) {
|
||||
//Success: 1%, Failure: 5%
|
||||
function attemptInfiltrationHack(inst) {
|
||||
var chance = getInfiltrationHackChance(inst);
|
||||
inst.gainHackingExp(inst.securityLevel / 75) * Player.hacking_exp_mult;
|
||||
inst.gainHackingExp(inst.securityLevel / 50) * Player.hacking_exp_mult;
|
||||
inst.gainIntelligenceExp(inst.securityLevel / 700);
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.03;
|
||||
return [true, 1.03];
|
||||
@ -736,7 +741,7 @@ function getInfiltrationHackChance(inst) {
|
||||
//Success: 0%, Failure: 8%
|
||||
function attemptInfiltrationSneak(inst) {
|
||||
var chance = getInfiltrationSneakChance(inst);
|
||||
inst.gainAgilityExp(inst.securityLevel / 75) * Player.agility_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 50) * Player.agility_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -757,7 +762,7 @@ function getInfiltrationSneakChance(inst) {
|
||||
//Success: 1%, Failure: 3%
|
||||
function attemptInfiltrationPickLockedDoor(inst) {
|
||||
var chance = getInfiltrationPickLockedDoorChance(inst);
|
||||
inst.gainDexterityExp(inst.securityLevel / 75) * Player.dexterity_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 40) * Player.dexterity_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
inst.securityLevel *= 1.01;
|
||||
return [true, 1.01];
|
||||
@ -778,7 +783,7 @@ function getInfiltrationPickLockedDoorChance(inst) {
|
||||
//Success: 0%, Failure: 15%,
|
||||
function attemptInfiltrationBribe(inst) {
|
||||
var chance = getInfiltrationBribeChance(inst);
|
||||
inst.gainCharismaExp(inst.securityLevel / 50) * Player.charisma_exp_mult;
|
||||
inst.gainCharismaExp(inst.securityLevel / 10) * Player.charisma_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
@ -797,8 +802,8 @@ function getInfiltrationBribeChance(inst) {
|
||||
//Failure: 5%
|
||||
function attemptInfiltrationEscape(inst) {
|
||||
var chance = getInfiltrationEscapeChance(inst);
|
||||
inst.gainAgilityExp(inst.securityLevel / 50) * Player.agility_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 50) * Player.dexterity_exp_mult;
|
||||
inst.gainAgilityExp(inst.securityLevel / 40) * Player.agility_exp_mult;
|
||||
inst.gainDexterityExp(inst.securityLevel / 40) * Player.dexterity_exp_mult;
|
||||
if (Math.random() <= chance) {
|
||||
return [true, 1];
|
||||
} else {
|
||||
|
@ -41,7 +41,8 @@ import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
||||
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
||||
sellStock, updateStockPrices, displayStockMarketContent,
|
||||
updateStockTicker, updateStockPlayerPosition,
|
||||
Stock} from "./StockMarket.js";
|
||||
Stock, shortStock, sellShort, OrderTypes,
|
||||
PositionTypes, placeOrder, cancelOrder} from "./StockMarket.js";
|
||||
import {post} from "./Terminal.js";
|
||||
import {TextFile, getTextFile, createTextFile} from "./TextFile.js";
|
||||
|
||||
@ -59,8 +60,8 @@ import {printArray, powerOfTwo} from "../utils/HelperFunctio
|
||||
import {createRandomIp} from "../utils/IPAddress.js";
|
||||
import {formatNumber, isString, isHTML} from "../utils/StringHelperFunctions.js";
|
||||
|
||||
var hasSingularitySF = false, hasAISF = false, hasBn11SF = false;
|
||||
var singularitySFLvl = 1;
|
||||
var hasSingularitySF=false, hasAISF=false, hasBn11SF=false, hasWallStreetSF=false;
|
||||
var singularitySFLvl=1, wallStreetSFLvl=1;
|
||||
|
||||
//Used to check and set flags for every Source File, despite the name of the function
|
||||
function initSingularitySFFlags() {
|
||||
@ -72,6 +73,10 @@ function initSingularitySFFlags() {
|
||||
if (Player.sourceFiles[i].n === 5) {
|
||||
hasAISF = true;
|
||||
}
|
||||
if (Player.sourceFiles[i].n === 8) {
|
||||
hasWallStreetSF = true;
|
||||
wallStreetSFLvl = Player.sourceFiles[i].lvl;
|
||||
}
|
||||
if (Player.sourceFiles[i].n === 11) {
|
||||
hasBn11SF = true;
|
||||
}
|
||||
@ -845,7 +850,7 @@ function NetscriptFunctions(workerScript) {
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
}
|
||||
return [stock.playerShares, stock.playerAvgPx];
|
||||
return [stock.playerShares, stock.playerAvgPx, stock.playerShortShares, stock.playerAvgShortPx];
|
||||
},
|
||||
buyStock : function(symbol, shares) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
@ -853,9 +858,9 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into buyStock()");
|
||||
}
|
||||
if (stock == null || shares < 0 || isNaN(shares)) {
|
||||
if (shares < 0 || isNaN(shares)) {
|
||||
workerScript.scriptRef.log("Error: Invalid 'shares' argument passed to buyStock()");
|
||||
return false;
|
||||
}
|
||||
@ -888,10 +893,9 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into sellStock()");
|
||||
}
|
||||
|
||||
if (stock == null || shares < 0 || isNaN(shares)) {
|
||||
if (shares < 0 || isNaN(shares)) {
|
||||
workerScript.scriptRef.log("Error: Invalid 'shares' argument passed to sellStock()");
|
||||
return false;
|
||||
}
|
||||
@ -919,6 +923,121 @@ function NetscriptFunctions(workerScript) {
|
||||
"$" + formatNumber(gains, 2));
|
||||
return true;
|
||||
},
|
||||
shortStock(symbol, shares) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use shortStock()");
|
||||
}
|
||||
if (Player.bitNodeN !== 8) {
|
||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use shortStock(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into shortStock()");
|
||||
}
|
||||
return shortStock(stock, shares, workerScript);
|
||||
},
|
||||
sellShort(symbol, shares) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use sellShort()");
|
||||
}
|
||||
if (Player.bitNodeN !== 8) {
|
||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use sellShort(). You must either be in BitNode-8 or you must have Level 2 of Source-File 8");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into sellShort()");
|
||||
}
|
||||
return sellShort(stock, shares, workerScript);
|
||||
},
|
||||
placeOrder(symbol, shares, price, type, pos) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use placeOrder()");
|
||||
}
|
||||
if (Player.bitNodeN !== 8) {
|
||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use placeOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into placeOrder()");
|
||||
}
|
||||
var orderType, orderPos;
|
||||
type = type.toLowerCase();
|
||||
if (type.includes("limit") && type.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (type.includes("limit") && type.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (type.includes("stop") && type.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (type.includes("stop") && type.includes("sell")) {
|
||||
orderType = OrderTypes.StopSell;
|
||||
} else {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid Order Type passed into placeOrder()");
|
||||
}
|
||||
|
||||
pos = pos.toLowerCase();
|
||||
if (pos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (pos.includes('s')) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid Position Type passed into placeOrder()");
|
||||
}
|
||||
|
||||
return placeOrder(stock, shares, price, orderType, orderPos, workerScript);
|
||||
},
|
||||
cancelOrder(symbol, shares, price, type, pos) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use cancelOrder()");
|
||||
}
|
||||
if (Player.bitNodeN !== 8) {
|
||||
if (!(hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Cannot use cancelOrder(). You must either be in BitNode-8 or have Level 3 of Source-File 8");
|
||||
}
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid stock symbol passed into cancelOrder()");
|
||||
}
|
||||
if (isNaN(shares) || isNaN(price)) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid shares or price argument passed into cancelOrder(). Must be numeric");
|
||||
}
|
||||
var orderType, orderPos;
|
||||
type = type.toLowerCase();
|
||||
if (type.includes("limit") && type.includes("buy")) {
|
||||
orderType = OrderTypes.LimitBuy;
|
||||
} else if (type.includes("limit") && type.includes("sell")) {
|
||||
orderType = OrderTypes.LimitSell;
|
||||
} else if (type.includes("stop") && type.includes("buy")) {
|
||||
orderType = OrderTypes.StopBuy;
|
||||
} else if (type.includes("stop") && type.includes("sell")) {
|
||||
orderType = OrderType.StopSell;
|
||||
} else {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid Order Type passed into placeOrder()");
|
||||
}
|
||||
|
||||
pos = pos.toLowerCase();
|
||||
if (pos.includes("l")) {
|
||||
orderPos = PositionTypes.Long;
|
||||
} else if (pos.includes('s')) {
|
||||
orderPos = PositionTypes.Short;
|
||||
} else {
|
||||
throw makeRuntimeRejectMsg(workerScript, "ERROR: Invalid Position Type passed into placeOrder()");
|
||||
}
|
||||
params = {
|
||||
stock: stock,
|
||||
shares: shares,
|
||||
price: price,
|
||||
type: orderType,
|
||||
pos: orderPos
|
||||
};
|
||||
return cancelOrder(params, workerScript);
|
||||
},
|
||||
purchaseServer : function(hostname, ram) {
|
||||
var hostnameStr = String(hostname);
|
||||
hostnameStr = hostnameStr.replace(/\s\s+/g, '');
|
||||
@ -1979,6 +2098,30 @@ function NetscriptFunctions(workerScript) {
|
||||
workerScript.scriptRef.log(txt);
|
||||
}
|
||||
|
||||
//Set Location to slums
|
||||
switch(Player.city) {
|
||||
case Locations.Aevum:
|
||||
Player.location = Locations.AevumSlums;
|
||||
break;
|
||||
case Locations.Chongqing:
|
||||
Player.location = Locations.ChongqingSlums;
|
||||
break;
|
||||
case Locations.Sector12:
|
||||
Player.location = Locations.Sector12Slums;
|
||||
break;
|
||||
case Locations.NewTokyo:
|
||||
Player.location = Locations.NewTokyoSlums;
|
||||
break;
|
||||
case Locations.Ishima:
|
||||
Player.location = Locations.IshimaSlums;
|
||||
break;
|
||||
case Locations.Volhaven:
|
||||
Player.location = Locations.VolhavenSlums;
|
||||
break;
|
||||
default:
|
||||
console.log("Invalid Player.city value");
|
||||
}
|
||||
|
||||
crime = crime.toLowerCase();
|
||||
if (crime.includes("shoplift")) {
|
||||
workerScript.scriptRef.log("Attempting to shoplift...");
|
||||
@ -2190,4 +2333,5 @@ function NetscriptFunctions(workerScript) {
|
||||
}
|
||||
}
|
||||
|
||||
export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF, hasBn11SF};
|
||||
export {NetscriptFunctions, initSingularitySFFlags, hasSingularitySF, hasBn11SF, hasWallStreetSF,
|
||||
wallStreetSFLvl};
|
||||
|
@ -13,7 +13,7 @@ import {Factions, Faction,
|
||||
displayFactionContent} from "./Faction.js";
|
||||
import {Gang, resetGangs} from "./Gang.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {hasBn11SF} from "./NetscriptFunctions.js";
|
||||
import {hasBn11SF, hasWallStreetSF} from "./NetscriptFunctions.js";
|
||||
import {AllServers, Server, AddToAllServers} from "./Server.js";
|
||||
import {SpecialServerIps, SpecialServerNames} from "./SpecialServerIps.js";
|
||||
import {SourceFiles, applySourceFile} from "./SourceFile.js";
|
||||
@ -367,6 +367,13 @@ PlayerObject.prototype.prestigeSourceFile = function() {
|
||||
this.hasWseAccount = false;
|
||||
this.hasTixApiAccess = false;
|
||||
|
||||
//BitNode 8: Ghost of Wall Street
|
||||
if (this.bitNodeN === 8) {this.money = new Decimal(100000000);}
|
||||
if (this.bitNodeN === 8 || hasWallStreetSF) {
|
||||
this.hasWseAccount = true;
|
||||
this.hasTixApiAccess = true;
|
||||
}
|
||||
|
||||
this.playtimeSinceLastAug = 0;
|
||||
this.scriptProdSinceLastAug = 0;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import {Factions, Faction, initFactions,
|
||||
joinFaction} from "./Faction.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {initMessages, Messages, Message} from "./Message.js";
|
||||
import {initSingularitySFFlags} from "./NetscriptFunctions.js";
|
||||
import {initSingularitySFFlags, hasWallStreetSF}from "./NetscriptFunctions.js";
|
||||
import {WorkerScript, workerScripts,
|
||||
prestigeWorkerScripts} from "./NetscriptWorker.js";
|
||||
import {Player} from "./Player.js";
|
||||
@ -116,6 +116,13 @@ function prestigeAugmentation() {
|
||||
}
|
||||
}
|
||||
|
||||
//BitNode 8: Ghost of Wall Street
|
||||
if (Player.bitNodeN === 8) {Player.money = new Decimal(100000000);}
|
||||
if (Player.bitNodeN === 8 || hasWallStreetSF) {
|
||||
Player.hasWseAccount = true;
|
||||
Player.hasTixApiAccess = true;
|
||||
}
|
||||
|
||||
var mainMenu = document.getElementById("mainmenu-container");
|
||||
mainMenu.style.visibility = "visible";
|
||||
Terminal.resetTerminalInput();
|
||||
|
@ -209,7 +209,7 @@ function loadBitVerse(destroyedBitNodeNum) {
|
||||
var elemId = "bitnode-" + i.toString();
|
||||
var elem = clearEventListeners(elemId);
|
||||
if (elem == null) {return;}
|
||||
if (i === 1 || i === 2 || i === 4 || i === 5 || i === 11) {
|
||||
if (i === 1 || i === 2 || i === 4 || i === 5 || i === 8 || i === 11) {
|
||||
elem.addEventListener("click", function() {
|
||||
var bitNodeKey = "BitNode" + i;
|
||||
var bitNode = BitNodes[bitNodeKey];
|
||||
|
@ -82,13 +82,15 @@ BitburnerSaveObject.prototype.saveGame = function(db) {
|
||||
}
|
||||
|
||||
request.onsuccess = function(e) {
|
||||
console.log("Successfully saved game to IndexedDB!");
|
||||
console.log("Saved game to IndexedDB!");
|
||||
}
|
||||
|
||||
try {
|
||||
window.localStorage.setItem("bitburnerSave", saveString);
|
||||
console.log("Saved game to LocalStorage!");
|
||||
} catch(e) {
|
||||
if (e.code == 22) {
|
||||
Engine.createStatusText("Save failed for localStorage! Check console(F12)");
|
||||
console.log("Failed to save game to localStorage because the size of the save file " +
|
||||
"is too large. However, the game will still be saved to IndexedDb if your browser " +
|
||||
"supports it. If you would like to save to localStorage as well, then " +
|
||||
@ -97,7 +99,6 @@ BitburnerSaveObject.prototype.saveGame = function(db) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Game saved!");
|
||||
Engine.createStatusText("Game saved!");
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,11 @@ function calculateRamUsage(codeCopy) {
|
||||
var scriptGetStockCount = numOccurrences(codeCopy, "getStockPrice(") +
|
||||
numOccurrences(codeCopy, "getStockPosition(");
|
||||
var scriptBuySellStockCount = numOccurrences(codeCopy, "buyStock(") +
|
||||
numOccurrences(codeCopy, "sellStock(");
|
||||
numOccurrences(codeCopy, "sellStock(") +
|
||||
numOccurrences(codeCopy, "shortStock(") +
|
||||
numOccurrences(codeCopy, "sellShort(") +
|
||||
numOccurrences(codeCopy, "placeOrder(") +
|
||||
numOccurrences(codeCopy, "cancelOrder(");
|
||||
var scriptPurchaseServerCount = numOccurrences(codeCopy, "purchaseServer(") +
|
||||
numOccurrences(codeCopy, "deleteServer(") +
|
||||
numOccurrences(codeCopy, "getPurchasedServers(");
|
||||
@ -307,7 +311,8 @@ function calculateRamUsage(codeCopy) {
|
||||
numOccurrences(codeCopy, "travelToCity(") +
|
||||
numOccurrences(codeCopy, "purchaseTor(") +
|
||||
numOccurrences(codeCopy, "purchaseProgram(") +
|
||||
numOccurrences(codeCopy, "getStats(");
|
||||
numOccurrences(codeCopy, "getStats(") +
|
||||
numOccurrences(codeCopy, "isBusy(");
|
||||
var singFn2Count = numOccurrences(codeCopy, "upgradeHomeRam(") +
|
||||
numOccurrences(codeCopy, "getUpgradeHomeRamCost(") +
|
||||
numOccurrences(codeCopy, "workForCompany(") +
|
||||
@ -319,6 +324,7 @@ function calculateRamUsage(codeCopy) {
|
||||
numOccurrences(codeCopy, "getFactionRep(");
|
||||
var singFn3Count = numOccurrences(codeCopy, "createProgram(") +
|
||||
numOccurrences(codeCopy, "commitCrime(") +
|
||||
numOccurrences(codeCopy, "getCrimeChance(") +
|
||||
numOccurrences(codeCopy, "getOwnedAugmentations(") +
|
||||
numOccurrences(codeCopy, "getAugmentationsFromFaction(") +
|
||||
numOccurrences(codeCopy, "getAugmentationCost(") +
|
||||
|
@ -44,7 +44,12 @@ function initSourceFiles() {
|
||||
"Level 3: 7%");
|
||||
SourceFiles["SourceFile6"] = new SourceFile(6);
|
||||
SourceFiles["SourceFile7"] = new SourceFile(7);
|
||||
SourceFiles["SourceFile8"] = new SourceFile(8);
|
||||
SourceFiles["SourceFile8"] = new SourceFile(8, "This Source-File grants the following benefits:<br><br>" +
|
||||
"Level 1: Permanent access to WSE and TIX API<br>" +
|
||||
"Level 2: Ability to short stocks in other BitNodes<br>" +
|
||||
"Level 3: Ability to use limit/stop orders in other BitNodes<br><br>" +
|
||||
"This Source-File also increases your hacking growth multipliers by: " +
|
||||
"<br>Level 1: 8%<br>Level 2: 12%<br>Level 3: 14%");
|
||||
SourceFiles["SourceFile9"] = new SourceFile(9);
|
||||
SourceFiles["SourceFile10"] = new SourceFile(10);
|
||||
SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File makes it so that company favor increases BOTH the player's salary and reputation gain rate " +
|
||||
@ -131,6 +136,14 @@ function applySourceFile(srcFile) {
|
||||
Player.hacking_mult *= incMult;
|
||||
Player.hacking_exp_mult *= incMult;
|
||||
break;
|
||||
case 8: //Ghost of Wall Street
|
||||
var mult = 0;
|
||||
for (var i = 0; i < srcFile.lvl; ++i) {
|
||||
mult += (8 / (Math.pow(2, i)));
|
||||
}
|
||||
var incMult = 1 + (mult / 100);
|
||||
Player.hacking_grow_mult *= incMult;
|
||||
break;
|
||||
case 11: //The Big Crash
|
||||
var mult = 0;
|
||||
for (var i = 0; i < srcFile.lvl; ++i) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {CONSTANTS} from "./Constants.js";
|
||||
import {Engine} from "./engine.js";
|
||||
import {Locations} from "./Location.js";
|
||||
import {hasWallStreetSF, wallStreetSFLvl} from "./NetscriptFunctions.js";
|
||||
import {WorkerScript} from "./NetscriptWorker.js";
|
||||
import {Player} from "./Player.js";
|
||||
|
||||
@ -10,6 +11,11 @@ import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
import numeral from "../utils/numeral.min.js";
|
||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
|
||||
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton,
|
||||
yesNoTxtInpBoxGetInput, yesNoBoxClose,
|
||||
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox.js";
|
||||
|
||||
/* StockMarket.js */
|
||||
function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
|
||||
@ -24,6 +30,8 @@ function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
|
||||
this.mv = mv;
|
||||
this.b = b;
|
||||
this.otlkMag = otlkMag;
|
||||
|
||||
this.posTxtEl = null;
|
||||
}
|
||||
|
||||
Stock.prototype.toJSON = function() {
|
||||
@ -36,9 +44,149 @@ Stock.fromJSON = function(value) {
|
||||
|
||||
Reviver.constructors.Stock = Stock;
|
||||
|
||||
//Order types (long and short for each):
|
||||
// - Limit Order
|
||||
// - Stop Order
|
||||
var OrderTypes = {
|
||||
LimitBuy: "Limit Buy Order",
|
||||
LimitSell: "Limit Sell Order",
|
||||
StopBuy: "Stop Buy Order",
|
||||
StopSell: "Stop Sell Order"
|
||||
}
|
||||
|
||||
var PositionTypes = {
|
||||
Long: "L",
|
||||
Short: "S"
|
||||
}
|
||||
|
||||
function placeOrder(stock, shares, price, type, position, workerScript=null) {
|
||||
var tixApi = (workerScript instanceof WorkerScript);
|
||||
var order = new Order(stock, shares, price, type, position);
|
||||
if (isNaN(shares) || isNaN(price)) {
|
||||
if (tixApi) {
|
||||
workerScript.scriptRef.log("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument");
|
||||
} else {
|
||||
dialogBoxCreate("ERROR: Invalid numeric value provided for either 'shares' or 'price' argument");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (StockMarket["Orders"] === null) {
|
||||
var orders = {};
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;}
|
||||
orders[stock.symbol] = [];
|
||||
}
|
||||
}
|
||||
StockMarket["Orders"] = orders;
|
||||
}
|
||||
StockMarket["Orders"][stock.symbol].push(order);
|
||||
//Process to see if it should be executed immediately
|
||||
processOrders(order.stock, order.type, order.pos);
|
||||
updateStockOrderList(order.stock);
|
||||
return true;
|
||||
}
|
||||
|
||||
//Returns true if successfully cancels an order, false otherwise
|
||||
function cancelOrder(params, workerScript=null) {
|
||||
var tixApi = (workerScript instanceof WorkerScript);
|
||||
if (StockMarket["Orders"] === null) {return false;}
|
||||
if (params.order && params.order instanceof Order) {
|
||||
var order = params.order;
|
||||
//An 'Order' object is passed in
|
||||
var stockOrders = StockMarket["Orders"][order.stock.symbol];
|
||||
for (var i = 0; i < stockOrders.length; ++i) {
|
||||
if (order == stockOrders[i]) {
|
||||
stockOrders.splice(i, 1);
|
||||
updateStockOrderList(order.stock);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else if (params.stock && params.shares && params.price && params.type &&
|
||||
params.pos && params.stock instanceof Stock) {
|
||||
//Order properties are passed in. Need to look for the order
|
||||
var stockOrders = StockMarket["Orders"][params.stock.symbol];
|
||||
var orderTxt = params.stock.symbol + " - " + params.shares + " @ " +
|
||||
numeral(params.price).format('$0.000a');
|
||||
for (var i = 0; i < stockOrders.length; ++i) {
|
||||
var order = stockOrders[i];
|
||||
if (params.shares === order.shares &&
|
||||
params.price === order.price &&
|
||||
params.type === order.type &&
|
||||
params.pos === order.pos) {
|
||||
stockOrders.splice(i, 1);
|
||||
updateStockOrderList(order.stock);
|
||||
if (tixApi) {
|
||||
workerScript.scriptRef.log("Successfully cancelled order: " + orderTxt);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (tixApi) {
|
||||
workerScript.scriptRef.log("Failed to cancel order: " + orderTxt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function executeOrder(order) {
|
||||
var stock = order.stock;
|
||||
var orderBook = StockMarket["Orders"];
|
||||
var stockOrders = orderBook[stock.symbol];
|
||||
var res = true;
|
||||
console.log("Executing the following order:");
|
||||
console.log(order);
|
||||
switch (order.type) {
|
||||
case OrderTypes.LimitBuy:
|
||||
case OrderTypes.StopBuy:
|
||||
if (order.pos === PositionTypes.Long) {
|
||||
res = buyStock(order.stock, order.shares) && res;
|
||||
} else if (order.pos === PositionTypes.Short) {
|
||||
res = shortStock(order.stock, order.shares) && res;
|
||||
}
|
||||
break;
|
||||
case OrderTypes.LimitSell:
|
||||
case OrderTypes.StopSell:
|
||||
if (order.pos === PositionTypes.Long) {
|
||||
res = sellStock(order.stock, order.shares) && res;
|
||||
} else if (order.pos === PositionTypes.Short) {
|
||||
res = sellShort(order.stock, order.shares) && res;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (res) {
|
||||
//Remove order from order book
|
||||
for (var i = 0; i < stockOrders.length; ++i) {
|
||||
if (order == stockOrders[i]) {
|
||||
stockOrders.splice(i, 1);
|
||||
updateStockOrderList(order.stock);
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.log("ERROR: Could not find the following Order in Order Book: ");
|
||||
console.log(order);
|
||||
} else {
|
||||
console.log("Order failed to execute");
|
||||
}
|
||||
}
|
||||
|
||||
function Order(stock, shares, price, type, position) {
|
||||
this.stock = stock;
|
||||
this.shares = shares;
|
||||
this.price = price;
|
||||
this.type = type;
|
||||
this.pos = position;
|
||||
}
|
||||
|
||||
Order.prototype.toJSON = function() {
|
||||
return Generic_toJSON("Order", this);
|
||||
}
|
||||
|
||||
Order.fromJSON = function(value) {
|
||||
return Generic_fromJSON(Order, value.data);
|
||||
}
|
||||
|
||||
Reviver.constructors.Order = Order;
|
||||
|
||||
let StockMarket = {} //Full name to stock object
|
||||
let StockSymbols = {} //Full name to symbol
|
||||
@ -179,7 +327,7 @@ function initStockMarket() {
|
||||
StockMarket[watchdog] = watchdogStk;
|
||||
|
||||
var lexocorp = Locations.VolhavenLexoCorp;
|
||||
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], 1.25, true, 3, getRandomInt(5000, 7500));
|
||||
var lexocorpStk = new Stock(lexocorp, StockSymbols[lexocorp], 1.25, true, 6, getRandomInt(5000, 7500));
|
||||
StockMarket[lexocorp] = lexocorpStk;
|
||||
|
||||
var rho = Locations.AevumRhoConstruction;
|
||||
@ -187,15 +335,15 @@ function initStockMarket() {
|
||||
StockMarket[rho] = rhoStk;
|
||||
|
||||
var alpha = Locations.Sector12AlphaEnterprises;
|
||||
var alphaStk = new Stock(alpha, StockSymbols[alpha], 1.05, true, 2, getRandomInt(5000, 7500));
|
||||
var alphaStk = new Stock(alpha, StockSymbols[alpha], 2, true, 10, getRandomInt(5000, 7500));
|
||||
StockMarket[alpha] = alphaStk;
|
||||
|
||||
var syscore = Locations.VolhavenSysCoreSecurities;
|
||||
var syscoreStk = new Stock(syscore, StockSymbols[syscore], 1.25, true, 0, getRandomInt(4000, 7000))
|
||||
var syscoreStk = new Stock(syscore, StockSymbols[syscore], 1.25, true, 2, getRandomInt(4000, 7000))
|
||||
StockMarket[syscore] = syscoreStk;
|
||||
|
||||
var computek = Locations.VolhavenCompuTek;
|
||||
var computekStk = new Stock(computek, StockSymbols[computek], 0.9, true, 0, getRandomInt(2000, 5000));
|
||||
var computekStk = new Stock(computek, StockSymbols[computek], 0.9, true, 2, getRandomInt(2000, 5000));
|
||||
StockMarket[computek] = computekStk;
|
||||
|
||||
var netlink = Locations.AevumNetLinkTechnologies;
|
||||
@ -211,15 +359,15 @@ function initStockMarket() {
|
||||
StockMarket[fns] = fnsStk;
|
||||
|
||||
var sigmacosm = "Sigma Cosmetics";
|
||||
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], 0.9, true, 0, getRandomInt(2000, 3000));
|
||||
var sigmacosmStk = new Stock(sigmacosm, StockSymbols[sigmacosm], 3, true, 0, getRandomInt(2000, 3000));
|
||||
StockMarket[sigmacosm] = sigmacosmStk;
|
||||
|
||||
var joesguns = "Joes Guns";
|
||||
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], 1, true, 1, getRandomInt(500, 1000));
|
||||
var joesgunsStk = new Stock(joesguns, StockSymbols[joesguns], 4, true, 1, getRandomInt(500, 1000));
|
||||
StockMarket[joesguns] = joesgunsStk;
|
||||
|
||||
var catalyst = "Catalyst Ventures";
|
||||
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], 1.25, true, 0, getRandomInt(1000, 1500));
|
||||
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], 1.6, true, 20, getRandomInt(500, 1000));
|
||||
StockMarket[catalyst] = catalystStk;
|
||||
|
||||
var microdyne = "Microdyne Technologies";
|
||||
@ -229,6 +377,16 @@ function initStockMarket() {
|
||||
var titanlabs = "Titan Laboratories";
|
||||
var titanlabsStk = new Stock(titanlabs, StockSymbols[titanlabs], 0.6, true, 11, getRandomInt(15000, 20000));
|
||||
StockMarket[titanlabs] = titanlabsStk;
|
||||
|
||||
var orders = {};
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;}
|
||||
orders[stock.symbol] = [];
|
||||
}
|
||||
}
|
||||
StockMarket["Orders"] = orders;
|
||||
}
|
||||
|
||||
function initSymbolToStockMap() {
|
||||
@ -250,8 +408,8 @@ function stockMarketCycle() {
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
var thresh = 0.62;
|
||||
if (stock.b) {thresh = 0.38;}
|
||||
var thresh = 0.6;
|
||||
if (stock.b) {thresh = 0.4;}
|
||||
if (Math.random() < thresh) {
|
||||
stock.b = !stock.b;
|
||||
}
|
||||
@ -409,6 +567,7 @@ function updateStockPrices() {
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;}
|
||||
var av = (v * stock.mv) / 100;
|
||||
if (isNaN(av)) {av = .02;}
|
||||
|
||||
@ -424,11 +583,19 @@ function updateStockPrices() {
|
||||
var c = Math.random();
|
||||
if (c < chc) {
|
||||
stock.price *= (1 + av);
|
||||
processOrders(stock, OrderTypes.LimitBuy, PositionTypes.Short);
|
||||
processOrders(stock, OrderTypes.LimitSell, PositionTypes.Long);
|
||||
processOrders(stock, OrderTypes.StopBuy, PositionTypes.Long);
|
||||
processOrders(stock, OrderTypes.StopSell, PositionTypes.Short);
|
||||
if (Engine.currentPage == Engine.Page.StockMarket) {
|
||||
updateStockTicker(stock, true);
|
||||
}
|
||||
} else {
|
||||
stock.price /= (1 + av);
|
||||
processOrders(stock, OrderTypes.LimitBuy, PositionTypes.Long);
|
||||
processOrders(stock, OrderTypes.LimitSell, PositionTypes.Short);
|
||||
processOrders(stock, OrderTypes.StopBuy, PositionTypes.Short);
|
||||
processOrders(stock, OrderTypes.StopSell, PositionTypes.Long);
|
||||
if (Engine.currentPage == Engine.Page.StockMarket) {
|
||||
updateStockTicker(stock, false);
|
||||
}
|
||||
@ -447,6 +614,68 @@ function updateStockPrices() {
|
||||
stock.otlkMag *= -1;
|
||||
stock.b = !stock.b;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Checks and triggers any orders for the specified stock
|
||||
function processOrders(stock, orderType, posType) {
|
||||
var orderBook = StockMarket["Orders"];
|
||||
if (orderBook === null) {
|
||||
var orders = {};
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
if (!(stock instanceof Stock)) {continue;}
|
||||
orders[stock.symbol] = [];
|
||||
}
|
||||
}
|
||||
StockMarket["Orders"] = orders;
|
||||
return; //Newly created, so no orders to process
|
||||
}
|
||||
var stockOrders = orderBook[stock.symbol];
|
||||
if (stockOrders === null || !(stockOrders.constructor === Array)) {
|
||||
console.log("ERROR: Invalid Order book for " + stock.symbol + " in processOrders()");
|
||||
stockOrders = [];
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < stockOrders.length; ++i) {
|
||||
var order = stockOrders[i];
|
||||
if (order.type === orderType && order.pos === posType) {
|
||||
switch(order.type) {
|
||||
case OrderTypes.LimitBuy:
|
||||
if (order.pos === PositionTypes.Long && stock.price <= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
} else if (order.pos === PositionTypes.Short && stock.price >= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
}
|
||||
break;
|
||||
case OrderTypes.LimitSell:
|
||||
if (order.pos === PositionTypes.Long && stock.price >= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
} else if (order.pos === PositionTypes.Short && stock.price <= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
}
|
||||
break;
|
||||
case OrderTypes.StopBuy:
|
||||
if (order.pos === PositionTypes.Long && stock.price >= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
} else if (order.pos === PositionTypes.Short && stock.price <= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
}
|
||||
break;
|
||||
case OrderTypes.StopSell:
|
||||
if (order.pos === PositionTypes.Long && stock.price <= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
} else if (order.pos === PositionTypes.Short && stock.price >= order.price) {
|
||||
executeOrder/*66*/(order);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log("Invalid order type: " + order.type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -493,6 +722,51 @@ function displayStockMarketContent() {
|
||||
return false;
|
||||
});
|
||||
|
||||
var investopediaButton = clearEventListeners("stock-market-investopedia");
|
||||
investopediaButton.addEventListener("click", function() {
|
||||
var txt = "When making a transaction on the stock market, there are two " +
|
||||
"types of positions: Long and Short. A Long position is the typical " +
|
||||
"scenario where you buy a stock and earn a profit if the price of that " +
|
||||
"stock increases. Meanwhile, a Short position is the exact opposite. " +
|
||||
"In a Short position you purchase shares of a stock and earn a profit " +
|
||||
"if the price of that stock decreases. This is also called 'shorting' a stock.<br><br>" +
|
||||
"NOTE: Shorting stocks is not available immediately, and must be unlocked later on in the game.<br><br>" +
|
||||
"There are three different types of orders you can make to buy or sell " +
|
||||
"stocks on the exchange: Market Order, Limit Order, and Stop Order. " +
|
||||
"Note that Limit Orders and Stop Orders are not available immediately, and must be unlocked " +
|
||||
"later on in the game.<br><br>" +
|
||||
"When you place a Market Order to buy or sell a stock, the order executes " +
|
||||
"immediately at whatever the current price of the stock is. For example " +
|
||||
"if you choose to short a stock with 5000 shares using a Market Order, " +
|
||||
"you immediately purchase those 5000 shares in a Short position at whatever " +
|
||||
"the current market price is for that stock.<br><br>" +
|
||||
"A Limit Order is an order that only executes under certain conditions. " +
|
||||
"A Limit Order is used to buy or sell a stock at a specified price or better. " +
|
||||
"For example, lets say you purchased a Long position of 100 shares of some stock " +
|
||||
"at a price of $10 per share. You can place a Limit Order to sell those 100 shares " +
|
||||
"at $50 or better. The Limit Order will execute when the price of the stock reaches a " +
|
||||
"value of $50 or higher.<br><br>" +
|
||||
"A Stop Order is the opposite of a Limit Order. It is used to buy or sell a stock " +
|
||||
"at a specified price (before the price gets 'worse'). For example, lets say you purchased " +
|
||||
"a Short position of 100 shares of some stock at a price of $100 per share. " +
|
||||
"The current price of the stock is $80 (a profit of $20 per share). You can place a " +
|
||||
"Stop Order to sell the Short position if the stock's price reaches $90 or higher. " +
|
||||
"This can be used to lock in your profits and limit any losses.<br><br>" +
|
||||
"Here is a summary of how each order works and when they execute:<br><br>" +
|
||||
"In a LONG Position:<br><br>" +
|
||||
"A Limit Order to buy will execute if the stock's price <= order's price<br>" +
|
||||
"A Limit Order to sell will execute if the stock's price >= order's price<br>" +
|
||||
"A Stop Order to buy will execute if the stock's price >= order's price<br>" +
|
||||
"A Stop Order to sell will execute if the stock's price <= order's price<br><br>" +
|
||||
"In a SHORT Position:<br><br>" +
|
||||
"A Limit Order to buy will execute if the stock's price >= order's price<br>" +
|
||||
"A Limit Order to sell will execute if the stock's price <= order's price<br>" +
|
||||
"A Stop Order to buy will execute if the stock's price <= order's price<br>" +
|
||||
"A Stop Order to sell will execute if the stock's price >= order's price.";
|
||||
dialogBoxCreate(txt);
|
||||
return false;
|
||||
});
|
||||
|
||||
var stockList = document.getElementById("stock-market-list");
|
||||
if (stockList == null) {return;}
|
||||
|
||||
@ -514,138 +788,14 @@ function displayStockMarketContent() {
|
||||
"This means all your positions are lost, so make sure to sell your stocks before installing " +
|
||||
"Augmentations!";
|
||||
|
||||
var hdrLi = document.createElement("li");
|
||||
var hdrName = document.createElement("p");
|
||||
var hdrSym = document.createElement("p");
|
||||
var hdrPrice = document.createElement("p");
|
||||
var hdrQty = document.createElement("p");
|
||||
var hdrBuySell = document.createElement("p")
|
||||
var hdrAvgPrice = document.createElement("p");
|
||||
var hdrShares = document.createElement("p");
|
||||
var hdrReturn = document.createElement("p");
|
||||
hdrName.style.display = "inline-block";
|
||||
hdrName.innerText = "Stock Name";
|
||||
hdrName.style.width = "8%";
|
||||
hdrSym.style.display = "inline-block";
|
||||
hdrSym.innerText = "Symbol";
|
||||
hdrSym.style.width = "4%";
|
||||
hdrPrice.style.display = "inline-block";
|
||||
hdrPrice.innerText = "Price";
|
||||
hdrPrice.style.width = "8%";
|
||||
hdrQty.style.display = "inline-block";
|
||||
hdrQty.innerText = "Quantity";
|
||||
hdrQty.style.width = "3%";
|
||||
hdrBuySell.style.display = "inline-block";
|
||||
hdrBuySell.innerText = "Buy/Sell";
|
||||
hdrBuySell.style.width = "5%";
|
||||
hdrAvgPrice.style.display = "inline-block";
|
||||
hdrAvgPrice.innerText = "Avg price of owned shares";
|
||||
hdrAvgPrice.style.width = "7.5%";
|
||||
hdrShares.style.display = "inline-block";
|
||||
hdrShares.innerText = "Shares owned";
|
||||
hdrShares.style.width = "4%";
|
||||
hdrReturn.style.display = "inline-block";
|
||||
hdrReturn.innerText = "Total Return";
|
||||
hdrReturn.style.width = "6%";
|
||||
hdrLi.appendChild(hdrName);
|
||||
hdrLi.appendChild(hdrSym);
|
||||
hdrLi.appendChild(hdrPrice);
|
||||
hdrLi.appendChild(hdrQty);
|
||||
hdrLi.appendChild(hdrBuySell);
|
||||
hdrLi.appendChild(hdrAvgPrice);
|
||||
hdrLi.appendChild(hdrShares);
|
||||
hdrLi.appendChild(hdrReturn);
|
||||
stockList.appendChild(hdrLi);
|
||||
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
(function() {
|
||||
var stock = StockMarket[name];
|
||||
|
||||
var li = document.createElement("li");
|
||||
var stkName = document.createElement("p");
|
||||
var stkSym = document.createElement("p");
|
||||
var stkPrice = document.createElement("p");
|
||||
var qtyInput = document.createElement("input");
|
||||
var buyButton = document.createElement("span");
|
||||
var sellButton = document.createElement("span");
|
||||
var avgPriceTxt = document.createElement("p");
|
||||
var sharesTxt = document.createElement("p");
|
||||
var returnTxt = document.createElement("p");
|
||||
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
stkName.setAttribute("id", tickerId + "-name");
|
||||
stkSym.setAttribute("id", tickerId + "-sym");
|
||||
stkPrice.setAttribute("id", tickerId + "-price");
|
||||
stkName.style.display = "inline-block";
|
||||
stkName.style.width = "8%";
|
||||
stkSym.style.display = "inline-block";
|
||||
stkSym.style.width = "4%";
|
||||
stkPrice.style.display = "inline-block";
|
||||
stkPrice.style.width = "9%";
|
||||
|
||||
li.setAttribute("display", "inline-block");
|
||||
|
||||
qtyInput.setAttribute("type", "text");
|
||||
qtyInput.setAttribute("id", tickerId + "-qty-input");
|
||||
qtyInput.setAttribute("class", "stock-market-qty-input");
|
||||
qtyInput.setAttribute("onkeydown", "return ( event.ctrlKey || event.altKey " +
|
||||
" || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) " +
|
||||
" || (95<event.keyCode && event.keyCode<106) " +
|
||||
" || (event.keyCode==8) || (event.keyCode==9) " +
|
||||
" || (event.keyCode>34 && event.keyCode<40) " +
|
||||
" || (event.keyCode==46) )");
|
||||
qtyInput.style.width = "3%";
|
||||
qtyInput.style.display = "inline-block";
|
||||
|
||||
buyButton.innerHTML = "Buy";
|
||||
buyButton.setAttribute("class", "stock-market-buy-sell-button");
|
||||
buyButton.style.width = "3%";
|
||||
buyButton.style.display = "inline-block";
|
||||
buyButton.addEventListener("click", function() {
|
||||
var shares = document.getElementById(tickerId + "-qty-input").value;
|
||||
shares = Number(shares);
|
||||
if (isNaN(shares)) {return false;}
|
||||
buyStock(stock, shares);
|
||||
});
|
||||
sellButton.innerHTML = "Sell";
|
||||
sellButton.setAttribute("class", "stock-market-buy-sell-button");
|
||||
sellButton.style.width = "3%";
|
||||
sellButton.style.display = "inline-block";
|
||||
sellButton.addEventListener("click", function() {
|
||||
var shares = document.getElementById(tickerId + "-qty-input").value;
|
||||
shares = Number(shares);
|
||||
if (isNaN(shares)) {return false;}
|
||||
sellStock(stock, shares);
|
||||
});
|
||||
|
||||
avgPriceTxt.setAttribute("id", tickerId + "-avgprice");
|
||||
avgPriceTxt.style.display = "inline-block";
|
||||
avgPriceTxt.style.width = "8%";
|
||||
avgPriceTxt.style.color = "white";
|
||||
sharesTxt.setAttribute("id", tickerId + "-shares");
|
||||
sharesTxt.style.display = "inline-block";
|
||||
sharesTxt.style.width = "4%";
|
||||
sharesTxt.style.color = "white";
|
||||
returnTxt.setAttribute("id", tickerId + "-return");
|
||||
returnTxt.style.display = "inline-block";
|
||||
returnTxt.style.width = "6%";
|
||||
returnTxt.style.color = "white";
|
||||
|
||||
li.appendChild(stkName);
|
||||
li.appendChild(stkSym);
|
||||
li.appendChild(stkPrice);
|
||||
li.appendChild(qtyInput);
|
||||
li.appendChild(buyButton);
|
||||
li.appendChild(sellButton);
|
||||
li.appendChild(avgPriceTxt);
|
||||
li.appendChild(sharesTxt);
|
||||
li.appendChild(returnTxt);
|
||||
stockList.appendChild(li);
|
||||
}()); //Immediate invocation
|
||||
}//End if
|
||||
|
||||
if (!(stock instanceof Stock)) {continue;} //orders property is an array
|
||||
createStockTicker(stock);
|
||||
}
|
||||
}
|
||||
setStockTickerClickHandlers(); //Clicking headers opens/closes panels
|
||||
stockMarketContentCreated = true;
|
||||
}
|
||||
|
||||
@ -653,8 +803,194 @@ function displayStockMarketContent() {
|
||||
for (var name in StockMarket) {
|
||||
if (StockMarket.hasOwnProperty(name)) {
|
||||
var stock = StockMarket[name];
|
||||
updateStockTicker(stock, true);
|
||||
updateStockTicker(stock, null);
|
||||
updateStockPlayerPosition(stock);
|
||||
updateStockOrderList(stock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createStockTicker(stock) {
|
||||
if (!(stock instanceof Stock)) {
|
||||
console.log("Invalid stock in createStockSticker()");
|
||||
return;
|
||||
}
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
var li = document.createElement("li"), hdr = document.createElement("button");
|
||||
hdr.classList.add("accordion-header");
|
||||
hdr.setAttribute("id", tickerId + "-hdr");
|
||||
hdr.innerHTML = stock.name + " - " + stock.symbol + " - $" + stock.price;
|
||||
|
||||
//Div for entire panel
|
||||
var stockDiv = document.createElement("div");
|
||||
stockDiv.classList.add("accordion-panel");
|
||||
|
||||
/* Create panel DOM */
|
||||
var qtyInput = document.createElement("input"),
|
||||
longShortSelect = document.createElement("select"),
|
||||
orderTypeSelect = document.createElement("select"),
|
||||
buyButton = document.createElement("span"),
|
||||
sellButton = document.createElement("span"),
|
||||
positionTxt = document.createElement("p"),
|
||||
orderList = document.createElement("ul");
|
||||
|
||||
qtyInput.classList.add("stock-market-input");
|
||||
qtyInput.placeholder = "Quantity (Shares)";
|
||||
qtyInput.setAttribute("id", tickerId + "-qty-input");
|
||||
qtyInput.setAttribute("onkeydown", "return ( event.ctrlKey || event.altKey " +
|
||||
" || (47<event.keyCode && event.keyCode<58 && event.shiftKey==false) " +
|
||||
" || (95<event.keyCode && event.keyCode<106) " +
|
||||
" || (event.keyCode==8) || (event.keyCode==9) " +
|
||||
" || (event.keyCode>34 && event.keyCode<40) " +
|
||||
" || (event.keyCode==46) )");
|
||||
|
||||
longShortSelect.classList.add("stock-market-input");
|
||||
longShortSelect.setAttribute("id", tickerId + "-pos-selector");
|
||||
var longOpt = document.createElement("option");
|
||||
longOpt.text = "Long";
|
||||
longShortSelect.add(longOpt);
|
||||
if (Player.bitNodeN === 8 || (hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
||||
var shortOpt = document.createElement("option");
|
||||
shortOpt.text = "Short";
|
||||
longShortSelect.add(shortOpt);
|
||||
}
|
||||
|
||||
orderTypeSelect.classList.add("stock-market-input");
|
||||
orderTypeSelect.setAttribute("id", tickerId + "-order-selector");
|
||||
var marketOpt = document.createElement("option");
|
||||
marketOpt.text = "Market Order";
|
||||
orderTypeSelect.add(marketOpt);
|
||||
if (Player.bitNodeN === 8 || (hasWallStreetSF && wallStreetSFLvl >= 3)) {
|
||||
var limitOpt = document.createElement("option");
|
||||
limitOpt.text = "Limit Order";
|
||||
orderTypeSelect.add(limitOpt);
|
||||
var stopOpt = document.createElement("option");
|
||||
stopOpt.text = "Stop Order";
|
||||
orderTypeSelect.add(stopOpt);
|
||||
}
|
||||
|
||||
buyButton.classList.add("stock-market-input");
|
||||
buyButton.classList.add("a-link-button");
|
||||
buyButton.innerHTML = "Buy";
|
||||
buyButton.addEventListener("click", ()=>{
|
||||
var pos = longShortSelect.options[longShortSelect.selectedIndex].text;
|
||||
pos === "Long" ? pos = PositionTypes.Long : pos = PositionTypes.Short;
|
||||
var ordType = orderTypeSelect.options[orderTypeSelect.selectedIndex].text;
|
||||
var shares = Number(document.getElementById(tickerId + "-qty-input").value);
|
||||
if (isNaN(shares)) {return false;}
|
||||
switch (ordType) {
|
||||
case "Market Order":
|
||||
pos === PositionTypes.Long ? buyStock(stock, shares) : shortStock(stock, shares, null);
|
||||
break;
|
||||
case "Limit Order":
|
||||
case "Stop Order":
|
||||
var yesBtn = yesNoTxtInpBoxGetYesButton(),
|
||||
noBtn = yesNoTxtInpBoxGetNoButton();
|
||||
yesBtn.innerText = "Place Buy " + ordType;
|
||||
noBtn.innerText = "Cancel Order";
|
||||
yesBtn.addEventListener("click", ()=>{
|
||||
var price = Number(yesNoTxtInpBoxGetInput()), type;
|
||||
if (ordType === "Limit Order") {
|
||||
type = OrderTypes.LimitBuy;
|
||||
} else {
|
||||
type = OrderTypes.StopBuy;
|
||||
}
|
||||
placeOrder(stock, shares, price, type, pos);
|
||||
yesNoTxtInpBoxClose();
|
||||
});
|
||||
noBtn.addEventListener("click", ()=>{
|
||||
yesNoTxtInpBoxClose();
|
||||
});
|
||||
yesNoTxtInpBoxCreate("Enter the price for your " + ordType);
|
||||
break;
|
||||
default:
|
||||
console.log("ERROR: Invalid order type");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
sellButton.classList.add("stock-market-input");
|
||||
sellButton.classList.add("a-link-button");
|
||||
sellButton.innerHTML = "Sell";
|
||||
sellButton.addEventListener("click", ()=>{
|
||||
var pos = longShortSelect.options[longShortSelect.selectedIndex].text;
|
||||
pos === "Long" ? pos = PositionTypes.Long : pos = PositionTypes.Short;
|
||||
var ordType = orderTypeSelect.options[orderTypeSelect.selectedIndex].text;
|
||||
var shares = Number(document.getElementById(tickerId + "-qty-input").value);
|
||||
if (isNaN(shares)) {return false;}
|
||||
switch (ordType) {
|
||||
case "Market Order":
|
||||
pos === PositionTypes.Long ? sellStock(stock, shares) : sellShort(stock, shares, null);
|
||||
break;
|
||||
case "Limit Order":
|
||||
case "Stop Order":
|
||||
var yesBtn = yesNoTxtInpBoxGetYesButton(),
|
||||
noBtn = yesNoTxtInpBoxGetNoButton();
|
||||
yesBtn.innerText = "Place Sell " + ordType;
|
||||
noBtn.innerText = "Cancel Order";
|
||||
yesBtn.addEventListener("click", ()=>{
|
||||
var price = Number(yesNoTxtInpBoxGetInput()), type;
|
||||
if (ordType === "Limit Order") {
|
||||
type = OrderTypes.LimitSell;
|
||||
} else {
|
||||
type = OrderTypes.StopSell;
|
||||
}
|
||||
yesNoTxtInpBoxClose();
|
||||
placeOrder(stock, shares, price, type, pos);
|
||||
});
|
||||
noBtn.addEventListener("click", ()=>{
|
||||
yesNoTxtInpBoxClose();
|
||||
});
|
||||
yesNoTxtInpBoxCreate("Enter the price for your " + ordType);
|
||||
break;
|
||||
default:
|
||||
console.log("ERROR: Invalid order type");
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
positionTxt.setAttribute("id", tickerId + "-position-text");
|
||||
positionTxt.classList.add("stock-market-position-text");
|
||||
stock.posTxtEl = positionTxt;
|
||||
|
||||
orderList.setAttribute("id", tickerId + "-order-list");
|
||||
orderList.classList.add("stock-market-order-list");
|
||||
|
||||
stockDiv.appendChild(qtyInput);
|
||||
stockDiv.appendChild(longShortSelect);
|
||||
stockDiv.appendChild(orderTypeSelect);
|
||||
stockDiv.appendChild(buyButton);
|
||||
stockDiv.appendChild(sellButton);
|
||||
stockDiv.appendChild(positionTxt);
|
||||
stockDiv.appendChild(orderList);
|
||||
|
||||
li.appendChild(hdr);
|
||||
li.appendChild(stockDiv);
|
||||
document.getElementById("stock-market-list").appendChild(li);
|
||||
|
||||
updateStockTicker(stock, true);
|
||||
updateStockOrderList(stock);
|
||||
}
|
||||
|
||||
function setStockTickerClickHandlers() {
|
||||
var stockList = document.getElementById("stock-market-list");
|
||||
var tickerHdrs = stockList.getElementsByClassName("accordion-header");
|
||||
if (tickerHdrs === null) {
|
||||
console.log("ERROR: Could not find header elements for stock tickers");
|
||||
return;
|
||||
}
|
||||
for (var i = 0; i < tickerHdrs.length; ++i) {
|
||||
tickerHdrs[i].onclick = function() {
|
||||
this.classList.toggle("active");
|
||||
|
||||
var panel = this.nextElementSibling;
|
||||
if (panel.style.display === "block") {
|
||||
panel.style.display = "none";
|
||||
} else {
|
||||
panel.style.display = "block";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -662,57 +998,132 @@ function displayStockMarketContent() {
|
||||
|
||||
//'increase' argument is a boolean indicating whether the price increased or decreased
|
||||
function updateStockTicker(stock, increase) {
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
let stkName = document.getElementById(tickerId + "-name");
|
||||
let stkSym = document.getElementById(tickerId + "-sym");
|
||||
let stkPrice = document.getElementById(tickerId + "-price");
|
||||
|
||||
if (stkName == null || stkSym == null || stkPrice == null) {
|
||||
console.log("ERROR, couldn't find elements with tickerId " + tickerId);
|
||||
if (Engine.currentPage !== Engine.Page.StockMarket) {return;}
|
||||
if (!(stock instanceof Stock)) {
|
||||
console.log("Invalid stock in updateStockTicker():");
|
||||
console.log(stock);
|
||||
return;
|
||||
}
|
||||
stkName.innerText = stock.name;
|
||||
stkSym.innerText = stock.symbol;
|
||||
stkPrice.innerText = "$" + formatNumber(stock.price, 2).toString();
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
var hdr = document.getElementById(tickerId + "-hdr");
|
||||
|
||||
var returnTxt = document.getElementById(tickerId + "-return");
|
||||
var totalCost = stock.playerShares * stock.playerAvgPx;
|
||||
var gains = (stock.price - stock.playerAvgPx) * stock.playerShares;
|
||||
var percentageGains = gains / totalCost;
|
||||
if (totalCost > 0) {
|
||||
returnTxt.innerText = "$" + formatNumber(gains, 2) + " (" +
|
||||
formatNumber(percentageGains * 100, 2) + "%)";
|
||||
} else {
|
||||
returnTxt.innerText = "N/A";
|
||||
if (hdr === null) {
|
||||
console.log("ERROR: Couldn't find ticker element for stock: " + stock.symbol);
|
||||
return;
|
||||
}
|
||||
hdr.innerHTML = stock.name + " - " + stock.symbol + " - $" + formatNumber(stock.price, 2);
|
||||
if (increase !== null) {
|
||||
increase ? hdr.style.color = "#66ff33" : hdr.style.color = "red";
|
||||
}
|
||||
|
||||
|
||||
if (increase) {
|
||||
stkName.style.color = "#66ff33";
|
||||
stkSym.style.color = "#66ff33";
|
||||
stkPrice.style.color = "#66ff33";
|
||||
} else {
|
||||
stkName.style.color = "red";
|
||||
stkSym.style.color = "red";
|
||||
stkPrice.style.color = "red";
|
||||
if (stock.playerShares > 0 || stock.playerShortShares > 0) {
|
||||
updateStockPlayerPosition(stock);
|
||||
}
|
||||
}
|
||||
|
||||
function updateStockPlayerPosition(stock) {
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
var avgPriceTxt = document.getElementById(tickerId + "-avgprice");
|
||||
var sharesTxt = document.getElementById(tickerId + "-shares");
|
||||
if (avgPriceTxt == null || sharesTxt == null) {
|
||||
dialogBoxCreate("Could not find element for player positions for stock " +
|
||||
stock.symbol + ". This is a bug please contact developer");
|
||||
if (Engine.currentPage !== Engine.Page.StockMarket) {return;}
|
||||
if (!(stock instanceof Stock)) {
|
||||
console.log("Invalid stock in updateStockPlayerPosition():");
|
||||
console.log(stock);
|
||||
return;
|
||||
}
|
||||
avgPriceTxt.innerText = "$" + formatNumber(stock.playerAvgPx, 2);
|
||||
sharesTxt.innerText = stock.playerShares.toString();
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
if (!(stock.posTxtEl instanceof Element)) {
|
||||
stock.posTxtEl = document.getElementById(tickerId + "-position-text");
|
||||
}
|
||||
if (stock.posTxtEl === null) {
|
||||
console.log("ERROR: Could not find stock position element for: " + stock.symbol);
|
||||
return;
|
||||
}
|
||||
|
||||
//Calculate returns
|
||||
var totalCost = stock.playerShares * stock.playerAvgPx,
|
||||
gains = (stock.price - stock.playerAvgPx) * stock.playerShares,
|
||||
percentageGains = gains / totalCost;
|
||||
if (isNaN(percentageGains)) {percentageGains = 0;}
|
||||
|
||||
var shortTotalCost = stock.playerShortShares * stock.playerAvgShortPx,
|
||||
shortGains = (stock.playerAvgShortPx - stock.price) * stock.playerShortShares,
|
||||
shortPercentageGains = shortGains/ shortTotalCost;
|
||||
if (isNaN(shortPercentageGains)) {shortPercentageGains = 0;}
|
||||
|
||||
stock.posTxtEl.innerHTML =
|
||||
"<h1 class='tooltip stock-market-position-text'>Long Position: " +
|
||||
"<span class='tooltiptext'>Shares in the long position will increase " +
|
||||
"in value if the price of the corresponding stock increases</span></h1>" +
|
||||
"<br>Shares: " + formatNumber(stock.playerShares, 0) +
|
||||
"<br>Average Price: " + numeral(stock.playerAvgPx).format('$0.000a') +
|
||||
" (Total Cost: " + numeral(totalCost).format('$0.000a') + ")" +
|
||||
"<br>Profit: " + numeral(gains).format('$0.000a') +
|
||||
" (" + formatNumber(percentageGains*100, 2) + "%)<br><br>";
|
||||
if (Player.bitNodeN === 8 || (hasWallStreetSF && wallStreetSFLvl >= 2)) {
|
||||
stock.posTxtEl.innerHTML +=
|
||||
"<h1 class='tooltip stock-market-position-text'>Short Position: " +
|
||||
"<span class='tooltiptext'>Shares in short position will increase " +
|
||||
"in value if the price of the corresponding stock decreases</span></h1>" +
|
||||
"<br>Shares: " + formatNumber(stock.playerShortShares, 0) +
|
||||
"<br>Average Price: " + numeral(stock.playerAvgShortPx).format('$0.000a') +
|
||||
" (Total Cost: " + numeral(shortTotalCost).format('$0.000a') + ")" +
|
||||
"<br>Profit: " + numeral(shortGains).format('$0.000a') +
|
||||
" (" + formatNumber(shortPercentageGains*100, 2) + "%)" +
|
||||
"<br><br><h1 class='stock-market-position-text'>Orders: </h1>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function updateStockOrderList(stock) {
|
||||
if (Engine.currentPage !== Engine.Page.StockMarket) {return;}
|
||||
var tickerId = "stock-market-ticker-" + stock.symbol;
|
||||
var orderList = document.getElementById(tickerId + "-order-list");
|
||||
if (orderList === null) {
|
||||
console.log("ERROR: Could not find order list for " + stock.symbol);
|
||||
return;
|
||||
}
|
||||
|
||||
var orderBook = StockMarket["Orders"];
|
||||
if (orderBook === null) {
|
||||
console.log("ERROR: Could not find order book in stock market");
|
||||
return;
|
||||
}
|
||||
var stockOrders = orderBook[stock.symbol];
|
||||
if (stockOrders === null) {
|
||||
console.log("ERROR: Could not find orders for: " + stock.symbol);
|
||||
return;
|
||||
}
|
||||
|
||||
//Remove everything from list
|
||||
while (orderList.firstChild) {
|
||||
orderList.removeChild(orderList.firstChild);
|
||||
}
|
||||
|
||||
for (var i = 0; i < stockOrders.length; ++i) {
|
||||
(function() {
|
||||
var order = stockOrders[i];
|
||||
var li = document.createElement("li");
|
||||
li.style.padding = "4px";
|
||||
var posText = (order.pos === PositionTypes.Long ? "Long Position" : "Short Position");
|
||||
li.style.color = "white";
|
||||
li.innerText = order.type + " - " + posText + " - " +
|
||||
order.shares + " @ $" + formatNumber(order.price, 2);
|
||||
|
||||
var cancelButton = document.createElement("span");
|
||||
cancelButton.classList.add("stock-market-order-cancel-btn");
|
||||
cancelButton.classList.add("a-link-button");
|
||||
cancelButton.innerHTML = "Cancel Order";
|
||||
cancelButton.addEventListener("click", function() {
|
||||
cancelOrder({order: order}, null);
|
||||
return false;
|
||||
});
|
||||
li.appendChild(cancelButton);
|
||||
orderList.appendChild(li);
|
||||
}());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
|
||||
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
|
||||
sellStock, updateStockPrices, displayStockMarketContent,
|
||||
sellStock, shortStock, sellShort, updateStockPrices, displayStockMarketContent,
|
||||
updateStockTicker, updateStockPlayerPosition, loadStockMarket,
|
||||
setStockMarketContentCreated};
|
||||
setStockMarketContentCreated, placeOrder, cancelOrder, Order, OrderTypes, PositionTypes};
|
||||
|
78
src/TextFile.js
Normal file
78
src/TextFile.js
Normal file
@ -0,0 +1,78 @@
|
||||
import {Server} from "./Server.js";
|
||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||
import {Reviver, Generic_toJSON,
|
||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||
|
||||
function TextFile(fn="", txt="") {
|
||||
this.fn = fn.endsWith(".txt") ? fn : fn + ".txt";
|
||||
this.text = String(txt);
|
||||
}
|
||||
|
||||
TextFile.prototype.append = function(txt) {
|
||||
this.text += String(txt);
|
||||
}
|
||||
|
||||
TextFile.prototype.write = function(txt) {
|
||||
this.text = String(txt);
|
||||
}
|
||||
|
||||
TextFile.prototype.read = function() {
|
||||
return this.txt;
|
||||
}
|
||||
|
||||
TextFile.prototype.show = function() {
|
||||
dialogBoxCreate(this.fn + "<br><br>" + this.text);
|
||||
}
|
||||
|
||||
TextFile.prototype.download = function() {
|
||||
var filename = this.fn;
|
||||
var file = new Blob([this.text], {type: 'text/plain'});
|
||||
if (window.navigator.msSaveOrOpenBlob) {// IE10+
|
||||
window.navigator.msSaveOrOpenBlob(file, filename);
|
||||
} else { // Others
|
||||
var a = document.createElement("a"),
|
||||
url = URL.createObjectURL(file);
|
||||
a.href = url;
|
||||
a.download = this.fn;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TextFile.prototype.toJSON = function() {
|
||||
return Generic_toJSON("TextFile", this);
|
||||
}
|
||||
|
||||
TextFile.fromJSON = function(value) {
|
||||
return Generic_fromJSON(TextFile, value.data);
|
||||
}
|
||||
|
||||
Reviver.constructors.TextFile = TextFile;
|
||||
|
||||
function getTextFile(fn, server) {
|
||||
if (!fn.endsWith(".txt")) {fn += ".txt";}
|
||||
for (var i = 0; i < server.textFiles.length; ++i) {
|
||||
if (server.textFiles[i].fn === fn) {
|
||||
return server.textFiles[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//Returns the TextFile object that was just created
|
||||
function createTextFile(fn, txt, server) {
|
||||
if (getTextFile(fn, server) !== null) {
|
||||
console.log("ERROR: createTextFile failed because the specified " +
|
||||
"server already has a text file with the same fn");
|
||||
return;
|
||||
}
|
||||
var file = new TextFile(fn, txt);
|
||||
server.textFiles.push(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
export {TextFile, getTextFile, createTextFile};
|
@ -376,8 +376,8 @@ let Engine = {
|
||||
loadStockMarketContent: function() {
|
||||
Engine.hideAllContent();
|
||||
Engine.Display.stockMarketContent.style.visibility = "visible";
|
||||
displayStockMarketContent();
|
||||
Engine.currentPage = Engine.Page.StockMarket;
|
||||
displayStockMarketContent();
|
||||
},
|
||||
|
||||
loadGangContent: function() {
|
||||
@ -988,7 +988,6 @@ let Engine = {
|
||||
}
|
||||
|
||||
if (Engine.Counters.sCr <= 0) {
|
||||
//Assume 4Sig will always indicate state of market
|
||||
if (Player.hasWseAccount) {
|
||||
stockMarketCycle();
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ function infiltrationBoxCreate(inst) {
|
||||
Player.gainDexterityExp(inst.dexExpGained);
|
||||
Player.gainAgilityExp(inst.agiExpGained);
|
||||
Player.gainCharismaExp(inst.chaExpGained);
|
||||
Player.gainIntelligenceExp(inst.intExpGained);
|
||||
|
||||
var totalValue = 0;
|
||||
for (var i = 0; i < inst.secretsStolen.length; ++i) {
|
||||
|
Loading…
Reference in New Issue
Block a user