Merge pull request #88 from danielyxie/dev

Dev v0.25.0
This commit is contained in:
danielyxie 2017-07-13 12:59:36 -04:00 committed by GitHub
commit 702f70f240
20 changed files with 5131 additions and 2011 deletions

@ -15,21 +15,18 @@
position: fixed; position: fixed;
} }
/* Script Editor */ /* Script Editor */
/* This temp element is used for auto adjusting filename field */ /* This temp element is used for auto adjusting filename field */
.tmp-element { .tmp-element {
visibility: hidden; visibility: hidden;
white-space: pre; white-space: pre;
} }
#script-editor-container { #script-editor-container {
position: fixed; position: fixed;
padding-top: 10px; padding-top: 10px;
} }
#script-editor-buttons-wrapper { #script-editor-buttons-wrapper {
width: 100%; width: 100%;
padding-right: 0xp; padding-right: 0xp;
@ -37,10 +34,15 @@
} }
#script-editor-save-and-close-button, #script-editor-save-and-close-button,
#script-editor-netscript-doc-button { #script-editor-netscript-doc-button,
#script-editor-status-text {
display: inline-block; display: inline-block;
} }
#script-editor-status-text {
margin: 10px;
}
#script-editor-save-and-close-button { #script-editor-save-and-close-button {
float:left; float:left;
} }

@ -94,6 +94,10 @@ tr:focus {
} }
/* Make html links ("a" elements) nice looking buttons with this class */ /* Make html links ("a" elements) nice looking buttons with this class */
a:link, a:visited {
color:white;
}
.a-link-button { .a-link-button {
text-decoration: none; text-decoration: none;
background-color: #555; background-color: #555;

@ -30,12 +30,10 @@
<!-- Netscript --> <!-- Netscript -->
<script src="src/NetscriptWorker.js"></script> <script src="src/NetscriptWorker.js"></script>
<script src="src/NetscriptInputStream.js"></script>
<script src="src/NetscriptTokenizer.js"></script>
<script src="src/NetscriptParser.js"></script>
<script src="src/NetscriptEvaluator.js"></script> <script src="src/NetscriptEvaluator.js"></script>
<script src="src/NetscriptEnvironment.js"></script> <script src="src/NetscriptEnvironment.js"></script>
<script src="src/NetscriptFunctions.js"></script> <script src="src/NetscriptFunctions.js"></script>
<script src="utils/acorn.js"></script>
<!-- Main game files --> <!-- Main game files -->
<script src="src/Constants.js"></script> <script src="src/Constants.js"></script>
@ -150,6 +148,7 @@
<textarea id="script-editor-text" tabindex="2" autofocus> </textarea> <textarea id="script-editor-text" tabindex="2" autofocus> </textarea>
<div id="script-editor-buttons-wrapper"> <div id="script-editor-buttons-wrapper">
<span id="script-editor-save-and-close-button" class="a-link-button">Save & Close (Ctrl + b)</span> <span id="script-editor-save-and-close-button" class="a-link-button">Save & Close (Ctrl + b)</span>
<p id="script-editor-status-text"> </p>
<span id="script-editor-netscript-doc-button" class="a-link-button"> Netscript Documentation </span> <span id="script-editor-netscript-doc-button" class="a-link-button"> Netscript Documentation </span>
</div> </div>
</div> </div>
@ -746,7 +745,7 @@
you 'reset' by installing Augmentations. you 'reset' by installing Augmentations.
</p> </p>
<a id="stock-market-buy-tix-api" class="a-link-button-inactive"> <a id="stock-market-buy-tix-api" class="a-link-button-inactive">
Buy Trade Information eXchange (TEX) API Access - COMING SOON Buy Trade Information eXchange (TIX) API Access - COMING SOON
</a> </a>
<p id="stock-market-commission"> </p> <p id="stock-market-commission"> </p>

@ -162,7 +162,7 @@ initAugmentations = function() {
//Combat stat augmentations //Combat stat augmentations
var HemoRecirculator = new Augmentation(AugmentationNames.HemoRecirculator); var HemoRecirculator = new Augmentation(AugmentationNames.HemoRecirculator);
HemoRecirculator.setInfo("A heart implant that greatly increases the body's ability to effectively use and pump " + HemoRecirculator.setInfo("A heart implant that greatly increases the body's ability to effectively use and pump " +
"blood. <br><br> This augmentation increases all of the player's combat stats by 10%.") "blood. <br><br> This augmentation increases all of the player's combat stats by 8%.")
HemoRecirculator.setRequirements(4000, 9000000); HemoRecirculator.setRequirements(4000, 9000000);
HemoRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate"]); HemoRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate"]);
if (augmentationExists(AugmentationNames.HemoRecirculator)) { if (augmentationExists(AugmentationNames.HemoRecirculator)) {
@ -175,7 +175,7 @@ initAugmentations = function() {
Targeting1.setInfo("This cranial implant is embedded within the player's inner ear structure and optic nerves. It regulates and enhances the user's " + Targeting1.setInfo("This cranial implant is embedded within the player's inner ear structure and optic nerves. It regulates and enhances the user's " +
"balance and hand-eye coordination. It is also capable of augmenting reality by projecting digital information " + "balance and hand-eye coordination. It is also capable of augmenting reality by projecting digital information " +
"directly onto the retina. These enhancements allow the player to better lock-on and keep track of enemies. <br><br>" + "directly onto the retina. These enhancements allow the player to better lock-on and keep track of enemies. <br><br>" +
"This augmentation increases the player's dexterity by 15%."); "This augmentation increases the player's dexterity by 10%.");
Targeting1.addToFactions(["Slum Snakes", "The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima", Targeting1.addToFactions(["Slum Snakes", "The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]); "OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
if (augmentationExists(AugmentationNames.Targeting1)) { if (augmentationExists(AugmentationNames.Targeting1)) {
@ -187,7 +187,7 @@ initAugmentations = function() {
Targeting2.setRequirements(3500, 8500000); Targeting2.setRequirements(3500, 8500000);
Targeting2.setInfo("This is an upgrade of the Augmented Targeting I cranial implant, which is capable of augmenting reality " + Targeting2.setInfo("This is an upgrade of the Augmented Targeting I cranial implant, which is capable of augmenting reality " +
"and enhances the user's balance and hand-eye coordination. <br><br>This upgrade increases the player's dexterity " + "and enhances the user's balance and hand-eye coordination. <br><br>This upgrade increases the player's dexterity " +
"by an additional 25%."); "by an additional 20%.");
Targeting2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima", Targeting2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]); "OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
if (augmentationExists(AugmentationNames.Targeting2)) { if (augmentationExists(AugmentationNames.Targeting2)) {
@ -199,7 +199,7 @@ initAugmentations = function() {
Targeting3.setRequirements(11000, 23000000); Targeting3.setRequirements(11000, 23000000);
Targeting3.setInfo("This is an upgrade of the Augmented Targeting II cranial implant, which is capable of augmenting reality " + Targeting3.setInfo("This is an upgrade of the Augmented Targeting II cranial implant, which is capable of augmenting reality " +
"and enhances the user's balance and hand-eye coordination. <br><br>This upgrade increases the player's dexterity " + "and enhances the user's balance and hand-eye coordination. <br><br>This upgrade increases the player's dexterity " +
"by an additional 40%."); "by an additional 30%.");
Targeting3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated", Targeting3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated",
"KuaiGong International", "Blade Industries", "The Covenant"]); "KuaiGong International", "Blade Industries", "The Covenant"]);
if (augmentationExists(AugmentationNames.Targeting3)) { if (augmentationExists(AugmentationNames.Targeting3)) {
@ -233,7 +233,7 @@ initAugmentations = function() {
AddToAugmentations(SynfibrilMuscle) AddToAugmentations(SynfibrilMuscle)
var CombatRib1 = new Augmentation(AugmentationNames.CombatRib1); var CombatRib1 = new Augmentation(AugmentationNames.CombatRib1);
CombatRib1.setRequirements(2500, 4500000); CombatRib1.setRequirements(3000, 4750000);
CombatRib1.setInfo("The human body's ribs are replaced with artificial ribs that automatically and continuously release cognitive " + CombatRib1.setInfo("The human body's ribs are replaced with artificial ribs that automatically and continuously release cognitive " +
"and performance-enhancing drugs into the bloodstream, improving the user's abilities in combat.<br><br>" + "and performance-enhancing drugs into the bloodstream, improving the user's abilities in combat.<br><br>" +
"This augmentation increases the player's strength and defense by 10%."); "This augmentation increases the player's strength and defense by 10%.");
@ -245,7 +245,7 @@ initAugmentations = function() {
AddToAugmentations(CombatRib1); AddToAugmentations(CombatRib1);
var CombatRib2 = new Augmentation(AugmentationNames.CombatRib2); var CombatRib2 = new Augmentation(AugmentationNames.CombatRib2);
CombatRib2.setRequirements(7000, 12000000); CombatRib2.setRequirements(7500, 13000000);
CombatRib2.setInfo("This is an upgrade to the Combat Rib I augmentation, and is capable of releasing even more potent combat-enhancing " + CombatRib2.setInfo("This is an upgrade to the Combat Rib I augmentation, and is capable of releasing even more potent combat-enhancing " +
"drugs into the bloodstream.<br><br>This upgrade increases the player's strength and defense by an additional 15%.") "drugs into the bloodstream.<br><br>This upgrade increases the player's strength and defense by an additional 15%.")
CombatRib2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima", CombatRib2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
@ -256,7 +256,7 @@ initAugmentations = function() {
AddToAugmentations(CombatRib2); AddToAugmentations(CombatRib2);
var CombatRib3 = new Augmentation(AugmentationNames.CombatRib3); var CombatRib3 = new Augmentation(AugmentationNames.CombatRib3);
CombatRib3.setRequirements(12000, 22000000); CombatRib3.setRequirements(14000, 24000000);
CombatRib3.setInfo("This is an upgrade to the Combat Rib II augmentation, and is capable of releasing even more potent combat-enhancing " + CombatRib3.setInfo("This is an upgrade to the Combat Rib II augmentation, and is capable of releasing even more potent combat-enhancing " +
"drugs into the bloodstream<br><br>. This upgrade increases the player's strength and defense by an additional 20%."); "drugs into the bloodstream<br><br>. This upgrade increases the player's strength and defense by an additional 20%.");
CombatRib3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated", CombatRib3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated",
@ -267,7 +267,7 @@ initAugmentations = function() {
AddToAugmentations(CombatRib3); AddToAugmentations(CombatRib3);
var NanofiberWeave = new Augmentation(AugmentationNames.NanofiberWeave); var NanofiberWeave = new Augmentation(AugmentationNames.NanofiberWeave);
NanofiberWeave.setRequirements(14000, 20000000); NanofiberWeave.setRequirements(15000, 25000000);
NanofiberWeave.setInfo("Synthetic nanofibers are woven into the skin's extracellular matrix using electrospinning. " + NanofiberWeave.setInfo("Synthetic nanofibers are woven into the skin's extracellular matrix using electrospinning. " +
"This improves the skin's ability to regenerate itself and protect the body from external stresses and forces.<br><br>" + "This improves the skin's ability to regenerate itself and protect the body from external stresses and forces.<br><br>" +
"This augmentation increases the player's strength and defense by 25%."); "This augmentation increases the player's strength and defense by 25%.");
@ -309,7 +309,7 @@ initAugmentations = function() {
GrapheneBoneLacings.setRequirements(450000, 850000000); GrapheneBoneLacings.setRequirements(450000, 850000000);
GrapheneBoneLacings.setInfo("A graphene-based material is grafted and fused into the user's bones, significantly increasing " + GrapheneBoneLacings.setInfo("A graphene-based material is grafted and fused into the user's bones, significantly increasing " +
"their density and tensile strength.<br><br>" + "their density and tensile strength.<br><br>" +
"This augmentation increases the player's strength and defense by 75%."); "This augmentation increases the player's strength and defense by 70%.");
GrapheneBoneLacings.addToFactions(["Fulcrum Secret Technologies", "The Covenant"]); GrapheneBoneLacings.addToFactions(["Fulcrum Secret Technologies", "The Covenant"]);
if (augmentationExists(AugmentationNames.GrapheneBoneLacings)) { if (augmentationExists(AugmentationNames.GrapheneBoneLacings)) {
delete Augmentations[AugmentationNames.GrapheneBoneLacings]; delete Augmentations[AugmentationNames.GrapheneBoneLacings];
@ -322,7 +322,7 @@ initAugmentations = function() {
"Not only is the Bionic Spine physically stronger than a human spine, but it is also capable of digitally " + "Not only is the Bionic Spine physically stronger than a human spine, but it is also capable of digitally " +
"stimulating and regulating the neural signals that are sent and received by the spinal cord. This results in " + "stimulating and regulating the neural signals that are sent and received by the spinal cord. This results in " +
"greatly improved senses and reaction speeds.<br><br>" + "greatly improved senses and reaction speeds.<br><br>" +
"This augmentation increases all of the player's combat stats by 18%."); "This augmentation increases all of the player's combat stats by 16%.");
BionicSpine.addToFactions(["Speakers for the Dead", "The Syndicate", "KuaiGong International", BionicSpine.addToFactions(["Speakers for the Dead", "The Syndicate", "KuaiGong International",
"OmniTek Incorporated", "Blade Industries"]); "OmniTek Incorporated", "Blade Industries"]);
if (augmentationExists(AugmentationNames.BionicSpine)) { if (augmentationExists(AugmentationNames.BionicSpine)) {
@ -334,7 +334,7 @@ initAugmentations = function() {
GrapheneBionicSpine.setRequirements(650000, 1200000000); GrapheneBionicSpine.setRequirements(650000, 1200000000);
GrapheneBionicSpine.setInfo("An upgrade to the Bionic Spine augmentation. It fuses the implant with an advanced graphene " + GrapheneBionicSpine.setInfo("An upgrade to the Bionic Spine augmentation. It fuses the implant with an advanced graphene " +
"material to make it much stronger and lighter.<br><br>" + "material to make it much stronger and lighter.<br><br>" +
"This augmentation increases all of the player's combat stats by 65%."); "This augmentation increases all of the player's combat stats by 60%.");
GrapheneBionicSpine.addToFactions(["Fulcrum Secret Technologies", "ECorp"]); GrapheneBionicSpine.addToFactions(["Fulcrum Secret Technologies", "ECorp"]);
if (augmentationExists(AugmentationNames.GrapheneBionicSpine)) { if (augmentationExists(AugmentationNames.GrapheneBionicSpine)) {
delete Augmentations[AugmentationNames.GrapheneBionicSpine]; delete Augmentations[AugmentationNames.GrapheneBionicSpine];
@ -390,7 +390,7 @@ initAugmentations = function() {
AddToAugmentations(TITN41Injection); AddToAugmentations(TITN41Injection);
var EnhancedSocialInteractionImplant = new Augmentation(AugmentationNames.EnhancedSocialInteractionImplant); var EnhancedSocialInteractionImplant = new Augmentation(AugmentationNames.EnhancedSocialInteractionImplant);
EnhancedSocialInteractionImplant.setRequirements(150000, 250000000); EnhancedSocialInteractionImplant.setRequirements(150000, 275000000);
EnhancedSocialInteractionImplant.setInfo("A cranial implant that greatly assists in the user's ability to analyze social situations " + EnhancedSocialInteractionImplant.setInfo("A cranial implant that greatly assists in the user's ability to analyze social situations " +
"and interactions. The system uses a wide variety of factors such as facial expression, body " + "and interactions. The system uses a wide variety of factors such as facial expression, body " +
"language, and the voice's tone/inflection to determine the best course of action during social" + "language, and the voice's tone/inflection to determine the best course of action during social" +
@ -751,7 +751,7 @@ initAugmentations = function() {
FocusWire.setInfo("A cranial implant that stops procrastination by blocking specific neural pathways " + FocusWire.setInfo("A cranial implant that stops procrastination by blocking specific neural pathways " +
"in the brain.<br><br>" + "in the brain.<br><br>" +
"This augmentation: <br>" + "This augmentation: <br>" +
"Increases all experience gains by 10%<br>" + "Increases all experience gains by 5%<br>" +
"Increases the amount of money the player gains from working by 20%<br>" + "Increases the amount of money the player gains from working by 20%<br>" +
"Increases the amount of reputation the player gains when working for a company by 10%"); "Increases the amount of reputation the player gains when working for a company by 10%");
FocusWire.addToFactions(["Bachman & Associates", "Clarke Incorporated", "Four Sigma", "KuaiGong International"]); FocusWire.addToFactions(["Bachman & Associates", "Clarke Incorporated", "Four Sigma", "KuaiGong International"]);
@ -775,7 +775,7 @@ initAugmentations = function() {
AddToAugmentations(PCDNI); AddToAugmentations(PCDNI);
var PCDNIOptimizer = new Augmentation(AugmentationNames.PCDNIOptimizer); var PCDNIOptimizer = new Augmentation(AugmentationNames.PCDNIOptimizer);
PCDNIOptimizer.setRequirements(200000, 875000000); PCDNIOptimizer.setRequirements(200000, 900000000);
PCDNIOptimizer.setInfo("This is a submodule upgrade to the PC Direct-Neural Interface augmentation. It " + PCDNIOptimizer.setInfo("This is a submodule upgrade to the PC Direct-Neural Interface augmentation. It " +
"improves the performance of the interface and gives the user more control options " + "improves the performance of the interface and gives the user more control options " +
"to the connected computer.<br><br>" + "to the connected computer.<br><br>" +
@ -789,7 +789,7 @@ initAugmentations = function() {
AddToAugmentations(PCDNIOptimizer); AddToAugmentations(PCDNIOptimizer);
var PCDNINeuralNetwork = new Augmentation(AugmentationNames.PCDNINeuralNetwork); var PCDNINeuralNetwork = new Augmentation(AugmentationNames.PCDNINeuralNetwork);
PCDNINeuralNetwork.setRequirements(600000, 1300000000); PCDNINeuralNetwork.setRequirements(600000, 1500000000);
PCDNINeuralNetwork.setInfo("This is an additional installation that upgrades the functionality of the " + PCDNINeuralNetwork.setInfo("This is an additional installation that upgrades the functionality of the " +
"PC Direct-Neural Interface augmentation. When connected to a computer, " + "PC Direct-Neural Interface augmentation. When connected to a computer, " +
"The NeuroNet Injector upgrade allows the user to use his/her own brain's " + "The NeuroNet Injector upgrade allows the user to use his/her own brain's " +
@ -922,7 +922,7 @@ initAugmentations = function() {
AddToAugmentations(Neurotrainer1); AddToAugmentations(Neurotrainer1);
var Neurotrainer2 = new Augmentation(AugmentationNames.Neurotrainer2); var Neurotrainer2 = new Augmentation(AugmentationNames.Neurotrainer2);
Neurotrainer2.setRequirements(4000, 8500000); Neurotrainer2.setRequirements(4000, 9000000);
Neurotrainer2.setInfo("A decentralized cranial implant that improves the brain's ability to learn. This " + Neurotrainer2.setInfo("A decentralized cranial implant that improves the brain's ability to learn. This " +
"is a more powerful version of the Neurotrainer I augmentation, but it does not " + "is a more powerful version of the Neurotrainer I augmentation, but it does not " +
"require Neurotrainer I to be installed as a prerequisite.<br><br>" + "require Neurotrainer I to be installed as a prerequisite.<br><br>" +
@ -934,7 +934,7 @@ initAugmentations = function() {
AddToAugmentations(Neurotrainer2); AddToAugmentations(Neurotrainer2);
var Neurotrainer3 = new Augmentation(AugmentationNames.Neurotrainer3); var Neurotrainer3 = new Augmentation(AugmentationNames.Neurotrainer3);
Neurotrainer3.setRequirements(10000, 25000000); Neurotrainer3.setRequirements(10000, 26000000);
Neurotrainer3.setInfo("A decentralized cranial implant that improves the brain's ability to learn. This " + Neurotrainer3.setInfo("A decentralized cranial implant that improves the brain's ability to learn. This " +
"is a more powerful version of the Neurotrainer I and Neurotrainer II augmentation, " + "is a more powerful version of the Neurotrainer I and Neurotrainer II augmentation, " +
"but it does not require either of them to be installed as a prerequisite.<br><br>" + "but it does not require either of them to be installed as a prerequisite.<br><br>" +
@ -983,7 +983,7 @@ initAugmentations = function() {
"Increases the player's agility by 10% <br>" + "Increases the player's agility by 10% <br>" +
"Increases the player's defense by 10% <br>" + "Increases the player's defense by 10% <br>" +
"Increases the amount of money the player gains from crimes by 25%"); "Increases the amount of money the player gains from crimes by 25%");
LuminCloaking2.setRequirements(2000, 5000000); LuminCloaking2.setRequirements(2000, 6000000);
LuminCloaking2.addToFactions(["Slum Snakes", "Tetrads"]); LuminCloaking2.addToFactions(["Slum Snakes", "Tetrads"]);
if (augmentationExists(AugmentationNames.LuminCloaking2)) { if (augmentationExists(AugmentationNames.LuminCloaking2)) {
delete Augmentations[AugmentationNames.LuminCloaking2]; delete Augmentations[AugmentationNames.LuminCloaking2];
@ -997,7 +997,7 @@ initAugmentations = function() {
"Increases the player's dexterity by 10%<br>" + "Increases the player's dexterity by 10%<br>" +
"Increases the player's dexterity experience gain rate by 15%<br>" + "Increases the player's dexterity experience gain rate by 15%<br>" +
"Increases the amount of money the player gains from crimes by 25%"); "Increases the amount of money the player gains from crimes by 25%");
SmartSonar.setRequirements(9000, 12000000); SmartSonar.setRequirements(9000, 15000000);
SmartSonar.addToFactions(["Slum Snakes"]); SmartSonar.addToFactions(["Slum Snakes"]);
if (augmentationExists(AugmentationNames.SmartSonar)) { if (augmentationExists(AugmentationNames.SmartSonar)) {
delete Augmentations[AugmentationNames.SmartSonar]; delete Augmentations[AugmentationNames.SmartSonar];
@ -1011,7 +1011,7 @@ initAugmentations = function() {
"This augmentation: <br>" + "This augmentation: <br>" +
"Increases all of the player's stats by 5%<br>" + "Increases all of the player's stats by 5%<br>" +
"Increases the player's experience gain rate for all stats by 10%"); "Increases the player's experience gain rate for all stats by 10%");
PowerRecirculator.setRequirements(10000, 33000000); PowerRecirculator.setRequirements(10000, 36000000);
PowerRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate", "NWO"]); PowerRecirculator.addToFactions(["Tetrads", "The Dark Army", "The Syndicate", "NWO"]);
if (augmentationExists(AugmentationNames.PowerRecirculator)) { if (augmentationExists(AugmentationNames.PowerRecirculator)) {
delete Augmentations[AugmentationNames.PowerRecirculator]; delete Augmentations[AugmentationNames.PowerRecirculator];
@ -1032,7 +1032,7 @@ initAugmentations = function() {
"Increases the player's hacking speed by 10%<br>" + "Increases the player's hacking speed by 10%<br>" +
"Increases the player's chance of successfully performing a hack by 30%<br>" + "Increases the player's chance of successfully performing a hack by 30%<br>" +
"Increases the amount of money the player gains from hacking by 100%"); "Increases the amount of money the player gains from hacking by 100%");
QLink.setRequirements(750000, 1200000000); QLink.setRequirements(750000, 1300000000);
QLink.addToFactions(["Illuminati"]); QLink.addToFactions(["Illuminati"]);
if (augmentationExists(AugmentationNames.QLink)) { if (augmentationExists(AugmentationNames.QLink)) {
delete Augmentations[AugmentationNames.QLink]; delete Augmentations[AugmentationNames.QLink];
@ -1058,7 +1058,7 @@ initAugmentations = function() {
"This augmentation: <br>" + "This augmentation: <br>" +
"Increases all of the player's combat stats by 75%<br>" + "Increases all of the player's combat stats by 75%<br>" +
"Increases the player's hacking skill by 15%"); "Increases the player's hacking skill by 15%");
SPTN97.setRequirements(500000, 950000000); SPTN97.setRequirements(500000, 975000000);
SPTN97.addToFactions(["The Covenant"]); SPTN97.addToFactions(["The Covenant"]);
if (augmentationExists(AugmentationNames.SPTN97)) { if (augmentationExists(AugmentationNames.SPTN97)) {
delete Augmentations[AugmentationNames.SPTN97]; delete Augmentations[AugmentationNames.SPTN97];
@ -1070,7 +1070,7 @@ initAugmentations = function() {
HiveMind.setInfo("A brain implant developed by ECorp. They do not reveal what " + HiveMind.setInfo("A brain implant developed by ECorp. They do not reveal what " +
"exactly the implant does, but they promise that it will greatly " + "exactly the implant does, but they promise that it will greatly " +
"enhance your abilities."); "enhance your abilities.");
HiveMind.setRequirements(600000, 1000000000); HiveMind.setRequirements(600000, 1100000000);
HiveMind.addToFactions(["ECorp"]); HiveMind.addToFactions(["ECorp"]);
if (augmentationExists(AugmentationNames.HiveMind)) { if (augmentationExists(AugmentationNames.HiveMind)) {
delete Augmentations[AugmentationNames.HiveMind]; delete Augmentations[AugmentationNames.HiveMind];
@ -1086,7 +1086,7 @@ initAugmentations = function() {
"This augmentation:<br>" + "This augmentation:<br>" +
"Increases all of the player's combat stats by 35%<br>" + "Increases all of the player's combat stats by 35%<br>" +
"Increases all of the player's combat stat experience gain rate by 35%"); "Increases all of the player's combat stat experience gain rate by 35%");
CordiARCReactor.setRequirements(450000, 975000000); CordiARCReactor.setRequirements(450000, 1000000000);
CordiARCReactor.addToFactions(["MegaCorp"]); CordiARCReactor.addToFactions(["MegaCorp"]);
if (augmentationExists(AugmentationNames.CordiARCReactor)) { if (augmentationExists(AugmentationNames.CordiARCReactor)) {
delete Augmentations[AugmentationNames.CordiARCReactor]; delete Augmentations[AugmentationNames.CordiARCReactor];
@ -1103,7 +1103,7 @@ initAugmentations = function() {
"Increases the player's charisma experience gain rate by 50%<br>" + "Increases the player's charisma experience gain rate by 50%<br>" +
"Increases the amount of reputation the player gains for a company by 25%<br>" + "Increases the amount of reputation the player gains for a company by 25%<br>" +
"Increases the amount of reputation the player gains for a faction by 25%"); "Increases the amount of reputation the player gains for a faction by 25%");
SmartJaw.setRequirements(150000, 500000000); SmartJaw.setRequirements(150000, 550000000);
SmartJaw.addToFactions(["Bachman & Associates"]); SmartJaw.addToFactions(["Bachman & Associates"]);
if (augmentationExists(AugmentationNames.SmartJaw)) { if (augmentationExists(AugmentationNames.SmartJaw)) {
delete Augmentations[AugmentationNames.SmartJaw]; delete Augmentations[AugmentationNames.SmartJaw];
@ -1117,7 +1117,7 @@ initAugmentations = function() {
"body's skin and bone cells, granting them the ability to repair " + "body's skin and bone cells, granting them the ability to repair " +
"and restructure themselves. <br><br>" + "and restructure themselves. <br><br>" +
"This augmentation increases the player's strength and defense by 55%"); "This augmentation increases the player's strength and defense by 55%");
Neotra.setRequirements(225000, 550000000); Neotra.setRequirements(225000, 575000000);
Neotra.addToFactions(["Blade Industries"]); Neotra.addToFactions(["Blade Industries"]);
if (augmentationExists(AugmentationNames.Neotra)) { if (augmentationExists(AugmentationNames.Neotra)) {
delete Augmentations[AugmentationNames.Neotra]; delete Augmentations[AugmentationNames.Neotra];
@ -1132,7 +1132,7 @@ initAugmentations = function() {
"This augmentation: <br>" + "This augmentation: <br>" +
"Increases all of the player's stats by 20%<br>" + "Increases all of the player's stats by 20%<br>" +
"Increases the player's experience gain rate for all stats by 15%"); "Increases the player's experience gain rate for all stats by 15%");
Xanipher.setRequirements(350000, 800000000); Xanipher.setRequirements(350000, 850000000);
Xanipher.addToFactions(["NWO"]); Xanipher.addToFactions(["NWO"]);
if (augmentationExists(AugmentationNames.Xanipher)) { if (augmentationExists(AugmentationNames.Xanipher)) {
delete Augmentations[AugmentationNames.Xanipher]; delete Augmentations[AugmentationNames.Xanipher];
@ -1145,7 +1145,7 @@ initAugmentations = function() {
"of negligible senescence, preventing the body from " + "of negligible senescence, preventing the body from " +
"deteriorating with age. <br><br>" + "deteriorating with age. <br><br>" +
"This augmentation increases all of the player's stats by 20%"); "This augmentation increases all of the player's stats by 20%");
nextSENS.setRequirements(175000, 375000000); nextSENS.setRequirements(175000, 385000000);
nextSENS.addToFactions(["Clarke Incorporated"]); nextSENS.addToFactions(["Clarke Incorporated"]);
if (augmentationExists(AugmentationNames.nextSENS)) { if (augmentationExists(AugmentationNames.nextSENS)) {
delete Augmentations[AugmentationNames.nextSENS]; delete Augmentations[AugmentationNames.nextSENS];
@ -1160,7 +1160,7 @@ initAugmentations = function() {
"This augmentation:<br>" + "This augmentation:<br>" +
"Increases the player's hacking skill by 20%<br>" + "Increases the player's hacking skill by 20%<br>" +
"Increases the player's hacking experience gain rate by 25%"); "Increases the player's hacking experience gain rate by 25%");
OmniTekInfoLoad.setRequirements(250000, 550000000) OmniTekInfoLoad.setRequirements(250000, 575000000)
OmniTekInfoLoad.addToFactions(["OmniTek Incorporated"]); OmniTekInfoLoad.addToFactions(["OmniTek Incorporated"]);
if (augmentationExists(AugmentationNames.OmniTekInfoLoad)) { if (augmentationExists(AugmentationNames.OmniTekInfoLoad)) {
delete Augmentations[AugmentationNames.OmniTekInfoLoad]; delete Augmentations[AugmentationNames.OmniTekInfoLoad];
@ -1177,7 +1177,7 @@ initAugmentations = function() {
"skin cells, allowing users to generate their own energy " + "skin cells, allowing users to generate their own energy " +
"and nutrition using solar power. <br><br>" + "and nutrition using solar power. <br><br>" +
"This augmentation increases the player's strength, defense, and agility by 40%"); "This augmentation increases the player's strength, defense, and agility by 40%");
PhotosyntheticCells.setRequirements(225000, 525000000); PhotosyntheticCells.setRequirements(225000, 550000000);
PhotosyntheticCells.addToFactions(["KuaiGong International"]); PhotosyntheticCells.addToFactions(["KuaiGong International"]);
if (augmentationExists(AugmentationNames.PhotosyntheticCells)) { if (augmentationExists(AugmentationNames.PhotosyntheticCells)) {
delete Augmentations[AugmentationNames.PhotosyntheticCells]; delete Augmentations[AugmentationNames.PhotosyntheticCells];
@ -1195,7 +1195,7 @@ initAugmentations = function() {
"Increases the player's chance of successfully performing a hack by 10%<br>" + "Increases the player's chance of successfully performing a hack by 10%<br>" +
"Increases the player's hacking speed by 5%<br>" + "Increases the player's hacking speed by 5%<br>" +
"Lets the player start with the FTPCrack.exe and relaySMTP.exe programs after a reset"); "Lets the player start with the FTPCrack.exe and relaySMTP.exe programs after a reset");
Neurolink.setRequirements(350000, 850000000); Neurolink.setRequirements(350000, 875000000);
Neurolink.addToFactions(["BitRunners"]); Neurolink.addToFactions(["BitRunners"]);
if (augmentationExists(AugmentationNames.Neurolink)) { if (augmentationExists(AugmentationNames.Neurolink)) {
delete Augmentations[AugmentationNames.Neurolink]; delete Augmentations[AugmentationNames.Neurolink];
@ -1213,7 +1213,7 @@ initAugmentations = function() {
"Increases the player's hacking skill by 10%<br>" + "Increases the player's hacking skill by 10%<br>" +
"Increases the player's hacking speed by 2%<br>" + "Increases the player's hacking speed by 2%<br>" +
"Increases the amount of money the player gains from hacking by 10%"); "Increases the amount of money the player gains from hacking by 10%");
TheBlackHand.setRequirements(40000, 100000000); TheBlackHand.setRequirements(40000, 110000000);
TheBlackHand.addToFactions(["The Black Hand"]); TheBlackHand.addToFactions(["The Black Hand"]);
if (augmentationExists(AugmentationNames.TheBlackHand)) { if (augmentationExists(AugmentationNames.TheBlackHand)) {
delete Augmentations[AugmentationNames.TheBlackHand]; delete Augmentations[AugmentationNames.TheBlackHand];
@ -1396,13 +1396,13 @@ applyAugmentation = function(aug, reapply=false) {
switch(aug.name) { switch(aug.name) {
//Combat stat augmentations //Combat stat augmentations
case AugmentationNames.Targeting1: case AugmentationNames.Targeting1:
Player.dexterity_mult *= 1.15; Player.dexterity_mult *= 1.10;
break; break;
case AugmentationNames.Targeting2: case AugmentationNames.Targeting2:
Player.dexterity_mult *= 1.25; Player.dexterity_mult *= 1.20;
break; break;
case AugmentationNames.Targeting3: case AugmentationNames.Targeting3:
Player.dexterity_mult *= 1.40; Player.dexterity_mult *= 1.30;
break; break;
case AugmentationNames.SyntheticHeart: //High level case AugmentationNames.SyntheticHeart: //High level
Player.agility_mult *= 1.5; Player.agility_mult *= 1.5;
@ -1436,20 +1436,20 @@ applyAugmentation = function(aug, reapply=false) {
Player.dexterity_mult *= 1.05; Player.dexterity_mult *= 1.05;
break; break;
case AugmentationNames.GrapheneBoneLacings: //High level case AugmentationNames.GrapheneBoneLacings: //High level
Player.strength_mult *= 1.75; Player.strength_mult *= 1.7;
Player.defense_mult *= 1.75; Player.defense_mult *= 1.7;
break; break;
case AugmentationNames.BionicSpine: //Med level case AugmentationNames.BionicSpine: //Med level
Player.strength_mult *= 1.18; Player.strength_mult *= 1.16;
Player.defense_mult *= 1.18; Player.defense_mult *= 1.16;
Player.agility_mult *= 1.18; Player.agility_mult *= 1.16;
Player.dexterity_mult *= 1.18; Player.dexterity_mult *= 1.16;
break; break;
case AugmentationNames.GrapheneBionicSpine: //High level case AugmentationNames.GrapheneBionicSpine: //High level
Player.strength_mult *= 1.65; Player.strength_mult *= 1.6;
Player.defense_mult *= 1.65; Player.defense_mult *= 1.6;
Player.agility_mult *= 1.65; Player.agility_mult *= 1.6;
Player.dexterity_mult *= 1.65; Player.dexterity_mult *= 1.6;
break; break;
case AugmentationNames.BionicLegs: //Med level case AugmentationNames.BionicLegs: //Med level
Player.agility_mult *= 1.6; Player.agility_mult *= 1.6;
@ -1579,12 +1579,12 @@ applyAugmentation = function(aug, reapply=false) {
Player.charisma_mult *= 1.1; Player.charisma_mult *= 1.1;
break; break;
case AugmentationNames.FocusWire: //Med level case AugmentationNames.FocusWire: //Med level
Player.hacking_exp_mult *= 1.1; Player.hacking_exp_mult *= 1.05;
Player.strength_exp_mult *= 1.1; Player.strength_exp_mult *= 1.05;
Player.defense_exp_mult *= 1.1; Player.defense_exp_mult *= 1.05;
Player.dexterity_exp_mult *= 1.1; Player.dexterity_exp_mult *= 1.05;
Player.agility_exp_mult *= 1.1; Player.agility_exp_mult *= 1.05;
Player.charisma_exp_mult *= 1.1; Player.charisma_exp_mult *= 1.05;
Player.company_rep_mult *= 1.1; Player.company_rep_mult *= 1.1;
Player.work_money_mult *= 1.2; Player.work_money_mult *= 1.2;
break; break;
@ -1710,10 +1710,10 @@ applyAugmentation = function(aug, reapply=false) {
Player.crime_money_mult *= 1.25; Player.crime_money_mult *= 1.25;
break; break;
case AugmentationNames.HemoRecirculator: case AugmentationNames.HemoRecirculator:
Player.strength_mult *= 1.1; Player.strength_mult *= 1.08;
Player.defense_mult *= 1.1; Player.defense_mult *= 1.08;
Player.agility_mult *= 1.1; Player.agility_mult *= 1.08;
Player.dexterity_mult *= 1.1; Player.dexterity_mult *= 1.08;
break; break;
case AugmentationNames.SmartSonar: case AugmentationNames.SmartSonar:
Player.dexterity_mult *= 1.1; Player.dexterity_mult *= 1.1;

@ -1,5 +1,5 @@
CONSTANTS = { CONSTANTS = {
Version: "0.24.1", Version: "0.25.0",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //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 //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -11,7 +11,7 @@ CONSTANTS = {
/* Base costs */ /* Base costs */
BaseCostFor1GBOfRamHome: 32000, BaseCostFor1GBOfRamHome: 32000,
BaseCostFor1GBOfRamServer: 55000, //1 GB of RAM BaseCostFor1GBOfRamServer: 60000, //1 GB of RAM
BaseCostFor1GBOfRamHacknetNode: 30000, BaseCostFor1GBOfRamHacknetNode: 30000,
BaseCostForHacknetNode: 1000, BaseCostForHacknetNode: 1000,
@ -19,9 +19,9 @@ CONSTANTS = {
/* Hacknet Node constants */ /* Hacknet Node constants */
HacknetNodeMoneyGainPerLevel: 1.55, HacknetNodeMoneyGainPerLevel: 1.55,
HacknetNodePurchaseNextMult: 1.75, //Multiplier when purchasing an additional hacknet node HacknetNodePurchaseNextMult: 1.85, //Multiplier when purchasing an additional hacknet node
HacknetNodeUpgradeLevelMult: 1.045, //Multiplier for cost when upgrading level HacknetNodeUpgradeLevelMult: 1.05, //Multiplier for cost when upgrading level
HacknetNodeUpgradeRamMult: 1.28, //Multiplier for cost when upgrading RAM HacknetNodeUpgradeRamMult: 1.29, //Multiplier for cost when upgrading RAM
HacknetNodeUpgradeCoreMult: 1.49, //Multiplier for cost when buying another core HacknetNodeUpgradeCoreMult: 1.49, //Multiplier for cost when buying another core
HacknetNodeMaxLevel: 200, HacknetNodeMaxLevel: 200,
@ -34,7 +34,7 @@ CONSTANTS = {
/* Augmentation */ /* Augmentation */
//NeuroFlux Governor cost multiplier as you level up //NeuroFlux Governor cost multiplier as you level up
NeuroFluxGovernorLevelMult: 1.13, NeuroFluxGovernorLevelMult: 1.14,
/* Script related things */ /* Script related things */
//Time (ms) it takes to run one operation in Netscript. //Time (ms) it takes to run one operation in Netscript.
@ -71,6 +71,10 @@ CONSTANTS = {
ScriptHNUpgLevelRamCost: 0.4, ScriptHNUpgLevelRamCost: 0.4,
ScriptHNUpgRamRamCost: 0.6, ScriptHNUpgRamRamCost: 0.6,
ScriptHNUpgCoreRamCost: 0.8, ScriptHNUpgCoreRamCost: 0.8,
ScriptGetStockRamCost: 2.0,
ScriptBuySellStockRamCost: 2.5,
ScriptPurchaseServerRamCost: 2.0,
ScriptRoundRamCost: 0.05,
MultithreadingRAMCost: 1, MultithreadingRAMCost: 1,
@ -96,8 +100,8 @@ CONSTANTS = {
InfiltrationMoneyValue: 2000, //Convert "secret" value to money InfiltrationMoneyValue: 2000, //Convert "secret" value to money
//Stock market constants //Stock market constants
WSEAccountCost: 50000000, WSEAccountCost: 200000000,
TIXAPICost: 1000000000, TIXAPICost: 5000000000,
StockMarketCommission: 100000, StockMarketCommission: 100000,
//Hospital/Health //Hospital/Health
@ -327,6 +331,10 @@ CONSTANTS = {
"the execution of a script is when it saves/loads. </strong><br><br>", "the execution of a script is when it saves/loads. </strong><br><br>",
TutorialNetscriptText: "Netscript is a programming language implemented for this game. The language has " + TutorialNetscriptText: "Netscript is a programming language implemented for this game. The language has " +
"your basic programming constructs and several built-in commands that are used to hack. <br><br>" + "your basic programming constructs and several built-in commands that are used to hack. <br><br>" +
"<u><h1>Official Wiki and Documentation</h1></u><br>" +
"<a href='http://bitburner.wikia.com/wiki/Netscript' target='_blank'>Check out Bitburner's wiki for the official Netscript documentation</a>" +
". The wiki documentation will contain more details and " +
"code examples than this documentation page. Also, it can be opened up in another tab/window for convenience!<br><br>" +
"<u><h1> Variables and data types </h1></u><br>" + "<u><h1> Variables and data types </h1></u><br>" +
"The following data types are supported by Netscript: <br>" + "The following data types are supported by Netscript: <br>" +
"numeric - Integers and floats (eg. 6, 10.4999)<br>" + "numeric - Integers and floats (eg. 6, 10.4999)<br>" +
@ -354,41 +362,7 @@ CONSTANTS = {
"&nbsp;==<br>" + "&nbsp;==<br>" +
"&nbsp;!=<br><br>" + "&nbsp;!=<br><br>" +
"<u><h1> Arrays </h1></u><br>" + "<u><h1> Arrays </h1></u><br>" +
"Arrays are special container objects. Arrays can hold many values under a single name. Each value in the array " + "Netscript arrays have the same properties and functions as javascript arrays. For information see javascripts <a href=\"https://www.w3schools.com/js/js_arrays.asp\" target='_blank'>array</a> documentation.<br><br>"+
"can be accessed using an index number. The following example shows how to declare an array: <br><br>" +
"thisIsAnArray = Array[1, 2, 3, 'bitburner!', false];<br><br>" +
"Note that the values in an array can be different types. To access this array we just declared, we can use the index " +
"operator on the array's name: <br><br>" +
"print(thisIsAnArray[0]); <br>" +
"thisIsAnArray[1] = 5;<br>" +
"thisIsAnArray[3] = 'string concatenation ' + 123;<br><br>" +
"Note that arrays are indexed starting at index 0. Using an index that is too large or less than 0 will result in an " +
"out of bounds runtime error. <br><br>" +
"If an element in an array is assigned to a value that includes a variable, then it holds a reference to that variable. " +
"What this means is that if the variable changes, the array element will also change accordingly. For example:<br><br>" +
"x = 10;<br>testArr = Array[x];<br>print(testArr[0]);<br>x = 20;<br>print(testArr[0]);<br><br>" +
"This code will print: <br><br>10<br>20<br><br>" +
"<strong>Array functions</strong><br>" +
"Arrays have built-in functions/properties that can be used to more easily access and manipulate the containers. <br><br>"+
"<i>length/length()</i><br>Returns the number of elements in the array.<br>" +
"The example below will print out 5:<br><br>" +
"arr = Array[1, 2, 3, 4, 5];<br>print(arr.length);<br><br>" +
"<i>clear/clear()</i><br>Removes all elements from the array.<br>" +
"The example below creates an array with three strings and then uses clear to remove all of those strings. The result is that 'arr' will be " +
"an empty array.<br><br>" +
"arr = Array['str1', 'str2', 'str3'];<br>arr.clear();<br><br>" +
"<i>push(e)</i><br>Adds the element e to the end of the array.<br>" +
"The example below will create an array holding one element: the number 1. It will then push the number 2 onto the array. The result " +
"is that 'arr' will be an array of size 2 with arr[0] == 1 and arr[1] == 2<br><br>" +
"arr = Array[1];<br>arr.push(2);<br><br>" +
"<i>insert(e)</i><br>Inserts an element e into an array at a specified index. Every element in the array that is at or after " +
"the specified index is shifted down. The array must be indexed with the [] operator when using this function.<br>" +
"The following example will insert the number 2 into index 1 of the array. The result afterwards is that 'arr' will hold the values [1, 2, 3, 4].<br><br>" +
"arr = Array[1, 3, 4];<br>arr[1].insert(2);<br><br>" +
"<i>remove()</i><br>Removes an element from a specified index. Every element in the array that is after the specified index " +
"will be shifted up. The array must be indexed with the [] operator when using this function.<br>" +
"The following example will remove the first element of the array. The result afterwards is that 'arr' will hold the values [2, 3].<br><br>" +
"arr = Array[1, 2, 3];<br>arr[0].remove();<br><br>" +
"<u><h1> Script Arguments </h1></u><br>" + "<u><h1> Script Arguments </h1></u><br>" +
"Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " + "Arguments passed into a script can be accessed using a special array called 'args'. The arguments can be accessed like a normal array using the [] " +
"operator. (args[0], args[1], args[2]...) <br><br>" + "operator. (args[0], args[1], args[2]...) <br><br>" +
@ -427,9 +401,7 @@ CONSTANTS = {
"any server, regardless of where the script is running. This command requires root access to the target server, but " + "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 " + "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>" + "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>" + "<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>" +
"WARNING: Do NOT call print() on an array. The script will crash. You can, however, call print on single elements of an array. For example, if " +
"the variable 'a' is an array, then do NOT call print(a), but it is okay to call print(a[0]).<br><br>" +
"<i>scan(hostname/ip)</i><br>Returns an array containing the hostnames of all servers that are one node away from the specified server. " + "<i>scan(hostname/ip)</i><br>Returns an array containing the hostnames 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 hostnames in the returned array are strings.<br><br>" + "The argument must be a string containing the IP or hostname of the target server. The hostnames 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. Does NOT work while offline <br> Example: nuke('foodnstuff'); <br><br>" + "<i>nuke(hostname/ip)</i><br>Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline <br> Example: nuke('foodnstuff'); <br><br>" +
@ -528,6 +500,14 @@ CONSTANTS = {
"<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>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 " +
"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 " + "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>" + "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, " +
"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>" +
"Purchasing a server using this Netscript function is twice as expensive as manually purchasing a server from a location in the World.<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>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>" +
"<u><h1>Hacknet Nodes API</h1></u><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>" + "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>hacknetnodes</i><br> A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
@ -549,54 +529,74 @@ CONSTANTS = {
"to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.<br><br>" + "to a level of at least 75, RAM to at least 8GB, and number of cores to at least 2.<br><br>" +
"while(hacknetnodes.length < 4) {<br>" + "while(hacknetnodes.length < 4) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;purchaseHacknetNode();<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;purchaseHacknetNode();<br>" +
"};<br>" + "}<br>" +
"for (i = 0; i < 4; i = i+1) {<br>" + "for (i = 0; i < 4; i = i++) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].level <= 75) {<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].level <= 75) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeLevel(5);<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeLevel(5);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;};<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;}<br>" +
"};<br>" + "}<br>" +
"for (i = 0; i < 4; i = i+1) {<br>" + "for (i = 0; i < 4; i = i++) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].ram < 8) {<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].ram < 8) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeRam();<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeRam();<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;};<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;}<br>" +
"};<br>" + "}<br>" +
"for (i = 0; i < 4; i = i+1) {<br>" + "for (i = 0; i < 4; i = i++) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].cores < 2) {<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;while (hacknetnodes[i].cores < 2) {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeCore();<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hacknetnodes[i].upgradeCore();<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(10000);<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;};<br>" + "&nbsp;&nbsp;&nbsp;&nbsp;}<br>" +
"};<br><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 " +
"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 " +
"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 " +
"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 " +
"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>" +
"<u><h1>While loops </h1></u><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> " + "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>&nbsp;&nbsp;&nbsp;&nbsp;<i>[code]</i><br>}</i><br><br>" + "<i>while (<i>[cond]</i>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;<i>[code]</i><br>}</i><br><br>" +
"As long as <i>[cond]</i> remains true, the code block <i>[code]</i> will continuously execute. Example: <br><br>" + "As long as <i>[cond]</i> remains true, the code block <i>[code]</i> will continuously execute. Example: <br><br>" +
"<i>i = 0; <br> while (i < 10) { <br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>&nbsp;&nbsp;&nbsp;&nbsp;i = i + 1;<br> }; </i><br><br>" + "<i>i = 0; <br> while (i < 10) { <br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>&nbsp;&nbsp;&nbsp;&nbsp;i = i + 1;<br> } </i><br><br>" +
"This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits. <br><br>" + "This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits. <br><br>" +
"<i>while(true) { <br>&nbsp;&nbsp;&nbsp;&nbsp; hack('foodnstuff'); <br> }; </i><br><br> " + "<i>while(true) { <br>&nbsp;&nbsp;&nbsp;&nbsp; hack('foodnstuff'); <br> }</i><br><br> " +
"This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " + "This while loop above is an infinite loop (continuously runs until the script is manually stopped) that repeatedly runs the 'hack('foodnstuff')' command. " +
"Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code<br><br> " + "Note that a semicolon is needed at closing bracket of the while loop, UNLESS it is at the end of the code<br><br> " +
"<u><h1>For loops</h1></u><br>" + "<u><h1>For loops</h1></u><br>" +
"A for loop is another control flow statement that allows code to be repeated by iterations. The structure is: <br><br> " + "A for loop is another control flow statement that allows code to be repeated by iterations. The structure is: <br><br> " +
"<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;<i>code</i> <br> }; </i><br><br>" + "<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br>&nbsp;&nbsp;&nbsp;&nbsp;<i>code</i> <br> } </i><br><br>" +
"The <i>[init]</i> expression evaluates before the for loop begins. The for loop will continue to execute " + "The <i>[init]</i> expression evaluates before the for loop begins. The for loop will continue to execute " +
"as long as <i>[cond]</i> is met. The <i>[post]</i> expression will evaluate at the end of every iteration " + "as long as <i>[cond]</i> is met. The <i>[post]</i> expression will evaluate at the end of every iteration " +
"of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " + "of the for loop. The following example shows code that will run the 'hack('foodnstuff');' command 10 times " +
" using a for loop: <br><br>" + " using a for loop: <br><br>" +
"<i>for (i = 0; i < 10; i = i+1) { <br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>}; </i><br><br>" + "<i>for (i = 0; i < 10; i = i++) { <br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>} </i><br><br>" +
"<u><h1> If statements </h1></u><br>" + "<u><h1> If statements </h1></u><br>" +
"If/Elif/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" + "If/Else if/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" +
"<i>if (condition1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;code1<br>} elif (condition2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;code2<br>} else {<br>" + "<i>if (condition1) {<br>&nbsp;&nbsp;&nbsp;&nbsp;code1<br>} else if (condition2) {<br>&nbsp;&nbsp;&nbsp;&nbsp;code2<br>} else {<br>" +
"&nbsp;&nbsp;&nbsp;&nbsp;code3<br>}</i><br><br>" + "&nbsp;&nbsp;&nbsp;&nbsp;code3<br>}</i><br><br>" +
"In the code above, first <i>condition1</i> will be checked. If this condition is true, then <i>code1</i> will execute and the " + "In the code above, first <i>condition1</i> will be checked. If this condition is true, then <i>code1</i> will execute and the " +
"rest of the if/elif/else statement will be skipped. If <i>condition1</i> is NOT true, then the code will then go on to check " + "rest of the if/else if/else statement will be skipped. If <i>condition1</i> is NOT true, then the code will then go on to check " +
"<i>condition2</i>. If <i>condition2</i> is true, then <i>code2</i> will be executed, and the rest of the if/elif/else statement " + "<i>condition2</i>. If <i>condition2</i> is true, then <i>code2</i> will be executed, and the rest of the if/else if/else statement " +
"will be skipped. If none of the conditions are true, then the code within the else block (<i>code3</i>) will be executed. " + "will be skipped. If none of the conditions are true, then the code within the else block (<i>code3</i>) will be executed. " +
"Note that a conditional statement can have any number of elif statements. <br><br>" + "Note that a conditional statement can have any number of 'else if' statements. <br><br>" +
"Example: <br><br>" + "Example: <br><br>" +
"if(getServerMoneyAvailable('foodnstuff') > 200000) {<br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>" + "if(getServerMoneyAvailable('foodnstuff') > 200000) {<br>&nbsp;&nbsp;&nbsp;&nbsp;hack('foodnstuff');<br>" +
"} else {<br>&nbsp;&nbsp;&nbsp;&nbsp;grow('foodnstuff');<br>};<br><br>" + "} else {<br>&nbsp;&nbsp;&nbsp;&nbsp;grow('foodnstuff');<br>}<br><br>" +
"The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " + "The code above will use the getServerMoneyAvailable() function to check how much money there is on the 'foodnstuff' server. " +
"If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " + "If there is more than $200,000, then it will try to hack that server. If there is $200,000 or less on the server, " +
"then the code will call grow('foodnstuff') instead and add more money to the server.<br><br>", "then the code will call grow('foodnstuff') instead and add more money to the server.<br><br>",
@ -699,6 +699,32 @@ CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>", "World Stock Exchange account and TIX API Access<br>",
Changelog: Changelog:
"v0.25.0<br> " +
"-Refactored Netscript to use the open-source Acorns Parser. This re-implementation was done by Github users MrNuggelz. " +
"This has resulted in several changes in the Netscript language. Some scripts might break because of these changes. " +
"Changes listed below: <br>" +
"-Arrays are now fully functional Javascript arrays. You no longer need to use the 'Array' keyword to declare them. <br>" +
"-The length(), clear/clear(), insert(), and remove() functions no longer work for arrays. <br>" +
"-All Javascript array methods are available (splice(), push(), pop(), join(), shift(), indexOf(), etc. See documentation)<br>" +
"-Variables assigned to arrays are now passed by value rather than reference<br>" +
"-Incrementing/Decrementing are now available (i++, ++i)<br>" +
"-You no longer need semicolons at the end of block statements<br>" +
"-Netscript's Hacknet Node API functions no longer log anything<br>" +
"-Stock prices now update every ~6 seconds when the game is active (was 10 seconds before)<br>" +
"-Added a new mechanic that affects how stock prices change<br>" +
"-Script editor now has dynamic indicators for RAM Usage and Line number<br>" +
"-Augmentation Rebalancing - Many late game augmentations are now slightly more expensive. Several early game " +
"augmentations had their effects slightly decreased<br>" +
"-Increased the amount of rewards (both money and rep) you get from infiltration<br>" +
"-Purchasing servers is now slightly more expensive<br>" +
"-Calling the Netscript function getServerMoneyAvailable('home') now return's the player's money<br>" +
"-Added round(n) Netscript function - Rounds a number<br>" +
"-Added purchaseServer(hostname, ram) Netscript function<br>" +
"-Added the TIX API. This must be purchased in the WSE. It persists through resets. Access to the TIX API " +
"allows you to write scripts that perform automated algorithmic trading. See Netscript documentation<br>" +
"-Minor rebalancing in a lot of different areas<br>" +
"-Changed the format of IP Addresses so that they are smaller (will consist mostly of single digit numbers now). This will reduce " +
"the size of the game's save file.<br><br>" +
"v0.24.1<br>" + "v0.24.1<br>" +
"-Adjusted cost of upgrading home computer RAM. Should be a little cheaper for the first few upgrades (up to ~64GB), and " + "-Adjusted cost of upgrading home computer RAM. Should be a little cheaper for the first few upgrades (up to ~64GB), and " +
"then will start being more expensive than before. High RAM upgrades should now be significantly more expensive than before.<br>" + "then will start being more expensive than before. High RAM upgrades should now be significantly more expensive than before.<br>" +
@ -914,7 +940,7 @@ CONSTANTS = {
"-Updated Tutorial<br>" + "-Updated Tutorial<br>" +
"-Created a Hacknet Node API for Netscript that allows you to access and upgrade your Hacknet Nodes. See the Netscript documentation for more details. WARNING The old upgradeHacknetNode() and getNumHacknetNodes() functions waere removed so any script that has these will no longer work <br><br>" + "-Created a Hacknet Node API for Netscript that allows you to access and upgrade your Hacknet Nodes. See the Netscript documentation for more details. WARNING The old upgradeHacknetNode() and getNumHacknetNodes() functions waere removed so any script that has these will no longer work <br><br>" +
"v0.15 <br>" + "v0.15 <br>" +
"-Slightly reduced production multiplier for Hacknet Node RAM<br>" + "-Slightly reduced production multiplier for Hacknet Node RAM<br>" +
"-Faction pages now scroll<br>" + "-Faction pages now scroll<br>" +
"-Slightly increased amount of money gained from hacking<br>" + "-Slightly increased amount of money gained from hacking<br>" +
"-Added 'alias' command<br>" + "-Added 'alias' command<br>" +
@ -925,36 +951,31 @@ CONSTANTS = {
"-You can now see what an Augmentation does and its price even while its locked<br><br>", "-You can now see what an Augmentation does and its price even while its locked<br><br>",
LatestUpdate: LatestUpdate:
"v0.24.1<br>" + "v0.25.0<br> " +
"-Adjusted cost of upgrading home computer RAM. Should be a little cheaper for the first few upgrades (up to ~64GB), and " + "-Refactored Netscript to use the open-source Acorns Parser. This re-implementation was done by Github users MrNuggelz. " +
"then will start being more expensive than before. High RAM upgrades should now be significantly more expensive than before.<br>" + "This has resulted in several changes in the Netscript language. Some scripts might break because of these changes. " +
"-Slightly lowered the starting money available on most mid-game and end-game servers (servers with required hacking level " + "Changes listed below: <br>" +
"greater than 200) by about 10-15%<br>" + "-Arrays are now fully functional Javascript arrays. You no longer need to use the 'Array' keyword to declare them. <br>" +
"-Rebalanced company/company position reputation gains and requirements<br>" + "-The length(), clear/clear(), insert(), and remove() functions no longer work for arrays. <br>" +
"-Studying at a university now gives slightly more EXP and early jobs give slightly less EXP<br>" + "-All Javascript array methods are available (splice(), push(), pop(), join(), shift(), indexOf(), etc. See documentation)<br>" +
"-Studying at a university is now considerably more expensive<br>" + "-Variables assigned to arrays are now passed by value rather than reference<br>" +
"-Rebalanced stock market<br>" + "-Incrementing/Decrementing are now available (i++, ++i)<br>" +
"-Significantly increased cost multiplier for purchasing additional Hacknet Nodes<br>" + "-You no longer need semicolons at the end of block statements<br>" +
"-The rate at which facility security level increases during infiltration for each clearance level " + "-Netscript's Hacknet Node API functions no longer log anything<br>" +
"was lowered slightly for all companies<br>" + "-Stock prices now update every ~6 seconds when the game is active (was 10 seconds before)<br>" +
"-Updated Faction descriptions<br>" + "-Added a new mechanic that affects how stock prices change<br>" +
"-Changed the way alias works. Normal aliases now only work at the start of a Terminal command (they will only " + "-Script editor now has dynamic indicators for RAM Usage and Line number<br>" +
"replace the first word in the Terminal command). You can also create global aliases that work on any part of the " + "-Augmentation Rebalancing - Many late game augmentations are now slightly more expensive. Several early game " +
'command, like before. Declare global aliases by entering the optional -g flag: alias -g name="value" - Courtesy of Github user MrNuggelz<br>' + "augmentations had their effects slightly decreased<br>" +
"-'top' Terminal command implemented courtesy of Github user LTCNugget. Currently, the formatting gets screwed up " + "-Increased the amount of rewards (both money and rep) you get from infiltration<br>" +
"if your script names are really long.<br><br>" + "-Purchasing servers is now slightly more expensive<br>" +
"v0.24.0<br>" + "-Calling the Netscript function getServerMoneyAvailable('home') now return's the player's money<br>" +
"-Players now have HP, which is displayed in the top right. To regain HP, visit the hospital. Currently " + "-Added round(n) Netscript function - Rounds a number<br>" +
"the only way to lose HP is through infiltration<br>" + "-Added purchaseServer(hostname, ram) Netscript function<br>" +
"-Infiltration - Attempt to infiltrate a company and steal their classified secrets. See 'Companies' documentation for more details<br>" + "-Added the TIX API. This must be purchased in the WSE. It persists through resets. Access to the TIX API " +
"-Stock Market - Added the World Stock Exchange (WSE), a brokerage that lets you buy/sell stocks. To begin trading you must first purchase " + "allows you to write scripts that perform automated algorithmic trading. See Netscript documentation<br>" +
"an account. A WSE account will persist even after resetting by installing Augmentations. How the stock market works should hopefully be " + "-Minor rebalancing in a lot of different areas<br>" +
"self explanatory. There is no documentation about it currently, I will add some later. NOTE: Stock prices only change when the game is open. " + "-Changed the format of IP Addresses so that they are smaller (will consist mostly of single digit numbers now). This will reduce " +
"The Stock Market is reset when installing Augmentations, which means you will lose all your stocks<br>" + "the size of the game's save file.<br>",
"-Decreased money gained from hacking by ~12%<br>" +
"-Increased reputation required for all Augmentations by ~40%<br>" +
"-Cost increase when purchasing multiple augmentations increased from 75% to 90%<br>" +
"-Added basic variable runtime to Netscript operations. Basic commands run in 100ms. Any function incurs another 100ms in runtime (200ms total). " +
"Any function that starts with getServer incurs another 100ms runtime (300ms total). exec() and scp() require 400ms total. <br>" +
"-Slightly reduced the amount of experience gained from hacking<br>",
} }

@ -34,7 +34,7 @@ document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
function HacknetNode(name) { function HacknetNode(name) {
this.level = 1; this.level = 1;
this.ram = 1; //GB this.ram = 1; //GB
this.numCores = 1; this.cores = 1;
this.name = name; this.name = name;
@ -50,7 +50,7 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
this.moneyGainRatePerSecond = (this.level * gainPerLevel) * this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
Math.pow(1.035, this.ram-1) * Math.pow(1.035, this.ram-1) *
((this.numCores + 5) / 6) * Player.hacknet_node_money_mult; ((this.cores + 5) / 6) * Player.hacknet_node_money_mult;
if (isNaN(this.moneyGainRatePerSecond)) { if (isNaN(this.moneyGainRatePerSecond)) {
this.moneyGainRatePerSecond = 0; this.moneyGainRatePerSecond = 0;
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer"); dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer");
@ -85,6 +85,11 @@ HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
return true; return true;
} }
//Wrapper function for Netscript
HacknetNode.prototype.upgradeLevel = function(levels=1) {
return this.purchaseLevelUpgrade(levels);
}
HacknetNode.prototype.calculateRamUpgradeCost = function() { HacknetNode.prototype.calculateRamUpgradeCost = function() {
var numUpgrades = Math.log2(this.ram); var numUpgrades = Math.log2(this.ram);
@ -106,23 +111,33 @@ HacknetNode.prototype.purchaseRamUpgrade = function() {
return true; return true;
} }
//Wrapper function for Netscript
HacknetNode.prototype.upgradeRam = function() {
return this.purchaseRamUpgrade();
}
HacknetNode.prototype.calculateCoreUpgradeCost = function() { HacknetNode.prototype.calculateCoreUpgradeCost = function() {
var coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore; var coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore;
var mult = CONSTANTS.HacknetNodeUpgradeCoreMult; var mult = CONSTANTS.HacknetNodeUpgradeCoreMult;
return coreBaseCost * Math.pow(mult, this.numCores-1) * Player.hacknet_node_core_cost_mult; return coreBaseCost * Math.pow(mult, this.cores-1) * Player.hacknet_node_core_cost_mult;
} }
HacknetNode.prototype.purchaseCoreUpgrade = function() { HacknetNode.prototype.purchaseCoreUpgrade = function() {
var cost = this.calculateCoreUpgradeCost(); var cost = this.calculateCoreUpgradeCost();
if (isNaN(cost)) {return false;} if (isNaN(cost)) {return false;}
if (cost > Player.money) {return false;} if (cost > Player.money) {return false;}
if (this.numCores >= CONSTANTS.HacknetNodeMaxCores) {return false;} if (this.cores >= CONSTANTS.HacknetNodeMaxCores) {return false;}
Player.loseMoney(cost); Player.loseMoney(cost);
++this.numCores; ++this.cores;
this.updateMoneyGainRate(); this.updateMoneyGainRate();
return true; return true;
} }
//Wrapper function for Netscript
HacknetNode.prototype.upgradeCore = function() {
return this.purchaseCoreUpgrade();
}
/* Saving and loading HackNets */ /* Saving and loading HackNets */
HacknetNode.prototype.toJSON = function() { HacknetNode.prototype.toJSON = function() {
return Generic_toJSON("HacknetNode", this); return Generic_toJSON("HacknetNode", this);
@ -150,8 +165,8 @@ purchaseHacknet = function() {
var cost = getCostOfNextHacknetNode(); var cost = getCostOfNextHacknetNode();
if (isNaN(cost)) {throw new Error("Cost is NaN"); return;} if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
if (cost > Player.money) { if (cost > Player.money) {
dialogBoxCreate("You cannot afford to purchase a Hacknet Node!"); //dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
return; return false;
} }
//Auto generate a name for the node for now...TODO //Auto generate a name for the node for now...TODO
@ -165,6 +180,7 @@ purchaseHacknet = function() {
displayHacknetNodesContent(); displayHacknetNodesContent();
updateTotalHacknetProduction(); updateTotalHacknetProduction();
return numOwned;
} }
//Calculates the total production from all HacknetNodes //Calculates the total production from all HacknetNodes
@ -361,7 +377,7 @@ updateHacknetNodeDomElement = function(nodeObj) {
" ($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" + " ($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
"Level: " + nodeObj.level + "<br>" + "Level: " + nodeObj.level + "<br>" +
"RAM: " + nodeObj.ram + "GB<br>" + "RAM: " + nodeObj.ram + "GB<br>" +
"Cores: " + nodeObj.numCores; "Cores: " + nodeObj.cores;
//Upgrade level //Upgrade level
var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName); var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
@ -408,7 +424,7 @@ updateHacknetNodeDomElement = function(nodeObj) {
//Upgrade Cores //Upgrade Cores
var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName); var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");} if (upgradeCoreButton == null) {throw new Error("Cannot find upgrade cores button element");}
if (nodeObj.numCores >= CONSTANTS.HacknetNodeMaxCores) { if (nodeObj.cores >= CONSTANTS.HacknetNodeMaxCores) {
upgradeCoreButton.innerHTML = "MAX CORES"; upgradeCoreButton.innerHTML = "MAX CORES";
upgradeCoreButton.setAttribute("class", "a-link-button-inactive"); upgradeCoreButton.setAttribute("class", "a-link-button-inactive");
} else { } else {

@ -369,7 +369,7 @@ displayLocationContent = function() {
purchaseTor.style.display = "block"; purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumECorp, setInfiltrateButton(infiltrate, Locations.AevumECorp,
6000, 100, 150, 13); 6000, 106, 150, 13);
break; break;
case Locations.AevumBachmanAndAssociates: case Locations.AevumBachmanAndAssociates:
@ -382,7 +382,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumBachmanAndAssociates, setInfiltrateButton(infiltrate, Locations.AevumBachmanAndAssociates,
1500, 36, 60, 9.5); 1500, 38, 60, 9.5);
break; break;
case Locations.AevumClarkeIncorporated: case Locations.AevumClarkeIncorporated:
@ -395,7 +395,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumClarkeIncorporated, setInfiltrateButton(infiltrate, Locations.AevumClarkeIncorporated,
2400, 28, 75, 9); 2400, 30, 75, 9);
break; break;
case Locations.AevumFulcrumTechnologies: case Locations.AevumFulcrumTechnologies:
@ -414,7 +414,7 @@ displayLocationContent = function() {
purchaseTor.style.display = "block"; purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumFulcrumTechnologies, setInfiltrateButton(infiltrate, Locations.AevumFulcrumTechnologies,
6000, 84, 100, 15); 6000, 88, 100, 15);
break; break;
case Locations.AevumAeroCorp: case Locations.AevumAeroCorp:
@ -426,7 +426,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumAeroCorp, setInfiltrateButton(infiltrate, Locations.AevumAeroCorp,
2000, 26, 50, 10); 2000, 28, 50, 10);
break; break;
case Locations.AevumGalacticCybersystems: case Locations.AevumGalacticCybersystems:
@ -439,7 +439,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
businessJob.style.display = "block"; businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumGalacticCybersystems, setInfiltrateButton(infiltrate, Locations.AevumGalacticCybersystems,
1400, 24, 50, 9); 1400, 26, 50, 9);
break; break;
case Locations.AevumWatchdogSecurity: case Locations.AevumWatchdogSecurity:
@ -453,7 +453,7 @@ displayLocationContent = function() {
securityJob.style.display = "block"; securityJob.style.display = "block";
agentJob.style.display = "block"; agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumWatchdogSecurity, setInfiltrateButton(infiltrate, Locations.AevumWatchdogSecurity,
850, 12, 30, 7.5); 850, 14, 30, 7.5);
break; break;
case Locations.AevumRhoConstruction: case Locations.AevumRhoConstruction:
@ -462,7 +462,7 @@ displayLocationContent = function() {
softwareJob.style.display = "block"; softwareJob.style.display = "block";
businessJob.style.display = "block"; businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumRhoConstruction, setInfiltrateButton(infiltrate, Locations.AevumRhoConstruction,
600, 8, 20, 4); 600, 10, 20, 4);
break; break;
case Locations.AevumPolice: case Locations.AevumPolice:
@ -471,7 +471,7 @@ displayLocationContent = function() {
softwareJob.style.display = "block"; softwareJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumPolice, setInfiltrateButton(infiltrate, Locations.AevumPolice,
700, 10, 25, 5); 700, 12, 25, 5);
break; break;
case Locations.AevumNetLinkTechnologies: case Locations.AevumNetLinkTechnologies:
@ -489,7 +489,7 @@ displayLocationContent = function() {
purchaseTor.style.display = "block"; purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumNetLinkTechnologies, setInfiltrateButton(infiltrate, Locations.AevumNetLinkTechnologies,
150, 5, 15, 3); 160, 8, 15, 3);
break; break;
case Locations.AevumCrushFitnessGym: case Locations.AevumCrushFitnessGym:
@ -523,7 +523,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.ChongqingKuaiGongInternational, setInfiltrateButton(infiltrate, Locations.ChongqingKuaiGongInternational,
5500, 42, 100, 14); 5500, 44, 100, 14);
break; break;
case Locations.ChongqingSolarisSpaceSystems: case Locations.ChongqingSolarisSpaceSystems:
@ -564,7 +564,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12MegaCorp, setInfiltrateButton(infiltrate, Locations.Sector12MegaCorp,
6000, 100, 125, 15); 6000, 104, 125, 15);
break; break;
case Locations.Sector12BladeIndustries: case Locations.Sector12BladeIndustries:
@ -577,7 +577,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12BladeIndustries, setInfiltrateButton(infiltrate, Locations.Sector12BladeIndustries,
3000, 40, 100, 10); 3000, 42, 100, 10);
break; break;
case Locations.Sector12FourSigma: case Locations.Sector12FourSigma:
@ -590,7 +590,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12FourSigma, setInfiltrateButton(infiltrate, Locations.Sector12FourSigma,
1500, 50, 100, 14.5); 1500, 52, 100, 14.5);
break; break;
case Locations.Sector12IcarusMicrosystems: case Locations.Sector12IcarusMicrosystems:
@ -603,7 +603,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
businessJob.style.display = "block"; businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12IcarusMicrosystems, setInfiltrateButton(infiltrate, Locations.Sector12IcarusMicrosystems,
900, 28, 70, 11); 900, 30, 70, 11);
break; break;
case Locations.Sector12UniversalEnergy: case Locations.Sector12UniversalEnergy:
@ -616,7 +616,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
businessJob.style.display = "block"; businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12UniversalEnergy, setInfiltrateButton(infiltrate, Locations.Sector12UniversalEnergy,
775, 20, 50, 9.5); 775, 22, 50, 9.5);
break; break;
case Locations.Sector12DeltaOne: case Locations.Sector12DeltaOne:
@ -628,7 +628,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12DeltaOne, setInfiltrateButton(infiltrate, Locations.Sector12DeltaOne,
1200, 30, 75, 10); 1200, 34, 75, 10);
break; break;
case Locations.Sector12CIA: case Locations.Sector12CIA:
@ -641,7 +641,7 @@ displayLocationContent = function() {
securityJob.style.display = "block"; securityJob.style.display = "block";
agentJob.style.display = "block"; agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12CIA, setInfiltrateButton(infiltrate, Locations.Sector12CIA,
1450, 38, 80, 12); 1450, 40, 80, 12);
break; break;
case Locations.Sector12NSA: case Locations.Sector12NSA:
@ -654,7 +654,7 @@ displayLocationContent = function() {
securityJob.style.display = "block"; securityJob.style.display = "block";
agentJob.style.display = "block"; agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12NSA, setInfiltrateButton(infiltrate, Locations.Sector12NSA,
1400, 34, 80, 11); 1400, 36, 80, 11);
break; break;
case Locations.Sector12AlphaEnterprises: case Locations.Sector12AlphaEnterprises:
@ -668,7 +668,7 @@ displayLocationContent = function() {
purchaseTor.style.display = "block"; purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12AlphaEnterprises, setInfiltrateButton(infiltrate, Locations.Sector12AlphaEnterprises,
250, 10, 40, 4.5); 250, 12, 40, 4.5);
break; break;
case Locations.Sector12CarmichaelSecurity: case Locations.Sector12CarmichaelSecurity:
@ -682,7 +682,7 @@ displayLocationContent = function() {
securityJob.style.display = "block"; securityJob.style.display = "block";
agentJob.style.display = "block"; agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12CarmichaelSecurity, setInfiltrateButton(infiltrate, Locations.Sector12CarmichaelSecurity,
500, 14, 60, 4.5); 500, 16, 60, 4.5);
break; break;
case Locations.Sector12FoodNStuff: case Locations.Sector12FoodNStuff:
@ -698,7 +698,7 @@ displayLocationContent = function() {
employeeJob.style.display = "block"; employeeJob.style.display = "block";
employeePartTimeJob.style.display = "block"; employeePartTimeJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12JoesGuns, setInfiltrateButton(infiltrate, Locations.Sector12JoesGuns,
100, 4, 20, 3.5); 120, 6, 20, 3.5);
break; break;
case Locations.Sector12IronGym: case Locations.Sector12IronGym:
@ -731,7 +731,7 @@ displayLocationContent = function() {
securityEngineerJob.style.display = "block"; securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoDefComm, setInfiltrateButton(infiltrate, Locations.NewTokyoDefComm,
1300, 24, 70, 9); 1300, 26, 70, 9);
break; break;
case Locations.NewTokyoVitaLife: case Locations.NewTokyoVitaLife:
@ -744,7 +744,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
businessJob.style.display = "block"; businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoVitaLife, setInfiltrateButton(infiltrate, Locations.NewTokyoVitaLife,
750, 18, 100, 8); 750, 20, 100, 8);
break; break;
case Locations.NewTokyoGlobalPharmaceuticals: case Locations.NewTokyoGlobalPharmaceuticals:
@ -758,7 +758,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoGlobalPharmaceuticals, setInfiltrateButton(infiltrate, Locations.NewTokyoGlobalPharmaceuticals,
900, 20, 80, 8.5); 900, 22, 80, 8.5);
break; break;
case Locations.NewTokyoNoodleBar: case Locations.NewTokyoNoodleBar:
@ -797,7 +797,7 @@ displayLocationContent = function() {
purchase256gb.style.display = "block"; purchase256gb.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaStormTechnologies, setInfiltrateButton(infiltrate, Locations.IshimaStormTechnologies,
700, 20, 100, 10); 700, 22, 100, 10);
break; break;
case Locations.IshimaNovaMedical: case Locations.IshimaNovaMedical:
@ -810,7 +810,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
businessJob.style.display = "block"; businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaNovaMedical, setInfiltrateButton(infiltrate, Locations.IshimaNovaMedical,
600, 16, 50, 7.5); 600, 18, 50, 7.5);
break; break;
case Locations.IshimaOmegaSoftware: case Locations.IshimaOmegaSoftware:
@ -828,7 +828,7 @@ displayLocationContent = function() {
purchaseTor.style.display = "block"; purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaOmegaSoftware, setInfiltrateButton(infiltrate, Locations.IshimaOmegaSoftware,
200, 5, 40, 4); 200, 8, 40, 4);
break; break;
case Locations.VolhavenTravelAgency: case Locations.VolhavenTravelAgency:
@ -861,7 +861,7 @@ displayLocationContent = function() {
purchase512gb.style.display = "block"; purchase512gb.style.display = "block";
purchase1tb.style.display = "block"; purchase1tb.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenOmniTekIncorporated, setInfiltrateButton(infiltrate, Locations.VolhavenOmniTekIncorporated,
1500, 38, 100, 9.5); 1500, 40, 100, 9.5);
break; break;
case Locations.VolhavenNWO: case Locations.VolhavenNWO:
@ -874,7 +874,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenNWO, setInfiltrateButton(infiltrate, Locations.VolhavenNWO,
1800, 48, 200, 11); 1800, 50, 200, 11);
break; break;
case Locations.VolhavenHeliosLabs: case Locations.VolhavenHeliosLabs:
@ -886,7 +886,7 @@ displayLocationContent = function() {
securityEngineerJob.style.display = "block"; securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenHeliosLabs, setInfiltrateButton(infiltrate, Locations.VolhavenHeliosLabs,
1200, 24, 75, 9); 1200, 26, 75, 9);
break; break;
case Locations.VolhavenOmniaCybersystems: case Locations.VolhavenOmniaCybersystems:
@ -898,7 +898,7 @@ displayLocationContent = function() {
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenOmniaCybersystems, setInfiltrateButton(infiltrate, Locations.VolhavenOmniaCybersystems,
900, 24, 90, 9.5); 900, 26, 90, 9.5);
break; break;
case Locations.VolhavenLexoCorp: case Locations.VolhavenLexoCorp:
@ -912,7 +912,7 @@ displayLocationContent = function() {
businessJob.style.display = "block"; businessJob.style.display = "block";
securityJob.style.display = "block"; securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenLexoCorp, setInfiltrateButton(infiltrate, Locations.VolhavenLexoCorp,
500, 10, 40, 5.5); 500, 12, 40, 5.5);
break; break;
case Locations.VolhavenSysCoreSecurities: case Locations.VolhavenSysCoreSecurities:
@ -923,7 +923,7 @@ displayLocationContent = function() {
securityEngineerJob.style.display = "block"; securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block"; networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenSysCoreSecurities, setInfiltrateButton(infiltrate, Locations.VolhavenSysCoreSecurities,
600, 12, 50, 6); 600, 14, 50, 6);
break; break;
case Locations.VolhavenCompuTek: case Locations.VolhavenCompuTek:
@ -944,7 +944,7 @@ displayLocationContent = function() {
purchaseTor.style.display = "block"; purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block"; purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenCompuTek, setInfiltrateButton(infiltrate, Locations.VolhavenCompuTek,
300, 8, 35, 5); 300, 10, 35, 5);
break; break;
case Locations.VolhavenMilleniumFitnessGym: case Locations.VolhavenMilleniumFitnessGym:

@ -1,8 +1,12 @@
/* Environment /* Environment
* NetScript program environment * NetScript program environment
*/ */
function Environment(parent) { function Environment(workerScript,parent) {
this.vars = Object.create(parent ? parent.vars : null); if (parent){
this.vars = parent.vars;
} else {
this.vars = NetscriptFunctions(workerScript);
}
this.parent = parent; this.parent = parent;
this.stopFlag = false; this.stopFlag = false;
} }
@ -44,7 +48,20 @@ Environment.prototype = {
} }
return (scope || this).vars[name] = value; return (scope || this).vars[name] = value;
}, },
setArrayElement: function(name, idx, value) {
var scope = this.lookup(name);
if (!scope && this.parent) {
console.log("Here");
throw new Error("Undefined variable " + name);
}
var arr = (scope || this).vars[name];
if (!(arr.constructor === Array || arr instanceof Array)) {
throw new Error("Variable is not an array: " + name);
}
return (scope || this).vars[name][idx] = value;
},
//Creates (or overwrites) a variable in the current scope //Creates (or overwrites) a variable in the current scope
def: function(name, value) { def: function(name, value) {
return this.vars[name] = value; return this.vars[name] = value;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,25 +0,0 @@
/* InputStream class. Creates a "stream object" that provides operations to read
* from a string. */
function InputStream(input) {
var pos = 0, line = 1, col = 0;
return {
next : next,
peek : peek,
eof : eof,
croak : croak,
};
function next() {
var ch = input.charAt(pos++);
if (ch == "\n") line++, col = 0; else col++;
return ch;
}
function peek() {
return input.charAt(pos);
}
function eof() {
return peek() == "";
}
function croak(msg) {
throw new Error(msg + " (" + line + ":" + col + ")");
}
}

@ -1,326 +0,0 @@
/* Parser
* Creates Abstract Syntax Tree Nodes
* Operates on a stream of tokens from the Tokenizer
*/
var FALSE = {type: "bool", value: false};
function Parser(input) {
var PRECEDENCE = {
"=": 1,
"||": 2,
"&&": 3,
"<": 7, ">": 7, "<=": 7, ">=": 7, "==": 7, "!=": 7,
"+": 10, "-": 10,
"*": 20, "/": 20, "%": 20,
};
return parse_toplevel();
//Returns true if the next token is a punc type with value ch
function is_punc(ch) {
var tok = input.peek();
return tok && tok.type == "punc" && (!ch || tok.value == ch) && tok;
}
//Returns true if the next token is the kw keyword
function is_kw(kw) {
var tok = input.peek();
return tok && tok.type == "kw" && (!kw || tok.value == kw) && tok;
}
//Returns true if the next token is an op type with the given op value
function is_op(op) {
var tok = input.peek();
return tok && tok.type == "op" && (!op || tok.value == op) && tok;
}
//Checks that the next character is the given punctuation character and throws
//an error if it's not. If it is, skips over it in the input
function checkPuncAndSkip(ch) {
if (is_punc(ch)) input.next();
else input.croak("Expecting punctuation: \"" + ch + "\"");
}
//Checks that the next character is the given keyword and throws an error
//if its not. If it is, skips over it in the input
function checkKeywordAndSkip(kw) {
if (is_kw(kw)) input.next();
else input.croak("Expecting keyword: \"" + kw + "\"");
}
//Checks that the next character is the given operator and throws an error
//if its not. If it is, skips over it in the input
function checkOpAndSkip(op) {
if (is_op(op)) input.next();
else input.croak("Expecting operator: \"" + op + "\"");
}
function unexpected() {
input.croak("Unexpected token: " + JSON.stringify(input.peek()));
}
function maybe_binary(left, my_prec) {
var tok = is_op();
if (tok) {
var his_prec = PRECEDENCE[tok.value];
if (his_prec > my_prec) {
input.next();
return maybe_binary({
type : tok.value == "=" ? "assign" : "binary",
operator : tok.value,
left : left,
right : maybe_binary(parse_atom(), his_prec)
}, my_prec);
}
}
return left;
}
function delimited(start, stop, separator, parser) {
var a = [], first = true;
checkPuncAndSkip(start);
while (!input.eof()) {
if (is_punc(stop)) break;
if (first) first = false; else checkPuncAndSkip(separator);
if (is_punc(stop)) break;
a.push(parser());
}
checkPuncAndSkip(stop);
return a;
}
function parse_call(func) {
return {
type: "call",
func: func,
args: delimited("(", ")", ",", parse_expression),
};
}
function parse_varname() {
var name = input.next();
if (name.type != "var") input.croak("Expecting variable name");
return name.value;
}
/* type: "if",
* cond: [ {"type": "var", "value": "cond1"}, {"type": "var", "value": "cond2"}...]
* then: [ {"type": "var", "value": "then1"}, {"type": "var", "value": "then2"}...]
* else: {"type": "var", "value": "foo"}
*/
function parse_if() {
checkKeywordAndSkip("if");
//Conditional
var cond = parse_expression();
//Body
var then = parse_expression();
var ret = {
type: "if",
cond: [],
then: [],
};
ret.cond.push(cond);
ret.then.push(then);
// Parse all elif branches
while (is_kw("elif")) {
input.next();
var cond = parse_expression();
var then = parse_expression();
ret.cond.push(cond);
ret.then.push(then);
}
// Parse else branch, if it exists
if (is_kw("else")) {
input.next();
ret.else = parse_expression();
}
return ret;
}
/* for (init, cond, postloop) {code;}
*
* type: "for",
* init: assign node,
* cond: var node,
* postloop: assign node
* code: prog node
*/
function parse_for() {
checkKeywordAndSkip("for");
temp = delimited("(", ")", ";", parse_expression);
var splitExpressions = temp.slice();
code = parse_expression();
if (splitExpressions.length != 3) {
throw new Error("for statement has incorrect number of arguments");
}
//TODO Check type of the init, cond, and postloop nodes
return {
type: "for",
init: splitExpressions[0],
cond: splitExpressions[1],
postloop: splitExpressions[2],
code: code
}
}
/* while (cond) {}
*
* type: "while",
* cond: var node
* code: prog node
*/
function parse_while() {
checkKeywordAndSkip("while");
var cond = parse_expression();
var code = parse_expression();
return {
type: "while",
cond: cond,
code: code
}
}
/* hacknetnodes[i].operator
*/
function parse_hacknetnodes() {
var index = null;
if (is_punc("[")) {
index = parse_expression();
if (index.type != "index") {
unexpected();
}
}
if (is_punc(".")) {
checkPuncAndSkip(".");
var op = maybe_call(function() {
var tok = input.next();
return tok;
});
return {
type: "var",
value: "hacknetnodes",
index: index,
op: op,
};
}
unexpected();
}
//Declaring a new array with Array[1,2,3]
function parse_arraydecl() {
var array = delimited("[", "]", ",", parse_expression);
return {type: "var",
value: "array",
array: array
};
}
//Parsing an operation on an array, such as accessing, push(), etc.
//tok is a reference to a token of type var
function parse_arrayop(tok) {
//Returns a variable node except with an extra "index" field so
//we can identify it as an index
if (is_punc("[")) {
var index = parse_arrayindex();
if (index.type != "index") {
unexpected();
}
}
var op = null;
if (is_punc(".")) {
checkPuncAndSkip(".");
op = maybe_call(function() {
var callTok = input.next();
return callTok;
});
}
tok.index = index;
tok.op = op; //Will be null if no operation
return tok;
}
function parse_arrayindex() {
var index = delimited("[", "]", ";", parse_expression);
var val = 0;
if (index.length == 1) {
val = index[0];
} else {
unexpected();
}
return { type: "index", value: val };
}
function parse_bool() {
return {
type : "bool",
value : input.next().value == "true"
};
}
function maybe_call(expr) {
expr = expr();
return is_punc("(") ? parse_call(expr) : expr;
}
function parse_atom() {
return maybe_call(function(){
if (is_punc("(")) {
input.next();
var exp = parse_expression();
checkPuncAndSkip(")");
return exp;
}
if (is_punc("{")) return parse_prog();
if (is_punc("[")) return parse_arrayindex();
if (is_kw("if")) return parse_if();
if (is_kw("for")) return parse_for();
if (is_kw("while")) return parse_while();
if (is_kw("true") || is_kw("false")) return parse_bool();
var tok = input.next();
if (tok.type == "var" && tok.value == "hacknetnodes") return parse_hacknetnodes();
if (tok.type == "var" && tok.value == "Array") return parse_arraydecl();
if (tok.type == "var" && (is_punc("[") || is_punc("."))) {
return parse_arrayop(tok);
}
if (tok.type == "var" || tok.type == "num" || tok.type == "str")
return tok;
unexpected();
});
}
function parse_toplevel() {
var prog = [];
while (!input.eof()) {
prog.push(parse_expression());
if (!input.eof()) checkPuncAndSkip(";");
}
//Return the top level Abstract Syntax Tree, where the top node is a "prog" node
return { type: "prog", prog: prog };
}
function parse_prog() {
var prog = delimited("{", "}", ";", parse_expression);
if (prog.length == 0) return FALSE;
if (prog.length == 1) return prog[0];
return { type: "prog", prog: prog };
}
function parse_expression() {
return maybe_call(function(){
return maybe_binary(parse_atom(), 0);
});
}
}

@ -1,168 +0,0 @@
/* Tokenizer
* Acts on top of the InputStream class. Takes in a character input stream and and parses it into tokens.
* Tokens can be accessed with peek() and next().
*
* Token types:
* {type: "punc", value: "(" } // punctuation: parens, comma, semicolon etc.
* {type: "num", value: 5 } // numbers (including floats)
* {type: "str", value: "Hello World!" } // strings
* {type: "kw", value: "for/if/..." } // keywords, see defs below
* {type: "var", value: "a" } // identifiers/variables
* {type: "op", value: "!=" } // operator characters
* {type: "bool", value: "true" } // Booleans
*
*/
function Tokenizer(input) {
var current = null;
var keywords = " if elif else true false while for ";
return {
next : next,
peek : peek,
eof : eof,
croak : input.croak
}
function is_keyword(x) {
return keywords.indexOf(" " + x + " ") >= 0;
}
function is_digit(ch) {
return /[0-9]/i.test(ch);
}
//An identifier can start with any letter or an underscore
function is_id_start(ch) {
return /[a-z_]/i.test(ch);
}
function is_id(ch) {
return is_id_start(ch) || "?!-<>=0123456789".indexOf(ch) >= 0;
}
function is_op_char(ch) {
return "+-*/%=&|<>!".indexOf(ch) >= 0;
}
function is_punc(ch) {
return ",;(){}[].".indexOf(ch) >= 0;
}
function is_whitespace(ch) {
return " \t\n".indexOf(ch) >= 0;
}
function read_while(predicate) {
var str = "";
while (!input.eof() && predicate(input.peek()))
str += input.next();
return str;
}
function read_number() {
var has_dot = false;
//Reads the number from the input. Checks for only a single decimal point
var number = read_while(function(ch){
if (ch == ".") {
if (has_dot) return false;
has_dot = true;
return true;
}
return is_digit(ch);
});
return { type: "num", value: parseFloat(number) };
}
//This function also checks the identifier against a list of known keywords (defined at the top)
//and will return a kw object rather than identifier if it is one
function read_ident() {
//Identifier must start with a letter or underscore..and can contain anything from ?!-<>=0123456789
var id = read_while(is_id);
return {
type : is_keyword(id) ? "kw" : "var",
value : id
};
}
function read_escaped(end) {
var escaped = false, str = "";
input.next(); //Skip the quotation mark
while (!input.eof()) {
var ch = input.next();
if (escaped) {
str += ch;
escaped = false;
} else if (ch == "\\") {
escaped = true;
} else if (ch == end) {
break;
} else {
str += ch;
}
}
return str;
}
function read_string(ch) {
if (ch == '"') {
return { type: "str", value: read_escaped('"') };
} else if (ch == '\'') {
return { type: "str", value: read_escaped('\'') };
}
}
//Only supports single-line comments right now
function skip_comment() {
read_while(function(ch){ return ch != "\n" });
input.next();
}
//Gets the next token
function read_next() {
//Skip over whitespace
read_while(is_whitespace);
if (input.eof()) return null;
//Peek the next character and decide what to do based on what that
//next character is
var ch = input.peek();
if (ch == "//") {
skip_comment();
return read_next();
}
if (ch == '"' || ch == '\'') return read_string(ch);
if (is_digit(ch)) return read_number();
if (is_id_start(ch)) return read_ident();
if (is_punc(ch)) return {
type : "punc",
value : input.next()
}
if (is_op_char(ch)) return {
type : "op",
value : read_while(is_op_char)
}
}
function peek() {
//Returns current token, unless its null in which case it grabs the next one
//and returns it
return current || (current = read_next());
}
function next() {
//The token might have been peaked already, in which case read_next() was already
//called so just return current
var tok = current;
current = null;
return tok || read_next();
}
function eof() {
return peek() == null;
}
}

@ -8,7 +8,8 @@ function WorkerScript(runningScriptObj) {
this.running = false; this.running = false;
this.serverIp = null; this.serverIp = null;
this.code = runningScriptObj.scriptRef.code; this.code = runningScriptObj.scriptRef.code;
this.env = new Environment(); this.env = new Environment(this);
this.env.set("args", runningScriptObj.args);
this.output = ""; this.output = "";
this.ramUsage = 0; this.ramUsage = 0;
this.scriptRef = runningScriptObj; this.scriptRef = runningScriptObj;
@ -31,7 +32,7 @@ function runScriptsLoop() {
//If it isn't running, start the script //If it isn't running, start the script
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) { if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
try { try {
var ast = Parser(Tokenizer(InputStream(workerScripts[i].code))); var ast = acorn.parse(workerScripts[i].code);
//console.log(ast); //console.log(ast);
} catch (e) { } catch (e) {
console.log("Error parsing script: " + workerScripts[i].name); console.log("Error parsing script: " + workerScripts[i].name);

@ -33,6 +33,18 @@ function scriptEditorInit() {
}; };
document.addEventListener("DOMContentLoaded", scriptEditorInit, false); document.addEventListener("DOMContentLoaded", scriptEditorInit, false);
//Updates line number and RAM usage in script
function upgradeScriptEditorContent() {
var txt = $("#script-editor-text")[0];
var lineNum = txt.value.substr(0, txt.selectionStart).split("\n").length;
var code = document.getElementById("script-editor-text").value;
var codeCopy = code.repeat(1);
var ramUsage = calculateRamUsage(codeCopy);
document.getElementById("script-editor-status-text").innerText =
"Line Number: " + lineNum + ", RAM: " + formatNumber(ramUsage, 2).toString() + "GB";
}
//Define key commands in script editor (ctrl o to save + close, etc.) //Define key commands in script editor (ctrl o to save + close, etc.)
$(document).keydown(function(e) { $(document).keydown(function(e) {
if (Engine.currentPage == Engine.Page.ScriptEditor) { if (Engine.currentPage == Engine.Page.ScriptEditor) {
@ -126,10 +138,17 @@ Script.prototype.saveScript = function() {
//Updates how much RAM the script uses when it is running. //Updates how much RAM the script uses when it is running.
Script.prototype.updateRamUsage = function() { Script.prototype.updateRamUsage = function() {
var baseRam = 1.4;
var codeCopy = this.code.repeat(1); var codeCopy = this.code.repeat(1);
this.ramUsage = calculateRamUsage(codeCopy);
console.log("ram usage: " + this.ramUsage);
if (isNaN(this.ramUsage)) {
dialogBoxCreate("ERROR in calculating ram usage. This is a bug, please report to game develoepr");
}
}
function calculateRamUsage(codeCopy) {
codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace
var baseRam = 1.4;
var whileCount = numOccurrences(codeCopy, "while("); var whileCount = numOccurrences(codeCopy, "while(");
var forCount = numOccurrences(codeCopy, "for("); var forCount = numOccurrences(codeCopy, "for(");
var ifCount = numOccurrences(codeCopy, "if("); var ifCount = numOccurrences(codeCopy, "if(");
@ -150,6 +169,7 @@ Script.prototype.updateRamUsage = function() {
var getHostnameCount = numOccurrences(codeCopy, "getHostname("); var getHostnameCount = numOccurrences(codeCopy, "getHostname(");
var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel("); var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel(");
var getServerMoneyAvailableCount = numOccurrences(codeCopy, "getServerMoneyAvailable("); var getServerMoneyAvailableCount = numOccurrences(codeCopy, "getServerMoneyAvailable(");
var getServerMaxMoneyCount = numOccurrences(codeCopy, "getServerMaxMoney(");
var getServerSecurityCount = numOccurrences(codeCopy, "getServerSecurityLevel("); var getServerSecurityCount = numOccurrences(codeCopy, "getServerSecurityLevel(");
var getServerBaseSecurityCount = numOccurrences(codeCopy, "getServerBaseSecurityLevel("); var getServerBaseSecurityCount = numOccurrences(codeCopy, "getServerBaseSecurityLevel(");
var getServerReqdHackingCount = numOccurrences(codeCopy, "getServerRequiredHackingLevel("); var getServerReqdHackingCount = numOccurrences(codeCopy, "getServerRequiredHackingLevel(");
@ -161,43 +181,50 @@ Script.prototype.updateRamUsage = function() {
var hnUpgLevelCount = numOccurrences(codeCopy, ".upgradeLevel("); var hnUpgLevelCount = numOccurrences(codeCopy, ".upgradeLevel(");
var hnUpgRamCount = numOccurrences(codeCopy, ".upgradeRam()"); var hnUpgRamCount = numOccurrences(codeCopy, ".upgradeRam()");
var hnUpgCoreCount = numOccurrences(codeCopy, ".upgradeCore()"); var hnUpgCoreCount = numOccurrences(codeCopy, ".upgradeCore()");
var scriptGetStockCount = numOccurrences(codeCopy, "getStockPrice(") +
numOccurrences(codeCopy, "getStockPosition(");
var scriptBuySellStockCount = numOccurrences(codeCopy, "buyStock(") +
numOccurrences(codeCopy, "sellStock(");
var scriptPurchaseServerCount = numOccurrences(codeCopy, "purchaseServer(");
var scriptRoundCount = numOccurrences(codeCopy, "round(");
this.ramUsage = baseRam + return baseRam +
((whileCount * CONSTANTS.ScriptWhileRamCost) + ((whileCount * CONSTANTS.ScriptWhileRamCost) +
(forCount * CONSTANTS.ScriptForRamCost) + (forCount * CONSTANTS.ScriptForRamCost) +
(ifCount * CONSTANTS.ScriptIfRamCost) + (ifCount * CONSTANTS.ScriptIfRamCost) +
(hackCount * CONSTANTS.ScriptHackRamCost) + (hackCount * CONSTANTS.ScriptHackRamCost) +
(growCount * CONSTANTS.ScriptGrowRamCost) + (growCount * CONSTANTS.ScriptGrowRamCost) +
(weakenCount * CONSTANTS.ScriptWeakenRamCost) + (weakenCount * CONSTANTS.ScriptWeakenRamCost) +
(scanCount * CONSTANTS.ScriptScanRamCost) + (scanCount * CONSTANTS.ScriptScanRamCost) +
(nukeCount * CONSTANTS.ScriptNukeRamCost) + (nukeCount * CONSTANTS.ScriptNukeRamCost) +
(brutesshCount * CONSTANTS.ScriptBrutesshRamCost) + (brutesshCount * CONSTANTS.ScriptBrutesshRamCost) +
(ftpcrackCount * CONSTANTS.ScriptFtpcrackRamCost) + (ftpcrackCount * CONSTANTS.ScriptFtpcrackRamCost) +
(relaysmtpCount * CONSTANTS.ScriptRelaysmtpRamCost) + (relaysmtpCount * CONSTANTS.ScriptRelaysmtpRamCost) +
(httpwormCount * CONSTANTS.ScriptHttpwormRamCost) + (httpwormCount * CONSTANTS.ScriptHttpwormRamCost) +
(sqlinjectCount * CONSTANTS.ScriptSqlinjectRamCost) + (sqlinjectCount * CONSTANTS.ScriptSqlinjectRamCost) +
(runCount * CONSTANTS.ScriptRunRamCost) + (runCount * CONSTANTS.ScriptRunRamCost) +
(execCount * CONSTANTS.ScriptExecRamCost) + (execCount * CONSTANTS.ScriptExecRamCost) +
(scpCount * CONSTANTS.ScriptScpRamCost) + (scpCount * CONSTANTS.ScriptScpRamCost) +
(hasRootAccessCount * CONSTANTS.ScriptHasRootAccessRamCost) + (hasRootAccessCount * CONSTANTS.ScriptHasRootAccessRamCost) +
(getHostnameCount * CONSTANTS.ScriptGetHostnameRamCost) + (getHostnameCount * CONSTANTS.ScriptGetHostnameRamCost) +
(getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) + (getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) +
(getServerMoneyAvailableCount * CONSTANTS.ScriptGetServerMoneyRamCost) + (getServerMoneyAvailableCount * CONSTANTS.ScriptGetServerMoneyRamCost) +
(getServerSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) + (getServerMaxMoneyCount * CONSTANTS.ScriptGetServerMoneyRamCost) +
(getServerBaseSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) + (getServerSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) +
(getServerReqdHackingCount * CONSTANTS.ScriptGetServerReqdHackRamCost) + (getServerBaseSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) +
(fileExistsCount * CONSTANTS.ScriptFileExistsRamCost) + (getServerReqdHackingCount * CONSTANTS.ScriptGetServerReqdHackRamCost) +
(isRunningCount * CONSTANTS.ScriptIsRunningRamCost) + (fileExistsCount * CONSTANTS.ScriptFileExistsRamCost) +
(numOperators * CONSTANTS.ScriptOperatorRamCost) + (isRunningCount * CONSTANTS.ScriptIsRunningRamCost) +
(purchaseHacknetCount * CONSTANTS.ScriptPurchaseHacknetRamCost) + (numOperators * CONSTANTS.ScriptOperatorRamCost) +
(hacknetnodesArrayCount * CONSTANTS.ScriptHacknetNodesRamCost) + (purchaseHacknetCount * CONSTANTS.ScriptPurchaseHacknetRamCost) +
(hnUpgLevelCount * CONSTANTS.ScriptHNUpgLevelRamCost) + (hacknetnodesArrayCount * CONSTANTS.ScriptHacknetNodesRamCost) +
(hnUpgRamCount * CONSTANTS.ScriptHNUpgRamRamCost) + (hnUpgLevelCount * CONSTANTS.ScriptHNUpgLevelRamCost) +
(hnUpgCoreCount * CONSTANTS.ScriptHNUpgCoreRamCost)); (hnUpgRamCount * CONSTANTS.ScriptHNUpgRamRamCost) +
console.log("ram usage: " + this.ramUsage); (hnUpgCoreCount * CONSTANTS.ScriptHNUpgCoreRamCost) +
if (isNaN(this.ramUsage)) { (scriptGetStockCount * CONSTANTS.ScriptGetStockRamCost) +
dialogBoxCreate("ERROR in calculating ram usage. This is a bug, please report to game develoepr"); (scriptBuySellStockCount * CONSTANTS.ScriptBuySellStockRamCost) +
} (scriptPurchaseServerCount * CONSTANTS.ScriptPurchaseServerRamCost) +
(scriptRoundCount * CONSTANTS.ScriptRoundRamCost));
} }
Script.prototype.toJSON = function() { Script.prototype.toJSON = function() {

@ -225,10 +225,20 @@ function initSymbolToStockMap() {
} }
} }
function stockMarketCycle() {
console.log("Cycling the Stock Market");
for (var name in StockMarket) {
if (StockMarket.hasOwnProperty(name)) {
var stock = StockMarket[name];
stock.b = !stock.b;
}
}
}
//Returns true if successful, false otherwise //Returns true if successful, false otherwise
function buyStock(stock, shares) { function buyStock(stock, shares) {
if (shares == 0) {return false;} if (shares == 0) {return false;}
if (stock == null || shares < 0) { if (stock == null || shares < 0 || isNaN(shares)) {
dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer"); dialogBoxCreate("Failed to buy stock. This may be a bug, contact developer");
return false; return false;
} }
@ -257,7 +267,7 @@ function buyStock(stock, shares) {
//Returns true if successful and false otherwise //Returns true if successful and false otherwise
function sellStock(stock, shares) { function sellStock(stock, shares) {
if (shares == 0) {return false;} if (shares == 0) {return false;}
if (stock == null || shares < 0) { if (stock == null || shares < 0 || isNaN(shares)) {
dialogBoxCreate("Failed to sell stock. This may be a bug, contact developer"); dialogBoxCreate("Failed to sell stock. This may be a bug, contact developer");
return false; return false;
} }
@ -328,8 +338,9 @@ function displayStockMarketContent() {
if (Player.hasWseAccount == null) {Player.hasWseAccount = false;} if (Player.hasWseAccount == null) {Player.hasWseAccount = false;}
if (Player.hasTixApiAccess == null) {Player.hasTixApiAccess = false;} if (Player.hasTixApiAccess == null) {Player.hasTixApiAccess = false;}
//Purchase WSE Account button
var wseAccountButton = clearEventListeners("stock-market-buy-account"); var wseAccountButton = clearEventListeners("stock-market-buy-account");
wseAccountButton.innerText = "Buy WSE Account - $" + formatNumber(CONSTANTS.WSEAccountCost, 2).toString() wseAccountButton.innerText = "Buy WSE Account - $" + formatNumber(CONSTANTS.WSEAccountCost, 2).toString();
if (!Player.hasWseAccount && Player.money >= CONSTANTS.WSEAccountCost) { if (!Player.hasWseAccount && Player.money >= CONSTANTS.WSEAccountCost) {
wseAccountButton.setAttribute("class", "a-link-button"); wseAccountButton.setAttribute("class", "a-link-button");
} else { } else {
@ -343,6 +354,22 @@ function displayStockMarketContent() {
return false; return false;
}); });
//Purchase TIX API Access account
var tixApiAccessButton = clearEventListeners("stock-market-buy-tix-api");
tixApiAccessButton.innerText = "Buy Trade Information eXchange (TIX) API Access - $" +
formatNumber(CONSTANTS.TIXAPICost, 2).toString();
if (!Player.hasTixApiAccess && Player.money >= CONSTANTS.TIXAPICost) {
tixApiAccessButton.setAttribute("class", "a-link-button");
} else {
tixApiAccessButton.setAttribute("class", "a-link-button-inactive");
}
tixApiAccessButton.addEventListener("click", function() {
Player.hasTixApiAccess = true;
Player.loseMoney(CONSTANTS.TIXAPICost);
displayStockMarketContent();
return false;
});
var stockList = document.getElementById("stock-market-list"); var stockList = document.getElementById("stock-market-list");
if (stockList == null) {return;} if (stockList == null) {return;}

@ -116,6 +116,7 @@ var Engine = {
document.getElementById("script-editor-text").value = code; document.getElementById("script-editor-text").value = code;
} }
document.getElementById("script-editor-text").focus(); document.getElementById("script-editor-text").focus();
upgradeScriptEditorContent();
Engine.currentPage = Engine.Page.ScriptEditor; Engine.currentPage = Engine.Page.ScriptEditor;
}, },
@ -568,7 +569,9 @@ var Engine = {
checkFactionInvitations: 100, //Check whether you qualify for any faction invitations every 5 minutes checkFactionInvitations: 100, //Check whether you qualify for any faction invitations every 5 minutes
passiveFactionGrowth: 600, passiveFactionGrowth: 600,
messages: 300, messages: 300,
stockTick: 50, //Update stock prices stockTick: 30, //Update stock prices
sCr: 1500,
updateScriptEditorDisplay: 5,
}, },
decrementAllCounters: function(numCycles = 1) { decrementAllCounters: function(numCycles = 1) {
@ -648,7 +651,32 @@ var Engine = {
if (Player.hasWseAccount) { if (Player.hasWseAccount) {
updateStockPrices(); updateStockPrices();
} }
Engine.Counters.stockTick = 50; Engine.Counters.stockTick = 30;
}
if (Engine.Counters.sCr <= 0) {
//Assume 4Sig will always indicate state of market
if (Player.hasWseAccount) {
console.log("Determining stock market cycle");
var thresh = 0.66;
var stock = StockMarket[Locations.Sector12FourSigma];
if (stock == null) {
console.log("ERR: Could not find 4Sigma stock");
return;
}
if (stock.b) {thresh = 0.34;}
if (Math.random() < thresh) {
stockMarketCycle();
}
}
Engine.Counters.sCr = 1500;
}
if (Engine.Counters.updateScriptEditorDisplay <= 0) {
if (Engine.currentPage == Engine.Page.ScriptEditor) {
upgradeScriptEditorContent();
}
Engine.Counters.updateScriptEditorDisplay = 5;
} }
}, },

@ -50,4 +50,10 @@ function compareArrays(a1, a2) {
function printArray(a) { function printArray(a) {
return "[" + a.join(", ") + "]"; return "[" + a.join(", ") + "]";
}
//Returns bool indicating whether or not its a power of 2
function powerOfTwo(n) {
if (isNaN(n)) {return false;}
return n && (n & (n-1)) === 0;
} }

@ -3,10 +3,10 @@
//Generate a random IP address //Generate a random IP address
//Will not return an IP address that already exists in the AllServers array //Will not return an IP address that already exists in the AllServers array
createRandomIp = function() { createRandomIp = function() {
var ip = createRandomByte() +'.' + var ip = createRandomByte(99) +'.' +
createRandomByte() +'.' + createRandomByte(9) +'.' +
createRandomByte() +'.' + createRandomByte(9) +'.' +
createRandomByte(); createRandomByte(9);
//If the Ip already exists, recurse to create a new one //If the Ip already exists, recurse to create a new one
if (ipExists(ip)) { if (ipExists(ip)) {
@ -27,8 +27,8 @@ ipExists = function(ip) {
return false; return false;
} }
createRandomByte = function() { createRandomByte = function(n=9) {
return Math.round(Math.random()*256); return Math.round(Math.random()*n);
} }
isValidIPAddress = function(ipaddress) { isValidIPAddress = function(ipaddress) {

3631
utils/acorn.js Normal file

File diff suppressed because it is too large Load Diff