mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-19 06:03:50 +01:00
Merge pull request #87 from danielyxie/netscript-refactor
Netscript refactor
This commit is contained in:
commit
8951593ede
@ -15,7 +15,6 @@
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
|
||||
/* Script Editor */
|
||||
/* This temp element is used for auto adjusting filename field */
|
||||
.tmp-element {
|
||||
@ -23,13 +22,11 @@
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
|
||||
#script-editor-container {
|
||||
position: fixed;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
#script-editor-buttons-wrapper {
|
||||
width: 100%;
|
||||
padding-right: 0xp;
|
||||
@ -37,10 +34,15 @@
|
||||
}
|
||||
|
||||
#script-editor-save-and-close-button,
|
||||
#script-editor-netscript-doc-button {
|
||||
#script-editor-netscript-doc-button,
|
||||
#script-editor-status-text {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
#script-editor-status-text {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#script-editor-save-and-close-button {
|
||||
float:left;
|
||||
}
|
||||
|
@ -94,6 +94,10 @@ tr:focus {
|
||||
}
|
||||
|
||||
/* Make html links ("a" elements) nice looking buttons with this class */
|
||||
a:link, a:visited {
|
||||
color:white;
|
||||
}
|
||||
|
||||
.a-link-button {
|
||||
text-decoration: none;
|
||||
background-color: #555;
|
||||
|
@ -30,12 +30,10 @@
|
||||
|
||||
<!-- Netscript -->
|
||||
<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/NetscriptEnvironment.js"></script>
|
||||
<script src="src/NetscriptFunctions.js"></script>
|
||||
<script src="utils/acorn.js"></script>
|
||||
|
||||
<!-- Main game files -->
|
||||
<script src="src/Constants.js"></script>
|
||||
@ -150,6 +148,7 @@
|
||||
<textarea id="script-editor-text" tabindex="2" autofocus> </textarea>
|
||||
<div id="script-editor-buttons-wrapper">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@ -746,7 +745,7 @@
|
||||
you 'reset' by installing Augmentations.
|
||||
</p>
|
||||
<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>
|
||||
<p id="stock-market-commission"> </p>
|
||||
|
||||
|
@ -162,7 +162,7 @@ initAugmentations = function() {
|
||||
//Combat stat augmentations
|
||||
var HemoRecirculator = new Augmentation(AugmentationNames.HemoRecirculator);
|
||||
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.addToFactions(["Tetrads", "The Dark Army", "The Syndicate"]);
|
||||
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 " +
|
||||
"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>" +
|
||||
"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",
|
||||
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.Targeting1)) {
|
||||
@ -187,7 +187,7 @@ initAugmentations = function() {
|
||||
Targeting2.setRequirements(3500, 8500000);
|
||||
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 " +
|
||||
"by an additional 25%.");
|
||||
"by an additional 20%.");
|
||||
Targeting2.addToFactions(["The Dark Army", "The Syndicate", "Sector-12", "Volhaven", "Ishima",
|
||||
"OmniTek Incorporated", "KuaiGong International", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.Targeting2)) {
|
||||
@ -199,7 +199,7 @@ initAugmentations = function() {
|
||||
Targeting3.setRequirements(11000, 23000000);
|
||||
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 " +
|
||||
"by an additional 40%.");
|
||||
"by an additional 30%.");
|
||||
Targeting3.addToFactions(["The Dark Army", "The Syndicate", "OmniTek Incorporated",
|
||||
"KuaiGong International", "Blade Industries", "The Covenant"]);
|
||||
if (augmentationExists(AugmentationNames.Targeting3)) {
|
||||
@ -233,7 +233,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(SynfibrilMuscle)
|
||||
|
||||
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 " +
|
||||
"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%.");
|
||||
@ -245,7 +245,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(CombatRib1);
|
||||
|
||||
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 " +
|
||||
"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",
|
||||
@ -256,7 +256,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(CombatRib2);
|
||||
|
||||
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 " +
|
||||
"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",
|
||||
@ -267,7 +267,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(CombatRib3);
|
||||
|
||||
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. " +
|
||||
"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%.");
|
||||
@ -309,7 +309,7 @@ initAugmentations = function() {
|
||||
GrapheneBoneLacings.setRequirements(450000, 850000000);
|
||||
GrapheneBoneLacings.setInfo("A graphene-based material is grafted and fused into the user's bones, significantly increasing " +
|
||||
"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"]);
|
||||
if (augmentationExists(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 " +
|
||||
"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>" +
|
||||
"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",
|
||||
"OmniTek Incorporated", "Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.BionicSpine)) {
|
||||
@ -334,7 +334,7 @@ initAugmentations = function() {
|
||||
GrapheneBionicSpine.setRequirements(650000, 1200000000);
|
||||
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>" +
|
||||
"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"]);
|
||||
if (augmentationExists(AugmentationNames.GrapheneBionicSpine)) {
|
||||
delete Augmentations[AugmentationNames.GrapheneBionicSpine];
|
||||
@ -390,7 +390,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(TITN41Injection);
|
||||
|
||||
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 " +
|
||||
"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" +
|
||||
@ -751,7 +751,7 @@ initAugmentations = function() {
|
||||
FocusWire.setInfo("A cranial implant that stops procrastination by blocking specific neural pathways " +
|
||||
"in the brain.<br><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 reputation the player gains when working for a company by 10%");
|
||||
FocusWire.addToFactions(["Bachman & Associates", "Clarke Incorporated", "Four Sigma", "KuaiGong International"]);
|
||||
@ -775,7 +775,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(PCDNI);
|
||||
|
||||
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 " +
|
||||
"improves the performance of the interface and gives the user more control options " +
|
||||
"to the connected computer.<br><br>" +
|
||||
@ -789,7 +789,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(PCDNIOptimizer);
|
||||
|
||||
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 " +
|
||||
"PC Direct-Neural Interface augmentation. When connected to a computer, " +
|
||||
"The NeuroNet Injector upgrade allows the user to use his/her own brain's " +
|
||||
@ -922,7 +922,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(Neurotrainer1);
|
||||
|
||||
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 " +
|
||||
"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>" +
|
||||
@ -934,7 +934,7 @@ initAugmentations = function() {
|
||||
AddToAugmentations(Neurotrainer2);
|
||||
|
||||
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 " +
|
||||
"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>" +
|
||||
@ -983,7 +983,7 @@ initAugmentations = function() {
|
||||
"Increases the player's agility by 10% <br>" +
|
||||
"Increases the player's defense by 10% <br>" +
|
||||
"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"]);
|
||||
if (augmentationExists(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 experience gain rate by 15%<br>" +
|
||||
"Increases the amount of money the player gains from crimes by 25%");
|
||||
SmartSonar.setRequirements(9000, 12000000);
|
||||
SmartSonar.setRequirements(9000, 15000000);
|
||||
SmartSonar.addToFactions(["Slum Snakes"]);
|
||||
if (augmentationExists(AugmentationNames.SmartSonar)) {
|
||||
delete Augmentations[AugmentationNames.SmartSonar];
|
||||
@ -1011,7 +1011,7 @@ initAugmentations = function() {
|
||||
"This augmentation: <br>" +
|
||||
"Increases all of the player's stats by 5%<br>" +
|
||||
"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"]);
|
||||
if (augmentationExists(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 chance of successfully performing a hack by 30%<br>" +
|
||||
"Increases the amount of money the player gains from hacking by 100%");
|
||||
QLink.setRequirements(750000, 1200000000);
|
||||
QLink.setRequirements(750000, 1300000000);
|
||||
QLink.addToFactions(["Illuminati"]);
|
||||
if (augmentationExists(AugmentationNames.QLink)) {
|
||||
delete Augmentations[AugmentationNames.QLink];
|
||||
@ -1058,7 +1058,7 @@ initAugmentations = function() {
|
||||
"This augmentation: <br>" +
|
||||
"Increases all of the player's combat stats by 75%<br>" +
|
||||
"Increases the player's hacking skill by 15%");
|
||||
SPTN97.setRequirements(500000, 950000000);
|
||||
SPTN97.setRequirements(500000, 975000000);
|
||||
SPTN97.addToFactions(["The Covenant"]);
|
||||
if (augmentationExists(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 " +
|
||||
"exactly the implant does, but they promise that it will greatly " +
|
||||
"enhance your abilities.");
|
||||
HiveMind.setRequirements(600000, 1000000000);
|
||||
HiveMind.setRequirements(600000, 1100000000);
|
||||
HiveMind.addToFactions(["ECorp"]);
|
||||
if (augmentationExists(AugmentationNames.HiveMind)) {
|
||||
delete Augmentations[AugmentationNames.HiveMind];
|
||||
@ -1086,7 +1086,7 @@ initAugmentations = function() {
|
||||
"This augmentation:<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%");
|
||||
CordiARCReactor.setRequirements(450000, 975000000);
|
||||
CordiARCReactor.setRequirements(450000, 1000000000);
|
||||
CordiARCReactor.addToFactions(["MegaCorp"]);
|
||||
if (augmentationExists(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 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%");
|
||||
SmartJaw.setRequirements(150000, 500000000);
|
||||
SmartJaw.setRequirements(150000, 550000000);
|
||||
SmartJaw.addToFactions(["Bachman & Associates"]);
|
||||
if (augmentationExists(AugmentationNames.SmartJaw)) {
|
||||
delete Augmentations[AugmentationNames.SmartJaw];
|
||||
@ -1117,7 +1117,7 @@ initAugmentations = function() {
|
||||
"body's skin and bone cells, granting them the ability to repair " +
|
||||
"and restructure themselves. <br><br>" +
|
||||
"This augmentation increases the player's strength and defense by 55%");
|
||||
Neotra.setRequirements(225000, 550000000);
|
||||
Neotra.setRequirements(225000, 575000000);
|
||||
Neotra.addToFactions(["Blade Industries"]);
|
||||
if (augmentationExists(AugmentationNames.Neotra)) {
|
||||
delete Augmentations[AugmentationNames.Neotra];
|
||||
@ -1132,7 +1132,7 @@ initAugmentations = function() {
|
||||
"This augmentation: <br>" +
|
||||
"Increases all of the player's stats by 20%<br>" +
|
||||
"Increases the player's experience gain rate for all stats by 15%");
|
||||
Xanipher.setRequirements(350000, 800000000);
|
||||
Xanipher.setRequirements(350000, 850000000);
|
||||
Xanipher.addToFactions(["NWO"]);
|
||||
if (augmentationExists(AugmentationNames.Xanipher)) {
|
||||
delete Augmentations[AugmentationNames.Xanipher];
|
||||
@ -1145,7 +1145,7 @@ initAugmentations = function() {
|
||||
"of negligible senescence, preventing the body from " +
|
||||
"deteriorating with age. <br><br>" +
|
||||
"This augmentation increases all of the player's stats by 20%");
|
||||
nextSENS.setRequirements(175000, 375000000);
|
||||
nextSENS.setRequirements(175000, 385000000);
|
||||
nextSENS.addToFactions(["Clarke Incorporated"]);
|
||||
if (augmentationExists(AugmentationNames.nextSENS)) {
|
||||
delete Augmentations[AugmentationNames.nextSENS];
|
||||
@ -1160,7 +1160,7 @@ initAugmentations = function() {
|
||||
"This augmentation:<br>" +
|
||||
"Increases the player's hacking skill by 20%<br>" +
|
||||
"Increases the player's hacking experience gain rate by 25%");
|
||||
OmniTekInfoLoad.setRequirements(250000, 550000000)
|
||||
OmniTekInfoLoad.setRequirements(250000, 575000000)
|
||||
OmniTekInfoLoad.addToFactions(["OmniTek Incorporated"]);
|
||||
if (augmentationExists(AugmentationNames.OmniTekInfoLoad)) {
|
||||
delete Augmentations[AugmentationNames.OmniTekInfoLoad];
|
||||
@ -1177,7 +1177,7 @@ initAugmentations = function() {
|
||||
"skin cells, allowing users to generate their own energy " +
|
||||
"and nutrition using solar power. <br><br>" +
|
||||
"This augmentation increases the player's strength, defense, and agility by 40%");
|
||||
PhotosyntheticCells.setRequirements(225000, 525000000);
|
||||
PhotosyntheticCells.setRequirements(225000, 550000000);
|
||||
PhotosyntheticCells.addToFactions(["KuaiGong International"]);
|
||||
if (augmentationExists(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 hacking speed by 5%<br>" +
|
||||
"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"]);
|
||||
if (augmentationExists(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 speed by 2%<br>" +
|
||||
"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"]);
|
||||
if (augmentationExists(AugmentationNames.TheBlackHand)) {
|
||||
delete Augmentations[AugmentationNames.TheBlackHand];
|
||||
@ -1396,13 +1396,13 @@ applyAugmentation = function(aug, reapply=false) {
|
||||
switch(aug.name) {
|
||||
//Combat stat augmentations
|
||||
case AugmentationNames.Targeting1:
|
||||
Player.dexterity_mult *= 1.15;
|
||||
Player.dexterity_mult *= 1.10;
|
||||
break;
|
||||
case AugmentationNames.Targeting2:
|
||||
Player.dexterity_mult *= 1.25;
|
||||
Player.dexterity_mult *= 1.20;
|
||||
break;
|
||||
case AugmentationNames.Targeting3:
|
||||
Player.dexterity_mult *= 1.40;
|
||||
Player.dexterity_mult *= 1.30;
|
||||
break;
|
||||
case AugmentationNames.SyntheticHeart: //High level
|
||||
Player.agility_mult *= 1.5;
|
||||
@ -1436,20 +1436,20 @@ applyAugmentation = function(aug, reapply=false) {
|
||||
Player.dexterity_mult *= 1.05;
|
||||
break;
|
||||
case AugmentationNames.GrapheneBoneLacings: //High level
|
||||
Player.strength_mult *= 1.75;
|
||||
Player.defense_mult *= 1.75;
|
||||
Player.strength_mult *= 1.7;
|
||||
Player.defense_mult *= 1.7;
|
||||
break;
|
||||
case AugmentationNames.BionicSpine: //Med level
|
||||
Player.strength_mult *= 1.18;
|
||||
Player.defense_mult *= 1.18;
|
||||
Player.agility_mult *= 1.18;
|
||||
Player.dexterity_mult *= 1.18;
|
||||
Player.strength_mult *= 1.16;
|
||||
Player.defense_mult *= 1.16;
|
||||
Player.agility_mult *= 1.16;
|
||||
Player.dexterity_mult *= 1.16;
|
||||
break;
|
||||
case AugmentationNames.GrapheneBionicSpine: //High level
|
||||
Player.strength_mult *= 1.65;
|
||||
Player.defense_mult *= 1.65;
|
||||
Player.agility_mult *= 1.65;
|
||||
Player.dexterity_mult *= 1.65;
|
||||
Player.strength_mult *= 1.6;
|
||||
Player.defense_mult *= 1.6;
|
||||
Player.agility_mult *= 1.6;
|
||||
Player.dexterity_mult *= 1.6;
|
||||
break;
|
||||
case AugmentationNames.BionicLegs: //Med level
|
||||
Player.agility_mult *= 1.6;
|
||||
@ -1579,12 +1579,12 @@ applyAugmentation = function(aug, reapply=false) {
|
||||
Player.charisma_mult *= 1.1;
|
||||
break;
|
||||
case AugmentationNames.FocusWire: //Med level
|
||||
Player.hacking_exp_mult *= 1.1;
|
||||
Player.strength_exp_mult *= 1.1;
|
||||
Player.defense_exp_mult *= 1.1;
|
||||
Player.dexterity_exp_mult *= 1.1;
|
||||
Player.agility_exp_mult *= 1.1;
|
||||
Player.charisma_exp_mult *= 1.1;
|
||||
Player.hacking_exp_mult *= 1.05;
|
||||
Player.strength_exp_mult *= 1.05;
|
||||
Player.defense_exp_mult *= 1.05;
|
||||
Player.dexterity_exp_mult *= 1.05;
|
||||
Player.agility_exp_mult *= 1.05;
|
||||
Player.charisma_exp_mult *= 1.05;
|
||||
Player.company_rep_mult *= 1.1;
|
||||
Player.work_money_mult *= 1.2;
|
||||
break;
|
||||
@ -1710,10 +1710,10 @@ applyAugmentation = function(aug, reapply=false) {
|
||||
Player.crime_money_mult *= 1.25;
|
||||
break;
|
||||
case AugmentationNames.HemoRecirculator:
|
||||
Player.strength_mult *= 1.1;
|
||||
Player.defense_mult *= 1.1;
|
||||
Player.agility_mult *= 1.1;
|
||||
Player.dexterity_mult *= 1.1;
|
||||
Player.strength_mult *= 1.08;
|
||||
Player.defense_mult *= 1.08;
|
||||
Player.agility_mult *= 1.08;
|
||||
Player.dexterity_mult *= 1.08;
|
||||
break;
|
||||
case AugmentationNames.SmartSonar:
|
||||
Player.dexterity_mult *= 1.1;
|
||||
|
217
src/Constants.js
217
src/Constants.js
@ -1,5 +1,5 @@
|
||||
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
|
||||
//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 */
|
||||
BaseCostFor1GBOfRamHome: 32000,
|
||||
BaseCostFor1GBOfRamServer: 55000, //1 GB of RAM
|
||||
BaseCostFor1GBOfRamServer: 60000, //1 GB of RAM
|
||||
BaseCostFor1GBOfRamHacknetNode: 30000,
|
||||
|
||||
BaseCostForHacknetNode: 1000,
|
||||
@ -19,9 +19,9 @@ CONSTANTS = {
|
||||
|
||||
/* Hacknet Node constants */
|
||||
HacknetNodeMoneyGainPerLevel: 1.55,
|
||||
HacknetNodePurchaseNextMult: 1.75, //Multiplier when purchasing an additional hacknet node
|
||||
HacknetNodeUpgradeLevelMult: 1.045, //Multiplier for cost when upgrading level
|
||||
HacknetNodeUpgradeRamMult: 1.28, //Multiplier for cost when upgrading RAM
|
||||
HacknetNodePurchaseNextMult: 1.85, //Multiplier when purchasing an additional hacknet node
|
||||
HacknetNodeUpgradeLevelMult: 1.05, //Multiplier for cost when upgrading level
|
||||
HacknetNodeUpgradeRamMult: 1.29, //Multiplier for cost when upgrading RAM
|
||||
HacknetNodeUpgradeCoreMult: 1.49, //Multiplier for cost when buying another core
|
||||
|
||||
HacknetNodeMaxLevel: 200,
|
||||
@ -34,7 +34,7 @@ CONSTANTS = {
|
||||
|
||||
/* Augmentation */
|
||||
//NeuroFlux Governor cost multiplier as you level up
|
||||
NeuroFluxGovernorLevelMult: 1.13,
|
||||
NeuroFluxGovernorLevelMult: 1.14,
|
||||
|
||||
/* Script related things */
|
||||
//Time (ms) it takes to run one operation in Netscript.
|
||||
@ -71,6 +71,10 @@ CONSTANTS = {
|
||||
ScriptHNUpgLevelRamCost: 0.4,
|
||||
ScriptHNUpgRamRamCost: 0.6,
|
||||
ScriptHNUpgCoreRamCost: 0.8,
|
||||
ScriptGetStockRamCost: 2.0,
|
||||
ScriptBuySellStockRamCost: 2.5,
|
||||
ScriptPurchaseServerRamCost: 2.0,
|
||||
ScriptRoundRamCost: 0.05,
|
||||
|
||||
MultithreadingRAMCost: 1,
|
||||
|
||||
@ -96,8 +100,8 @@ CONSTANTS = {
|
||||
InfiltrationMoneyValue: 2000, //Convert "secret" value to money
|
||||
|
||||
//Stock market constants
|
||||
WSEAccountCost: 50000000,
|
||||
TIXAPICost: 1000000000,
|
||||
WSEAccountCost: 200000000,
|
||||
TIXAPICost: 5000000000,
|
||||
StockMarketCommission: 100000,
|
||||
|
||||
//Hospital/Health
|
||||
@ -327,6 +331,10 @@ CONSTANTS = {
|
||||
"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 " +
|
||||
"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>" +
|
||||
"The following data types are supported by Netscript: <br>" +
|
||||
"numeric - Integers and floats (eg. 6, 10.4999)<br>" +
|
||||
@ -354,41 +362,7 @@ CONSTANTS = {
|
||||
" ==<br>" +
|
||||
" !=<br><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 " +
|
||||
"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>" +
|
||||
"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>"+
|
||||
"<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 [] " +
|
||||
"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 " +
|
||||
"there is no required hacking level to run the command. Returns " +
|
||||
"0.1. Works offline at a slower rate<br> Example: weaken('foodnstuff');<br><br>" +
|
||||
"<i>print(x)</i> <br>Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br>" +
|
||||
"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>print(x)</i> <br>Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br><br>" +
|
||||
"<i>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>" +
|
||||
"<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 " +
|
||||
"at the end of the Hacknet Node's name (e.g The Hacknet Node named 'hacknet-node-4' will have an index of 4). If the player cannot afford to purchase " +
|
||||
"a new Hacknet Node then the function will return false. Does NOT work offline<br><br>" +
|
||||
"<i>purchaseServer(hostname, ram)</i><br> Purchases a server with the specified hostname and amount of RAM. The first argument can be any data type, " +
|
||||
"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>" +
|
||||
"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 " +
|
||||
@ -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>" +
|
||||
"while(hacknetnodes.length < 4) {<br>" +
|
||||
" purchaseHacknetNode();<br>" +
|
||||
"};<br>" +
|
||||
"for (i = 0; i < 4; i = i+1) {<br>" +
|
||||
"}<br>" +
|
||||
"for (i = 0; i < 4; i = i++) {<br>" +
|
||||
" while (hacknetnodes[i].level <= 75) {<br>" +
|
||||
" hacknetnodes[i].upgradeLevel(5);<br>" +
|
||||
" sleep(10000);<br>" +
|
||||
" };<br>" +
|
||||
"};<br>" +
|
||||
"for (i = 0; i < 4; i = i+1) {<br>" +
|
||||
" }<br>" +
|
||||
"}<br>" +
|
||||
"for (i = 0; i < 4; i = i++) {<br>" +
|
||||
" while (hacknetnodes[i].ram < 8) {<br>" +
|
||||
" hacknetnodes[i].upgradeRam();<br>" +
|
||||
" sleep(10000);<br>" +
|
||||
" };<br>" +
|
||||
"};<br>" +
|
||||
"for (i = 0; i < 4; i = i+1) {<br>" +
|
||||
" }<br>" +
|
||||
"}<br>" +
|
||||
"for (i = 0; i < 4; i = i++) {<br>" +
|
||||
" while (hacknetnodes[i].cores < 2) {<br>" +
|
||||
" hacknetnodes[i].upgradeCore();<br>" +
|
||||
" sleep(10000);<br>" +
|
||||
" };<br>" +
|
||||
"};<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>" +
|
||||
"A while loop is a control flow statement that repeatedly executes code as long as a condition is met. <br><br> " +
|
||||
"<i>while (<i>[cond]</i>) {<br> <i>[code]</i><br>}</i><br><br>" +
|
||||
"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> hack('foodnstuff');<br> i = i + 1;<br> }; </i><br><br>" +
|
||||
"<i>i = 0; <br> while (i < 10) { <br> hack('foodnstuff');<br> i = i + 1;<br> } </i><br><br>" +
|
||||
"This code above repeats the 'hack('foodnstuff')' command 10 times before it stops and exits. <br><br>" +
|
||||
"<i>while(true) { <br> hack('foodnstuff'); <br> }; </i><br><br> " +
|
||||
"<i>while(true) { <br> 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. " +
|
||||
"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>" +
|
||||
"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> <i>code</i> <br> }; </i><br><br>" +
|
||||
"<i>for (<i>[init]</i>; <i>[cond]</i>; <i>[post]</i>) {<br> <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 " +
|
||||
"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 " +
|
||||
" using a for loop: <br><br>" +
|
||||
"<i>for (i = 0; i < 10; i = i+1) { <br> hack('foodnstuff');<br>}; </i><br><br>" +
|
||||
"<i>for (i = 0; i < 10; i = i++) { <br> hack('foodnstuff');<br>} </i><br><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>" +
|
||||
"<i>if (condition1) {<br> code1<br>} elif (condition2) {<br> code2<br>} else {<br>" +
|
||||
"If/Else if/Else statements are conditional statements used to perform different actions based on different conditions: <br><br>" +
|
||||
"<i>if (condition1) {<br> code1<br>} else if (condition2) {<br> code2<br>} else {<br>" +
|
||||
" 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 " +
|
||||
"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 " +
|
||||
"<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 " +
|
||||
"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/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. " +
|
||||
"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>" +
|
||||
"if(getServerMoneyAvailable('foodnstuff') > 200000) {<br> hack('foodnstuff');<br>" +
|
||||
"} else {<br> grow('foodnstuff');<br>};<br><br>" +
|
||||
"} else {<br> grow('foodnstuff');<br>}<br><br>" +
|
||||
"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, " +
|
||||
"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>",
|
||||
|
||||
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>" +
|
||||
"-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>" +
|
||||
@ -925,36 +951,31 @@ CONSTANTS = {
|
||||
"-You can now see what an Augmentation does and its price even while its locked<br><br>",
|
||||
|
||||
LatestUpdate:
|
||||
"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 " +
|
||||
"then will start being more expensive than before. High RAM upgrades should now be significantly more expensive than before.<br>" +
|
||||
"-Slightly lowered the starting money available on most mid-game and end-game servers (servers with required hacking level " +
|
||||
"greater than 200) by about 10-15%<br>" +
|
||||
"-Rebalanced company/company position reputation gains and requirements<br>" +
|
||||
"-Studying at a university now gives slightly more EXP and early jobs give slightly less EXP<br>" +
|
||||
"-Studying at a university is now considerably more expensive<br>" +
|
||||
"-Rebalanced stock market<br>" +
|
||||
"-Significantly increased cost multiplier for purchasing additional Hacknet Nodes<br>" +
|
||||
"-The rate at which facility security level increases during infiltration for each clearance level " +
|
||||
"was lowered slightly for all companies<br>" +
|
||||
"-Updated Faction descriptions<br>" +
|
||||
"-Changed the way alias works. Normal aliases now only work at the start of a Terminal command (they will only " +
|
||||
"replace the first word in the Terminal command). You can also create global aliases that work on any part of the " +
|
||||
'command, like before. Declare global aliases by entering the optional -g flag: alias -g name="value" - Courtesy of Github user MrNuggelz<br>' +
|
||||
"-'top' Terminal command implemented courtesy of Github user LTCNugget. Currently, the formatting gets screwed up " +
|
||||
"if your script names are really long.<br><br>" +
|
||||
"v0.24.0<br>" +
|
||||
"-Players now have HP, which is displayed in the top right. To regain HP, visit the hospital. Currently " +
|
||||
"the only way to lose HP is through infiltration<br>" +
|
||||
"-Infiltration - Attempt to infiltrate a company and steal their classified secrets. See 'Companies' documentation for more details<br>" +
|
||||
"-Stock Market - Added the World Stock Exchange (WSE), a brokerage that lets you buy/sell stocks. To begin trading you must first purchase " +
|
||||
"an account. A WSE account will persist even after resetting by installing Augmentations. How the stock market works should hopefully be " +
|
||||
"self explanatory. There is no documentation about it currently, I will add some later. NOTE: Stock prices only change when the game is open. " +
|
||||
"The Stock Market is reset when installing Augmentations, which means you will lose all your stocks<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>",
|
||||
"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>",
|
||||
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ document.addEventListener("DOMContentLoaded", hacknetNodesInit, false);
|
||||
function HacknetNode(name) {
|
||||
this.level = 1;
|
||||
this.ram = 1; //GB
|
||||
this.numCores = 1;
|
||||
this.cores = 1;
|
||||
|
||||
this.name = name;
|
||||
|
||||
@ -50,7 +50,7 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
|
||||
|
||||
this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
|
||||
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)) {
|
||||
this.moneyGainRatePerSecond = 0;
|
||||
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer");
|
||||
@ -85,6 +85,11 @@ HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeLevel = function(levels=1) {
|
||||
return this.purchaseLevelUpgrade(levels);
|
||||
}
|
||||
|
||||
HacknetNode.prototype.calculateRamUpgradeCost = function() {
|
||||
var numUpgrades = Math.log2(this.ram);
|
||||
|
||||
@ -106,23 +111,33 @@ HacknetNode.prototype.purchaseRamUpgrade = function() {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeRam = function() {
|
||||
return this.purchaseRamUpgrade();
|
||||
}
|
||||
|
||||
HacknetNode.prototype.calculateCoreUpgradeCost = function() {
|
||||
var coreBaseCost = CONSTANTS.BaseCostForHacknetNodeCore;
|
||||
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() {
|
||||
var cost = this.calculateCoreUpgradeCost();
|
||||
if (isNaN(cost)) {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);
|
||||
++this.numCores;
|
||||
++this.cores;
|
||||
this.updateMoneyGainRate();
|
||||
return true;
|
||||
}
|
||||
|
||||
//Wrapper function for Netscript
|
||||
HacknetNode.prototype.upgradeCore = function() {
|
||||
return this.purchaseCoreUpgrade();
|
||||
}
|
||||
|
||||
/* Saving and loading HackNets */
|
||||
HacknetNode.prototype.toJSON = function() {
|
||||
return Generic_toJSON("HacknetNode", this);
|
||||
@ -150,8 +165,8 @@ purchaseHacknet = function() {
|
||||
var cost = getCostOfNextHacknetNode();
|
||||
if (isNaN(cost)) {throw new Error("Cost is NaN"); return;}
|
||||
if (cost > Player.money) {
|
||||
dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
|
||||
return;
|
||||
//dialogBoxCreate("You cannot afford to purchase a Hacknet Node!");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Auto generate a name for the node for now...TODO
|
||||
@ -165,6 +180,7 @@ purchaseHacknet = function() {
|
||||
|
||||
displayHacknetNodesContent();
|
||||
updateTotalHacknetProduction();
|
||||
return numOwned;
|
||||
}
|
||||
|
||||
//Calculates the total production from all HacknetNodes
|
||||
@ -361,7 +377,7 @@ updateHacknetNodeDomElement = function(nodeObj) {
|
||||
" ($" + formatNumber(nodeObj.moneyGainRatePerSecond, 2) + " / second) <br>" +
|
||||
"Level: " + nodeObj.level + "<br>" +
|
||||
"RAM: " + nodeObj.ram + "GB<br>" +
|
||||
"Cores: " + nodeObj.numCores;
|
||||
"Cores: " + nodeObj.cores;
|
||||
|
||||
//Upgrade level
|
||||
var upgradeLevelButton = document.getElementById("hacknet-node-upgrade-level-" + nodeName);
|
||||
@ -408,7 +424,7 @@ updateHacknetNodeDomElement = function(nodeObj) {
|
||||
//Upgrade Cores
|
||||
var upgradeCoreButton = document.getElementById("hacknet-node-upgrade-core-" + nodeName);
|
||||
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.setAttribute("class", "a-link-button-inactive");
|
||||
} else {
|
||||
|
@ -369,7 +369,7 @@ displayLocationContent = function() {
|
||||
purchaseTor.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumECorp,
|
||||
6000, 100, 150, 13);
|
||||
6000, 106, 150, 13);
|
||||
break;
|
||||
|
||||
case Locations.AevumBachmanAndAssociates:
|
||||
@ -382,7 +382,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumBachmanAndAssociates,
|
||||
1500, 36, 60, 9.5);
|
||||
1500, 38, 60, 9.5);
|
||||
break;
|
||||
|
||||
case Locations.AevumClarkeIncorporated:
|
||||
@ -395,7 +395,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumClarkeIncorporated,
|
||||
2400, 28, 75, 9);
|
||||
2400, 30, 75, 9);
|
||||
break;
|
||||
|
||||
case Locations.AevumFulcrumTechnologies:
|
||||
@ -414,7 +414,7 @@ displayLocationContent = function() {
|
||||
purchaseTor.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumFulcrumTechnologies,
|
||||
6000, 84, 100, 15);
|
||||
6000, 88, 100, 15);
|
||||
break;
|
||||
|
||||
case Locations.AevumAeroCorp:
|
||||
@ -426,7 +426,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumAeroCorp,
|
||||
2000, 26, 50, 10);
|
||||
2000, 28, 50, 10);
|
||||
break;
|
||||
|
||||
case Locations.AevumGalacticCybersystems:
|
||||
@ -439,7 +439,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
businessJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumGalacticCybersystems,
|
||||
1400, 24, 50, 9);
|
||||
1400, 26, 50, 9);
|
||||
break;
|
||||
|
||||
case Locations.AevumWatchdogSecurity:
|
||||
@ -453,7 +453,7 @@ displayLocationContent = function() {
|
||||
securityJob.style.display = "block";
|
||||
agentJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumWatchdogSecurity,
|
||||
850, 12, 30, 7.5);
|
||||
850, 14, 30, 7.5);
|
||||
break;
|
||||
|
||||
case Locations.AevumRhoConstruction:
|
||||
@ -462,7 +462,7 @@ displayLocationContent = function() {
|
||||
softwareJob.style.display = "block";
|
||||
businessJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumRhoConstruction,
|
||||
600, 8, 20, 4);
|
||||
600, 10, 20, 4);
|
||||
break;
|
||||
|
||||
case Locations.AevumPolice:
|
||||
@ -471,7 +471,7 @@ displayLocationContent = function() {
|
||||
softwareJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumPolice,
|
||||
700, 10, 25, 5);
|
||||
700, 12, 25, 5);
|
||||
break;
|
||||
|
||||
case Locations.AevumNetLinkTechnologies:
|
||||
@ -489,7 +489,7 @@ displayLocationContent = function() {
|
||||
purchaseTor.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.AevumNetLinkTechnologies,
|
||||
150, 5, 15, 3);
|
||||
160, 8, 15, 3);
|
||||
break;
|
||||
|
||||
case Locations.AevumCrushFitnessGym:
|
||||
@ -523,7 +523,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.ChongqingKuaiGongInternational,
|
||||
5500, 42, 100, 14);
|
||||
5500, 44, 100, 14);
|
||||
break;
|
||||
|
||||
case Locations.ChongqingSolarisSpaceSystems:
|
||||
@ -564,7 +564,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12MegaCorp,
|
||||
6000, 100, 125, 15);
|
||||
6000, 104, 125, 15);
|
||||
break;
|
||||
|
||||
case Locations.Sector12BladeIndustries:
|
||||
@ -577,7 +577,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12BladeIndustries,
|
||||
3000, 40, 100, 10);
|
||||
3000, 42, 100, 10);
|
||||
break;
|
||||
|
||||
case Locations.Sector12FourSigma:
|
||||
@ -590,7 +590,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12FourSigma,
|
||||
1500, 50, 100, 14.5);
|
||||
1500, 52, 100, 14.5);
|
||||
break;
|
||||
|
||||
case Locations.Sector12IcarusMicrosystems:
|
||||
@ -603,7 +603,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
businessJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12IcarusMicrosystems,
|
||||
900, 28, 70, 11);
|
||||
900, 30, 70, 11);
|
||||
break;
|
||||
|
||||
case Locations.Sector12UniversalEnergy:
|
||||
@ -616,7 +616,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
businessJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12UniversalEnergy,
|
||||
775, 20, 50, 9.5);
|
||||
775, 22, 50, 9.5);
|
||||
break;
|
||||
|
||||
case Locations.Sector12DeltaOne:
|
||||
@ -628,7 +628,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12DeltaOne,
|
||||
1200, 30, 75, 10);
|
||||
1200, 34, 75, 10);
|
||||
break;
|
||||
|
||||
case Locations.Sector12CIA:
|
||||
@ -641,7 +641,7 @@ displayLocationContent = function() {
|
||||
securityJob.style.display = "block";
|
||||
agentJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12CIA,
|
||||
1450, 38, 80, 12);
|
||||
1450, 40, 80, 12);
|
||||
break;
|
||||
|
||||
case Locations.Sector12NSA:
|
||||
@ -654,7 +654,7 @@ displayLocationContent = function() {
|
||||
securityJob.style.display = "block";
|
||||
agentJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12NSA,
|
||||
1400, 34, 80, 11);
|
||||
1400, 36, 80, 11);
|
||||
break;
|
||||
|
||||
case Locations.Sector12AlphaEnterprises:
|
||||
@ -668,7 +668,7 @@ displayLocationContent = function() {
|
||||
purchaseTor.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12AlphaEnterprises,
|
||||
250, 10, 40, 4.5);
|
||||
250, 12, 40, 4.5);
|
||||
break;
|
||||
|
||||
case Locations.Sector12CarmichaelSecurity:
|
||||
@ -682,7 +682,7 @@ displayLocationContent = function() {
|
||||
securityJob.style.display = "block";
|
||||
agentJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12CarmichaelSecurity,
|
||||
500, 14, 60, 4.5);
|
||||
500, 16, 60, 4.5);
|
||||
break;
|
||||
|
||||
case Locations.Sector12FoodNStuff:
|
||||
@ -698,7 +698,7 @@ displayLocationContent = function() {
|
||||
employeeJob.style.display = "block";
|
||||
employeePartTimeJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.Sector12JoesGuns,
|
||||
100, 4, 20, 3.5);
|
||||
120, 6, 20, 3.5);
|
||||
break;
|
||||
|
||||
case Locations.Sector12IronGym:
|
||||
@ -731,7 +731,7 @@ displayLocationContent = function() {
|
||||
securityEngineerJob.style.display = "block";
|
||||
networkEngineerJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.NewTokyoDefComm,
|
||||
1300, 24, 70, 9);
|
||||
1300, 26, 70, 9);
|
||||
break;
|
||||
|
||||
case Locations.NewTokyoVitaLife:
|
||||
@ -744,7 +744,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
businessJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.NewTokyoVitaLife,
|
||||
750, 18, 100, 8);
|
||||
750, 20, 100, 8);
|
||||
break;
|
||||
|
||||
case Locations.NewTokyoGlobalPharmaceuticals:
|
||||
@ -758,7 +758,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.NewTokyoGlobalPharmaceuticals,
|
||||
900, 20, 80, 8.5);
|
||||
900, 22, 80, 8.5);
|
||||
break;
|
||||
|
||||
case Locations.NewTokyoNoodleBar:
|
||||
@ -797,7 +797,7 @@ displayLocationContent = function() {
|
||||
purchase256gb.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.IshimaStormTechnologies,
|
||||
700, 20, 100, 10);
|
||||
700, 22, 100, 10);
|
||||
break;
|
||||
|
||||
case Locations.IshimaNovaMedical:
|
||||
@ -810,7 +810,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
businessJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.IshimaNovaMedical,
|
||||
600, 16, 50, 7.5);
|
||||
600, 18, 50, 7.5);
|
||||
break;
|
||||
|
||||
case Locations.IshimaOmegaSoftware:
|
||||
@ -828,7 +828,7 @@ displayLocationContent = function() {
|
||||
purchaseTor.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.IshimaOmegaSoftware,
|
||||
200, 5, 40, 4);
|
||||
200, 8, 40, 4);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenTravelAgency:
|
||||
@ -861,7 +861,7 @@ displayLocationContent = function() {
|
||||
purchase512gb.style.display = "block";
|
||||
purchase1tb.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenOmniTekIncorporated,
|
||||
1500, 38, 100, 9.5);
|
||||
1500, 40, 100, 9.5);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenNWO:
|
||||
@ -874,7 +874,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenNWO,
|
||||
1800, 48, 200, 11);
|
||||
1800, 50, 200, 11);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenHeliosLabs:
|
||||
@ -886,7 +886,7 @@ displayLocationContent = function() {
|
||||
securityEngineerJob.style.display = "block";
|
||||
networkEngineerJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenHeliosLabs,
|
||||
1200, 24, 75, 9);
|
||||
1200, 26, 75, 9);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenOmniaCybersystems:
|
||||
@ -898,7 +898,7 @@ displayLocationContent = function() {
|
||||
networkEngineerJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenOmniaCybersystems,
|
||||
900, 24, 90, 9.5);
|
||||
900, 26, 90, 9.5);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenLexoCorp:
|
||||
@ -912,7 +912,7 @@ displayLocationContent = function() {
|
||||
businessJob.style.display = "block";
|
||||
securityJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenLexoCorp,
|
||||
500, 10, 40, 5.5);
|
||||
500, 12, 40, 5.5);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenSysCoreSecurities:
|
||||
@ -923,7 +923,7 @@ displayLocationContent = function() {
|
||||
securityEngineerJob.style.display = "block";
|
||||
networkEngineerJob.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenSysCoreSecurities,
|
||||
600, 12, 50, 6);
|
||||
600, 14, 50, 6);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenCompuTek:
|
||||
@ -944,7 +944,7 @@ displayLocationContent = function() {
|
||||
purchaseTor.style.display = "block";
|
||||
purchaseHomeRam.style.display = "block";
|
||||
setInfiltrateButton(infiltrate, Locations.VolhavenCompuTek,
|
||||
300, 8, 35, 5);
|
||||
300, 10, 35, 5);
|
||||
break;
|
||||
|
||||
case Locations.VolhavenMilleniumFitnessGym:
|
||||
|
@ -1,8 +1,12 @@
|
||||
/* Environment
|
||||
* NetScript program environment
|
||||
*/
|
||||
function Environment(parent) {
|
||||
this.vars = Object.create(parent ? parent.vars : null);
|
||||
function Environment(workerScript,parent) {
|
||||
if (parent){
|
||||
this.vars = parent.vars;
|
||||
} else {
|
||||
this.vars = NetscriptFunctions(workerScript);
|
||||
}
|
||||
this.parent = parent;
|
||||
this.stopFlag = false;
|
||||
}
|
||||
@ -45,6 +49,19 @@ Environment.prototype = {
|
||||
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
|
||||
def: function(name, value) {
|
||||
return this.vars[name] = value;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,162 +1,32 @@
|
||||
/* Netscript Functions
|
||||
* Implementation for Netscript features */
|
||||
function netscriptArray(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
var arr = env.get(exp.value);
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (exp.index == null || exp.index == undefined) {
|
||||
if ((exp.op.type == "call" && exp.op.func.value == "length") ||
|
||||
(exp.op.type == "var" && exp.op.value == "length")) {
|
||||
return resolve(arr.length);
|
||||
} else if ((exp.op.type == "call" && exp.op.func.value == "clear") ||
|
||||
(exp.op.type == "var" && exp.op.value == "clear")) {
|
||||
arr.length = 0;
|
||||
return resolve(true);
|
||||
} else if (exp.op.type == "call" && exp.op.func.value == "push") {
|
||||
if (exp.op.args.length == 1) {
|
||||
var entry = Object.assign({}, exp.op.args[0]);
|
||||
arr.push(entry);
|
||||
return resolve(true);
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array.push() command. Takes 1 argument"));
|
||||
function NetscriptFunctions(workerScript) {
|
||||
return {
|
||||
hacknetnodes : Player.hacknetNodes,
|
||||
scan : function(ip=workerScript.serverIp){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, 'Invalid IP or hostname passed into scan() command');
|
||||
}
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid operation on an array"));
|
||||
var out = [];
|
||||
for (var i = 0; i < server.serversOnNetwork.length; i++) {
|
||||
var entry = server.getServerOnNetwork(i).hostname;
|
||||
if (entry == null) {
|
||||
continue;
|
||||
}
|
||||
out.push(entry);
|
||||
}
|
||||
|
||||
//The array is being indexed
|
||||
var indexPromise = evaluate(exp.index.value, workerScript);
|
||||
indexPromise.then(function(i) {
|
||||
if (isNaN(i)) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
|
||||
} else if (i >= arr.length || i < 0) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
||||
} else {
|
||||
if (exp.op && exp.op.type == "call") {
|
||||
switch(exp.op.func.value) {
|
||||
case "insert":
|
||||
if (exp.op.args.length == 1) {
|
||||
var entry = Object.assign({}, exp.op.args[0]);
|
||||
arr.splice(i, 0, entry);
|
||||
return resolve(arr.length);
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array insert() call. Takes 1 argument"));
|
||||
workerScript.scriptRef.log('scan() returned ' + server.serversOnNetwork.length + ' connections for ' + server.hostname);
|
||||
return out;
|
||||
},
|
||||
hack : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Hack() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
break;
|
||||
case "remove":
|
||||
if (exp.op.args.length == 0) {
|
||||
return resolve(arr.splice(i, 1));
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid number of arguments passed into array remove() call. Takes 1 argument"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid call on array element: " + exp.op.func.value));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//Return the indexed element
|
||||
var resPromise = evaluate(arr[i], workerScript);
|
||||
resPromise.then(function(res) {
|
||||
resolve(res);
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function netscriptAssign(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
return new Promise(function(resolve, reject) {
|
||||
if (env.stopFlag) {return reject(workerScript);}
|
||||
|
||||
if (exp.left.type != "var") {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Cannot assign to " + JSON.stringify(exp.left)));
|
||||
}
|
||||
|
||||
//Assigning an element in an array
|
||||
if (exp.left.index) {
|
||||
try {
|
||||
var res = env.get(exp.left.value);
|
||||
if (res.constructor === Array || res instanceof Array) {
|
||||
var i = 0;
|
||||
var iPromise = evaluate(exp.left.index.value, workerScript);
|
||||
iPromise.then(function(idx) {
|
||||
if (isNaN(idx)) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
|
||||
} else if (idx >= res.length || idx < 0) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Out of bounds: Invalid index in [] operator"));
|
||||
} else {
|
||||
//Clone res to be exp.right
|
||||
i = idx;
|
||||
res[i] = Object.assign({}, exp.right);
|
||||
return evaluate(exp.right, workerScript);
|
||||
}
|
||||
}).then(function(finalRes) {
|
||||
resolve(finalRes);
|
||||
}).catch(function(e) {
|
||||
return reject(e);
|
||||
});
|
||||
} else {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Trying to access a non-array variable using the [] operator"));
|
||||
}
|
||||
} catch(e) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, e.toString()));
|
||||
}
|
||||
} else {
|
||||
var expRightPromise = evaluate(exp.right, workerScript);
|
||||
expRightPromise.then(function(expRight) {
|
||||
try {
|
||||
env.set(exp.left.value, expRight);
|
||||
} catch (e) {
|
||||
return reject(makeRuntimeRejectMsg(workerScript, "Failed to set environment variable: " + e.toString()));
|
||||
}
|
||||
resolve(false); //Return false so this doesnt cause conditionals to evaluate
|
||||
}, function(e) {
|
||||
reject(e);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function netscriptBinary(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
|
||||
var opPromises = [evaluate(exp.left, workerScript), evaluate(exp.right, workerScript)];
|
||||
return Promise.all(opPromises).then(function (ops) {
|
||||
try {
|
||||
var result = apply_op(exp.operator, ops[0], ops[1]);
|
||||
return Promise.resolve(result);
|
||||
} catch(e) {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
});
|
||||
}
|
||||
|
||||
function netscriptHack(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var threads = workerScript.scriptRef.threads;
|
||||
if (isNaN(threads) || threads < 1) {threads = 1;}
|
||||
|
||||
if (exp.args.length != 1) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Hack() call has incorrect number of arguments. Takes 1 argument"));
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
return ipPromise.then(function(ip) {
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("hack() error. Invalid IP or hostname passed in: " + ip + ". Stopping...");
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into hack() command"));
|
||||
throw makeRuntimeRejectMsg(workerScript, "hack() error. Invalid IP or hostname passed in: " + ip + ". Stopping...");
|
||||
}
|
||||
|
||||
//Calculate the hacking time
|
||||
@ -165,20 +35,18 @@ function netscriptHack(exp, workerScript) {
|
||||
//No root access or skill level too low
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user does not have root access");
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because it did not have root access to " + server.hostname));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot hack this server (" + server.hostname + ") because user does not have root access");
|
||||
}
|
||||
|
||||
if (server.requiredHackingSkill > Player.hacking_skill) {
|
||||
workerScript.scriptRef.log("Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough");
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because player's hacking skill is not high enough to hack " + server.hostname));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot hack this server (" + server.hostname + ") because user's hacking skill is not high enough");
|
||||
}
|
||||
|
||||
workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds (t=" + threads + ")");
|
||||
return Promise.resolve([server, hackingTime]);
|
||||
}).then(function([server, hackingTime]) {
|
||||
//console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds (t=" + threads + ")");
|
||||
return netscriptDelay(hackingTime* 1000).then(function() {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var hackChance = scriptCalculateHackingChance(server);
|
||||
var rand = Math.random();
|
||||
var expGainedOnSuccess = scriptCalculateExpGain(server) * threads;
|
||||
@ -214,45 +82,39 @@ function netscriptHack(exp, workerScript) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
});
|
||||
}).then(function(res) {
|
||||
return Promise.resolve(res);
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
});
|
||||
},
|
||||
sleep : function(time){
|
||||
if (time === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "sleep() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
|
||||
function netscriptGrow(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
workerScript.scriptRef.log("Sleeping for " + time + " milliseconds");
|
||||
return netscriptDelay(time).then(function() {
|
||||
return Promise.resolve(true);
|
||||
});
|
||||
},
|
||||
grow : function(ip){
|
||||
var threads = workerScript.scriptRef.threads;
|
||||
if (isNaN(threads) || threads < 1) {threads = 1;}
|
||||
if (exp.args.length != 1) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "grow() call has incorrect number of arguments. Takes 1 argument"));
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "grow() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
return ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot grow(). Invalid IP or hostname passed in: " + ip);
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into grow() command"));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot grow(). Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
//No root access or skill level too low
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("Cannot grow this server (" + server.hostname + ") because user does not have root access");
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because it did not have root access to " + server.hostname));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot grow this server (" + server.hostname + ") because user does not have root access");
|
||||
}
|
||||
|
||||
var growTime = scriptCalculateGrowTime(server);
|
||||
//console.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds")
|
||||
workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds (t=" + threads + ")");
|
||||
|
||||
return Promise.resolve([server, growTime]);
|
||||
}).then(function([server, growTime]) {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
return netscriptDelay(growTime).then(function() {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
|
||||
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
|
||||
workerScript.scriptRef.recordGrow(server.ip, threads);
|
||||
@ -267,46 +129,31 @@ function netscriptGrow(exp, workerScript) {
|
||||
Player.gainHackingExp(expGain);
|
||||
return Promise.resolve(growthPercentage);
|
||||
});
|
||||
}).then(function(res) {
|
||||
return Promise.resolve(res);
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
})
|
||||
}
|
||||
|
||||
function netscriptWeaken(exp, workerScript) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
},
|
||||
weaken : function(ip){
|
||||
var threads = workerScript.scriptRef.threads;
|
||||
if (isNaN(threads) || threads < 1) {threads = 1;}
|
||||
if (exp.args.length != 1) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "weaken() call has incorrect number of arguments. Takes 1 argument"));
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "weaken() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
return ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot weaken(). Invalid IP or hostname passed in: " + ip);
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into weaken() command"));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot weaken(). Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
//No root access or skill level too low
|
||||
if (server.hasAdminRights == false) {
|
||||
workerScript.scriptRef.log("Cannot weaken this server (" + server.hostname + ") because user does not have root access");
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Script crashed because it did not have root access to " + server.hostname));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot weaken this server (" + server.hostname + ") because user does not have root access");
|
||||
}
|
||||
|
||||
var weakenTime = scriptCalculateWeakenTime(server);
|
||||
//console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds")
|
||||
workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " +
|
||||
formatNumber(weakenTime/1000, 3) + " seconds (t=" + threads + ")");
|
||||
|
||||
return Promise.resolve([server, weakenTime]);
|
||||
}).then(function([server, weakenTime]) {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
return netscriptDelay(weakenTime).then(function() {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
|
||||
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
|
||||
workerScript.scriptRef.recordWeaken(server.ip, threads);
|
||||
var expGain = scriptCalculateExpGain(server) * threads;
|
||||
@ -316,67 +163,24 @@ function netscriptWeaken(exp, workerScript) {
|
||||
Player.gainHackingExp(expGain);
|
||||
return Promise.resolve(CONSTANTS.ServerWeakenAmount * threads);
|
||||
});
|
||||
}).then(function(res) {
|
||||
return Promise.resolve(res);
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
});
|
||||
},
|
||||
print : function(args){
|
||||
if (args === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "print() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
|
||||
function netscriptRunProgram(exp, workerScript, programName) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (exp.args.length != 1) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument"));
|
||||
workerScript.scriptRef.log(args.toString());
|
||||
},
|
||||
nuke : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var ipPromise = evaluate(exp.args[0], workerScript);
|
||||
return ipPromise.then(function(ip) {
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid IP or hostname passed into " + programName + " command"));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
if (!Player.hasProgram(programName)) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Player does not have " + programName + " on home computer"));
|
||||
}
|
||||
|
||||
switch(programName) {
|
||||
case Programs.NukeProgram:
|
||||
return netscriptRunNukeProgram(exp, workerScript, server);
|
||||
break;
|
||||
case Programs.BruteSSHProgram:
|
||||
return netscriptRunBrutesshProgram(exp, workerScript, server);
|
||||
break;
|
||||
case Programs.FTPCrackProgram:
|
||||
return netscriptRunFtpcrackProgram(exp, workerScript, server);
|
||||
break;
|
||||
case Programs.RelaySMTPProgram:
|
||||
return netscriptRunRelaysmtpProgram(exp, workerScript, server);
|
||||
break;
|
||||
case Programs.HTTPWormProgram:
|
||||
return netscriptRunHttpwormProgram(exp, workerScript, server);
|
||||
break;
|
||||
case Programs.SQLInjectProgram:
|
||||
return netscriptRunSqlinjectProgram(exp, workerScript, server);
|
||||
break;
|
||||
default:
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Invalid program. This is a bug please contact game dev"));
|
||||
break;
|
||||
}
|
||||
}).then(function(res) {
|
||||
return Promise.resolve(res);
|
||||
}).catch(function(e) {
|
||||
return Promise.reject(e);
|
||||
});
|
||||
}
|
||||
|
||||
function netscriptRunNukeProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (server.openPortCount < server.numOpenPortsRequired) {
|
||||
return Promise.reject(makeRuntimeRejectMsg(workerScript, "Not enough ports opened to use NUKE.exe virus"));
|
||||
throw makeRuntimeRejectMsg(workerScript, "Not enough ports opened to use NUKE.exe virus");
|
||||
}
|
||||
if (server.hasAdminRights) {
|
||||
workerScript.scriptRef.log("Already have root access to " + server.hostname);
|
||||
@ -384,12 +188,17 @@ function netscriptRunNukeProgram(exp, workerScript, server) {
|
||||
server.hasAdminRights = true;
|
||||
workerScript.scriptRef.log("Executed NUKE.exe virus on " + server.hostname + " to gain root access");
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
},
|
||||
brutessh : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
function netscriptRunBrutesshProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (!server.sshPortOpen) {
|
||||
workerScript.scriptRef.log("Executed BruteSSH.exe virus on " + server.hostname + " to open SSH port (22)");
|
||||
server.sshPortOpen = true;
|
||||
@ -397,12 +206,17 @@ function netscriptRunBrutesshProgram(exp, workerScript, server) {
|
||||
} else {
|
||||
workerScript.scriptRef.log("SSH Port (22) already opened on " + server.hostname);
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
},
|
||||
ftpcrack : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
function netscriptRunFtpcrackProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (!server.ftpPortOpen) {
|
||||
workerScript.scriptRef.log("Executed FTPCrack.exe virus on " + server.hostname + " to open FTP port (21)");
|
||||
server.ftpPortOpen = true;
|
||||
@ -410,12 +224,17 @@ function netscriptRunFtpcrackProgram(exp, workerScript, server) {
|
||||
} else {
|
||||
workerScript.scriptRef.log("FTP Port (21) already opened on " + server.hostname);
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
},
|
||||
relaysmtp : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
function netscriptRunRelaysmtpProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (!server.smtpPortOpen) {
|
||||
workerScript.scriptRef.log("Executed relaySMTP.exe virus on " + server.hostname + " to open SMTP port (25)");
|
||||
server.smtpPortOpen = true;
|
||||
@ -423,12 +242,17 @@ function netscriptRunRelaysmtpProgram(exp, workerScript, server) {
|
||||
} else {
|
||||
workerScript.scriptRef.log("SMTP Port (25) already opened on " + server.hostname);
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
},
|
||||
httpworm : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
function netscriptRunHttpwormProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (!server.httpPortOpen) {
|
||||
workerScript.scriptRef.log("Executed HTTPWorm.exe virus on " + server.hostname + " to open HTTP port (80)");
|
||||
server.httpPortOpen = true;
|
||||
@ -436,12 +260,17 @@ function netscriptRunHttpwormProgram(exp, workerScript, server) {
|
||||
} else {
|
||||
workerScript.scriptRef.log("HTTP Port (80) already opened on " + server.hostname);
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
},
|
||||
sqlinject : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Program call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot call " + programName + ". Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
|
||||
function netscriptRunSqlinjectProgram(exp, workerScript, server) {
|
||||
var env = workerScript.env;
|
||||
if (env.stopFlag) {return Promise.reject(workerScript);}
|
||||
if (!server.sqlPortOpen) {
|
||||
workerScript.scriptRef.log("Executed SQLInject.exe virus on " + server.hostname + " to open SQL port (1433)");
|
||||
server.sqlPortOpen = true;
|
||||
@ -449,5 +278,377 @@ function netscriptRunSqlinjectProgram(exp, workerScript, server) {
|
||||
} else {
|
||||
workerScript.scriptRef.log("SQL Port (1433) already opened on " + server.hostname);
|
||||
}
|
||||
return Promise.resolve(true);
|
||||
return true;
|
||||
},
|
||||
run : function(scriptname,threads = 1){
|
||||
if (scriptname === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "run() call has incorrect number of arguments. Usage: run(scriptname, [numThreads], [arg1], [arg2]...)");
|
||||
}
|
||||
if (isNaN(threads) || threads < 1) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into run(). Must be numeric and greater than 0");
|
||||
}
|
||||
var argsForNewScript = [];
|
||||
for (var i = 2; i < arguments.length; ++i) {
|
||||
argsForNewScript.push(arguments[i]);
|
||||
}
|
||||
var scriptServer = getServer(workerScript.serverIp);
|
||||
if (scriptServer == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev");
|
||||
}
|
||||
|
||||
return runScriptFromScript(scriptServer, scriptname, argsForNewScript, workerScript, threads);
|
||||
},
|
||||
exec : function(scriptname,ip,threads = 1){
|
||||
if (scriptname === undefined || ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "exec() call has incorrect number of arguments. Usage: exec(scriptname, server, [numThreads], [arg1], [arg2]...)");
|
||||
}
|
||||
if (isNaN(threads) || threads < 1) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid argument for thread count passed into exec(). Must be numeric and greater than 0");
|
||||
}
|
||||
var argsForNewScript = [];
|
||||
for (var i = 3; i < arguments.length; ++i) {
|
||||
argsForNewScript.push(arguments[i]);
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into exec() command: " + args[1]);
|
||||
}
|
||||
return runScriptFromScript(server, scriptname, argsForNewScript, workerScript, threads);
|
||||
},
|
||||
kill : function(filename,ip){
|
||||
if (filename === undefined || ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "kill() call has incorrect number of arguments. Usage: kill(scriptname, server, [arg1], [arg2]...)");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("kill() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "kill() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
var argsForKillTarget = [];
|
||||
for (var i = 2; i < arguments.length; ++i) {
|
||||
argsForKillTarget.push(arguments[i]);
|
||||
}
|
||||
var runningScriptObj = findRunningScript(filename, argsForKillTarget, server);
|
||||
if (runningScriptObj == null) {
|
||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget));
|
||||
return false;
|
||||
}
|
||||
var res = killWorkerScript(runningScriptObj, server.ip);
|
||||
if (res) {
|
||||
workerScript.scriptRef.log("Killing " + filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget) + ". May take up to a few minutes for the scripts to die...");
|
||||
return true;
|
||||
} else {
|
||||
workerScript.scriptRef.log("kill() failed. No such script "+ filename + " on " + server.hostname + " with args: " + printArray(argsForKillTarget));
|
||||
return false;
|
||||
}
|
||||
},
|
||||
killall : function(ip){
|
||||
if (ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "killall() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("killall() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "killall() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
for (var i = server.runningScripts.length-1; i >= 0; --i) {
|
||||
killWorkerScript(server.runningScripts[i], server.ip);
|
||||
}
|
||||
workerScript.scriptRef.log("killall(): Killing all scripts on " + server.hostname + ". May take a few minutes for the scripts to die");
|
||||
return true;
|
||||
},
|
||||
scp : function(scriptname,ip){
|
||||
if (scriptname === undefined || ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments");
|
||||
}
|
||||
var destServer = getServer(ip);
|
||||
if (destServer == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into scp() command: " + ip);
|
||||
}
|
||||
|
||||
var currServ = getServer(workerScript.serverIp);
|
||||
if (currServ == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer");
|
||||
}
|
||||
|
||||
var sourceScript = null;
|
||||
for (var i = 0; i < currServ.scripts.length; ++i) {
|
||||
if (scriptname == currServ.scripts[i].filename) {
|
||||
sourceScript = currServ.scripts[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sourceScript == null) {
|
||||
workerScript.scriptRef.log(scriptname + " does not exist. scp() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Overwrite script if it already exists
|
||||
for (var i = 0; i < destServer.scripts.length; ++i) {
|
||||
if (scriptname == destServer.scripts[i].filename) {
|
||||
workerScript.scriptRef.log("WARNING: " + scriptname + " already exists on " + destServer.hostname + " and it will be overwritten.");
|
||||
workerScript.scriptRef.log(scriptname + " overwritten on " + destServer.hostname);
|
||||
var oldScript = destServer.scripts[i];
|
||||
oldScript.code = sourceScript.code;
|
||||
oldScript.ramUsage = sourceScript.ramUsage;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//Create new script if it does not already exist
|
||||
var newScript = new Script();
|
||||
newScript.filename = scriptname;
|
||||
newScript.code = sourceScript.code;
|
||||
newScript.ramUsage = sourceScript.ramUsage;
|
||||
newScript.server = destServer.ip;
|
||||
destServer.scripts.push(newScript);
|
||||
workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname);
|
||||
return true;
|
||||
},
|
||||
hasRootAccess : function(ip){
|
||||
if (ip===undefined){
|
||||
throw makeRuntimeRejectMsg(workerScript, "hasRootAccess() call has incorrect number of arguments. Takes 1 argument");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null){
|
||||
workerScript.scriptRef.log("hasRootAccess() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "hasRootAccess() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
return server.hasAdminRights;
|
||||
},
|
||||
getHostname : function(){
|
||||
var scriptServer = getServer(workerScript.serverIp);
|
||||
if (scriptServer == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev");
|
||||
}
|
||||
return scriptServer.hostname;
|
||||
},
|
||||
getHackingLevel : function(){
|
||||
Player.updateSkillLevels();
|
||||
workerScript.scriptRef.log("getHackingLevel() returned " + Player.hacking_skill);
|
||||
return Player.hacking_skill;
|
||||
},
|
||||
getServerMoneyAvailable : function(ip){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
if (server.hostname == "home") {
|
||||
//Return player's money
|
||||
workerScript.scriptRef.log("getServerMoneyAvailable('home') returned player's money: $" + formatNumber(Player.money, 2));
|
||||
return Player.money;
|
||||
}
|
||||
workerScript.scriptRef.log("getServerMoneyAvailable() returned " + formatNumber(server.moneyAvailable, 2) + " for " + server.hostname);
|
||||
return server.moneyAvailable;
|
||||
},
|
||||
getServerSecurityLevel : function(ip){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
workerScript.scriptRef.log("getServerSecurityLevel() returned " + formatNumber(server.hackDifficulty, 3) + " for " + server.hostname);
|
||||
return server.hackDifficulty;
|
||||
},
|
||||
getServerBaseSecurityLevel : function(ip){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerBaseSecurityLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
workerScript.scriptRef.log("getServerBaseSecurityLevel() returned " + formatNumber(server.baseDifficulty, 3) + " for " + server.hostname);
|
||||
return server.baseDifficulty;
|
||||
},
|
||||
getServerRequiredHackingLevel : function(ip){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
workerScript.scriptRef.log("getServerRequiredHackingLevel returned " + formatNumber(server.requiredHackingSkill, 0) + " for " + server.hostname);
|
||||
return server.requiredHackingSkill;
|
||||
},
|
||||
getServerMaxMoney : function(ip){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerRequiredHackingLevel() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
workerScript.scriptRef.log("getServerMaxMoney() returned " + formatNumber(server.moneyMax, 0) + " for " + server.hostname);
|
||||
return server.moneyMax;
|
||||
},
|
||||
getServerNumPortsRequired : function(ip){
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "getServerNumPortsRequired() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
workerScript.scriptRef.log("getServerNumPortsRequired() returned " + formatNumber(server.numOpenPortsRequired, 0) + " for " + server.hostname);
|
||||
return server.numOpenPortsRequired;
|
||||
},
|
||||
fileExists : function(filename,ip=workerScript.serverIp){
|
||||
if (filename === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "fileExists() call has incorrect number of arguments. Usage: fileExists(scriptname, [server])");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("fileExists() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "fileExists() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
for (var i = 0; i < server.scripts.length; ++i) {
|
||||
if (filename == server.scripts[i].filename) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < server.programs.length; ++i) {
|
||||
if (filename.toLowerCase() == server.programs[i].toLowerCase()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
isRunning : function(filename,ip){
|
||||
if (filename === undefined || ip === undefined) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "isRunning() call has incorrect number of arguments. Usage: isRunning(scriptname, server, [arg1], [arg2]...)");
|
||||
}
|
||||
var server = getServer(ip);
|
||||
if (server == null) {
|
||||
workerScript.scriptRef.log("isRunning() failed. Invalid IP or hostname passed in: " + ip);
|
||||
throw makeRuntimeRejectMsg(workerScript, "isRunning() failed. Invalid IP or hostname passed in: " + ip);
|
||||
}
|
||||
var argsForTargetScript = [];
|
||||
for (var i = 2; i < arguments.length; ++i) {
|
||||
argsForTargetScript.push(arguments[i]);
|
||||
}
|
||||
return (findRunningScript(filename, argsForTargetScript, server) != null);
|
||||
},
|
||||
purchaseHacknetNode : purchaseHacknet,
|
||||
getStockPrice : function(symbol) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockPrice()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
}
|
||||
return parseFloat(stock.price.toFixed(3));
|
||||
},
|
||||
getStockPosition : function(symbol) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use getStockPosition()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
}
|
||||
return [stock.playerShares, stock.playerAvgPx];
|
||||
},
|
||||
buyStock : function(symbol, shares) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use buyStock()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
}
|
||||
if (shares == 0) {return false;}
|
||||
if (stock == null || shares < 0 || isNaN(shares)) {
|
||||
workerScript.scriptRef.log("Error: Invalid 'shares' argument passed to buyStock()");
|
||||
return false;
|
||||
}
|
||||
shares = Math.round(shares);
|
||||
|
||||
var totalPrice = stock.price * shares;
|
||||
if (Player.money < totalPrice + CONSTANTS.StockMarketCommission) {
|
||||
workerScript.scriptRef.log("Not enough money to purchase " + formatNumber(shares, 0) + " shares of " +
|
||||
symbol + ". Need $" +
|
||||
formatNumber(totalPrice + CONSTANTS.StockMarketCommission, 2).toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
var origTotal = stock.playerShares * stock.playerAvgPx;
|
||||
Player.loseMoney(totalPrice + CONSTANTS.StockMarketCommission);
|
||||
var newTotal = origTotal + totalPrice;
|
||||
stock.playerShares += shares;
|
||||
stock.playerAvgPx = newTotal / stock.playerShares;
|
||||
if (Engine.currentPage == Engine.Page.StockMarket) {
|
||||
updateStockPlayerPosition(stock);
|
||||
}
|
||||
workerScript.scriptRef.log("Bought " + formatNumber(shares, 0) + " shares of " + stock.symbol + " at $" +
|
||||
formatNumber(stock.price, 2) + " per share");
|
||||
return true;
|
||||
},
|
||||
sellStock : function(symbol, shares) {
|
||||
if (!Player.hasTixApiAccess) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "You don't have TIX API Access! Cannot use sellStock()");
|
||||
}
|
||||
var stock = SymbolToStockMap[symbol];
|
||||
if (stock == null) {
|
||||
throw makeRuntimeRejectMsg(workerScript, "Invalid stock symbol passed into getStockPrice()");
|
||||
}
|
||||
if (shares == 0) {return false;}
|
||||
if (stock == null || shares < 0 || isNaN(shares)) {
|
||||
workerScript.scriptRef.log("Error: Invalid 'shares' argument passed to sellStock()");
|
||||
return false;
|
||||
}
|
||||
if (shares > stock.playerShares) {shares = stock.playerShares;}
|
||||
if (shares == 0) {return false;}
|
||||
var gains = stock.price * shares - CONSTANTS.StockMarketCommission;
|
||||
Player.gainMoney(gains);
|
||||
|
||||
//Calculate net profit and add to script stats
|
||||
var netProfit = ((stock.price - stock.playerAvgPx) * shares) - CONSTANTS.StockMarketCommission;
|
||||
if (isNaN(netProfit)) {netProfit = 0;}
|
||||
workerScript.scriptRef.onlineMoneyMade += netProfit;
|
||||
|
||||
stock.playerShares -= shares;
|
||||
if (stock.playerShares == 0) {
|
||||
stock.playerAvgPx = 0;
|
||||
}
|
||||
if (Engine.currentPage == Engine.Page.StockMarket) {
|
||||
updateStockPlayerPosition(stock);
|
||||
}
|
||||
workerScript.scriptRef.log("Sold " + formatNumber(shares, 0) + " shares of " + stock.symbol + " at $" +
|
||||
formatNumber(stock.price, 2) + " per share. Gained " +
|
||||
"$" + formatNumber(gains, 2));
|
||||
return true;
|
||||
},
|
||||
purchaseServer : function(hostname, ram) {
|
||||
var hostnameStr = String(hostname);
|
||||
hostnameStr = hostnameStr.replace(/\s\s+/g, '');
|
||||
if (hostnameStr == "") {
|
||||
workerScript.scriptRef.log("Error: Passed empty string for hostname argument of purchaseServer()");
|
||||
return "";
|
||||
}
|
||||
|
||||
ram = Math.round(ram);
|
||||
if (isNaN(ram) || !powerOfTwo(ram)) {
|
||||
workerScript.scriptRef.log("Error: Invalid ram argument passed to purchaseServer(). Must be numeric and a power of 2");
|
||||
return "";
|
||||
}
|
||||
|
||||
var cost = 2 * ram * CONSTANTS.BaseCostFor1GBOfRamServer;
|
||||
if (cost > Player.money) {
|
||||
workerScript.scriptRef.log("Error: Not enough money to purchase server. Need $" + formatNumber(cost, 2));
|
||||
return "";
|
||||
}
|
||||
var newServ = new Server();
|
||||
newServ.init(createRandomIp(), hostnameStr, "", true, false, true, true, ram);
|
||||
AddToAllServers(newServ);
|
||||
|
||||
Player.purchasedServers.push(newServ.ip);
|
||||
var homeComputer = Player.getHomeComputer();
|
||||
homeComputer.serversOnNetwork.push(newServ.ip);
|
||||
newServ.serversOnNetwork.push(homeComputer.ip);
|
||||
Player.loseMoney(cost);
|
||||
workerScript.scriptRef.log("Purchased new server with hostname " + newServ.hostname + " for $" + formatNumber(cost, 2));
|
||||
return newServ.hostname;
|
||||
},
|
||||
round : function(n) {
|
||||
if (isNaN(n)) {return 0;}
|
||||
return Math.round(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.serverIp = null;
|
||||
this.code = runningScriptObj.scriptRef.code;
|
||||
this.env = new Environment();
|
||||
this.env = new Environment(this);
|
||||
this.env.set("args", runningScriptObj.args);
|
||||
this.output = "";
|
||||
this.ramUsage = 0;
|
||||
this.scriptRef = runningScriptObj;
|
||||
@ -31,7 +32,7 @@ function runScriptsLoop() {
|
||||
//If it isn't running, start the script
|
||||
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
|
||||
try {
|
||||
var ast = Parser(Tokenizer(InputStream(workerScripts[i].code)));
|
||||
var ast = acorn.parse(workerScripts[i].code);
|
||||
//console.log(ast);
|
||||
} catch (e) {
|
||||
console.log("Error parsing script: " + workerScripts[i].name);
|
||||
|
@ -33,6 +33,18 @@ function scriptEditorInit() {
|
||||
};
|
||||
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.)
|
||||
$(document).keydown(function(e) {
|
||||
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.
|
||||
Script.prototype.updateRamUsage = function() {
|
||||
var baseRam = 1.4;
|
||||
var codeCopy = this.code.repeat(1);
|
||||
codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace
|
||||
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
|
||||
var baseRam = 1.4;
|
||||
var whileCount = numOccurrences(codeCopy, "while(");
|
||||
var forCount = numOccurrences(codeCopy, "for(");
|
||||
var ifCount = numOccurrences(codeCopy, "if(");
|
||||
@ -150,6 +169,7 @@ Script.prototype.updateRamUsage = function() {
|
||||
var getHostnameCount = numOccurrences(codeCopy, "getHostname(");
|
||||
var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel(");
|
||||
var getServerMoneyAvailableCount = numOccurrences(codeCopy, "getServerMoneyAvailable(");
|
||||
var getServerMaxMoneyCount = numOccurrences(codeCopy, "getServerMaxMoney(");
|
||||
var getServerSecurityCount = numOccurrences(codeCopy, "getServerSecurityLevel(");
|
||||
var getServerBaseSecurityCount = numOccurrences(codeCopy, "getServerBaseSecurityLevel(");
|
||||
var getServerReqdHackingCount = numOccurrences(codeCopy, "getServerRequiredHackingLevel(");
|
||||
@ -161,8 +181,14 @@ Script.prototype.updateRamUsage = function() {
|
||||
var hnUpgLevelCount = numOccurrences(codeCopy, ".upgradeLevel(");
|
||||
var hnUpgRamCount = numOccurrences(codeCopy, ".upgradeRam()");
|
||||
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) +
|
||||
(forCount * CONSTANTS.ScriptForRamCost) +
|
||||
(ifCount * CONSTANTS.ScriptIfRamCost) +
|
||||
@ -183,6 +209,7 @@ Script.prototype.updateRamUsage = function() {
|
||||
(getHostnameCount * CONSTANTS.ScriptGetHostnameRamCost) +
|
||||
(getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) +
|
||||
(getServerMoneyAvailableCount * CONSTANTS.ScriptGetServerMoneyRamCost) +
|
||||
(getServerMaxMoneyCount * CONSTANTS.ScriptGetServerMoneyRamCost) +
|
||||
(getServerSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) +
|
||||
(getServerBaseSecurityCount * CONSTANTS.ScriptGetServerSecurityRamCost) +
|
||||
(getServerReqdHackingCount * CONSTANTS.ScriptGetServerReqdHackRamCost) +
|
||||
@ -193,11 +220,11 @@ Script.prototype.updateRamUsage = function() {
|
||||
(hacknetnodesArrayCount * CONSTANTS.ScriptHacknetNodesRamCost) +
|
||||
(hnUpgLevelCount * CONSTANTS.ScriptHNUpgLevelRamCost) +
|
||||
(hnUpgRamCount * CONSTANTS.ScriptHNUpgRamRamCost) +
|
||||
(hnUpgCoreCount * CONSTANTS.ScriptHNUpgCoreRamCost));
|
||||
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");
|
||||
}
|
||||
(hnUpgCoreCount * CONSTANTS.ScriptHNUpgCoreRamCost) +
|
||||
(scriptGetStockCount * CONSTANTS.ScriptGetStockRamCost) +
|
||||
(scriptBuySellStockCount * CONSTANTS.ScriptBuySellStockRamCost) +
|
||||
(scriptPurchaseServerCount * CONSTANTS.ScriptPurchaseServerRamCost) +
|
||||
(scriptRoundCount * CONSTANTS.ScriptRoundRamCost));
|
||||
}
|
||||
|
||||
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
|
||||
function buyStock(stock, shares) {
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
@ -257,7 +267,7 @@ function buyStock(stock, shares) {
|
||||
//Returns true if successful and false otherwise
|
||||
function sellStock(stock, shares) {
|
||||
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");
|
||||
return false;
|
||||
}
|
||||
@ -328,8 +338,9 @@ function displayStockMarketContent() {
|
||||
if (Player.hasWseAccount == null) {Player.hasWseAccount = false;}
|
||||
if (Player.hasTixApiAccess == null) {Player.hasTixApiAccess = false;}
|
||||
|
||||
//Purchase WSE Account button
|
||||
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) {
|
||||
wseAccountButton.setAttribute("class", "a-link-button");
|
||||
} else {
|
||||
@ -343,6 +354,22 @@ function displayStockMarketContent() {
|
||||
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");
|
||||
if (stockList == null) {return;}
|
||||
|
||||
|
@ -116,6 +116,7 @@ var Engine = {
|
||||
document.getElementById("script-editor-text").value = code;
|
||||
}
|
||||
document.getElementById("script-editor-text").focus();
|
||||
upgradeScriptEditorContent();
|
||||
Engine.currentPage = Engine.Page.ScriptEditor;
|
||||
},
|
||||
|
||||
@ -568,7 +569,9 @@ var Engine = {
|
||||
checkFactionInvitations: 100, //Check whether you qualify for any faction invitations every 5 minutes
|
||||
passiveFactionGrowth: 600,
|
||||
messages: 300,
|
||||
stockTick: 50, //Update stock prices
|
||||
stockTick: 30, //Update stock prices
|
||||
sCr: 1500,
|
||||
updateScriptEditorDisplay: 5,
|
||||
},
|
||||
|
||||
decrementAllCounters: function(numCycles = 1) {
|
||||
@ -648,7 +651,32 @@ var Engine = {
|
||||
if (Player.hasWseAccount) {
|
||||
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;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -51,3 +51,9 @@ function compareArrays(a1, a2) {
|
||||
function printArray(a) {
|
||||
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
|
||||
//Will not return an IP address that already exists in the AllServers array
|
||||
createRandomIp = function() {
|
||||
var ip = createRandomByte() +'.' +
|
||||
createRandomByte() +'.' +
|
||||
createRandomByte() +'.' +
|
||||
createRandomByte();
|
||||
var ip = createRandomByte(99) +'.' +
|
||||
createRandomByte(9) +'.' +
|
||||
createRandomByte(9) +'.' +
|
||||
createRandomByte(9);
|
||||
|
||||
//If the Ip already exists, recurse to create a new one
|
||||
if (ipExists(ip)) {
|
||||
@ -27,8 +27,8 @@ ipExists = function(ip) {
|
||||
return false;
|
||||
}
|
||||
|
||||
createRandomByte = function() {
|
||||
return Math.round(Math.random()*256);
|
||||
createRandomByte = function(n=9) {
|
||||
return Math.round(Math.random()*n);
|
||||
}
|
||||
|
||||
isValidIPAddress = function(ipaddress) {
|
||||
|
3631
utils/acorn.js
Normal file
3631
utils/acorn.js
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user