All 0.28.0 Changes - Bitnodes 4 and 11 and webpack migration

This commit is contained in:
danielyxie 2017-08-30 12:44:29 -05:00
parent 33c10ccc64
commit 7a05d3585a
50 changed files with 47063 additions and 1738 deletions

@ -7,6 +7,7 @@
top: 0; top: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow:auto;
background-color: rbga(var(--my-background-color), 0.4); background-color: rbga(var(--my-background-color), 0.4);
} }
@ -16,7 +17,6 @@
padding: 12px; padding: 12px;
border: 5px solid var(--my-highlight-color); border: 5px solid var(--my-highlight-color);
width: 70%; width: 70%;
overflow: auto; /* Enable scroll if needed */
color: var(--my-font-color); color: var(--my-font-color);
} }

43825
dist/bundle.js vendored Normal file

File diff suppressed because one or more lines are too long

@ -839,8 +839,6 @@
</label> </label>
<input type ="range" max="200" min="25" <input type ="range" max="200" min="25"
oninput="document.getElementById('settingsNSExecTimeRangeValLabel').innerHTML = this.value + 'ms';
Settings.CodeInstructionRunTime=this.value;"
step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100"> step="1" name="settingsNSExecTimeRangeVal" id="settingsNSExecTimeRangeVal" value="100">
</input> </input>
<em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em> <em id="settingsNSExecTimeRangeValLabel" style="font-style: normal;"></em>
@ -857,8 +855,6 @@
</label> </label>
<input type="range" max="100" min="20" <input type="range" max="100" min="20"
oninput="document.getElementById('settingsNSLogRangeValLabel').innerHTML = this.value;
Settings.MaxLogCapacity=this.value;"
step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50"> step="1" name="settingsNSLogRangeVal" id="settingsNSLogRangeVal" value="50">
</input> </input>
<em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em> <em id="settingsNSLogRangeValLabel" style="font-style: normal;"></em>
@ -875,8 +871,6 @@
</label> </label>
<input type="range" max="100" min="20" <input type="range" max="100" min="20"
oninput="document.getElementById('settingsNSPortRangeValLabel').innerHTML = this.value;
Settings.MaxPortCapacity=this.value;"
step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50"> step="1" name="settingsNSPortRangeVal" id="settingsNSPortRangeVal" value="50">
</input> </input>
<em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em> <em id="settingsNSPortRangeValLabel" style="font-style: normal;"></em>
@ -891,8 +885,7 @@
and can be viewed with the 'cat' Terminal command. and can be viewed with the 'cat' Terminal command.
</span> </span>
</label> </label>
<input type="checkbox" name="settingsSuppressMessages" id="settingsSuppressMessages" <input type="checkbox" name="settingsSuppressMessages" id="settingsSuppressMessages">
onclick="Settings.SuppressMessages = this.checked;">
</fieldset> </fieldset>
<!-- Suppress faction invites --> <!-- Suppress faction invites -->
@ -903,8 +896,7 @@
on the screen. Your outstanding faction invites can be viewed in the 'Factions' page. on the screen. Your outstanding faction invites can be viewed in the 'Factions' page.
</span> </span>
</label> </label>
<input type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites" <input type="checkbox" name="settingsSuppressFactionInvites" id="settingsSuppressFactionInvites">
onclick="Settings.SuppressFactionInvites = this.checked;">
</fieldset> </fieldset>
<!-- Donate button --> <!-- Donate button -->
@ -924,7 +916,7 @@
<a id="delete-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Delete Game </a> <a id="delete-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Delete Game </a>
<a id="export-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Export Game </a> <a id="export-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Export Game </a>
<input type="file" id="import-game-file-selector" name="file"/> <input type="file" id="import-game-file-selector" name="file"/>
<a id="import-game-link" class="a-link-button" style="display:inline-block;width:46%;" onclick="saveObject.importGame();"> Import Game </a> <a id="import-game-link" class="a-link-button" style="display:inline-block;width:46%;"> Import Game </a>
<a id="debug-delete-scripts-link" class="a-link-button tooltip" style="display:block;width:46%;"> <a id="debug-delete-scripts-link" class="a-link-button tooltip" style="display:block;width:46%;">
(DEBUG) Delete Active Scripts (DEBUG) Delete Active Scripts
<span class="tooltiptext"> <span class="tooltiptext">
@ -949,64 +941,5 @@
<div class="loaderlabel">Loading Bitburner...</div> <div class="loaderlabel">Loading Bitburner...</div>
</div> </div>
</body> </body>
<!--jQuery library--> <script src="dist/bundle.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<!-- Utils -->
<script src="utils/IPAddress.js"></script>
<script src="utils/JSONReviver.js"></script>
<script src="utils/StringHelperFunctions.js"></script>
<script src="utils/HelperFunctions.js"></script>
<script src="utils/DialogBox.js"></script>
<script src="utils/FactionInvitationBox.js"></script>
<script src="utils/GameOptions.js"></script>
<script src="utils/LogBox.js"></script>
<script src="utils/InfiltrationBox.js"></script>
<script src="utils/decimal.js"></script>
<script src="utils/YesNoBox.js"></script>
<script src="utils/numeral.min.js"></script>
<!-- Netscript -->
<script src="src/NetscriptWorker.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>
<script src="src/HelpText.js"></script>
<script src="src/SpecialServerIps.js"></script>
<script src="src/Location.js"></script>
<script src="src/Script.js"></script>
<script src="src/Server.js"></script>
<script src="src/Player.js"></script>
<script src="src/Faction.js"></script>
<script src="src/FactionInfo.js"></script>
<script src="src/Company.js"></script>
<script src="src/CompanyJobApplication.js"></script>
<script src="src/Terminal.js"></script>
<script src="src/ServerPurchases.js"></script>
<script src="src/CreateProgram.js"></script>
<script src="src/Augmentations.js"></script>
<script src="src/Perk.js"></script>
<script src="src/HacknetNode.js"></script>
<script src="src/Crimes.js"></script>
<script src="src/Prestige.js"></script>
<script src="src/SaveObject.js"></script>
<script src="src/DarkWeb.js"></script>
<script src="src/InteractiveTutorial.js"></script>
<script src="src/Alias.js"></script>
<script src="src/Message.js"></script>
<script src="src/ActiveScriptsUI.js"></script>
<script src="src/Infiltration.js"></script>
<script src="src/StockMarket.js"></script>
<script src="src/RedPill.js"></script>
<script src="src/BitNode.js"></script>
<script src="src/Settings.js"></script>
<script src="src/SourceFile.js"></script>
<script src="src/Gang.js"></script>
<script src="src/Literature.js"></script>
<script src="src/engine.js"></script>
</html> </html>

@ -1,5 +1,14 @@
/* Active Scripts UI*/ import {workerScripts,
addWorkerScript,
killWorkerScript} from "./NetscriptWorker.js";
import {getServer} from "./Server.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {printArray} from "../utils/HelperFunctions.js";
import {logBoxCreate} from "../utils/LogBox.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
/* Active Scripts UI*/
function setActiveScriptsClickHandlers() { function setActiveScriptsClickHandlers() {
//Server panel click handlers //Server panel click handlers
var serverPanels = document.getElementsByClassName("active-scripts-server-header"); var serverPanels = document.getElementsByClassName("active-scripts-server-header");
@ -82,7 +91,6 @@ function createActiveScriptsServerPanel(server) {
setActiveScriptsClickHandlers() //Reset click handlers setActiveScriptsClickHandlers() //Reset click handlers
return panelDiv; return panelDiv;
//TODO Alphabetize Active Scripts list?
} }
//Deletes the info for a particular server (Dropdown header + Panel with all info) //Deletes the info for a particular server (Dropdown header + Panel with all info)
@ -253,3 +261,5 @@ function createActiveScriptsText(workerscript, item) {
//Return total online production rate //Return total online production rate
return onlineMps; return onlineMps;
} }
export {setActiveScriptsClickHandlers, addActiveScriptsItem, deleteActiveScriptsItem, updateActiveScriptsItems};

@ -1,6 +1,23 @@
/* Alias.js */ import {post} from "./Terminal.js";
Aliases = {};
GlobalAliases = {}; let Aliases = {};
let GlobalAliases = {};
function loadAliases(saveString) {
if (saveString === "") {
Aliases = {};
} else {
Aliases = JSON.parse(saveString);
}
}
function loadGlobalAliases(saveString) {
if (saveString === "") {
GlobalAliases = {};
} else {
GlobalAliases = JSON.parse(saveString);
}
}
//Print all aliases to terminal //Print all aliases to terminal
function printAliases() { function printAliases() {
@ -92,3 +109,6 @@ function substituteAliases(origCommand) {
} }
return commandArray.join(" "); return commandArray.join(" ");
} }
export {Aliases, GlobalAliases, printAliases, parseAliasDeclaration,
removeAlias, substituteAliases, loadAliases, loadGlobalAliases};

@ -1,3 +1,12 @@
import {BitNodeMultipliers} from "./BitNode.js";
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {prestigeAugmentation} from "./Prestige.js";
import {Factions, getNextNeurofluxLevel} from "./Faction.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
//Augmentations //Augmentations
function Augmentation(name) { function Augmentation(name) {
this.name = name; this.name = name;
@ -18,8 +27,8 @@ Augmentation.prototype.setInfo = function(inf) {
} }
Augmentation.prototype.setRequirements = function(rep, cost) { Augmentation.prototype.setRequirements = function(rep, cost) {
this.baseRepRequirement = rep * CONSTANTS.AugmentationRepMultiplier; this.baseRepRequirement = rep * CONSTANTS.AugmentationRepMultiplier * BitNodeMultipliers.AugmentationRepCost;
this.baseCost = cost * CONSTANTS.AugmentationCostMultiplier; this.baseCost = cost * CONSTANTS.AugmentationCostMultiplier * BitNodeMultipliers.AugmentationMoneyCost;
} }
//Takes in an array of faction names and adds this augmentation to all of those factions //Takes in an array of faction names and adds this augmentation to all of those factions
@ -57,14 +66,14 @@ Augmentation.fromJSON = function(value) {
Reviver.constructors.Augmentation = Augmentation; Reviver.constructors.Augmentation = Augmentation;
Augmentations = {} let Augmentations = {}
AddToAugmentations = function(aug) { function AddToAugmentations(aug) {
var name = aug.name; var name = aug.name;
Augmentations[name] = aug; Augmentations[name] = aug;
} }
AugmentationNames = { let AugmentationNames = {
Targeting1: "Augmented Targeting I", Targeting1: "Augmented Targeting I",
Targeting2: "Augmented Targeting II", Targeting2: "Augmented Targeting II",
Targeting3: "Augmented Targeting III", Targeting3: "Augmented Targeting III",
@ -153,7 +162,7 @@ AugmentationNames = {
SNA: "Social Negotiation Assistant (S.N.A)" SNA: "Social Negotiation Assistant (S.N.A)"
} }
initAugmentations = function() { function initAugmentations() {
for (var name in Factions) { for (var name in Factions) {
if (Factions.hasOwnProperty(name)) { if (Factions.hasOwnProperty(name)) {
Factions[name].augmentations = []; Factions[name].augmentations = [];
@ -377,7 +386,7 @@ initAugmentations = function() {
} }
AddToAugmentations(SpeechProcessor); AddToAugmentations(SpeechProcessor);
TITN41Injection = new Augmentation(AugmentationNames.TITN41Injection); let TITN41Injection = new Augmentation(AugmentationNames.TITN41Injection);
TITN41Injection.setRequirements(10000, 38000000); TITN41Injection.setRequirements(10000, 38000000);
TITN41Injection.setInfo("TITN is a series of viruses that targets and alters the sequences of human DNA in genes that " + TITN41Injection.setInfo("TITN is a series of viruses that targets and alters the sequences of human DNA in genes that " +
"control personality. The TITN-41 strain alters these genes so that the subject becomes more " + "control personality. The TITN-41 strain alters these genes so that the subject becomes more " +
@ -1403,7 +1412,7 @@ initAugmentations = function() {
} }
} }
applyAugmentation = function(aug, reapply=false) { function applyAugmentation(aug, reapply=false) {
Augmentations[aug.name].owned = true; Augmentations[aug.name].owned = true;
switch(aug.name) { switch(aug.name) {
//Combat stat augmentations //Combat stat augmentations
@ -1904,7 +1913,7 @@ function PlayerOwnedAugmentation(name) {
function installAugmentations() { function installAugmentations() {
if (Player.queuedAugmentations.length == 0) { if (Player.queuedAugmentations.length == 0) {
dialogBoxCreate("You have not purchased any Augmentations to install!"); dialogBoxCreate("You have not purchased any Augmentations to install!");
return; return false;
} }
var augmentationList = ""; var augmentationList = "";
for (var i = 0; i < Player.queuedAugmentations.length; ++i) { for (var i = 0; i < Player.queuedAugmentations.length; ++i) {
@ -1923,39 +1932,6 @@ function installAugmentations() {
prestigeAugmentation(); prestigeAugmentation();
} }
PlayerObject.prototype.reapplyAllAugmentations = function(resetMultipliers=true) {
console.log("Re-applying augmentations");
if (resetMultipliers) {
this.resetMultipliers();
}
for (i = 0; i < this.augmentations.length; ++i) {
//Compatibility with new version
if (typeof this.augmentations[i] === 'string' || this.augmentations[i] instanceof String) {
var newOwnedAug = new PlayerOwnedAugmentation(this.augmentations[i]);
if (this.augmentations[i] == AugmentationNames.NeuroFluxGovernor) {
newOwnedAug.level = Augmentations[AugmentationNames.NeuroFluxGovernor].level;
}
this.augmentations[i] = newOwnedAug;
}
var augName = this.augmentations[i].name;
var aug = Augmentations[augName];
aug.owned = true;
if (aug == null) {
console.log("WARNING: Invalid augmentation name");
continue;
}
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
for (j = 0; j < aug.level; ++j) {
applyAugmentation(this.augmentations[i], true);
}
continue;
}
applyAugmentation(this.augmentations[i], true);
}
}
function augmentationExists(name) { function augmentationExists(name) {
return Augmentations.hasOwnProperty(name); return Augmentations.hasOwnProperty(name);
} }
@ -1970,3 +1946,6 @@ function giveAllAugmentations() {
} }
Player.reapplyAllAugmentations(); Player.reapplyAllAugmentations();
} }
export {AugmentationNames, Augmentations, PlayerOwnedAugmentation, installAugmentations,
initAugmentations, applyAugmentation, augmentationExists, Augmentation};

@ -1,7 +1,16 @@
/* BitNode.js */ import {Player} from "./Player.js";
BitNodes = { function BitNode(n, name, desc="", info="") {
BitNode1: new BitNode(1, "Source Genesis", "The original BitNode", this.number = n;
this.name = name;
this.desc = desc;
this.info = info;
}
let BitNodes = {};
function initBitNodes() {
BitNodes = {};
BitNodes["BitNode1"] = new BitNode(1, "Source Genesis", "The original BitNode",
"The first BitNode created by the Enders to imprison the minds of humans. It became " + "The first BitNode created by the Enders to imprison the minds of humans. It became " +
"the prototype and testing-grounds for all of the BitNodes that followed.<br><br>" + "the prototype and testing-grounds for all of the BitNodes that followed.<br><br>" +
"This is the first BitNode that you play through. It has no special " + "This is the first BitNode that you play through. It has no special " +
@ -12,8 +21,8 @@ BitNodes = {
"new BitNode, and also increases all of the player's multipliers by:<br><br>" + "new BitNode, and also increases all of the player's multipliers by:<br><br>" +
"Level 1: 16%<br>" + "Level 1: 16%<br>" +
"Level 2: 24%<br>" + "Level 2: 24%<br>" +
"Level 3: 28%"), "Level 3: 28%");
BitNode2: new BitNode(2, "Rise of the Underworld", "From the shadows, they rose", //Gangs BitNodes["BitNode2"] = new BitNode(2, "Rise of the Underworld", "From the shadows, they rose", //Gangs
"From the shadows, they rose.<br><br>Organized crime groups quickly filled the void of power " + "From the shadows, they rose.<br><br>Organized crime groups quickly filled the void of power " +
"left behind from the collapse of Western government in the 2050's. As society and civlization broke down, " + "left behind from the collapse of Western government in the 2050's. As society and civlization broke down, " +
"people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " + "people quickly succumbed to the innate human impulse of evil and savagery. The organized crime " +
@ -31,52 +40,71 @@ BitNodes = {
"crime money, and charisma multipliers by:<br><br>" + "crime money, and charisma multipliers by:<br><br>" +
"Level 1: 20%<br>" + "Level 1: 20%<br>" +
"Level 2: 30%<br>" + "Level 2: 30%<br>" +
"Level 3: 35%"), "Level 3: 35%");
BitNode3: new BitNode(3, "The Price of Civilization", "COMING SOON"), //Corporate Warfare, Run own company BitNodes["BitNode3"] = new BitNode(3, "The Price of Civilization", "COMING SOON"); //Corporate Warfare, Run own company
BitNode4: new BitNode(4, "The Singularity", "COMING SOON"), //Everything automatable BitNodes["BitNode4"] = new BitNode(4, "The Singularity", "The Man and the Machine", "The Singularity has arrived. The human race is gone, replaced " +
BitNode5: new BitNode(5, "Artificial Intelligence", "COMING SOON"), //Big Brother "by artificially superintelligent beings that are more machine than man. <br><br>" +
BitNode6: new BitNode(6, "Hacktocracy", "COMING SOON"), //Healthy Hacknet balancing mechanic "In this BitNode, progressing is significantly harder. Experience gain rates " +
BitNode7: new BitNode(7, "Do Androids Dream?", "COMING SOON"), //Build androids for automation "for all stats are reduced. Most methods of earning money will now give significantly less.<br><br>" +
BitNode8: new BitNode(8, "Ghost of Wall Street", "COMING SOON"), //Trading only viable strategy "In this BitNode you will gain access to a new set of Netscript Functions known as Singularity Functions. " +
BitNode9: new BitNode(9, "MegaCorp", "COMING SOON"), //Single corp/server with increasing difficulty "These functions allow you to control most aspects of the game through scripts, including working for factions/companies, " +
BitNode10: new BitNode(10, "Wasteland", "COMING SOON"), //Postapocalyptic "purchasing/installing Augmentations, and creating programs.<br><br>" +
BitNode11: new BitNode(11, "The Big Crash", "COMING SOON"), //Crashing economy "Destroying this BitNode will give you Source-File 4, or if you already have this Source-File it will " +
/* Okay. Sell it all. "upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " +
"The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " + "Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " +
"of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " + "that you can use.");
"the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.<br><br>" + BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "COMING SOON"); //Int
"In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of this chaos and confusion hackers " + BitNodes["BitNode6"] = new BitNode(6, "Hacktocracy", "COMING SOON"); //Healthy Hacknet balancing mechanic
"were able to steal billions of dollars from the world's largest electronic banks, prompting an international banking crisis as " + BitNodes["BitNode7"] = new BitNode(7, "Do Androids Dream?", "COMING SOON"); //Build androids for automation
"governments were unable to bail out insolvent banks. Now, the world is slowly crumbling in the middle of the biggest economic crisis of all time.<br><br>" + BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "COMING SOON"); //Trading only viable strategy
"In this BitNode:<br><br>" + BitNodes["BitNode9"] = new BitNode(9, "MegaCorp", "COMING SOON"); //Single corp/server with increasing difficulty
"The starting and maximum amount of money available on servers is significantly decreased<br>" + BitNodes["BitNode10"] = new BitNode(10, "Wasteland", "COMING SOON"); //Postapocalyptic
"The growth rate of servers is halved<br>" + BitNodes["BitNode11"] = new BitNode(11, "The Big Crash", "Okay. Sell it all.", //Crashing economy
"Weakening a server is twice as effective<br>" + "The 2050s was defined by the massive amounts of violent civil unrest and anarchic rebellion that rose all around the world. It was this period " +
"Company wages are decreased by 25%<br>" + "of disorder that eventually lead to the governmental reformation of many global superpowers, most notably " +
"Hacknet Node production is significantly decreased<br>" + "the USA and China. But just as the world was slowly beginning to recover from these dark times, financial catastrophe hit.<br><br>" +
"Augmentations are twice as expensive<br><br>" + "In many countries, the high cost of trying to deal with the civil disorder bankrupted the governments. In all of this chaos and confusion, hackers " +
"Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will " + "were able to steal billions of dollars from the world's largest electronic banks, prompting an international banking crisis as " +
"upgrade its level up to a maximum of 3. This Source-File increases the player's company salary multiplier by:<br><br>" + "governments were unable to bail out insolvent banks. Now, the world is slowly crumbling in the middle of the biggest economic crisis of all time.<br><br>" +
"Level 1: 60%<br>" + "In this BitNode:<br><br>" +
"Level 2: 90%<br>" + "The starting and maximum amount of money available on servers is significantly decreased<br>" +
"Level 3: 105%"; "The growth rate of servers is halved<br>" +
"Weakening a server is twice as effective<br>" +
"Company wages are decreased by 50%<br>" +
"Hacknet Node production is significantly decreased<br>" +
"Augmentations are twice as expensive<br><br>" +
"Destroying this BitNode will give you Source-File 11, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File increases the player's company salary and reputation gain multipliers by:<br><br>" +
"Level 1: 60%<br>" +
"Level 2: 90%<br>" +
"Level 3: 105%");
*/ BitNodes["BitNode12"] = new BitNode(12, "Eye of the World", "COMING SOON"); //Become AI
BitNode12: new BitNode(12, "Eye of the World", "COMING SOON"), //Become AI
} }
function BitNode(n, name, desc="", info="") { let BitNodeMultipliers = {
this.number = n;
this.name = name;
this.desc = desc;
this.info = info;
}
BitNodeMultipliers = {
ServerMaxMoney: 1, ServerMaxMoney: 1,
ServerStartingMoney: 1,
ServerGrowthRate: 1,
ServerWeakenRate: 1,
ManualHackMoney: 1,
ScriptHackMoney: 1,
CompanyWorkMoney: 1,
CrimeMoney: 1, CrimeMoney: 1,
HacknetNodeMoney: 1,
CompanyWorkExpGain: 1,
ClassGymExpGain: 1,
FactionWorkExpGain: 1,
HackExpGain: 1,
CrimeExpGain: 1,
FactionWorkRepGain: 1, FactionWorkRepGain: 1,
FactionPassiveRepGain: 1, FactionPassiveRepGain: 1,
AugmentationRepCost: 1,
AugmentationMoneyCost: 1,
} }
function initBitNodeMultipliers() { function initBitNodeMultipliers() {
@ -93,13 +121,37 @@ function initBitNodeMultipliers() {
case 1: case 1:
break; break;
case 2: //Rise of the Underworld case 2: //Rise of the Underworld
BitNodeMultipliers.ServerMaxMoney = 0.2; BitNodeMultipliers.ServerMaxMoney = 0.2;
BitNodeMultipliers.CrimeMoney = 2; BitNodeMultipliers.CrimeMoney = 2;
BitNodeMultipliers.FactionWorkRepGain = 0.5; BitNodeMultipliers.FactionWorkRepGain = 0.5;
BitNodeMultipliers.FactionPassiveRepGain = 0; BitNodeMultipliers.FactionPassiveRepGain = 0;
break;
case 4: //The Singularity
BitNodeMultipliers.ServerMaxMoney = 0.15;
BitNodeMultipliers.ScriptHackMoney = 0.2;
BitNodeMultipliers.CompanyWorkMoney = 0.1;
BitNodeMultipliers.CrimeMoney = 0.2;
BitNodeMultipliers.HacknetNodeMoney = 0.05;
BitNodeMultipliers.CompanyWorkExpGain = 0.5;
BitNodeMultipliers.ClassGymExpGain = 0.5;
BitNodeMultipliers.FactionWorkExpGain = 0.5;
BitNodeMultipliers.HackExpGain = 0.4;
BitNodeMultipliers.CrimeExpGain = 0.5;
BitNodeMultipliers.FactionWorkRepGain = 0.75;
break;
case 11: //The Big Crash
BitNodeMultipliers.ServerMaxMoney = 0.1;
BitNodeMultipliers.ServerStartingMoney = 0.25;
BitNodeMultipliers.ServerGrowthRate = 0.5;
BitNodeMultipliers.ServerWeakenRate = 2;
BitNodeMultipliers.CompanyWorkMoney = 0.5;
BitNodeMultipliers.HacknetNodeMoney = 0.1;
BitNodeMultipliers.AugmentationMoneyCost = 2;
break; break;
default: default:
console.log("WARNING: Player.bitNodeN invalid"); console.log("WARNING: Player.bitNodeN invalid");
break; break;
} }
} }
export {initBitNodes, BitNode, BitNodes, BitNodeMultipliers, initBitNodeMultipliers};

@ -1,3 +1,10 @@
import {CONSTANTS} from "./Constants.js";
import {Locations} from "./Location.js";
import {Player} from "./Player.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
//Netburner Company class //Netburner Company class
// Note: Company Positions can be loaded every time with init() but Company class needs // Note: Company Positions can be loaded every time with init() but Company class needs
// to be saved/loaded from localStorage // to be saved/loaded from localStorage
@ -251,7 +258,7 @@ CompanyPosition.fromJSON = function(value) {
Reviver.constructors.CompanyPosition = CompanyPosition; Reviver.constructors.CompanyPosition = CompanyPosition;
CompanyPositions = { let CompanyPositions = {
//Constructor: CompanyPosition(name, reqHack, reqStr, reqDef, reqDex, reqAgi, reqCha, reqRep, salary) //Constructor: CompanyPosition(name, reqHack, reqStr, reqDef, reqDex, reqAgi, reqCha, reqRep, salary)
//Software //Software
@ -403,7 +410,7 @@ CompanyPositions = {
//Returns the next highest position in the company for the relevant career/field //Returns the next highest position in the company for the relevant career/field
//I.E returns what your next job would be if you qualify for a promotion //I.E returns what your next job would be if you qualify for a promotion
getNextCompanyPosition = function(currPos) { function getNextCompanyPosition(currPos) {
if (currPos == null) {return null;} if (currPos == null) {return null;}
//Software //Software
if (currPos.positionName == CompanyPositions.SoftwareIntern.positionName) { if (currPos.positionName == CompanyPositions.SoftwareIntern.positionName) {
@ -511,7 +518,7 @@ getNextCompanyPosition = function(currPos) {
/* Initialize all companies. Only called when creating new game/prestiging. Otherwise companies are /* Initialize all companies. Only called when creating new game/prestiging. Otherwise companies are
* usually loaded from localStorage */ * usually loaded from localStorage */
initCompanies = function() { function initCompanies() {
/* Companies that also have servers */ /* Companies that also have servers */
//Megacorporations //Megacorporations
var ECorp = new Company(Locations.AevumECorp, 3.0, 3.0, 249); var ECorp = new Company(Locations.AevumECorp, 3.0, 3.0, 249);
@ -1088,10 +1095,14 @@ initCompanies = function() {
} }
//Map of all companies that exist in the game, indexed by their name //Map of all companies that exist in the game, indexed by their name
Companies = {} let Companies = {}
function loadCompanies(saveString) {
Companies = JSON.parse(saveString, Reviver);
}
//Add a Company object onto the map of all Companies in the game //Add a Company object onto the map of all Companies in the game
AddToCompanies = function (company) { function AddToCompanies(company) {
var name = company.companyName; var name = company.companyName;
Companies[name] = company; Companies[name] = company;
} }
@ -1099,3 +1110,40 @@ AddToCompanies = function (company) {
function companyExists(name) { function companyExists(name) {
return Companies.hasOwnProperty(name); return Companies.hasOwnProperty(name);
} }
function getJobRequirementText(company, pos, tooltiptext=false) {
var reqText = "";
var offset = company.jobStatReqOffset;
var reqHacking = pos.requiredHacking > 0 ? pos.requiredHacking+offset : 0;
var reqStrength = pos.requiredStrength > 0 ? pos.requiredStrength+offset : 0;
var reqDefense = pos.requiredDefense > 0 ? pos.requiredDefense+offset : 0;
var reqDexterity = pos.requiredDexterity > 0 ? pos.requiredDexterity+offset : 0;
var reqAgility = pos.requiredDexterity > 0 ? pos.requiredDexterity+offset : 0;
var reqCharisma = pos.requiredCharisma > 0 ? pos.requiredCharisma+offset : 0;
var reqRep = pos.requiredReputation;
if (tooltiptext) {
reqText = "Requires:<br>";
reqText += (reqHacking.toString() + " hacking<br>");
reqText += (reqStrength.toString() + " strength<br>");
reqText += (reqDefense.toString() + " defense<br>");
reqText += (reqDexterity.toString() + " dexterity<br>");
reqText += (reqAgility.toString() + " agility<br>");
reqText += (reqCharisma.toString() + " charisma<br>");
reqText += (reqRep.toString() + " reputation");
} else {
reqText = "(Requires ";
if (reqHacking > 0) {reqText += (reqHacking + " hacking, ");}
if (reqStrength > 0) {reqText += (reqStrength + " strength, ");}
if (reqDefense > 0) {reqText += (reqDefense + " defense, ");}
if (reqDexterity > 0) {reqText += (reqDexterity + " dexterity, ");}
if (reqAgility > 0) {reqText += (reqAgility + " agility, ");}
if (reqCharisma > 0) {reqText += (reqCharisma + " charisma, ");}
if (reqRep > 1) {reqText += (reqRep + " reputation, ");}
reqText = reqText.substring(0, reqText.length - 2);
reqText += ")";
}
return reqText;
}
export {CompanyPositions, initCompanies, Companies, getJobRequirementText,
getNextCompanyPosition, loadCompanies, Company, CompanyPosition};

@ -1,273 +1 @@
/* Functions that handle applying for different jobs/positions in a Company */ //TODO probably just move this to whatever file needs it then delete this
//Determines the job that the Player should get (if any) at the current
//company
PlayerObject.prototype.applyForJob = function(entryPosType) {
var currCompany = "";
if (this.companyName != "") {
currCompany = Companies[this.companyName];
}
var currPositionName = "";
if (this.companyPosition != "") {
currPositionName = this.companyPosition.positionName;
}
var company = Companies[this.location]; //Company being applied to
var pos = entryPosType;
if (!this.isQualified(company, pos)) {
var reqText = getJobRequirementText(company, pos);
dialogBoxCreate("Unforunately, you do not qualify for this position<br>" + reqText);
return;
}
while (true) {
if (Engine.Debug) {console.log("Determining qualification for next Company Position");}
var newPos = getNextCompanyPosition(pos);
if (newPos == null) {break;}
//Check if this company has this position
if (company.hasPosition(newPos)) {
if (!this.isQualified(company, newPos)) {
//If player not qualified for next job, break loop so player will be given current job
break;
}
pos = newPos;
} else {
break;
}
}
//Check if the determined job is the same as the player's current job
if (currCompany != "") {
if (currCompany.companyName == company.companyName &&
pos.positionName == currPositionName) {
var nextPos = getNextCompanyPosition(pos);
if (nextPos == null) {
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
} else if (company.hasPosition(nextPos)) {
var reqText = getJobRequirementText(company, nextPos);
dialogBoxCreate("Unfortunately, you do not qualify for a promotion<br>" + reqText);
} else {
dialogBoxCreate("You are already at the highest position for your field! No promotion available");
}
return; //Same job, do nothing
}
}
//Lose reputation from a Company if you are leaving it for another job
var leaveCompany = false;
var oldCompanyName = "";
if (currCompany != "") {
if (currCompany.companyName != company.companyName) {
leaveCompany = true;
oldCompanyName = currCompany.companyName;
company.playerReputation -= 1000;
if (company.playerReputation < 0) {company.playerReputation = 0;}
if (Engine.debug) {
console.log("Lost reputation for " + company.companyName + ". It is now " + company.playerReputation);
}
}
}
this.companyName = company.companyName;
this.companyPosition = pos;
if (leaveCompany) {
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " +
pos.positionName + "!<br>" +
"You lost 1000 reputation at your old company " + oldCompanyName + " because you left.");
} else {
dialogBoxCreate("Congratulations! You were offered a new job at " + this.companyName + " as a " + pos.positionName + "!");
}
Engine.loadLocationContent();
}
function getJobRequirementText(company, pos, tooltiptext=false) {
var reqText = "";
var offset = company.jobStatReqOffset;
var reqHacking = pos.requiredHacking > 0 ? pos.requiredHacking+offset : 0;
var reqStrength = pos.requiredStrength > 0 ? pos.requiredStrength+offset : 0;
var reqDefense = pos.requiredDefense > 0 ? pos.requiredDefense+offset : 0;
var reqDexterity = pos.requiredDexterity > 0 ? pos.requiredDexterity+offset : 0;
var reqAgility = pos.requiredDexterity > 0 ? pos.requiredDexterity+offset : 0;
var reqCharisma = pos.requiredCharisma > 0 ? pos.requiredCharisma+offset : 0;
var reqRep = pos.requiredReputation;
if (tooltiptext) {
reqText = "Requires:<br>";
reqText += (reqHacking.toString() + " hacking<br>");
reqText += (reqStrength.toString() + " strength<br>");
reqText += (reqDefense.toString() + " defense<br>");
reqText += (reqDexterity.toString() + " dexterity<br>");
reqText += (reqAgility.toString() + " agility<br>");
reqText += (reqCharisma.toString() + " charisma<br>");
reqText += (reqRep.toString() + " reputation");
} else {
reqText = "(Requires ";
if (reqHacking > 0) {reqText += (reqHacking + " hacking, ");}
if (reqStrength > 0) {reqText += (reqStrength + " strength, ");}
if (reqDefense > 0) {reqText += (reqDefense + " defense, ");}
if (reqDexterity > 0) {reqText += (reqDexterity + " dexterity, ");}
if (reqAgility > 0) {reqText += (reqAgility + " agility, ");}
if (reqCharisma > 0) {reqText += (reqCharisma + " charisma, ");}
if (reqRep > 1) {reqText += (reqRep + " reputation, ");}
reqText = reqText.substring(0, reqText.length - 2);
reqText += ")";
}
return reqText;
}
//Returns your next position at a company given the field (software, business, etc.)
PlayerObject.prototype.getNextCompanyPosition = function(company, entryPosType) {
var currCompany = null;
if (this.companyName != "") {
currCompany = Companies[this.companyName];
}
//Not employed at this company, so return the entry position
if (currCompany == null || (currCompany.companyName != company.companyName)) {
return entryPosType;
}
//If the entry pos type and the player's current position have the same type,
//return the player's "nextCompanyPosition". Otherwise return the entryposType
//Employed at this company, so just return the next position if it exists.
if ((this.companyPosition.isSoftwareJob() && entryPosType.isSoftwareJob()) ||
(this.companyPosition.isITJob() && entryPosType.isITJob()) ||
(this.companyPosition.isSecurityEngineerJob() && entryPosType.isSecurityEngineerJob()) ||
(this.companyPosition.isNetworkEngineerJob() && entryPosType.isNetworkEngineerJob()) ||
(this.companyPosition.isSecurityJob() && entryPosType.isSecurityJob()) ||
(this.companyPosition.isAgentJob() && entryPosTypeisAgentJob()) ||
(this.companyPosition.isSoftwareConsultantJob() && entryPosType.isSoftwareConsultantJob()) ||
(this.companyPosition.isBusinessConsultantJob() && entryPosType.isBusinessConsultantJob()) ||
(this.companyPosition.isPartTimeJob() && entryPosType.isPartTimeJob())) {
return getNextCompanyPosition(this.companyPosition);
}
return entryPosType;
}
PlayerObject.prototype.applyForSoftwareJob = function() {
this.applyForJob(CompanyPositions.SoftwareIntern);
}
PlayerObject.prototype.applyForSoftwareConsultantJob = function() {
this.applyForJob(CompanyPositions.SoftwareConsultant);
}
PlayerObject.prototype.applyForItJob = function() {
this.applyForJob(CompanyPositions.ITIntern);
}
PlayerObject.prototype.applyForSecurityEngineerJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.SecurityEngineer)) {
this.applyForJob(CompanyPositions.SecurityEngineer);
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForNetworkEngineerJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.NetworkEngineer)) {
this.applyForJob(CompanyPositions.NetworkEngineer);
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForBusinessJob = function() {
this.applyForJob(CompanyPositions.BusinessIntern);
}
PlayerObject.prototype.applyForBusinessConsultantJob = function() {
this.applyForJob(CompanyPositions.BusinessConsultant);
}
PlayerObject.prototype.applyForSecurityJob = function() {
//TODO If case for POlice departments
this.applyForJob(CompanyPositions.SecurityGuard);
}
PlayerObject.prototype.applyForAgentJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.FieldAgent)) {
this.applyForJob(CompanyPositions.FieldAgent);
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForEmployeeJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.Employee)) {
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.Employee;
dialogBoxCreate("Congratulations, you are now employed at " + this.companyName);
Engine.loadLocationContent();
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForPartTimeEmployeeJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.PartTimeEmployee)) {
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.PartTimeEmployee;
dialogBoxCreate("Congratulations, you are now employed part-time at " + this.companyName);
Engine.loadLocationContent();
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForWaiterJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.Waiter)) {
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.Waiter;
dialogBoxCreate("Congratulations, you are now employed as a waiter at " + this.companyName);
Engine.loadLocationContent();
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
PlayerObject.prototype.applyForPartTimeWaiterJob = function() {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.PartTimeWaiter)) {
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.PartTimeWaiter;
dialogBoxCreate("Congratulations, you are now employed as a part-time waiter at " + this.companyName);
Engine.loadLocationContent();
} else {
dialogBoxCreate("Unforunately, you do not qualify for this position");
}
}
//Checks if the Player is qualified for a certain position
PlayerObject.prototype.isQualified = function(company, position) {
var offset = company.jobStatReqOffset;
var reqHacking = position.requiredHacking > 0 ? position.requiredHacking+offset : 0;
var reqStrength = position.requiredStrength > 0 ? position.requiredStrength+offset : 0;
var reqDefense = position.requiredDefense > 0 ? position.requiredDefense+offset : 0;
var reqDexterity = position.requiredDexterity > 0 ? position.requiredDexterity+offset : 0;
var reqAgility = position.requiredDexterity > 0 ? position.requiredDexterity+offset : 0;
var reqCharisma = position.requiredCharisma > 0 ? position.requiredCharisma+offset : 0;
if (this.hacking_skill >= reqHacking &&
this.strength >= reqStrength &&
this.defense >= reqDefense &&
this.dexterity >= reqDexterity &&
this.agility >= reqAgility &&
this.charisma >= reqCharisma &&
company.playerReputation >= position.requiredReputation) {
return true;
}
return false;
}

@ -1,5 +1,5 @@
CONSTANTS = { let CONSTANTS = {
Version: "0.27.3", Version: "0.28.0",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience //Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then //and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@ -75,8 +75,12 @@ CONSTANTS = {
ScriptRoundRamCost: 0.05, ScriptRoundRamCost: 0.05,
ScriptReadWriteRamCost: 1.0, ScriptReadWriteRamCost: 1.0,
ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args ScriptArbScriptRamCost: 1.0, //Functions that apply to all scripts regardless of args
ScriptGetScriptCost: 0.1, ScriptGetScriptRamCost: 0.1,
ScriptGetHackTimeCost: 0.05, ScriptGetHackTimeRamCost: 0.05,
ScriptSingularityFn1RamCost: 1,
ScriptSingularityFn2RamCost: 2,
ScriptSingularityFn3RamCost: 3,
MultithreadingRAMCost: 1, MultithreadingRAMCost: 1,
@ -320,6 +324,9 @@ CONSTANTS = {
"numeric - Integers and floats (eg. 6, 10.4999)<br>" + "numeric - Integers and floats (eg. 6, 10.4999)<br>" +
"string - Encapsulated by single or double quotes (eg. 'this is a string')<br>" + "string - Encapsulated by single or double quotes (eg. 'this is a string')<br>" +
"boolean - true or false<br><br>" + "boolean - true or false<br><br>" +
"Strings are fully functional <a href='https://www.w3schools.com/jsref/jsref_obj_string.asp' target='_blank'>Javascript strings</a>, " +
"which means that all of the member functions of Javascript strings such as toLowerCase() and includes() are also " +
"available in Netscript!<br><br>" +
"To create a variable, use the assign (=) operator. The language is not strongly typed. Examples: <br>" + "To create a variable, use the assign (=) operator. The language is not strongly typed. Examples: <br>" +
"i = 5;<br>" + "i = 5;<br>" +
"s = 'this game is awesome!';<br><br>" + "s = 'this game is awesome!';<br><br>" +
@ -717,38 +724,11 @@ CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>", "World Stock Exchange account and TIX API Access<br>",
LatestUpdate: LatestUpdate:
"v0.27.3<br>" + "v0.28.0<br>" +
"-You can now purchase upgrades for Gang Members (BitNode 2 only)<br>" + "-Added BitNode-4: The Singularity<br>" +
"-Decreased Gang respect gains and slightly increased wanted gains (BitNode 2 only)<br>" + "-Added BitNode-11: The Big Crash<br>" +
"-Other gangs will increase in power faster (BitNode 2 only)<br>" + "-Migrated the codebase to use webpack (doesn't affect any in game content, except maybe some slight " +
"-Added getHackTime(), getGrowTime(), and getWeakenTime() Netscript functions<br><br>" + "performance improvements and there may be bugs that result from dependency errors)"
"v0.27.2<br>" +
"-Added getServerGrowth() Netscript function<br>" +
"-Added getNextHacknetNodeCost() Netscript function<br>" +
"-Added new 'literature' files (.lit extension) that are used to build lore for the game. " +
"These .lit files can be found in certain servers throughout the game. They can be viewed with the 'cat' Terminal " +
"command and copied over to other servers using the 'scp' command. These .lit files won't be found until you reset " +
"by installing Augmentations<br>" +
"Fixed some bugs with Gang Territory(BitNode 2 only)<br><br>" +
"v0.27.1<br>" +
"-Changed the way Gang power was calculated to make it scale better late game (BitNode 2 only)<br>" +
"-Lowered the respect gain rate in Gangs (Bitnode 2 only)<br>" +
"-Added '| grep pattern' option for ls Terminal command. This allows you to only list files that contain a certain pattern<br>" +
"-Added break statement in Netscript<br>" +
"-Display for some numerical values is now done in shorthand (e.g 1.000m instead of 1,000,000)<br><br>" +
"v0.27.0<br>" +
"-Added secondary 'prestige' system - featuring Source Files and BitNodes<br>" +
"-MILD SPOILERS HERE: Installing 'The Red Pill' Augmentation from Daedalus will unlock a special server called " +
"w0r1d_d43m0n. Finding and manually hacking this server through Terminal will destroy the Player's current BitNode, and allow the player " +
"to enter a new one. When destroying a BitNode, the player loses everything except the scripts on his/her " +
"home computer. The player will then gain a powerful second-tier persistent upgrade called a Source File. The player can then " +
"enter a new BitNode to start the game over. Each BitNode has different characteristics, and many will have new content/mechanics " +
"as well. Right now there are only 2 BitNodes. Each BitNode grants its own unique Source File. Restarting and destroying a BitNode you already " +
"have a Source File for will upgrade your Source File up to a maximum level of 3.<br><br>" +
"-Reputation gain with factions and companies is no longer a linear conversion, but an exponential one. It " +
"will be much easier to gain faction favor at first, but much harder later on. <br>" +
"-Significantly increased Infiltration exp gains<br>" +
"-Fixed a bug with company job requirement tooltips<br>" +
"-Added scriptRunning(), scriptKill(), and getScriptRam() Netscript functions. See documentation for details<br>" +
"-Fixed a bug with deleteServer() Netscript function<br><br>"
} }
export {CONSTANTS};

@ -1,17 +1,20 @@
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
/* Create programs */ /* Create programs */
Programs = { let Programs = {
NukeProgram: "NUKE.exe", NukeProgram: "NUKE.exe",
BruteSSHProgram: "BruteSSH.exe", BruteSSHProgram: "BruteSSH.exe",
FTPCrackProgram: "FTPCrack.exe", FTPCrackProgram: "FTPCrack.exe",
RelaySMTPProgram: "relaySMTP.exe", RelaySMTPProgram: "relaySMTP.exe",
HTTPWormProgram: "HTTPWorm.exe", HTTPWormProgram: "HTTPWorm.exe",
SQLInjectProgram: "SQLInject.exe", SQLInjectProgram: "SQLInject.exe",
DeepscanV1: "DeepscanV1.exe", DeepscanV1: "DeepscanV1.exe",
DeepscanV2: "DeepscanV2.exe", DeepscanV2: "DeepscanV2.exe",
ServerProfiler: "ServerProfiler.exe", ServerProfiler: "ServerProfiler.exe",
AutoLink: "AutoLink.exe", AutoLink: "AutoLink.exe",
Flight: "fl1ght.exe", Flight: "fl1ght.exe",
} };
//TODO Right now the times needed to complete work are hard-coded... //TODO Right now the times needed to complete work are hard-coded...
//maybe later make this dependent on hacking level or something //maybe later make this dependent on hacking level or something
@ -187,3 +190,6 @@ function initCreateProgramButtons() {
return false; return false;
}); });
} }
export {Programs, displayCreateProgramContent, getNumAvailableCreateProgram,
initCreateProgramButtons};

@ -1,3 +1,7 @@
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
/* Crimes.js */ /* Crimes.js */
function commitShopliftCrime() { function commitShopliftCrime() {
Player.crimeType = CONSTANTS.CrimeShoplift; Player.crimeType = CONSTANTS.CrimeShoplift;
@ -202,3 +206,14 @@ function determineCrimeChanceHeist() {
chance *= Player.crime_success_mult; chance *= Player.crime_success_mult;
return Math.min(chance, 1); return Math.min(chance, 1);
} }
export {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
commitLarcenyCrime, commitDealDrugsCrime, commitTraffickArmsCrime,
commitHomicideCrime, commitGrandTheftAutoCrime, commitKidnapCrime,
commitAssassinationCrime, commitHeistCrime, determineCrimeSuccess,
determineCrimeChanceShoplift, determineCrimeChanceRobStore,
determineCrimeChanceMug, determineCrimeChanceLarceny,
determineCrimeChanceDealDrugs, determineCrimeChanceTraffickArms,
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
determineCrimeChanceHeist};

@ -1,6 +1,14 @@
import {Programs} from "./CreateProgram.js";
import {Player} from "./Player.js";
import {SpecialServerIps} from "./SpecialServerIps.js";
import {post} from "./Terminal.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
/* DarkWeb.js */ /* DarkWeb.js */
//Posts a "help" message if connected to DarkWeb //Posts a "help" message if connected to DarkWeb
checkIfConnectedToDarkweb = function() { function checkIfConnectedToDarkweb() {
if (SpecialServerIps.hasOwnProperty("Darkweb Server")) { if (SpecialServerIps.hasOwnProperty("Darkweb Server")) {
var darkwebIp = SpecialServerIps["Darkweb Server"]; var darkwebIp = SpecialServerIps["Darkweb Server"];
if (!isValidIPAddress(darkwebIp)) {return;} if (!isValidIPAddress(darkwebIp)) {return;}
@ -16,7 +24,7 @@ checkIfConnectedToDarkweb = function() {
//Handler for dark web commands. The terminal's executeCommand() function will pass //Handler for dark web commands. The terminal's executeCommand() function will pass
//dark web-specific commands into this. It will pass in the raw split command array //dark web-specific commands into this. It will pass in the raw split command array
//rather than the command string //rather than the command string
executeDarkwebTerminalCommand = function(commandArray) { function executeDarkwebTerminalCommand(commandArray) {
if (commandArray.length == 0) {return;} if (commandArray.length == 0) {return;}
switch (commandArray[0]) { switch (commandArray[0]) {
case "buy": case "buy":
@ -38,7 +46,7 @@ executeDarkwebTerminalCommand = function(commandArray) {
} }
} }
listAllDarkwebItems = function() { function listAllDarkwebItems() {
for (var item in DarkWebItems) { for (var item in DarkWebItems) {
if (DarkWebItems.hasOwnProperty(item)) { if (DarkWebItems.hasOwnProperty(item)) {
var item = DarkWebItems[item]; var item = DarkWebItems[item];
@ -76,7 +84,7 @@ listAllDarkwebItems = function() {
else {return price;} else {return price;}
} }
buyDarkwebItem = function(itemName) { function buyDarkwebItem(itemName) {
if (itemName.toLowerCase() == Programs.BruteSSHProgram.toLowerCase()) { if (itemName.toLowerCase() == Programs.BruteSSHProgram.toLowerCase()) {
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram); var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
if (price > 0 && Player.money.gt(price)) { if (price > 0 && Player.money.gt(price)) {
@ -152,7 +160,7 @@ buyDarkwebItem = function(itemName) {
} }
} }
parseDarkwebItemPrice = function(itemDesc) { function parseDarkwebItemPrice(itemDesc) {
var split = itemDesc.split(" - "); var split = itemDesc.split(" - ");
if (split.length == 3) { if (split.length == 3) {
var priceString = split[1]; var priceString = split[1];
@ -173,12 +181,16 @@ parseDarkwebItemPrice = function(itemDesc) {
} }
} }
DarkWebItems = { let DarkWebItems = {
BruteSSHProgram: Programs.BruteSSHProgram + " - $500,000 - Opens up SSH Ports", BruteSSHProgram: "BruteSSH.exe - $500,000 - Opens up SSH Ports",
FTPCrackProgram: Programs.FTPCrackProgram + " - $1,500,000 - Opens up FTP Ports", FTPCrackProgram: "FTPCrack.exe - $1,500,000 - Opens up FTP Ports",
RelaySMTPProgram: Programs.RelaySMTPProgram + " - $5,000,000 - Opens up SMTP Ports", RelaySMTPProgram: "relaySMTP.exe - $5,000,000 - Opens up SMTP Ports",
HTTPWormProgram: Programs.HTTPWormProgram + " - $30,000,000 - Opens up HTTP Ports", HTTPWormProgram: "HTTPWorm.exe - $30,000,000 - Opens up HTTP Ports",
SQLInjectProgram: Programs.SQLInjectProgram + " - $250,000,000 - Opens up SQL Ports", SQLInjectProgram: "SQLInject.exe - $250,000,000 - Opens up SQL Ports",
DeepScanV1Program: Programs.DeepscanV1 + " - $500,000 - Enables 'scan-analyze' with a depth up to 5", DeepScanV1Program: "DeepscanV1.exe - $500,000 - Enables 'scan-analyze' with a depth up to 5",
DeepScanV2Program: Programs.DeepscanV2 + " - $25,000,000 - Enables 'scan-analyze' with a depth up to 10", DeepScanV2Program: "DeepscanV2.exe - $25,000,000 - Enables 'scan-analyze' with a depth up to 10",
} }
export {checkIfConnectedToDarkweb, executeDarkwebTerminalCommand,
listAllDarkwebItems, buyDarkwebItem, parseDarkwebItemPrice,
DarkWebItems};

@ -1,3 +1,21 @@
import {Augmentations, AugmentationNames,
PlayerOwnedAugmentation} from "./Augmentations.js";
import {BitNodeMultipliers} from "./BitNode.js";
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {Engine} from "./engine.js";
import {FactionInfo} from "./FactionInfo.js";
import {Settings} from "./Settings.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {factionInvitationBoxCreate} from "../utils/FactionInvitationBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
import {yesNoBoxCreate, yesNoBoxGetYesButton,
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
//Netburner Faction class //Netburner Faction class
function factionInit() { function factionInit() {
$('#faction-donate-input').on('input', function() { $('#faction-donate-input').on('input', function() {
@ -97,9 +115,13 @@ Faction.fromJSON = function(value) {
Reviver.constructors.Faction = Faction; Reviver.constructors.Faction = Faction;
//Map of factions indexed by faction name //Map of factions indexed by faction name
Factions = {} let Factions = {}
AddToFactions = function(faction) { function loadFactions(saveString) {
Factions = JSON.parse(saveString, Reviver);
}
function AddToFactions(faction) {
var name = faction.name; var name = faction.name;
Factions[name] = faction; Factions[name] = faction;
} }
@ -110,7 +132,7 @@ function factionExists(name) {
//TODO Augmentation price and rep requirement mult are 1 for everything right now, //TODO Augmentation price and rep requirement mult are 1 for everything right now,
// This might change in the future for balance // This might change in the future for balance
initFactions = function() { function initFactions() {
//Endgame //Endgame
var Illuminati = new Faction("Illuminati"); var Illuminati = new Faction("Illuminati");
Illuminati.setInfo(FactionInfo.IlluminatiInfo); Illuminati.setInfo(FactionInfo.IlluminatiInfo);
@ -368,304 +390,7 @@ initFactions = function() {
AddToFactions(CyberSec); AddToFactions(CyberSec);
} }
//This function sets the requirements to join a Faction. It checks whether the Player meets function inviteToFaction(faction) {
//those requirements and will return an array of all factions that the Player should
//receive an invitation to
PlayerObject.prototype.checkForFactionInvitations = function() {
invitedFactions = []; //Array which will hold all Factions th eplayer should be invited to
var numAugmentations = this.augmentations.length;
var company = Companies[this.companyName];
var companyRep = 0;
if (company != null) {
companyRep = company.playerReputation;
}
//Illuminati
var illuminatiFac = Factions["Illuminati"];
if (!illuminatiFac.isBanned && !illuminatiFac.isMember && !illuminatiFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(150000000000) &&
this.hacking_skill >= 1500 &&
this.strength >= 1200 && this.defense >= 1200 &&
this.dexterity >= 1200 && this.agility >= 1200) {
invitedFactions.push(illuminatiFac);
}
//Daedalus
var daedalusFac = Factions["Daedalus"];
if (!daedalusFac.isBanned && !daedalusFac.isMember && !daedalusFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(100000000000) &&
(this.hacking_skill >= 2500 ||
(this.strength >= 1500 && this.defense >= 1500 &&
this.dexterity >= 1500 && this.agility >= 1500))) {
invitedFactions.push(daedalusFac);
}
//The Covenant
var covenantFac = Factions["The Covenant"];
if (!covenantFac.isBanned && !covenantFac.isMember && !covenantFac.alreadyInvited &&
numAugmentations >= 30 &&
this.money.gte(75000000000) &&
this.hacking_skill >= 850 &&
this.strength >= 850 &&
this.defense >= 850 &&
this.dexterity >= 850 &&
this.agility >= 850) {
invitedFactions.push(covenantFac);
}
//ECorp
var ecorpFac = Factions["ECorp"];
if (!ecorpFac.isBanned && !ecorpFac.isMember && !ecorpFac.alreadyInvited &&
this.companyName == Locations.AevumECorp && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(ecorpFac);
}
//MegaCorp
var megacorpFac = Factions["MegaCorp"];
if (!megacorpFac.isBanned && !megacorpFac.isMember && !megacorpFac.alreadyInvited &&
this.companyName == Locations.Sector12MegaCorp && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(megacorpFac);
}
//Bachman & Associates
var bachmanandassociatesFac = Factions["Bachman & Associates"];
if (!bachmanandassociatesFac.isBanned && !bachmanandassociatesFac.isMember &&
!bachmanandassociatesFac.alreadyInvited &&
this.companyName == Locations.AevumBachmanAndAssociates && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(bachmanandassociatesFac);
}
//Blade Industries
var bladeindustriesFac = Factions["Blade Industries"];
if (!bladeindustriesFac.isBanned && !bladeindustriesFac.isMember && !bladeindustriesFac.alreadyInvited &&
this.companyName == Locations.Sector12BladeIndustries && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(bladeindustriesFac);
}
//NWO
var nwoFac = Factions["NWO"];
if (!nwoFac.isBanned && !nwoFac.isMember && !nwoFac.alreadyInvited &&
this.companyName == Locations.VolhavenNWO && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(nwoFac);
}
//Clarke Incorporated
var clarkeincorporatedFac = Factions["Clarke Incorporated"];
if (!clarkeincorporatedFac.isBanned && !clarkeincorporatedFac.isMember && !clarkeincorporatedFac.alreadyInvited &&
this.companyName == Locations.AevumClarkeIncorporated && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(clarkeincorporatedFac);
}
//OmniTek Incorporated
var omnitekincorporatedFac = Factions["OmniTek Incorporated"];
if (!omnitekincorporatedFac.isBanned && !omnitekincorporatedFac.isMember && !omnitekincorporatedFac.alreadyInvited &&
this.companyName == Locations.VolhavenOmniTekIncorporated && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(omnitekincorporatedFac);
}
//Four Sigma
var foursigmaFac = Factions["Four Sigma"];
if (!foursigmaFac.isBanned && !foursigmaFac.isMember && !foursigmaFac.alreadyInvited &&
this.companyName == Locations.Sector12FourSigma && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(foursigmaFac);
}
//KuaiGong International
var kuaigonginternationalFac = Factions["KuaiGong International"];
if (!kuaigonginternationalFac.isBanned && !kuaigonginternationalFac.isMember &&
!kuaigonginternationalFac.alreadyInvited &&
this.companyName == Locations.ChongqingKuaiGongInternational && companyRep >= CONSTANTS.CorpFactionRepRequirement) {
invitedFactions.push(kuaigonginternationalFac);
}
//Fulcrum Secret Technologies - If u've unlocked fulcrum secret technolgoies server and have a high rep with the company
var fulcrumsecrettechonologiesFac = Factions["Fulcrum Secret Technologies"];
var fulcrumSecretServer = AllServers[SpecialServerIps[SpecialServerNames.FulcrumSecretTechnologies]];
if (fulcrumSecretServer == null) {
console.log("ERROR: Could not find Fulcrum Secret Technologies Server");
} else {
if (!fulcrumsecrettechonologiesFac.isBanned && !fulcrumsecrettechonologiesFac.isMember &&
!fulcrumsecrettechonologiesFac.alreadyInvited &&
fulcrumSecretServer.manuallyHacked &&
this.companyName == Locations.AevumFulcrumTechnologies && companyRep >= 250000) {
invitedFactions.push(fulcrumsecrettechonologiesFac);
}
}
//BitRunners
var bitrunnersFac = Factions["BitRunners"];
var homeComp = this.getHomeComputer();
var bitrunnersServer = AllServers[SpecialServerIps[SpecialServerNames.BitRunnersServer]];
if (bitrunnersServer == null) {
console.log("ERROR: Could not find BitRunners Server");
} else if (!bitrunnersFac.isBanned && !bitrunnersFac.isMember && bitrunnersServer.manuallyHacked &&
!bitrunnersFac.alreadyInvited && this.hacking_skill >= 500 && homeComp.maxRam >= 128) {
invitedFactions.push(bitrunnersFac);
}
//The Black Hand
var theblackhandFac = Factions["The Black Hand"];
var blackhandServer = AllServers[SpecialServerIps[SpecialServerNames.TheBlackHandServer]];
if (blackhandServer == null) {
console.log("ERROR: Could not find The Black Hand Server");
} else if (!theblackhandFac.isBanned && !theblackhandFac.isMember && blackhandServer.manuallyHacked &&
!theblackhandFac.alreadyInvited && this.hacking_skill >= 350 && homeComp.maxRam >= 64) {
invitedFactions.push(theblackhandFac);
}
//NiteSec
var nitesecFac = Factions["NiteSec"];
var nitesecServer = AllServers[SpecialServerIps[SpecialServerNames.NiteSecServer]];
if (nitesecServer == null) {
console.log("ERROR: Could not find NiteSec Server");
} else if (!nitesecFac.isBanned && !nitesecFac.isMember && nitesecServer.manuallyHacked &&
!nitesecFac.alreadyInvited && this.hacking_skill >= 200 && homeComp.maxRam >= 32) {
invitedFactions.push(nitesecFac);
}
//Chongqing
var chongqingFac = Factions["Chongqing"];
if (!chongqingFac.isBanned && !chongqingFac.isMember && !chongqingFac.alreadyInvited &&
this.money.gte(20000000) && this.city == Locations.Chongqing) {
invitedFactions.push(chongqingFac);
}
//Sector-12
var sector12Fac = Factions["Sector-12"];
if (!sector12Fac.isBanned && !sector12Fac.isMember && !sector12Fac.alreadyInvited &&
this.money.gte(15000000) && this.city == Locations.Sector12) {
invitedFactions.push(sector12Fac);
}
//New Tokyo
var newtokyoFac = Factions["New Tokyo"];
if (!newtokyoFac.isBanned && !newtokyoFac.isMember && !newtokyoFac.alreadyInvited &&
this.money.gte(20000000) && this.city == Locations.NewTokyo) {
invitedFactions.push(newtokyoFac);
}
//Aevum
var aevumFac = Factions["Aevum"];
if (!aevumFac.isBanned && !aevumFac.isMember && !aevumFac.alreadyInvited &&
this.money.gte(40000000) && this.city == Locations.Aevum) {
invitedFactions.push(aevumFac);
}
//Ishima
var ishimaFac = Factions["Ishima"];
if (!ishimaFac.isBanned && !ishimaFac.isMember && !ishimaFac.alreadyInvited &&
this.money.gte(30000000) && this.city == Locations.Ishima) {
invitedFactions.push(ishimaFac);
}
//Volhaven
var volhavenFac = Factions["Volhaven"];
if (!volhavenFac.isBanned && !volhavenFac.isMember && !volhavenFac.alreadyInvited &&
this.money.gte(50000000) && this.city == Locations.Volhaven) {
invitedFactions.push(volhavenFac);
}
//Speakers for the Dead
var speakersforthedeadFac = Factions["Speakers for the Dead"];
if (!speakersforthedeadFac.isBanned && !speakersforthedeadFac.isMember && !speakersforthedeadFac.alreadyInvited &&
this.hacking_skill >= 100 && this.strength >= 300 && this.defense >= 300 &&
this.dexterity >= 300 && this.agility >= 300 && this.numPeopleKilled >= 30 &&
this.karma <= -45 && this.companyName != Locations.Sector12CIA &&
this.companyName != Locations.Sector12NSA) {
invitedFactions.push(speakersforthedeadFac);
}
//The Dark Army
var thedarkarmyFac = Factions["The Dark Army"];
if (!thedarkarmyFac.isBanned && !thedarkarmyFac.isMember && !thedarkarmyFac.alreadyInvited &&
this.hacking_skill >= 300 && this.strength >= 300 && this.defense >= 300 &&
this.dexterity >= 300 && this.agility >= 300 && this.city == Locations.Chongqing &&
this.numPeopleKilled >= 5 && this.karma <= -45 && this.companyName != Locations.Sector12CIA &&
this.companyName != Locations.Sector12NSA) {
invitedFactions.push(thedarkarmyFac);
}
//The Syndicate
var thesyndicateFac = Factions["The Syndicate"];
if (!thesyndicateFac.isBanned && !thesyndicateFac.isMember && !thesyndicateFac.alreadyInvited &&
this.hacking_skill >= 200 && this.strength >= 200 && this.defense >= 200 &&
this.dexterity >= 200 && this.agility >= 200 &&
(this.city == Locations.Aevum || this.city == Locations.Sector12) &&
this.money.gte(10000000) && this.karma <= -90 &&
this.companyName != Locations.Sector12CIA && this.companyName != Locations.Sector12NSA) {
invitedFactions.push(thesyndicateFac);
}
//Silhouette
var silhouetteFac = Factions["Silhouette"];
if (!silhouetteFac.isBanned && !silhouetteFac.isMember && !silhouetteFac.alreadyInvited &&
(this.companyPosition.positionName == CompanyPositions.CTO.positionName ||
this.companyPosition.positionName == CompanyPositions.CFO.positionName ||
this.companyPosition.positionName == CompanyPositions.CEO.positionName) &&
this.money.gte(15000000) && this.karma <= -22) {
invitedFactions.push(silhouetteFac);
}
//Tetrads
var tetradsFac = Factions["Tetrads"];
if (!tetradsFac.isBanned && !tetradsFac.isMember && !tetradsFac.alreadyInvited &&
(this.city == Locations.Chongqing || this.city == Locations.NewTokyo ||
this.city == Locations.Ishima) && this.strength >= 75 && this.defense >= 75 &&
this.dexterity >= 75 && this.agility >= 75 && this.karma <= -18) {
invitedFactions.push(tetradsFac);
}
//SlumSnakes
var slumsnakesFac = Factions["Slum Snakes"];
if (!slumsnakesFac.isBanned && !slumsnakesFac.isMember && !slumsnakesFac.alreadyInvited &&
this.strength >= 30 && this.defense >= 30 && this.dexterity >= 30 &&
this.agility >= 30 && this.karma <= -9 && this.money.gte(1000000)) {
invitedFactions.push(slumsnakesFac);
}
//Netburners
var netburnersFac = Factions["Netburners"];
var totalHacknetRam = 0;
var totalHacknetCores = 0;
var totalHacknetLevels = 0;
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
totalHacknetLevels += Player.hacknetNodes[i].level;
totalHacknetRam += Player.hacknetNodes[i].ram;
totalHacknetCores += Player.hacknetNodes[i].cores;
}
if (!netburnersFac.isBanned && !netburnersFac.isMember && !netburnersFac.alreadyInvited &&
this.hacking_skill >= 80 && totalHacknetRam >= 8 &&
totalHacknetCores >= 4 && totalHacknetLevels >= 100) {
invitedFactions.push(netburnersFac);
}
//Tian Di Hui
var tiandihuiFac = Factions["Tian Di Hui"];
if (!tiandihuiFac.isBanned && !tiandihuiFac.isMember && !tiandihuiFac.alreadyInvited &&
this.money.gte(1000000) && this.hacking_skill >= 50 &&
(this.city == Locations.Chongqing || this.city == Locations.NewTokyo ||
this.city == Locations.Ishima)) {
invitedFactions.push(tiandihuiFac);
}
//CyberSec
var cybersecFac = Factions["CyberSec"];
var cybersecServer = AllServers[SpecialServerIps[SpecialServerNames.CyberSecServer]];
if (cybersecServer == null) {
console.log("ERROR: Could not find CyberSec Server");
} else if (!cybersecFac.isBanned && !cybersecFac.isMember && cybersecServer.manuallyHacked &&
!cybersecFac.alreadyInvited && this.hacking_skill >= 50) {
invitedFactions.push(cybersecFac);
}
return invitedFactions;
}
inviteToFaction = function(faction) {
if (Settings.SuppressFactionInvites) { if (Settings.SuppressFactionInvites) {
faction.alreadyInvited = true; faction.alreadyInvited = true;
Player.factionInvitations.push(faction.name); Player.factionInvitations.push(faction.name);
@ -674,7 +399,7 @@ inviteToFaction = function(faction) {
} }
} }
joinFaction = function(faction) { function joinFaction(faction) {
faction.isMember = true; faction.isMember = true;
Player.factions.push(faction.name); Player.factions.push(faction.name);
@ -710,47 +435,8 @@ joinFaction = function(faction) {
} }
} }
leaveFaction = function(faction) {
faction.isMember = false;
var i = Player.factions.indexOf(faction.name);
if (i > -1) {
Player.factions.splice(i, 1);
}
//Unban from faction
if (faction.name == "Chongqing") {
Factions["Sector-12"].isBanned = false;
Factions["Aevum"].isBanned = false;
Factions["Volhaven"].isBanned = false;
} else if (faction.name == "Sector-12") {
Factions["Chongqing"].isBanned = false;
Factions["New Tokyo"].isBanned = false;
Factions["Ishima"].isBanned = false;
Factions["Volhaven"].isBanned = false;
} else if (faction.name == "New Tokyo") {
Factions["Sector-12"].isBanned = false;
Factions["Aevum"].isBanned = false;
Factions["Volhaven"].isBanned = false;
} else if (faction.name == "Aevum") {
Factions["Chongqing"].isBanned = false;
Factions["New Tokyo"].isBanned = false;
Factions["Ishima"].isBanned = false;
Factions["Volhaven"].isBanned = false;
} else if (faction.name == "Ishima") {
Factions["Sector-12"].isBanned = false;
Factions["Aevum"].isBanned = false;
Factions["Volhaven"].isBanned = false;
} else if (faction.name == "Volhaven") {
Factions["Chongqing"].isBanned = false;
Factions["Sector-12"].isBanned = false;
Factions["New Tokyo"].isBanned = false;
Factions["Aevum"].isBanned = false;
Factions["Ishima"].isBanned = false;
}
}
//Displays the HTML content for a specific faction //Displays the HTML content for a specific faction
displayFactionContent = function(factionName) { function displayFactionContent(factionName) {
var faction = Factions[factionName]; var faction = Factions[factionName];
document.getElementById("faction-name").innerHTML = factionName; document.getElementById("faction-name").innerHTML = factionName;
document.getElementById("faction-info").innerHTML = "<i>" + faction.info + "</i>"; document.getElementById("faction-info").innerHTML = "<i>" + faction.info + "</i>";
@ -1077,7 +763,7 @@ displayFactionContent = function(factionName) {
} }
} }
displayFactionAugmentations = function(factionName) { function displayFactionAugmentations(factionName) {
document.getElementById("faction-augmentations-page-desc").innerHTML = "Lists all augmentations that are available to purchase from " + factionName; document.getElementById("faction-augmentations-page-desc").innerHTML = "Lists all augmentations that are available to purchase from " + factionName;
var faction = Factions[factionName]; var faction = Factions[factionName];
@ -1150,87 +836,12 @@ displayFactionAugmentations = function(factionName) {
} }
} }
purchaseAugmentationBoxCreate = function(aug, fac) { function purchaseAugmentationBoxCreate(aug, fac) {
var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton(); var yesBtn = yesNoBoxGetYesButton(), noBtn = yesNoBoxGetNoButton();
yesBtn.innerHTML = "Purchase"; yesBtn.innerHTML = "Purchase";
noBtn.innerHTML = "Cancel"; noBtn.innerHTML = "Cancel";
yesBtn.addEventListener("click", function() { yesBtn.addEventListener("click", function() {
//TODO Requirements for specific augmentations (e.g Embedded Netburner Module b4 its upgrades) purchaseAugmentation(aug, fac);
if (aug.name == AugmentationNames.Targeting2 &&
Augmentations[AugmentationNames.Targeting1].owned == false) {
dialogBoxCreate("You must first install Augmented Targeting I before you can upgrade it to Augmented Targeting II");
} else if (aug.name == AugmentationNames.Targeting3 &&
Augmentations[AugmentationNames.Targeting2].owned == false) {
dialogBoxCreate("You must first install Augmented Targeting II before you can upgrade it to Augmented Targeting III");
} else if (aug.name == AugmentationNames.CombatRib2 &&
Augmentations[AugmentationNames.CombatRib1].owned == false) {
dialogBoxCreate("You must first install Combat Rib I before you can upgrade it to Combat Rib II");
} else if (aug.name == AugmentationNames.CombatRib3 &&
Augmentations[AugmentationNames.CombatRib2].owned == false) {
dialogBoxCreate("You must first install Combat Rib II before you can upgrade it to Combat Rib III");
} else if (aug.name == AugmentationNames.GrapheneBionicSpine &&
Augmentations[AugmentationNames.BionicSpine].owned == false) {
dialogBoxCreate("You must first install a Bionic Spine before you can upgrade it to a Graphene Bionic Spine");
} else if (aug.name == AugmentationNames.GrapheneBionicLegs &&
Augmentations[AugmentationNames.BionicLegs].owned == false) {
dialogBoxCreate("You must first install Bionic Legs before you can upgrade it to Graphene Bionic Legs");
} else if (aug.name == AugmentationNames.ENMCoreV2 &&
Augmentations[AugmentationNames.ENMCore].owned == false) {
dialogBoxCreate("You must first install Embedded Netburner Module Core Implant before you can upgrade it to V2");
} else if (aug.name == AugmentationNames.ENMCoreV3 &&
Augmentations[AugmentationNames.ENMCoreV2].owned == false) {
dialogBoxCreate("You must first install Embedded Netburner Module Core V2 Upgrade before you can upgrade it to V3");
} else if ((aug.name == AugmentationNames.ENMCore ||
aug.name == AugmentationNames.ENMAnalyzeEngine ||
aug.name == AugmentationNames.ENMDMA) &&
Augmentations[AugmentationNames.ENM].owned == false) {
dialogBoxCreate("You must first install the Embedded Netburner Module before installing any upgrades to it");
} else if ((aug.name == AugmentationNames.PCDNIOptimizer ||
aug.name == AugmentationNames.PCDNINeuralNetwork) &&
Augmentations[AugmentationNames.PCDNI].owned == false) {
dialogBoxCreate("You must first install the Pc Direct-Neural Interface before installing this upgrade");
} else if (aug.name == AugmentationNames.GrapheneBrachiBlades &&
Augmentations[AugmentationNames.BrachiBlades].owned == false) {
dialogBoxCreate("You must first install the Brachi Blades augmentation before installing this upgrade");
} else if (aug.name == AugmentationNames.GrapheneBionicArms &&
Augmentations[AugmentationNames.BionicArms].owned == false) {
dialogBoxCreate("You must first install the Bionic Arms augmentation before installing this upgrade");
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
var queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
queuedAugmentation.level = getNextNeurofluxLevel();
}
Player.queuedAugmentations.push(queuedAugmentation);
Player.loseMoney((aug.baseCost * fac.augmentationPriceMult));
dialogBoxCreate("You purchased " + aug.name + ". It's enhancements will not take " +
"effect until they are installed. To install your augmentations, go to the " +
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
"augmentations will now be more expensive.");
//If you just purchased Neuroflux Governor, recalculate the cost
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
var nextLevel = getNextNeurofluxLevel();
--nextLevel;
var mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
aug.setRequirements(500 * mult, 750000 * mult);
for (var i = 0; i < Player.queuedAugmentations.length-1; ++i) {
aug.baseCost *= CONSTANTS.MultipleAugMultiplier;
}
}
for (var name in Augmentations) {
if (Augmentations.hasOwnProperty(name)) {
Augmentations[name].baseCost *= CONSTANTS.MultipleAugMultiplier;
}
}
displayFactionAugmentations(fac.name);
} else {
dialogBoxCreate("You don't have enough money to purchase this Augmentation!");
}
yesNoBoxClose();
}); });
noBtn.addEventListener("click", function() { noBtn.addEventListener("click", function() {
yesNoBoxClose(); yesNoBoxClose();
@ -1242,6 +853,105 @@ purchaseAugmentationBoxCreate = function(aug, fac) {
formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?"); formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?");
} }
function purchaseAugmentation(aug, fac, sing=false) {
if (aug.name == AugmentationNames.Targeting2 &&
Augmentations[AugmentationNames.Targeting1].owned == false) {
var txt = "You must first install Augmented Targeting I before you can upgrade it to Augmented Targeting II";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.Targeting3 &&
Augmentations[AugmentationNames.Targeting2].owned == false) {
var txt = "You must first install Augmented Targeting II before you can upgrade it to Augmented Targeting III";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.CombatRib2 &&
Augmentations[AugmentationNames.CombatRib1].owned == false) {
var txt = "You must first install Combat Rib I before you can upgrade it to Combat Rib II";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.CombatRib3 &&
Augmentations[AugmentationNames.CombatRib2].owned == false) {
var txt = "You must first install Combat Rib II before you can upgrade it to Combat Rib III";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBionicSpine &&
Augmentations[AugmentationNames.BionicSpine].owned == false) {
var txt = "You must first install a Bionic Spine before you can upgrade it to a Graphene Bionic Spine";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBionicLegs &&
Augmentations[AugmentationNames.BionicLegs].owned == false) {
var txt = "You must first install Bionic Legs before you can upgrade it to Graphene Bionic Legs";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.ENMCoreV2 &&
Augmentations[AugmentationNames.ENMCore].owned == false) {
var txt = "You must first install Embedded Netburner Module Core Implant before you can upgrade it to V2";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.ENMCoreV3 &&
Augmentations[AugmentationNames.ENMCoreV2].owned == false) {
var txt = "You must first install Embedded Netburner Module Core V2 Upgrade before you can upgrade it to V3";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if ((aug.name == AugmentationNames.ENMCore ||
aug.name == AugmentationNames.ENMAnalyzeEngine ||
aug.name == AugmentationNames.ENMDMA) &&
Augmentations[AugmentationNames.ENM].owned == false) {
var txt = "You must first install the Embedded Netburner Module before installing any upgrades to it";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if ((aug.name == AugmentationNames.PCDNIOptimizer ||
aug.name == AugmentationNames.PCDNINeuralNetwork) &&
Augmentations[AugmentationNames.PCDNI].owned == false) {
var txt = "You must first install the Pc Direct-Neural Interface before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBrachiBlades &&
Augmentations[AugmentationNames.BrachiBlades].owned == false) {
var txt = "You must first install the Brachi Blades augmentation before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (aug.name == AugmentationNames.GrapheneBionicArms &&
Augmentations[AugmentationNames.BionicArms].owned == false) {
var txt = "You must first install the Bionic Arms augmentation before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
var queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
queuedAugmentation.level = getNextNeurofluxLevel();
}
Player.queuedAugmentations.push(queuedAugmentation);
Player.loseMoney((aug.baseCost * fac.augmentationPriceMult));
//If you just purchased Neuroflux Governor, recalculate the cost
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
var nextLevel = getNextNeurofluxLevel();
--nextLevel;
var mult = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel);
aug.setRequirements(500 * mult, 750000 * mult);
for (var i = 0; i < Player.queuedAugmentations.length-1; ++i) {
aug.baseCost *= CONSTANTS.MultipleAugMultiplier;
}
}
for (var name in Augmentations) {
if (Augmentations.hasOwnProperty(name)) {
Augmentations[name].baseCost *= CONSTANTS.MultipleAugMultiplier;
}
}
if (sing) {
return "You purchased " + aug.name;
} else {
dialogBoxCreate("You purchased " + aug.name + ". It's enhancements will not take " +
"effect until they are installed. To install your augmentations, go to the " +
"'Augmentations' tab on the left-hand navigation menu. Purchasing additional " +
"augmentations will now be more expensive.");
}
displayFactionAugmentations(fac.name);
} else {
if (sing) {
return "You don't have enough money to purchase " + aug.name;
} else {
dialogBoxCreate("You don't have enough money to purchase this Augmentation!");
}
}
yesNoBoxClose();
}
function getNextNeurofluxLevel() { function getNextNeurofluxLevel() {
var aug = Augmentations[AugmentationNames.NeuroFluxGovernor]; var aug = Augmentations[AugmentationNames.NeuroFluxGovernor];
if (aug == null) { if (aug == null) {
@ -1277,3 +987,7 @@ function processPassiveFactionRepGain(numCycles) {
} }
} }
} }
export {getNextNeurofluxLevel, Factions, initFactions, inviteToFaction,
joinFaction, displayFactionContent, processPassiveFactionRepGain,
loadFactions, Faction, purchaseAugmentation, factionExists};

@ -1,6 +1,6 @@
//Contains the "information" property for all the Factions, which is just a description //Contains the "information" property for all the Factions, which is just a description
//of each faction //of each faction
FactionInfo = { let FactionInfo = {
//Endgame //Endgame
IlluminatiInfo: "Humanity never changes. No matter how civilized society becomes, it will eventually fall back " + IlluminatiInfo: "Humanity never changes. No matter how civilized society becomes, it will eventually fall back " +
"into chaos. And from this chaos, we are the Invisible hand that guides them to order. ", "into chaos. And from this chaos, we are the Invisible hand that guides them to order. ",
@ -128,3 +128,5 @@ FactionInfo = {
"We serve only to protect society, to protect humanity, to protect the world from its imminent collapse.", "We serve only to protect society, to protect humanity, to protect the world from its imminent collapse.",
} }
export {FactionInfo};

@ -1,3 +1,20 @@
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {Faction, Factions} from "./Faction.js";
import {Locations} from "./Location.js";
import {Player} from "./Player.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
import {getRandomInt} from "../utils/HelperFunctions.js";
import numeral from "../utils/numeral.min.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton,
yesNoTxtInpBoxGetInput, yesNoBoxClose,
yesNoTxtInpBoxClose, yesNoBoxOpen} from "../utils/YesNoBox.js";
/* Gang.js */ /* Gang.js */
//Switch between territory and management screen with 1 and 2 //Switch between territory and management screen with 1 and 2
$(document).keydown(function(event) { $(document).keydown(function(event) {
@ -29,11 +46,11 @@ $(document).mousedown(function(event) {
} }
}); });
GangNames = ["Slum Snakes", "Tetrads", "The Syndicate", "The Dark Army", "Speakers for the Dead", let GangNames = ["Slum Snakes", "Tetrads", "The Syndicate", "The Dark Army", "Speakers for the Dead",
"NiteSec", "The Black Hand"]; "NiteSec", "The Black Hand"];
GangLocations = [Locations.Aevum, Locations.Chongqing, Locations.Sector12, Locations.NewTokyo, let GangLocations = [Locations.Aevum, Locations.Chongqing, Locations.Sector12, Locations.NewTokyo,
Locations.Ishima, Locations.Volhaven]; Locations.Ishima, Locations.Volhaven];
AllGangs = { let AllGangs = {
"Slum Snakes" : { "Slum Snakes" : {
power: 1, power: 1,
territory: 1/7, territory: 1/7,
@ -64,8 +81,12 @@ AllGangs = {
}, },
} }
function loadAllGangs(saveString) {
AllGangs = JSON.parse(saveString, Reviver);
}
//Power is an estimate of a gang's ability to gain/defend territory //Power is an estimate of a gang's ability to gain/defend territory
gangStoredPowerCycles = 0; let gangStoredPowerCycles = 0;
function processAllGangPowerGains(numCycles=1) { function processAllGangPowerGains(numCycles=1) {
if (!Player.inGang()) {return;} if (!Player.inGang()) {return;}
gangStoredPowerCycles += numCycles; gangStoredPowerCycles += numCycles;
@ -85,7 +106,7 @@ function processAllGangPowerGains(numCycles=1) {
gangStoredPowerCycles -= 150; gangStoredPowerCycles -= 150;
} }
gangStoredTerritoryCycles = 0; let gangStoredTerritoryCycles = 0;
function processAllGangTerritory(numCycles=1) { function processAllGangTerritory(numCycles=1) {
if (!Player.inGang()) {return;} if (!Player.inGang()) {return;}
gangStoredTerritoryCycles += numCycles; gangStoredTerritoryCycles += numCycles;
@ -118,12 +139,6 @@ function processAllGangTerritory(numCycles=1) {
gangStoredTerritoryCycles -= CONSTANTS.GangTerritoryUpdateTimer; gangStoredTerritoryCycles -= CONSTANTS.GangTerritoryUpdateTimer;
} }
//Returns true if Player is in a gang and false otherwise
PlayerObject.prototype.inGang = function() {
if (this.gang == null || this.gang == undefined) {return false;}
return (this.gang instanceof Gang);
}
/* faction - Name of corresponding faction /* faction - Name of corresponding faction
hacking - Boolean indicating whether its a hacking gang or not hacking - Boolean indicating whether its a hacking gang or not
*/ */
@ -230,7 +245,6 @@ Gang.fromJSON = function(value) {
Reviver.constructors.Gang = Gang; Reviver.constructors.Gang = Gang;
/*** Gang Member object ***/ /*** Gang Member object ***/
function GangMember(name) { function GangMember(name) {
this.name = name; this.name = name;
@ -405,7 +419,7 @@ GangMemberTask.fromJSON = function(value) {
Reviver.constructors.GangMemberTask = GangMemberTask; Reviver.constructors.GangMemberTask = GangMemberTask;
//TODO Human trafficking and an equivalent hacking crime //TODO Human trafficking and an equivalent hacking crime
GangMemberTasks = { let GangMemberTasks = {
"Ransomware" : new GangMemberTask( "Ransomware" : new GangMemberTask(
"Ransomware", "Ransomware",
"Assign this gang member to create and distribute ransomware<br><br>" + "Assign this gang member to create and distribute ransomware<br><br>" +
@ -674,7 +688,7 @@ GangMemberUpgrade.fromJSON = function(value) {
Reviver.constructors.GangMemberUpgrade = GangMemberUpgrade; Reviver.constructors.GangMemberUpgrade = GangMemberUpgrade;
GangMemberUpgrades = { let GangMemberUpgrades = {
"Baseball Bat" : new GangMemberUpgrade("Baseball Bat", "Baseball Bat" : new GangMemberUpgrade("Baseball Bat",
"Increases strength and defense by 10%", 1000000, "w"), "Increases strength and defense by 10%", 1000000, "w"),
"Katana" : new GangMemberUpgrade("Katana", "Katana" : new GangMemberUpgrade("Katana",
@ -716,7 +730,7 @@ GangMemberUpgrades = {
} }
//Create a pop-up box that lets player purchase upgrades //Create a pop-up box that lets player purchase upgrades
var gangMemberUpgradeBoxOpened = false; let gangMemberUpgradeBoxOpened = false;
function createGangMemberUpgradeBox(memberObj) { function createGangMemberUpgradeBox(memberObj) {
console.log("Creating gang member upgrade box for " + memberObj.name); console.log("Creating gang member upgrade box for " + memberObj.name);
var container = document.getElementById("gang-purchase-upgrade-container"); var container = document.getElementById("gang-purchase-upgrade-container");
@ -838,7 +852,7 @@ function createGangMemberUpgradeButtons(memberObj, upgNames, memberUpgrade, cont
} }
} }
var gangContentCreated = false; let gangContentCreated = false;
function displayGangContent() { function displayGangContent() {
if (!gangContentCreated) { if (!gangContentCreated) {
gangContentCreated = true; gangContentCreated = true;
@ -1084,7 +1098,7 @@ function setGangMemberClickHandlers() {
console.log("ERROR: Could not find Active Scripts server panels"); console.log("ERROR: Could not find Active Scripts server panels");
return; return;
} }
for (i = 0; i < gangMemberHdrs.length; ++i) { for (let i = 0; i < gangMemberHdrs.length; ++i) {
gangMemberHdrs[i].onclick = function() { gangMemberHdrs[i].onclick = function() {
this.classList.toggle("active"); this.classList.toggle("active");
@ -1167,7 +1181,7 @@ function createGangMemberDisplayElement(memberObj) {
if (memberObj.task instanceof GangMemberTask) { if (memberObj.task instanceof GangMemberTask) {
var taskName = memberObj.task.name; var taskName = memberObj.task.name;
var taskIndex = 0; var taskIndex = 0;
for (i = 0; i < tasks.length; ++i) { for (let i = 0; i < tasks.length; ++i) {
if (taskName == tasks[i]) { if (taskName == tasks[i]) {
taskIndex = i; taskIndex = i;
break; break;
@ -1246,3 +1260,5 @@ function setGangMemberTaskDescription(memberObj, taskName) {
taskDesc.innerHTML = desc; taskDesc.innerHTML = desc;
} }
} }
export {Gang, displayGangContent, updateGangContent, loadAllGangs, AllGangs};

@ -1,3 +1,15 @@
import {BitNodeMultipliers} from "./BitNode.js";
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {iTutorialSteps, iTutorialNextStep,
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
import {Player} from "./Player.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
/* HacknetNode.js */ /* HacknetNode.js */
function hacknetNodesInit() { function hacknetNodesInit() {
var mult1x = document.getElementById("hacknet-nodes-1x-multiplier"); var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
@ -50,7 +62,9 @@ HacknetNode.prototype.updateMoneyGainRate = function() {
this.moneyGainRatePerSecond = (this.level * gainPerLevel) * this.moneyGainRatePerSecond = (this.level * gainPerLevel) *
Math.pow(1.035, this.ram-1) * Math.pow(1.035, this.ram-1) *
((this.cores + 5) / 6) * Player.hacknet_node_money_mult; ((this.cores + 5) / 6) *
Player.hacknet_node_money_mult *
BitNodeMultipliers.HacknetNodeMoney;
if (isNaN(this.moneyGainRatePerSecond)) { if (isNaN(this.moneyGainRatePerSecond)) {
this.moneyGainRatePerSecond = 0; this.moneyGainRatePerSecond = 0;
dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer"); dialogBoxCreate("Error in calculating Hacknet Node production. Please report to game developer");
@ -165,7 +179,7 @@ HacknetNode.fromJSON = function(value) {
Reviver.constructors.HacknetNode = HacknetNode; Reviver.constructors.HacknetNode = HacknetNode;
purchaseHacknet = function() { function purchaseHacknet() {
/* INTERACTIVE TUTORIAL */ /* INTERACTIVE TUTORIAL */
if (iTutorialIsRunning) { if (iTutorialIsRunning) {
if (currITutorialStep == iTutorialSteps.HacknetNodesIntroduction) { if (currITutorialStep == iTutorialSteps.HacknetNodesIntroduction) {
@ -199,7 +213,7 @@ purchaseHacknet = function() {
} }
//Calculates the total production from all HacknetNodes //Calculates the total production from all HacknetNodes
updateTotalHacknetProduction = function() { function updateTotalHacknetProduction() {
var total = 0; var total = 0;
for (var i = 0; i < Player.hacknetNodes.length; ++i) { for (var i = 0; i < Player.hacknetNodes.length; ++i) {
total += Player.hacknetNodes[i].moneyGainRatePerSecond; total += Player.hacknetNodes[i].moneyGainRatePerSecond;
@ -207,7 +221,7 @@ updateTotalHacknetProduction = function() {
Player.totalHacknetNodeProduction = total; Player.totalHacknetNodeProduction = total;
} }
getCostOfNextHacknetNode = function() { function getCostOfNextHacknetNode() {
//Cost increases exponentially based on how many you own //Cost increases exponentially based on how many you own
var numOwned = Player.hacknetNodes.length; var numOwned = Player.hacknetNodes.length;
var mult = CONSTANTS.HacknetNodePurchaseNextMult; var mult = CONSTANTS.HacknetNodePurchaseNextMult;
@ -215,7 +229,7 @@ getCostOfNextHacknetNode = function() {
} }
var hacknetNodePurchaseMultiplier = 1; var hacknetNodePurchaseMultiplier = 1;
updateHacknetNodesMultiplierButtons = function() { function updateHacknetNodesMultiplierButtons() {
var mult1x = document.getElementById("hacknet-nodes-1x-multiplier"); var mult1x = document.getElementById("hacknet-nodes-1x-multiplier");
var mult5x = document.getElementById("hacknet-nodes-5x-multiplier"); var mult5x = document.getElementById("hacknet-nodes-5x-multiplier");
var mult10x = document.getElementById("hacknet-nodes-10x-multiplier"); var mult10x = document.getElementById("hacknet-nodes-10x-multiplier");
@ -242,7 +256,7 @@ updateHacknetNodesMultiplierButtons = function() {
//Calculate the maximum number of times the Player can afford to upgrade //Calculate the maximum number of times the Player can afford to upgrade
//a Hacknet Node's level" //a Hacknet Node's level"
getMaxNumberLevelUpgrades = function(nodeObj) { function getMaxNumberLevelUpgrades(nodeObj) {
if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;} if (Player.money.lt(nodeObj.calculateLevelUpgradeCost(1))) {return 0;}
var min = 1; var min = 1;
var max = CONSTANTS.HacknetNodeMaxLevel-1; var max = CONSTANTS.HacknetNodeMaxLevel-1;
@ -268,7 +282,7 @@ getMaxNumberLevelUpgrades = function(nodeObj) {
} }
//Creates Hacknet Node DOM elements when the page is opened //Creates Hacknet Node DOM elements when the page is opened
displayHacknetNodesContent = function() { function displayHacknetNodesContent() {
//Update Hacknet Nodes button //Update Hacknet Nodes button
var newPurchaseButton = clearEventListeners("hacknet-nodes-purchase-button"); var newPurchaseButton = clearEventListeners("hacknet-nodes-purchase-button");
@ -294,7 +308,7 @@ displayHacknetNodesContent = function() {
} }
//Update information on all Hacknet Node DOM elements //Update information on all Hacknet Node DOM elements
updateHacknetNodesContent = function() { function updateHacknetNodesContent() {
//Set purchase button to inactive if not enough money, and update its price display //Set purchase button to inactive if not enough money, and update its price display
var cost = getCostOfNextHacknetNode(); var cost = getCostOfNextHacknetNode();
var purchaseButton = document.getElementById("hacknet-nodes-purchase-button"); var purchaseButton = document.getElementById("hacknet-nodes-purchase-button");
@ -317,7 +331,7 @@ updateHacknetNodesContent = function() {
} }
//Creates a single Hacknet Node DOM element //Creates a single Hacknet Node DOM element
createHacknetNodeDomElement = function(nodeObj) { function createHacknetNodeDomElement(nodeObj) {
var nodeName = nodeObj.name; var nodeName = nodeObj.name;
var listItem = document.createElement("li"); var listItem = document.createElement("li");
@ -383,7 +397,7 @@ createHacknetNodeDomElement = function(nodeObj) {
} }
//Updates information on a single hacknet node DOM element //Updates information on a single hacknet node DOM element
updateHacknetNodeDomElement = function(nodeObj) { function updateHacknetNodeDomElement(nodeObj) {
var nodeName = nodeObj.name; var nodeName = nodeObj.name;
var txt = document.getElementById("hacknet-node-text-" + nodeName); var txt = document.getElementById("hacknet-node-text-" + nodeName);
if (txt == null) {throw new Error("Cannot find text element");} if (txt == null) {throw new Error("Cannot find text element");}
@ -453,7 +467,7 @@ updateHacknetNodeDomElement = function(nodeObj) {
} }
} }
processAllHacknetNodeEarnings = function(numCycles) { function processAllHacknetNodeEarnings(numCycles) {
var total = 0; var total = 0;
for (var i = 0; i < Player.hacknetNodes.length; ++i) { for (var i = 0; i < Player.hacknetNodes.length; ++i) {
total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]); total += processSingleHacknetNodeEarnings(numCycles, Player.hacknetNodes[i]);
@ -461,7 +475,7 @@ processAllHacknetNodeEarnings = function(numCycles) {
return total; return total;
} }
processSingleHacknetNodeEarnings = function(numCycles, nodeObj) { function processSingleHacknetNodeEarnings(numCycles, nodeObj) {
var cyclesPerSecond = 1000 / Engine._idleSpeed; var cyclesPerSecond = 1000 / Engine._idleSpeed;
var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond; var earningPerCycle = nodeObj.moneyGainRatePerSecond / cyclesPerSecond;
if (isNaN(earningPerCycle)) {throw new Error("Calculated Earnings is not a number");} if (isNaN(earningPerCycle)) {throw new Error("Calculated Earnings is not a number");}
@ -472,7 +486,7 @@ processSingleHacknetNodeEarnings = function(numCycles, nodeObj) {
return totalEarnings; return totalEarnings;
} }
getHacknetNode = function(name) { function getHacknetNode(name) {
for (var i = 0; i < Player.hacknetNodes.length; ++i) { for (var i = 0; i < Player.hacknetNodes.length; ++i) {
if (Player.hacknetNodes[i].name == name) { if (Player.hacknetNodes[i].name == name) {
return Player.hacknetNodes[i]; return Player.hacknetNodes[i];
@ -480,3 +494,8 @@ getHacknetNode = function(name) {
} }
return null; return null;
} }
export {hacknetNodesInit, HacknetNode, purchaseHacknet, updateTotalHacknetProduction,
getCostOfNextHacknetNode, updateHacknetNodesMultiplierButtons, getMaxNumberLevelUpgrades,
displayHacknetNodesContent, updateHacknetNodesContent, processAllHacknetNodeEarnings,
getHacknetNode};

@ -1,5 +1,5 @@
/* HelpText.js */ /* HelpText.js */
TerminalHelpText = let TerminalHelpText =
"Type 'help name' to learn more about the command 'name'<br><br>" + "Type 'help name' to learn more about the command 'name'<br><br>" +
'alias [-g] [name="value"] Create or display Terminal aliases<br>' + 'alias [-g] [name="value"] Create or display Terminal aliases<br>' +
"analyze Get information about the current machine <br>" + "analyze Get information about the current machine <br>" +
@ -31,7 +31,7 @@ TerminalHelpText =
"top Displays all running scripts and their RAM usage<br>" + "top Displays all running scripts and their RAM usage<br>" +
'unalias "[alias name]" Deletes the specified alias<br>'; 'unalias "[alias name]" Deletes the specified alias<br>';
HelpTexts = { let HelpTexts = {
alias: 'alias [-g] [name="value"] <br>' + alias: 'alias [-g] [name="value"] <br>' +
"Create or display aliases. An alias enables a replacement of a word with another string. " + "Create or display aliases. An alias enables a replacement of a word with another string. " +
"It can be used to abbreviate a commonly used command, or commonly used parts of a command. The NAME " + "It can be used to abbreviate a commonly used command, or commonly used parts of a command. The NAME " +
@ -193,3 +193,5 @@ HelpTexts = {
"It is not necessary to differentiate between global and non-global aliases when using 'unalias'", "It is not necessary to differentiate between global and non-global aliases when using 'unalias'",
} }
export {TerminalHelpText, HelpTexts};

@ -1,3 +1,11 @@
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {Player} from "./Player.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners, getRandomInt} from "../utils/HelperFunctions.js";
import {infiltrationBoxCreate} from "../utils/InfiltrationBox.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
/* Infiltration.js /* Infiltration.js
* *
* Kill * Kill
@ -16,7 +24,7 @@
* Escape * Escape
*/ */
InfiltrationScenarios = { let InfiltrationScenarios = {
Guards: "You see an armed security guard patrolling the area.", Guards: "You see an armed security guard patrolling the area.",
TechOnly: "The area is equipped with a state-of-the-art security system: cameras, laser tripwires, and sentry turrets.", TechOnly: "The area is equipped with a state-of-the-art security system: cameras, laser tripwires, and sentry turrets.",
TechOrLockedDoor: "The area is equipped with a state-of-the-art security system. There is a locked door on the side of the " + TechOrLockedDoor: "The area is equipped with a state-of-the-art security system. There is a locked door on the side of the " +
@ -71,8 +79,6 @@ InfiltrationInstance.prototype.gainCharismaExp = function(amt) {
this.chaExpGained += amt; this.chaExpGained += amt;
} }
function beginInfiltration(companyName, startLevel, val, maxClearance, diff) { function beginInfiltration(companyName, startLevel, val, maxClearance, diff) {
var inst = new InfiltrationInstance(companyName, startLevel, val, maxClearance, diff); var inst = new InfiltrationInstance(companyName, startLevel, val, maxClearance, diff);
clearInfiltrationStatusText(); clearInfiltrationStatusText();
@ -796,3 +802,5 @@ function getInfiltrationEscapeChance(inst) {
(2 * Player.agility + (2 * Player.agility +
Player.dexterity) / lvl); Player.dexterity) / lvl);
} }
export {beginInfiltration};

@ -1,5 +1,9 @@
import {Engine} from "./engine.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
/* InteractiveTutorial.js */ /* InteractiveTutorial.js */
iTutorialSteps = { let iTutorialSteps = {
Start: "Start", Start: "Start",
GoToCharacterPage: "Click on the Character page menu link", GoToCharacterPage: "Click on the Character page menu link",
CharacterPage: "Introduction to Character page", CharacterPage: "Introduction to Character page",
@ -652,3 +656,6 @@ function iTutorialSetText(txt) {
textBox.innerHTML = txt; textBox.innerHTML = txt;
textBox.parentElement.scrollTop = 0; // this resets scroll position textBox.parentElement.scrollTop = 0; // this resets scroll position
} }
export {iTutorialSteps, iTutorialEnd, iTutorialStart, iTutorialNextStep, currITutorialStep,
iTutorialIsRunning};

@ -1,3 +1,5 @@
import {dialogBoxCreate} from "../utils/DialogBox.js";
/* Literature.js /* Literature.js
* Lore / world building literature that can be found on servers * Lore / world building literature that can be found on servers
*/ */
@ -15,7 +17,7 @@ function showLiterature(fn) {
dialogBoxCreate(txt); dialogBoxCreate(txt);
} }
Literatures = {} let Literatures = {}
function initLiterature() { function initLiterature() {
var title, fn, txt; var title, fn, txt;
@ -125,7 +127,7 @@ function initLiterature() {
"Soon the cries rose everywhere, with revolt and riot<br>Until one day, finally, all was quiet<br>" + "Soon the cries rose everywhere, with revolt and riot<br>Until one day, finally, all was quiet<br>" +
"From the ashes rose a new order, corporatocracy was its name<br>" + "From the ashes rose a new order, corporatocracy was its name<br>" +
"Rome, Mongol, Byzantine, all of history is just the same<br>" + "Rome, Mongol, Byzantine, all of history is just the same<br>" +
"For man will never change in a fundamental way<br>" "For man will never change in a fundamental way<br>" +
"And now democracy is dead, in the USA"; "And now democracy is dead, in the USA";
Literatures[fn] = new Literature(title, fn, txt); Literatures[fn] = new Literature(title, fn, txt);
@ -265,7 +267,7 @@ function initLiterature() {
title = "The Hidden World"; title = "The Hidden World";
fn = "the-hidden-world.lit"; fn = "the-hidden-world.lit";
txt = "WAKE UP SHEEPLE<br><br>" txt = "WAKE UP SHEEPLE<br><br>" +
"THE GOVERNMENT DOES NOT EXIST. CORPORATIONS DO NOT RUN SOCIETY<br><br>" + "THE GOVERNMENT DOES NOT EXIST. CORPORATIONS DO NOT RUN SOCIETY<br><br>" +
"THE ILLUMINATI ARE THE SECRET RULERS OF THE WORLD!<br><br>" + "THE ILLUMINATI ARE THE SECRET RULERS OF THE WORLD!<br><br>" +
"Yes, the Illuminati of legends. The ancient secret society that controls the entire " + "Yes, the Illuminati of legends. The ancient secret society that controls the entire " +
@ -317,3 +319,5 @@ function initLiterature() {
txt = "" txt = ""
Literatures[fn] = new Literature(title, fn, txt); Literatures[fn] = new Literature(title, fn, txt);
} }
export {Literatures, initLiterature, showLiterature};

@ -1,7 +1,36 @@
import {CompanyPositions, initCompanies,
Companies, getJobRequirementText} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
import {commitShopliftCrime, commitRobStoreCrime, commitMugCrime,
commitLarcenyCrime, commitDealDrugsCrime, commitTraffickArmsCrime,
commitHomicideCrime, commitGrandTheftAutoCrime, commitKidnapCrime,
commitAssassinationCrime, commitHeistCrime, determineCrimeSuccess,
determineCrimeChanceShoplift, determineCrimeChanceRobStore,
determineCrimeChanceMug, determineCrimeChanceLarceny,
determineCrimeChanceDealDrugs, determineCrimeChanceTraffickArms,
determineCrimeChanceHomicide, determineCrimeChanceGrandTheftAuto,
determineCrimeChanceKidnap, determineCrimeChanceAssassination,
determineCrimeChanceHeist} from "./Crimes.js";
import {Engine} from "./engine.js";
import {beginInfiltration} from "./Infiltration.js";
import {Player} from "./Player.js";
import {Server, AllServers, AddToAllServers} from "./Server.js";
import {purchaseServer,
purchaseRamForHomeComputer} from "./ServerPurchases.js";
import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {createRandomIp} from "../utils/IPAddress.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
import {yesNoBoxCreate, yesNoTxtInpBoxCreate,
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton,
yesNoTxtInpBoxGetInput, yesNoBoxClose,
yesNoTxtInpBoxClose} from "../utils/YesNoBox.js";
/* Display Location Content when visiting somewhere in the World*/ /* Display Location Content when visiting somewhere in the World*/
let Locations = {
Locations = {
//Cities //Cities
Aevum: "Aevum", Aevum: "Aevum",
//AevumDesc: "" //AevumDesc: ""
@ -86,7 +115,7 @@ Locations = {
WorldStockExchange: "World Stock Exchange", WorldStockExchange: "World Stock Exchange",
} }
displayLocationContent = function() { function displayLocationContent() {
if (Engine.debug) { if (Engine.debug) {
console.log("displayLocationContent() called with location " + Player.location) console.log("displayLocationContent() called with location " + Player.location)
} }
@ -1058,458 +1087,457 @@ displayLocationContent = function() {
} }
} }
initLocationButtons = function() { function initLocationButtons() {
//Buttons to travel to different locations in World //Buttons to travel to different locations in World
aevumTravelAgency = document.getElementById("aevum-travelagency"); let aevumTravelAgency = document.getElementById("aevum-travelagency");
aevumTravelAgency.addEventListener("click", function() { aevumTravelAgency.addEventListener("click", function() {
Player.location = Locations.AevumTravelAgency; Player.location = Locations.AevumTravelAgency;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumHospital = document.getElementById("aevum-hospital"); let aevumHospital = document.getElementById("aevum-hospital");
aevumHospital.addEventListener("click", function() { aevumHospital.addEventListener("click", function() {
Player.location = Locations.Hospital; Player.location = Locations.Hospital;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumSummitUniversity = document.getElementById("aevum-summituniversity"); let aevumSummitUniversity = document.getElementById("aevum-summituniversity");
aevumSummitUniversity.addEventListener("click", function() { aevumSummitUniversity.addEventListener("click", function() {
Player.location = Locations.AevumSummitUniversity; Player.location = Locations.AevumSummitUniversity;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumECorp = document.getElementById("aevum-ecorp"); let aevumECorp = document.getElementById("aevum-ecorp");
aevumECorp.addEventListener("click", function() { aevumECorp.addEventListener("click", function() {
Player.location = Locations.AevumECorp; Player.location = Locations.AevumECorp;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumBachmanAndAssociates = document.getElementById("aevum-bachmanandassociates"); let aevumBachmanAndAssociates = document.getElementById("aevum-bachmanandassociates");
aevumBachmanAndAssociates.addEventListener("click", function() { aevumBachmanAndAssociates.addEventListener("click", function() {
Player.location = Locations.AevumBachmanAndAssociates; Player.location = Locations.AevumBachmanAndAssociates;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumClarkeIncorporated = document.getElementById("aevum-clarkeincorporated"); let aevumClarkeIncorporated = document.getElementById("aevum-clarkeincorporated");
aevumClarkeIncorporated.addEventListener("click", function() { aevumClarkeIncorporated.addEventListener("click", function() {
Player.location = Locations.AevumClarkeIncorporated; Player.location = Locations.AevumClarkeIncorporated;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumFulcrumTechnologies = document.getElementById("aevum-fulcrumtechnologies"); let aevumFulcrumTechnologies = document.getElementById("aevum-fulcrumtechnologies");
aevumFulcrumTechnologies.addEventListener("click", function() { aevumFulcrumTechnologies.addEventListener("click", function() {
Player.location = Locations.AevumFulcrumTechnologies; Player.location = Locations.AevumFulcrumTechnologies;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumAeroCorp = document.getElementById("aevum-aerocorp"); let aevumAeroCorp = document.getElementById("aevum-aerocorp");
aevumAeroCorp.addEventListener("click", function() { aevumAeroCorp.addEventListener("click", function() {
Player.location = Locations.AevumAeroCorp; Player.location = Locations.AevumAeroCorp;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumGalacticCybersystems = document.getElementById("aevum-galacticcybersystems"); let aevumGalacticCybersystems = document.getElementById("aevum-galacticcybersystems");
aevumGalacticCybersystems.addEventListener("click", function() { aevumGalacticCybersystems.addEventListener("click", function() {
Player.location = Locations.AevumGalacticCybersystems; Player.location = Locations.AevumGalacticCybersystems;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumWatchdogSecurity = document.getElementById("aevum-watchdogsecurity"); let aevumWatchdogSecurity = document.getElementById("aevum-watchdogsecurity");
aevumWatchdogSecurity.addEventListener("click", function() { aevumWatchdogSecurity.addEventListener("click", function() {
Player.location = Locations.AevumWatchdogSecurity; Player.location = Locations.AevumWatchdogSecurity;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumRhoConstruction = document.getElementById("aevum-rhoconstruction"); let aevumRhoConstruction = document.getElementById("aevum-rhoconstruction");
aevumRhoConstruction.addEventListener("click", function() { aevumRhoConstruction.addEventListener("click", function() {
Player.location = Locations.AevumRhoConstruction; Player.location = Locations.AevumRhoConstruction;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumPolice = document.getElementById("aevum-aevumpolice"); let aevumPolice = document.getElementById("aevum-aevumpolice");
aevumPolice.addEventListener("click", function() { aevumPolice.addEventListener("click", function() {
Player.location = Locations.AevumPolice; Player.location = Locations.AevumPolice;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumNetLinkTechnologies = document.getElementById("aevum-netlinktechnologies"); let aevumNetLinkTechnologies = document.getElementById("aevum-netlinktechnologies");
aevumNetLinkTechnologies.addEventListener("click", function() { aevumNetLinkTechnologies.addEventListener("click", function() {
Player.location = Locations.AevumNetLinkTechnologies; Player.location = Locations.AevumNetLinkTechnologies;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumCrushFitnessGym = document.getElementById("aevum-crushfitnessgym"); let aevumCrushFitnessGym = document.getElementById("aevum-crushfitnessgym");
aevumCrushFitnessGym.addEventListener("click", function() { aevumCrushFitnessGym.addEventListener("click", function() {
Player.location = Locations.AevumCrushFitnessGym; Player.location = Locations.AevumCrushFitnessGym;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumSnapFitnessGym = document.getElementById("aevum-snapfitnessgym"); let aevumSnapFitnessGym = document.getElementById("aevum-snapfitnessgym");
aevumSnapFitnessGym.addEventListener("click", function() { aevumSnapFitnessGym.addEventListener("click", function() {
Player.location = Locations.AevumSnapFitnessGym; Player.location = Locations.AevumSnapFitnessGym;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
aevumSlums = document.getElementById("aevum-slums"); let aevumSlums = document.getElementById("aevum-slums");
aevumSlums.addEventListener("click", function() { aevumSlums.addEventListener("click", function() {
Player.location = Locations.AevumSlums; Player.location = Locations.AevumSlums;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
chongqingTravelAgency = document.getElementById("chongqing-travelagency"); let chongqingTravelAgency = document.getElementById("chongqing-travelagency");
chongqingTravelAgency.addEventListener("click", function() { chongqingTravelAgency.addEventListener("click", function() {
Player.location = Locations.ChongqingTravelAgency; Player.location = Locations.ChongqingTravelAgency;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
chongqingHospital = document.getElementById("chongqing-hospital"); let chongqingHospital = document.getElementById("chongqing-hospital");
chongqingHospital.addEventListener("click", function() { chongqingHospital.addEventListener("click", function() {
Player.location = Locations.Hospital; Player.location = Locations.Hospital;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
chongqingKuaiGongInternational = document.getElementById("chongqing-kuaigonginternational"); let chongqingKuaiGongInternational = document.getElementById("chongqing-kuaigonginternational");
chongqingKuaiGongInternational.addEventListener("click", function() { chongqingKuaiGongInternational.addEventListener("click", function() {
Player.location = Locations.ChongqingKuaiGongInternational; Player.location = Locations.ChongqingKuaiGongInternational;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
chongqingSolarisSpaceSystems = document.getElementById("chongqing-solarisspacesystems"); let chongqingSolarisSpaceSystems = document.getElementById("chongqing-solarisspacesystems");
chongqingSolarisSpaceSystems.addEventListener("click", function() { chongqingSolarisSpaceSystems.addEventListener("click", function() {
Player.location = Locations.ChongqingSolarisSpaceSystems; Player.location = Locations.ChongqingSolarisSpaceSystems;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
chongqingSlums = document.getElementById("chongqing-slums"); let chongqingSlums = document.getElementById("chongqing-slums");
chongqingSlums.addEventListener("click", function() { chongqingSlums.addEventListener("click", function() {
Player.location = Locations.ChongqingSlums; Player.location = Locations.ChongqingSlums;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
let sector12TravelAgency = document.getElementById("sector12-travelagency");
sector12TravelAgency = document.getElementById("sector12-travelagency");
sector12TravelAgency.addEventListener("click", function() { sector12TravelAgency.addEventListener("click", function() {
Player.location = Locations.Sector12TravelAgency; Player.location = Locations.Sector12TravelAgency;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12Hospital = document.getElementById("sector12-hospital"); let sector12Hospital = document.getElementById("sector12-hospital");
sector12Hospital.addEventListener("click", function() { sector12Hospital.addEventListener("click", function() {
Player.location = Locations.Hospital; Player.location = Locations.Hospital;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12RothmanUniversity = document.getElementById("sector12-rothmanuniversity"); let sector12RothmanUniversity = document.getElementById("sector12-rothmanuniversity");
sector12RothmanUniversity.addEventListener("click", function() { sector12RothmanUniversity.addEventListener("click", function() {
Player.location = Locations.Sector12RothmanUniversity; Player.location = Locations.Sector12RothmanUniversity;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12MegaCorp = document.getElementById("sector12-megacorp"); let sector12MegaCorp = document.getElementById("sector12-megacorp");
sector12MegaCorp.addEventListener("click", function() { sector12MegaCorp.addEventListener("click", function() {
Player.location = Locations.Sector12MegaCorp; Player.location = Locations.Sector12MegaCorp;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12BladeIndustries = document.getElementById("sector12-bladeindustries"); let sector12BladeIndustries = document.getElementById("sector12-bladeindustries");
sector12BladeIndustries.addEventListener("click", function() { sector12BladeIndustries.addEventListener("click", function() {
Player.location = Locations.Sector12BladeIndustries; Player.location = Locations.Sector12BladeIndustries;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12FourSigma = document.getElementById("sector12-foursigma"); let sector12FourSigma = document.getElementById("sector12-foursigma");
sector12FourSigma.addEventListener("click", function() { sector12FourSigma.addEventListener("click", function() {
Player.location = Locations.Sector12FourSigma; Player.location = Locations.Sector12FourSigma;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12IcarusMicrosystems = document.getElementById("sector12-icarusmicrosystems"); let sector12IcarusMicrosystems = document.getElementById("sector12-icarusmicrosystems");
sector12IcarusMicrosystems.addEventListener("click", function() { sector12IcarusMicrosystems.addEventListener("click", function() {
Player.location = Locations.Sector12IcarusMicrosystems; Player.location = Locations.Sector12IcarusMicrosystems;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12UniversalEnergy = document.getElementById("sector12-universalenergy"); let sector12UniversalEnergy = document.getElementById("sector12-universalenergy");
sector12UniversalEnergy.addEventListener("click", function() { sector12UniversalEnergy.addEventListener("click", function() {
Player.location = Locations.Sector12UniversalEnergy; Player.location = Locations.Sector12UniversalEnergy;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12DeltaOne = document.getElementById("sector12-deltaone"); let sector12DeltaOne = document.getElementById("sector12-deltaone");
sector12DeltaOne.addEventListener("click", function() { sector12DeltaOne.addEventListener("click", function() {
Player.location = Locations.Sector12DeltaOne; Player.location = Locations.Sector12DeltaOne;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12CIA = document.getElementById("sector12-cia"); let sector12CIA = document.getElementById("sector12-cia");
sector12CIA.addEventListener("click", function() { sector12CIA.addEventListener("click", function() {
Player.location = Locations.Sector12CIA; Player.location = Locations.Sector12CIA;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12NSA = document.getElementById("sector12-nsa"); let sector12NSA = document.getElementById("sector12-nsa");
sector12NSA.addEventListener("click", function() { sector12NSA.addEventListener("click", function() {
Player.location = Locations.Sector12NSA; Player.location = Locations.Sector12NSA;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12AlphaEnterprises = document.getElementById("sector12-alphaenterprises"); let sector12AlphaEnterprises = document.getElementById("sector12-alphaenterprises");
sector12AlphaEnterprises.addEventListener("click", function() { sector12AlphaEnterprises.addEventListener("click", function() {
Player.location = Locations.Sector12AlphaEnterprises; Player.location = Locations.Sector12AlphaEnterprises;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12CarmichaelSecurity = document.getElementById("sector12-carmichaelsecurity"); let sector12CarmichaelSecurity = document.getElementById("sector12-carmichaelsecurity");
sector12CarmichaelSecurity.addEventListener("click", function() { sector12CarmichaelSecurity.addEventListener("click", function() {
Player.location = Locations.Sector12CarmichaelSecurity; Player.location = Locations.Sector12CarmichaelSecurity;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12FoodNStuff = document.getElementById("sector12-foodnstuff"); let sector12FoodNStuff = document.getElementById("sector12-foodnstuff");
sector12FoodNStuff.addEventListener("click", function() { sector12FoodNStuff.addEventListener("click", function() {
Player.location = Locations.Sector12FoodNStuff; Player.location = Locations.Sector12FoodNStuff;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12JoesGuns = document.getElementById("sector12-joesguns"); let sector12JoesGuns = document.getElementById("sector12-joesguns");
sector12JoesGuns.addEventListener("click", function() { sector12JoesGuns.addEventListener("click", function() {
Player.location = Locations.Sector12JoesGuns; Player.location = Locations.Sector12JoesGuns;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12IronGym = document.getElementById("sector12-irongym"); let sector12IronGym = document.getElementById("sector12-irongym");
sector12IronGym.addEventListener("click", function() { sector12IronGym.addEventListener("click", function() {
Player.location = Locations.Sector12IronGym; Player.location = Locations.Sector12IronGym;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12PowerhouseGym = document.getElementById("sector12-powerhousegym"); let sector12PowerhouseGym = document.getElementById("sector12-powerhousegym");
sector12PowerhouseGym.addEventListener("click", function() { sector12PowerhouseGym.addEventListener("click", function() {
Player.location = Locations.Sector12PowerhouseGym; Player.location = Locations.Sector12PowerhouseGym;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
sector12Slums = document.getElementById("sector12-slums"); let sector12Slums = document.getElementById("sector12-slums");
sector12Slums.addEventListener("click", function() { sector12Slums.addEventListener("click", function() {
Player.location = Locations.Sector12Slums; Player.location = Locations.Sector12Slums;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoTravelAgency = document.getElementById("newtokyo-travelagency"); let newTokyoTravelAgency = document.getElementById("newtokyo-travelagency");
newTokyoTravelAgency.addEventListener("click", function() { newTokyoTravelAgency.addEventListener("click", function() {
Player.location = Locations.NewTokyoTravelAgency; Player.location = Locations.NewTokyoTravelAgency;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoHospital = document.getElementById("newtokyo-hospital"); let newTokyoHospital = document.getElementById("newtokyo-hospital");
newTokyoHospital.addEventListener("click", function() { newTokyoHospital.addEventListener("click", function() {
Player.location = Locations.Hospital; Player.location = Locations.Hospital;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoDefComm = document.getElementById("newtokyo-defcomm"); let newTokyoDefComm = document.getElementById("newtokyo-defcomm");
newTokyoDefComm.addEventListener("click", function() { newTokyoDefComm.addEventListener("click", function() {
Player.location = Locations.NewTokyoDefComm; Player.location = Locations.NewTokyoDefComm;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoVitaLife = document.getElementById("newtokyo-vitalife"); let newTokyoVitaLife = document.getElementById("newtokyo-vitalife");
newTokyoVitaLife.addEventListener("click", function() { newTokyoVitaLife.addEventListener("click", function() {
Player.location = Locations.NewTokyoVitaLife; Player.location = Locations.NewTokyoVitaLife;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoGlobalPharmaceuticals = document.getElementById("newtokyo-globalpharmaceuticals"); let newTokyoGlobalPharmaceuticals = document.getElementById("newtokyo-globalpharmaceuticals");
newTokyoGlobalPharmaceuticals.addEventListener("click", function() { newTokyoGlobalPharmaceuticals.addEventListener("click", function() {
Player.location = Locations.NewTokyoGlobalPharmaceuticals; Player.location = Locations.NewTokyoGlobalPharmaceuticals;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoNoodleBar = document.getElementById("newtokyo-noodlebar"); let newTokyoNoodleBar = document.getElementById("newtokyo-noodlebar");
newTokyoNoodleBar.addEventListener("click", function() { newTokyoNoodleBar.addEventListener("click", function() {
Player.location = Locations.NewTokyoNoodleBar; Player.location = Locations.NewTokyoNoodleBar;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
newTokyoSlums = document.getElementById("newtokyo-slums"); let newTokyoSlums = document.getElementById("newtokyo-slums");
newTokyoSlums.addEventListener("click", function() { newTokyoSlums.addEventListener("click", function() {
Player.location = Locations.NewTokyoSlums; Player.location = Locations.NewTokyoSlums;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
ishimaTravelAgency = document.getElementById("ishima-travelagency"); let ishimaTravelAgency = document.getElementById("ishima-travelagency");
ishimaTravelAgency.addEventListener("click", function() { ishimaTravelAgency.addEventListener("click", function() {
Player.location = Locations.IshimaTravelAgency; Player.location = Locations.IshimaTravelAgency;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
ishimaHospital = document.getElementById("ishima-hospital"); let ishimaHospital = document.getElementById("ishima-hospital");
ishimaHospital.addEventListener("click", function() { ishimaHospital.addEventListener("click", function() {
Player.location = Locations.Hospital; Player.location = Locations.Hospital;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
ishimaStormTechnologies = document.getElementById("ishima-stormtechnologies"); let ishimaStormTechnologies = document.getElementById("ishima-stormtechnologies");
ishimaStormTechnologies.addEventListener("click", function() { ishimaStormTechnologies.addEventListener("click", function() {
Player.location = Locations.IshimaStormTechnologies; Player.location = Locations.IshimaStormTechnologies;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
ishimaNovaMedical = document.getElementById("ishima-novamedical"); let ishimaNovaMedical = document.getElementById("ishima-novamedical");
ishimaNovaMedical.addEventListener("click", function() { ishimaNovaMedical.addEventListener("click", function() {
Player.location = Locations.IshimaNovaMedical; Player.location = Locations.IshimaNovaMedical;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
ishimaOmegaSoftware = document.getElementById("ishima-omegasoftware"); let ishimaOmegaSoftware = document.getElementById("ishima-omegasoftware");
ishimaOmegaSoftware.addEventListener("click", function() { ishimaOmegaSoftware.addEventListener("click", function() {
Player.location = Locations.IshimaOmegaSoftware; Player.location = Locations.IshimaOmegaSoftware;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
ishimaSlums = document.getElementById("ishima-slums"); let ishimaSlums = document.getElementById("ishima-slums");
ishimaSlums.addEventListener("click", function() { ishimaSlums.addEventListener("click", function() {
Player.location = Locations.IshimaSlums; Player.location = Locations.IshimaSlums;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenTravelAgency = document.getElementById("volhaven-travelagency"); let volhavenTravelAgency = document.getElementById("volhaven-travelagency");
volhavenTravelAgency.addEventListener("click", function() { volhavenTravelAgency.addEventListener("click", function() {
Player.location = Locations.VolhavenTravelAgency; Player.location = Locations.VolhavenTravelAgency;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenHospital = document.getElementById("volhaven-hospital"); let volhavenHospital = document.getElementById("volhaven-hospital");
volhavenHospital.addEventListener("click", function() { volhavenHospital.addEventListener("click", function() {
Player.location = Locations.Hospital; Player.location = Locations.Hospital;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenZBInstituteOfTechnology = document.getElementById("volhaven-zbinstituteoftechnology"); let volhavenZBInstituteOfTechnology = document.getElementById("volhaven-zbinstituteoftechnology");
volhavenZBInstituteOfTechnology.addEventListener("click", function() { volhavenZBInstituteOfTechnology.addEventListener("click", function() {
Player.location = Locations.VolhavenZBInstituteOfTechnology; Player.location = Locations.VolhavenZBInstituteOfTechnology;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenOmniTekIncorporated = document.getElementById("volhaven-omnitekincorporated"); let volhavenOmniTekIncorporated = document.getElementById("volhaven-omnitekincorporated");
volhavenOmniTekIncorporated.addEventListener("click", function() { volhavenOmniTekIncorporated.addEventListener("click", function() {
Player.location = Locations.VolhavenOmniTekIncorporated; Player.location = Locations.VolhavenOmniTekIncorporated;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenNWO = document.getElementById("volhaven-nwo"); let volhavenNWO = document.getElementById("volhaven-nwo");
volhavenNWO.addEventListener("click", function() { volhavenNWO.addEventListener("click", function() {
Player.location = Locations.VolhavenNWO; Player.location = Locations.VolhavenNWO;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenHeliosLabs = document.getElementById("volhaven-helioslabs"); let volhavenHeliosLabs = document.getElementById("volhaven-helioslabs");
volhavenHeliosLabs.addEventListener("click", function() { volhavenHeliosLabs.addEventListener("click", function() {
Player.location = Locations.VolhavenHeliosLabs; Player.location = Locations.VolhavenHeliosLabs;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenOmniaCybersystems = document.getElementById("volhaven-omniacybersystems"); let volhavenOmniaCybersystems = document.getElementById("volhaven-omniacybersystems");
volhavenOmniaCybersystems.addEventListener("click", function() { volhavenOmniaCybersystems.addEventListener("click", function() {
Player.location = Locations.VolhavenOmniaCybersystems; Player.location = Locations.VolhavenOmniaCybersystems;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenLexoCorp = document.getElementById("volhaven-lexocorp"); let volhavenLexoCorp = document.getElementById("volhaven-lexocorp");
volhavenLexoCorp.addEventListener("click", function() { volhavenLexoCorp.addEventListener("click", function() {
Player.location = Locations.VolhavenLexoCorp; Player.location = Locations.VolhavenLexoCorp;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenSysCoreSecurities = document.getElementById("volhaven-syscoresecurities"); let volhavenSysCoreSecurities = document.getElementById("volhaven-syscoresecurities");
volhavenSysCoreSecurities.addEventListener("click", function() { volhavenSysCoreSecurities.addEventListener("click", function() {
Player.location = Locations.VolhavenSysCoreSecurities; Player.location = Locations.VolhavenSysCoreSecurities;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenCompuTek = document.getElementById("volhaven-computek"); let volhavenCompuTek = document.getElementById("volhaven-computek");
volhavenCompuTek.addEventListener("click", function() { volhavenCompuTek.addEventListener("click", function() {
Player.location = Locations.VolhavenCompuTek; Player.location = Locations.VolhavenCompuTek;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenMilleniumFitnessGym = document.getElementById("volhaven-milleniumfitnessgym"); let volhavenMilleniumFitnessGym = document.getElementById("volhaven-milleniumfitnessgym");
volhavenMilleniumFitnessGym.addEventListener("click", function() { volhavenMilleniumFitnessGym.addEventListener("click", function() {
Player.location = Locations.VolhavenMilleniumFitnessGym; Player.location = Locations.VolhavenMilleniumFitnessGym;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
volhavenSlums = document.getElementById("volhaven-slums"); let volhavenSlums = document.getElementById("volhaven-slums");
volhavenSlums.addEventListener("click", function() { volhavenSlums.addEventListener("click", function() {
Player.location = Locations.VolhavenSlums; Player.location = Locations.VolhavenSlums;
Engine.loadLocationContent(); Engine.loadLocationContent();
return false; return false;
}); });
worldStockExchange = document.getElementById("generic-location-wse"); let worldStockExchange = document.getElementById("generic-location-wse");
worldStockExchange.addEventListener("click", function() { worldStockExchange.addEventListener("click", function() {
Player.location = Locations.WorldStockExchange; Player.location = Locations.WorldStockExchange;
Engine.loadStockMarketContent(); Engine.loadStockMarketContent();
@ -1811,7 +1839,7 @@ initLocationButtons = function() {
}); });
} }
travelToCity = function(destCityName, cost) { function travelToCity(destCityName, cost) {
if (Player.money.lt(cost)) { if (Player.money.lt(cost)) {
dialogBoxCreate("You cannot afford to travel to " + destCityName); dialogBoxCreate("You cannot afford to travel to " + destCityName);
return; return;
@ -1823,7 +1851,7 @@ travelToCity = function(destCityName, cost) {
Engine.loadWorldContent(); Engine.loadWorldContent();
} }
purchaseTorRouter = function() { function purchaseTorRouter() {
if (Player.money.lt(CONSTANTS.TorRouterCost)) { if (Player.money.lt(CONSTANTS.TorRouterCost)) {
dialogBoxCreate("You cannot afford to purchase the Tor router"); dialogBoxCreate("You cannot afford to purchase the Tor router");
return; return;
@ -1841,7 +1869,7 @@ purchaseTorRouter = function() {
dialogBoxCreate("You have purchased a Tor router!<br>You now have access to the dark web from your home computer<br>Use the scan/netstat commands to search for the dark web connection."); dialogBoxCreate("You have purchased a Tor router!<br>You now have access to the dark web from your home computer<br>Use the scan/netstat commands to search for the dark web connection.");
} }
displayUniversityLocationContent = function(costMult) { function displayUniversityLocationContent(costMult) {
var studyComputerScienceButton = document.getElementById("location-study-computer-science"); var studyComputerScienceButton = document.getElementById("location-study-computer-science");
var classDataStructuresButton = document.getElementById("location-data-structures-class"); var classDataStructuresButton = document.getElementById("location-data-structures-class");
var classNetworksButton = document.getElementById("location-networks-class"); var classNetworksButton = document.getElementById("location-networks-class");
@ -1870,7 +1898,7 @@ displayUniversityLocationContent = function(costMult) {
classLeadershipButton.innerHTML = "Take Leadership course ($" + leadershipCost + " / sec)"; classLeadershipButton.innerHTML = "Take Leadership course ($" + leadershipCost + " / sec)";
} }
setUniversityLocationButtons = function(costMult, expMult) { function setUniversityLocationButtons(costMult, expMult) {
var newStudyCS = clearEventListeners("location-study-computer-science"); var newStudyCS = clearEventListeners("location-study-computer-science");
newStudyCS.addEventListener("click", function() { newStudyCS.addEventListener("click", function() {
Player.startClass(costMult, expMult, CONSTANTS.ClassStudyComputerScience); Player.startClass(costMult, expMult, CONSTANTS.ClassStudyComputerScience);
@ -1908,7 +1936,7 @@ setUniversityLocationButtons = function(costMult, expMult) {
}); });
} }
displayGymLocationContent = function(costMult) { function displayGymLocationContent(costMult) {
var gymStrButton = document.getElementById("location-gym-train-str"); var gymStrButton = document.getElementById("location-gym-train-str");
var gymDefButton = document.getElementById("location-gym-train-def"); var gymDefButton = document.getElementById("location-gym-train-def");
var gymDexButton = document.getElementById("location-gym-train-dex"); var gymDexButton = document.getElementById("location-gym-train-dex");
@ -1928,7 +1956,7 @@ displayGymLocationContent = function(costMult) {
gymAgiButton.innerHTML = "Train Agility ($" + cost + " / sec)"; gymAgiButton.innerHTML = "Train Agility ($" + cost + " / sec)";
} }
setGymLocationButtons = function(costMult, expMult) { function setGymLocationButtons(costMult, expMult) {
var gymStr = clearEventListeners("location-gym-train-str"); var gymStr = clearEventListeners("location-gym-train-str");
gymStr.addEventListener("click", function() { gymStr.addEventListener("click", function() {
Player.startClass(costMult, expMult, CONSTANTS.ClassGymStrength); Player.startClass(costMult, expMult, CONSTANTS.ClassGymStrength);
@ -1954,7 +1982,7 @@ setGymLocationButtons = function(costMult, expMult) {
}); });
} }
setInfiltrateButton = function(btn, companyName, startLevel, val, maxClearance, difficulty) { function setInfiltrateButton(btn, companyName, startLevel, val, maxClearance, difficulty) {
btn.style.display = "block"; btn.style.display = "block";
btn.addEventListener("click", function() { btn.addEventListener("click", function() {
Engine.loadInfiltrationContent(); Engine.loadInfiltrationContent();
@ -2008,3 +2036,5 @@ function purchaseServerBoxCreate(ram, cost) {
"GB of RAM for $" + formatNumber(cost, 2) + "?<br><br>" + "GB of RAM for $" + formatNumber(cost, 2) + "?<br><br>" +
"Please enter the server hostname below:<br>"); "Please enter the server hostname below:<br>");
} }
export {Locations, displayLocationContent, initLocationButtons};

@ -1,3 +1,13 @@
import {Augmentations, Augmentation,
AugmentationNames} from "./Augmentations.js";
import {Programs} from "./CreateProgram.js";
import {Player} from "./Player.js";
import {GetServerByHostname} from "./Server.js";
import {Settings} from "./Settings.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
/* Message.js */ /* Message.js */
function Message(filename="", msg="") { function Message(filename="", msg="") {
this.filename = filename; this.filename = filename;
@ -56,6 +66,11 @@ function checkForMessagesToSend() {
var bitrunnersTest = Messages[MessageFilenames.BitRunnersTest]; var bitrunnersTest = Messages[MessageFilenames.BitRunnersTest];
var redpill = Messages[MessageFilenames.RedPill]; var redpill = Messages[MessageFilenames.RedPill];
var redpillOwned = false;
if (Augmentations[AugmentationNames.TheRedPill].owned) {
redpillOwned = true;
}
if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) { if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
sendMessage(jumper0); sendMessage(jumper0);
} else if (jumper1 && !jumper1.recvd && Player.hacking_skill >= 40) { } else if (jumper1 && !jumper1.recvd && Player.hacking_skill >= 40) {
@ -75,7 +90,7 @@ function checkForMessagesToSend() {
} else if (jumper5 && !jumper5.recvd && Player.hacking_skill >= 1000) { } else if (jumper5 && !jumper5.recvd && Player.hacking_skill >= 1000) {
sendMessage(jumper5); sendMessage(jumper5);
Player.getHomeComputer().programs.push(Programs.Flight); Player.getHomeComputer().programs.push(Programs.Flight);
} else if (redpill && !redpill.recvd && Player.hacking_skill >= 2000) { } else if (redpill && !redpill.recvd && Player.hacking_skill >= 2000 && redpillOwned) {
sendMessage(redpill); sendMessage(redpill);
} }
} }
@ -84,9 +99,13 @@ function AddToAllMessages(msg) {
Messages[msg.filename] = msg; Messages[msg.filename] = msg;
} }
Messages = {} let Messages = {}
MessageFilenames = { function loadMessages(saveString) {
Messages = JSON.parse(saveString, Reviver);
}
let MessageFilenames = {
Jumper0: "j0.msg", Jumper0: "j0.msg",
Jumper1: "j1.msg", Jumper1: "j1.msg",
Jumper2: "j2.msg", Jumper2: "j2.msg",
@ -160,3 +179,6 @@ function initMessages() {
"@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" + "@_#(%_@#M(BDSPOMB__THE-CAVE_#)$(*@#$)@#BNBEGB<br>" +
"DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)")); "DFLSMFVMV)#@($*)@#*$MV)@#(*$V)M#(*$)M@(#*VM$)"));
} }
export {Messages, checkForMessagesToSend, sendMessage, showMessage, loadMessages,
initMessages, Message};

@ -1,3 +1,4 @@
import {NetscriptFunctions} from "./NetscriptFunctions.js";
/* Environment /* Environment
* NetScript program environment * NetScript program environment
*/ */
@ -67,3 +68,5 @@ Environment.prototype = {
return this.vars[name] = value; return this.vars[name] = value;
} }
}; };
export {Environment};

@ -1,3 +1,17 @@
import {BitNodeMultipliers} from "./BitNode.js";
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {Environment} from "./NetscriptEnvironment.js";
import {WorkerScript, addWorkerScript} from "./NetscriptWorker.js";
import {Server} from "./Server.js";
import {Settings} from "./Settings.js";
import {Script, findRunningScript,
RunningScript} from "./Script.js";
import {printArray} from "../utils/HelperFunctions.js";
import {isValidIPAddress} from "../utils/IPAddress.js";
import {isString} from "../utils/StringHelperFunctions.js";
/* Evaluator /* Evaluator
* Evaluates the Abstract Syntax Tree for Netscript * Evaluates the Abstract Syntax Tree for Netscript
* generated by the Parser class * generated by the Parser class
@ -20,7 +34,7 @@ function evaluate(exp, workerScript) {
evaluateProgPromise.then(function(w) { evaluateProgPromise.then(function(w) {
resolve(workerScript); resolve(workerScript);
}, function(e) { }, function(e) {
if (typeof e === 'string' || e instanceof String) { if (isString(e)) {
workerScript.errorMessage = e; workerScript.errorMessage = e;
reject(workerScript); reject(workerScript);
} else if (e instanceof WorkerScript) { } else if (e instanceof WorkerScript) {
@ -35,7 +49,7 @@ function evaluate(exp, workerScript) {
break; break;
case "Identifier": case "Identifier":
if (!(exp.name in env.vars)){ if (!(exp.name in env.vars)){
reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.name + " not definied")); reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.name + " not defined"));
} }
resolve(env.get(exp.name)) resolve(env.get(exp.name))
break; break;
@ -172,7 +186,7 @@ function evaluate(exp, workerScript) {
} }
resolve(env.get(exp.argument.name)) resolve(env.get(exp.argument.name))
} else { } else {
reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.argument.name + " not definied")); reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.argument.name + " not defined"));
} }
} else { } else {
reject(makeRuntimeRejectMsg(workerScript, "argument must be an identifier")); reject(makeRuntimeRejectMsg(workerScript, "argument must be an identifier"));
@ -336,7 +350,7 @@ function evalAssignment(exp, workerScript) {
} }
if (exp.operator !== "=" && !(exp.left.name in env.vars)){ if (exp.operator !== "=" && !(exp.left.name in env.vars)){
return reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.left.name + " not definied")); return reject(makeRuntimeRejectMsg(workerScript, "variable " + exp.left.name + " not defined"));
} }
var expRightPromise = evaluate(exp.right, workerScript); var expRightPromise = evaluate(exp.right, workerScript);
@ -347,7 +361,7 @@ function evalAssignment(exp, workerScript) {
//Index designated by exp.left.property //Index designated by exp.left.property
var name = exp.left.object.name; var name = exp.left.object.name;
if (!(name in env.vars)){ if (!(name in env.vars)){
reject(makeRuntimeRejectMsg(workerScript, "variable " + name + " not definied")); reject(makeRuntimeRejectMsg(workerScript, "variable " + name + " not defined"));
} }
var arr = env.get(name); var arr = env.get(name);
if (arr.constructor === Array || arr instanceof Array) { if (arr.constructor === Array || arr instanceof Array) {
@ -631,7 +645,8 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
} }
function isScriptErrorMessage(msg) { function isScriptErrorMessage(msg) {
splitMsg = msg.split("|"); if (!isString(msg)) {return false;}
let splitMsg = msg.split("|");
if (splitMsg.length != 4){ if (splitMsg.length != 4){
return false; return false;
} }
@ -666,7 +681,7 @@ function scriptCalculateExpGain(server) {
if (server.baseDifficulty == null) { if (server.baseDifficulty == null) {
server.baseDifficulty = server.hackDifficulty; server.baseDifficulty = server.hackDifficulty;
} }
return (server.baseDifficulty * Player.hacking_exp_mult * 0.3 + 3); return (server.baseDifficulty * Player.hacking_exp_mult * 0.3 + 3) * BitNodeMultipliers.HackExpGain;
} }
//The same as Player's calculatePercentMoneyHacked() function but takes in the server as an argument //The same as Player's calculatePercentMoneyHacked() function but takes in the server as an argument
@ -676,7 +691,7 @@ function scriptCalculatePercentMoneyHacked(server) {
var percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / 240; var percentMoneyHacked = difficultyMult * skillMult * Player.hacking_money_mult / 240;
if (percentMoneyHacked < 0) {return 0;} if (percentMoneyHacked < 0) {return 0;}
if (percentMoneyHacked > 1) {return 1;} if (percentMoneyHacked > 1) {return 1;}
return percentMoneyHacked; return percentMoneyHacked * BitNodeMultipliers.ScriptHackMoney;
} }
//Amount of time to execute grow() in milliseconds //Amount of time to execute grow() in milliseconds
@ -694,3 +709,9 @@ function scriptCalculateWeakenTime(server) {
var weakenTime = 20 * skillFactor / Player.hacking_speed_mult; //This is in seconds var weakenTime = 20 * skillFactor / Player.hacking_speed_mult; //This is in seconds
return weakenTime * 1000; return weakenTime * 1000;
} }
export {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
scriptCalculateHackingChance, scriptCalculateHackingTime,
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
scriptCalculateGrowTime, scriptCalculateWeakenTime, evaluate,
isScriptErrorMessage};

@ -1,10 +1,53 @@
function initSingularitySFFlags() { import {Augmentations, Augmentation,
//TODO augmentationExists, installAugmentations} from "./Augmentations.js";
} import {Companies, Company, CompanyPosition,
CompanyPositions} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {parseDarkwebItemPrice, DarkWebItems} from "./DarkWeb.js";
import {Factions, Faction, joinFaction,
factionExists, purchaseAugmentation} from "./Faction.js";
import {getCostOfNextHacknetNode,
purchaseHacknet} from "./HacknetNode.js";
import {Locations} from "./Location.js";
import {Player} from "./Player.js";
import {Script, findRunningScript, RunningScript} from "./Script.js";
import {Server, getServer, AddToAllServers,
AllServers, processSingleServerGrowth,
GetServerByHostname} from "./Server.js";
import {Settings} from "./Settings.js";
import {SpecialServerIps} from "./SpecialServerIps.js";
import {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
sellStock, updateStockPrices, displayStockMarketContent,
updateStockTicker, updateStockPlayerPosition,
Stock} from "./StockMarket.js";
import {WorkerScript, workerScripts,
killWorkerScript, NetscriptPorts} from "./NetscriptWorker.js";
import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
scriptCalculateHackingChance, scriptCalculateHackingTime,
scriptCalculateExpGain, scriptCalculatePercentMoneyHacked,
scriptCalculateGrowTime, scriptCalculateWeakenTime} from "./NetscriptEvaluator.js";
import {Environment} from "./NetscriptEnvironment.js";
import Decimal from '../utils/decimal.js';
import {printArray, powerOfTwo} from "../utils/HelperFunctions.js";
import {createRandomIp} from "../utils/IPAddress.js";
import {formatNumber, isString} from "../utils/StringHelperFunctions.js";
var hasSingularitySF = false; var hasSingularitySF = false;
var singularitySFLvl = 1; var singularitySFLvl = 1;
function initSingularitySFFlags() {
for (var i = 0; i < Player.sourceFiles.length; ++i) {
if (Player.sourceFiles[i].n === 4) {
hasSingularitySF = true;
singularitySFLvl = Player.sourceFiles[i].lvl;
}
}
}
function NetscriptFunctions(workerScript) { function NetscriptFunctions(workerScript) {
return { return {
hacknetnodes : Player.hacknetNodes, hacknetnodes : Player.hacknetNodes,
@ -215,6 +258,7 @@ function NetscriptFunctions(workerScript) {
throw makeRuntimeRejectMsg(workerScript, "Cannot call brutessh(). Invalid IP or hostname passed in: " + ip); throw makeRuntimeRejectMsg(workerScript, "Cannot call brutessh(). Invalid IP or hostname passed in: " + ip);
} }
if (!Player.hasProgram(Programs.BruteSSHProgram)) { if (!Player.hasProgram(Programs.BruteSSHProgram)) {
workerScript.scriptRef.log("You do not have the BruteSSH.exe program!");
throw makeRuntimeRejectMsg(workerScript, "You do not have the BruteSSH.exe program!"); throw makeRuntimeRejectMsg(workerScript, "You do not have the BruteSSH.exe program!");
} }
if (!server.sshPortOpen) { if (!server.sshPortOpen) {
@ -875,21 +919,40 @@ function NetscriptFunctions(workerScript) {
/* Singularity Functions */ /* Singularity Functions */
universityCourse(universityName, className) { universityCourse(universityName, className) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run universityCourse(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
return false;
}
}
if (Player.isWorking) { if (Player.isWorking) {
var txt = Player.singularityStopWork(); var txt = Player.singularityStopWork();
workerScript.scriptRef.log(txt); workerScript.scriptRef.log(txt);
} }
var costMult, expMult; var costMult, expMult;
switch(universityName.toLowerCase()) { switch(universityName.toLowerCase()) {
case Locations.AevumSummitUniversity.toLowerCase(): case Locations.AevumSummitUniversity.toLowerCase():
if (Player.city != Locations.Aevum) {
workerScript.scriptRef.log("ERROR: You cannot study at Summit University because you are not in Aevum. universityCourse() failed");
return false;
}
costMult = 4; costMult = 4;
expMult = 3; expMult = 3;
break; break;
case Locations.Sector12RothmanUniversity.toLowerCase(): case Locations.Sector12RothmanUniversity.toLowerCase():
if (Player.city != Locations.Sector12) {
workerScript.scriptRef.log("ERROR: You cannot study at Rothman University because you are not in Sector-12. universityCourse() failed");
return false;
}
costMult = 3; costMult = 3;
expMult = 2; expMult = 2;
break; break;
case Locations.VolhavenZBInstituteOfTechnology.toLowerCase(): case Locations.VolhavenZBInstituteOfTechnology.toLowerCase():
if (Player.city != Locations.Aevum) {
workerScript.scriptRef.log("ERROR: You cannot study at ZB Institute of Technology because you are not in Volhaven. universityCourse() failed");
return false;
}
costMult = 5; costMult = 5;
expMult = 4; expMult = 4;
break; break;
@ -898,48 +961,714 @@ function NetscriptFunctions(workerScript) {
return false; return false;
} }
var task;
switch(className.toLowerCase()) { switch(className.toLowerCase()) {
case "Study Computer Science".toLowerCase(): case "Study Computer Science".toLowerCase():
task = CONSTANTS.ClassStudyComputerScience;
break; break;
case "Data Structures".toLowerCase(): case "Data Structures".toLowerCase():
task = CONSTANTS.ClassDataStructures;
break; break;
case "Networks".toLowerCase(): case "Networks".toLowerCase():
task = CONSTANTS.ClassNetworks;
break; break;
case "Algorithms".toLowerCase(): case "Algorithms".toLowerCase():
task = CONSTANTS.ClassAlgorithms;
break; break;
case "Management".toLowerCase(): case "Management".toLowerCase():
task = CONSTANTS.ClassManagement;
break; break;
case "Leadership".toLowerCase(): case "Leadership".toLowerCase():
task = CONSTANTS.ClassLeadership;
break; break;
default: default:
workerScript.scriptRef.log("Invalid class name: " + className + ". universityCourse() failed"); workerScript.scriptRef.log("Invalid class name: " + className + ". universityCourse() failed");
return false;
}
Player.startClass(costMult, expMult, task);
workerScript.scriptRef.log("Started " + task + " at " + universityName);
return true;
},
gymWorkout(gymName, stat) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run gymWorkout(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
return false;
}
}
if (Player.isWorking) {
var txt = Player.singularityStopWork();
workerScript.scriptRef.log(txt);
}
var costMult, expMult;
switch(gymName.toLowerCase()) {
case Locations.AevumCrushFitnessGym.toLowerCase():
if (Player.city != Locations.Aevum) {
workerScript.scriptRef.log("ERROR: You cannot workout at Crush Fitness because you are not in Aevum. gymWorkout() failed");
return false;
}
costMult = 2;
expMult = 1.5;
break; break;
case Locations.AevumSnapFitnessGym.toLowerCase():
if (Player.city != Locations.Aevum) {
workerScript.scriptRef.log("ERROR: You cannot workout at Snap Fitness because you are not in Aevum. gymWorkout() failed");
return false;
}
costMult = 6;
expMult = 4;
break;
case Locations.Sector12IronGym.toLowerCase():
if (Player.city != Locations.Sector12) {
workerScript.scriptRef.log("ERROR: You cannot workout at Iron Gym because you are not in Sector-12. gymWorkout() failed");
return false;
}
costMult = 1;
expMult = 1;
break;
case Locations.Sector12PowerhouseGym.toLowerCase():
if (Player.city != Locations.Sector12) {
workerScript.scriptRef.log("ERROR: You cannot workout at Powerhouse Gym because you are not in Sector-12. gymWorkout() failed");
return false;
}
costMult = 10;
expMult = 7.5;
break;
default:
workerScript.scriptRef.log("Invalid gym name: " + gymName + ". gymWorkout() failed");
return false;
}
switch(stat.toLowerCase()) {
case "strength".toLowerCase():
case "str".toLowerCase():
Player.startClass(costMult, expMult, CONSTANTS.ClassGymStrength);
break;
case "defense".toLowerCase():
case "def".toLowerCase():
Player.startClass(costMult, expMult, CONSTANTS.ClassGymDefense);
break;
case "dexterity".toLowerCase():
case "dex".toLowerCase():
Player.startClass(costMult, expMult, CONSTANTS.ClassGymDexterity);
break;
case "agility".toLowerCase():
case "agi".toLowerCase():
Player.startClass(costMult, expMult, CONSTANTS.ClassGymAgility);
break;
default:
workerScript.scriptRef.log("Invalid stat: " + stat + ". gymWorkout() failed");
return false;
}
workerScript.scriptRef.log("Started training " + stat + " at " + gymName);
return true;
},
travelToCity(cityname) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run travelToCity(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
return false;
}
}
switch(cityname) {
case Locations.Aevum:
case Locations.Chongqing:
case Locations.Sector12:
case Locations.NewTokyo:
case Locations.Ishima:
case Locations.Volhaven:
Player.loseMoney(200000);
Player.city = cityname;
workerScript.scriptRef.log("Traveled to " + cityname);
return true;
default:
workerScript.scriptRef.log("ERROR: Invalid city name passed into travelToCity().");
return false;
} }
}, },
//gymWorkout(gymName, stat);
//travelToCity(cityname); purchaseTor() {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run purchaseTor(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
return false;
}
}
//purchaseTor(); if (SpecialServerIps["Darkweb Server"] != null) {
workerScript.scriptRef.log("You already have a TOR router! purchaseTor() failed");
return false;
}
//homeComp.upgradeRam(); if (Player.money.lt(CONSTANTS.TorRouterCost)) {
//homeComp.getUpgradeRamCost(); workerScript.scriptRef.log("ERROR: You cannot afford to purchase a Tor router. purchaseTor() failed");
return false;
}
Player.loseMoney(CONSTANTS.TorRouterCost);
//workForCompany(); var darkweb = new Server(createRandomIp(), "darkweb", "", false, false, false, 1);
//applyToCompany(companyName, field); AddToAllServers(darkweb);
//getCompanyRep(companyName); SpecialServerIps.addIp("Darkweb Server", darkweb.ip);
//checkFactionInvitations(); document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button-inactive");
//joinFaction(name);
//workForFaction(facName, type);
//getFactionRep(name);
//createProgram(); Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
darkweb.serversOnNetwork.push(Player.getHomeComputer().ip);
workerScript.scriptRef.log("You have purchased a Tor router!");
return true;
},
purchaseProgram(programName) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 1)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run purchaseProgram(). It is a Singularity Function and requires SourceFile-4 (level 1) to run.");
return false;
}
}
//getAugmentationCost(name); if (SpecialServerIps["Darkweb Server"] == null) {
//purchaseAugmentation(faction, name); workerScript.scriptRef.log("ERROR: You do not have TOR router. purchaseProgram() failed.");
//installAugmentations(); return false;
}
switch(programName.toLowerCase()) {
case Programs.BruteSSHProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.BruteSSHProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.BruteSSHProgram);
workerScript.scriptRef.log("You have purchased the BruteSSH.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
}
return true;
case Programs.FTPCrackProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.FTPCrackProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.FTPCrackProgram);
workerScript.scriptRef.log("You have purchased the FTPCrack.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
}
return true;
case Programs.RelaySMTPProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.RelaySMTPProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.RelaySMTPProgram);
workerScript.scriptRef.log("You have purchased the relaySMTP.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
}
return true;
case Programs.HTTPWormProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.HTTPWormProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.HTTPWormProgram);
workerScript.scriptRef.log("You have purchased the HTTPWorm.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
}
return true;
case Programs.SQLInjectProgram.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.SQLInjectProgram);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.SQLInjectProgram);
workerScript.scriptRef.log("You have purchased the SQLInject.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
}
return true;
case Programs.DeepscanV1.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV1Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV1);
workerScript.scriptRef.log("You have purchased the DeepscanV1.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
}
return true;
case Programs.DeepscanV2.toLowerCase():
var price = parseDarkwebItemPrice(DarkWebItems.DeepScanV2Program);
if (price > 0 && Player.money.gt(price)) {
Player.loseMoney(price);
Player.getHomeComputer().programs.push(Programs.DeepscanV2);
workerScript.scriptRef.log("You have purchased the DeepscanV2.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
}
return true;
default:
workerScript.scriptRef.log("ERROR: Invalid program passed into purchaseProgram().");
return false;
}
return true;
},
upgradeHomeRam() {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run upgradeHomeRam(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
//Calculate how many times ram has been upgraded (doubled)
var currentRam = Player.getHomeComputer().maxRam;
var numUpgrades = Math.log2(currentRam);
//Calculate cost
//Have cost increase by some percentage each time RAM has been upgraded
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
var mult = Math.pow(1.55, numUpgrades);
cost = cost * mult;
if (Player.money.lt(cost)) {
workerScript.scriptRef.log("You do not have enough money to purchase additional RAM for your home computer");
return false;
}
var homeComputer = Player.getHomeComputer();
homeComputer.maxRam *= 2;
Player.loseMoney(cost);
workerScript.scriptRef.log("Purchased additional RAM for home computer! It now has " + homeComputer.maxRam + "GB of RAM.");
return true;
},
getUpgradeHomeRamCost() {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getUpgradeHomeRamCost(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
//Calculate how many times ram has been upgraded (doubled)
var currentRam = Player.getHomeComputer().maxRam;
var numUpgrades = Math.log2(currentRam);
//Calculate cost
//Have cost increase by some percentage each time RAM has been upgraded
var cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome;
var mult = Math.pow(1.55, numUpgrades);
return cost * mult;
},
workForCompany() {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run workForCompany(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
if (Player.companyPosition == "" || !(Player.companyPosition instanceof CompanyPosition)) {
workerScript.scriptRef.log("ERROR: workForCompany() failed because you do not have a job");
return false;
}
if (Player.isWorking) {
var txt = Player.singularityStopWork();
workerScript.scriptRef.log(txt);
}
if (Player.companyPosition.isPartTimeJob()) {
Player.startWorkPartTime();
} else {
Player.startWork();
}
workerScript.scriptRef.log("Began working at " + Player.companyName + " as a " + Player.companyPosition.positionName);
return true;
},
applyToCompany(companyName, field) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run applyToCompany(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
Player.location = companyName;
var res;
switch (field.toLowerCase()) {
case "software":
res = Player.applyForSoftwareJob(true);
break;
case "software consultant":
res = Player.applyForSoftwareConsultantJob(true);
break;
case "it":
res = Player.applyForItJob(true);
break;
case "security engineer":
res = Player.applyForSecurityEngineerJob(true);
break;
case "network engineer":
res = Player.applyForNetworkEngineerJob(true);
break;
case "business":
res = Player.applyForBusinessJob(true);
break;
case "business consultant":
res = Player.applyForBusinessConsultantJob(true);
break;
case "security":
res = Player.applyForSecurityJob(true);
break;
case "agent":
res = Player.applyForAgentJob(true);
break;
case "employee":
res = Player.applyForEmployeeJob(true);
break;
case "part-time employee":
res = Player.applyForPartTimeEmployeeJob(true);
break;
case "waiter":
res = Player.applyForWaiterJob(true);
break;
case "part-time waiter":
res = Player.applyForPartTimeWaiterJob(true);
break;
default:
workerScript.scriptRef.log("ERROR: Invalid job passed into applyToCompany: " + field + ". applyToCompany() failed");
return false;
}
//The Player object's applyForJob function can return string with special error messages
if (isString(res)) {
workerScript.scriptRef.log(res);
return false;
}
if (res) {
workerScript.scriptRef.log("You were offered a new job at " + companyName + " as a " + Player.companyPosition.positionName);
} else {
workerScript.scriptRef.log("You failed to get a new job/promotion at " + companyName + " in the " + field + " field.");
}
return res;
},
getCompanyRep(companyName) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getCompanyRep(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
var company = Companies[companyName];
if (company === null || !(company instanceof Company)) {
workerScript.scriptRef.log("ERROR: Invalid companyName passed into getCompanyRep(): " + companyName);
return -1;
}
return company.playerReputation;
},
checkFactionInvitations() {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run checkFactionInvitations(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
//Make a copy of Player.factionInvitations
return Player.factionInvitations.slice();
},
joinFaction(name) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run joinFaction(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
if (!factionExists(name)) {
workerScript.scriptRef.log("ERROR: Faction specified in joinFaction() does not exist.");
return false;
}
if (!Player.factionInvitations.includes(name)) {
workerScript.scriptRef.log("ERROR: Cannot join " + name + " Faction because you have not been invited. joinFaction() failed");
return false;
}
var index = Player.factionInvitations.indexOf(name);
if (index === -1) {
//Redundant and should never happen...
workerScript.scriptRef.log("ERROR: Cannot join " + name + " Faction because you have not been invited. joinFaction() failed");
return false;
}
Player.factionInvitations.splice(index, 1);
var fac = Factions[name];
joinFaction(fac);
workerScript.scriptRef.log("Joined the " + name + " faction.");
return true;
},
workForFaction(name, type) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run workForFaction(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return false;
}
}
if (!factionExists(name)) {
workerScript.scriptRef.log("ERROR: Faction specified in workForFaction() does not exist.");
return false;
}
if (Player.isWorking) {
var txt = Player.singularityStopWork();
workerScript.scriptRef.log(txt);
}
var fac = Factions[name];
//Arrays listing factions that allow each time of work
var hackAvailable = ["Illuminati", "Daedalus", "The Covenant", "ECorp", "MegaCorp",
"Bachman & Associates", "Blade Industries", "NWO", "Clarke Incorporated",
"OmniTek Incorporated", "Four Sigma", "KuaiGong International",
"Fulcrum Secret Technologies", "BitRunners", "The Black Hand",
"NiteSec", "Chongqing", "Sector-12", "New Tokyo", "Aevum",
"Ishima", "Volhaven", "Speakers for the Dead", "The Dark Army",
"The Syndicate", "Silhouette", "Netburners", "Tian Di Hui", "CyberSec"];
var fdWkAvailable = ["Illuminati", "Daedalus", "The Covenant", "ECorp", "MegaCorp",
"Bachman & Associates", "Blade Industries", "NWO", "Clarke Incorporated",
"OmniTek Incorporated", "Four Sigma", "KuaiGong International",
"The Black Hand", "Chongqing", "Sector-12", "New Tokyo", "Aevum",
"Ishima", "Volhaven", "Speakers for the Dead", "The Dark Army",
"The Syndicate", "Silhouette", "Tetrads", "Slum Snakes"];
var scWkAvailable = ["ECorp", "MegaCorp",
"Bachman & Associates", "Blade Industries", "NWO", "Clarke Incorporated",
"OmniTek Incorporated", "Four Sigma", "KuaiGong International",
"Fulcrum Secret Technologies", "Chongqing", "Sector-12", "New Tokyo", "Aevum",
"Ishima", "Volhaven", "Speakers for the Dead",
"The Syndicate", "Tetrads", "Slum Snakes", "Tian Di Hui"];
switch (type.toLowerCase()) {
case "hacking":
case "hacking contracts":
case "hackingcontracts":
if (!hackAvailable.includes(fac.name)) {
workerScript.scriptRef.log("ERROR: Cannot carry out hacking contracts for " + fac.name + ". workForFaction() failed");
return false;
}
Player.startFactionHackWork(fac);
workerScript.scriptRef.log("Started carrying out hacking contracts for " + fac.name);
return true;
case "field":
case "fieldwork":
case "field work":
if (!fdWkAvailable.includes(fac.name)) {
workerScript.scriptRef.log("ERROR: Cannot carry out field missions for " + fac.name + ". workForFaction() failed");
return false;
}
Player.startFactionFieldWork(fac);
workerScript.scriptRef.log("Started carrying out field missions for " + fac.name);
return true;
case "security":
case "securitywork":
case "security work":
if (!scWkAvailable.includes(fac.name)) {
workerScript.scriptRef.log("ERROR: Cannot serve as security detail for " + fac.name + ". workForFaction() failed");
return false;
}
Player.startFactionSecurityWork(fac);
workerScript.scriptRef.log("Started serving as security details for " + fac.name);
return true;
default:
workerScript.scriptRef.log("ERROR: Invalid work type passed into workForFaction(): " + type);
}
},
getFactionRep(name) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 2)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getFactionRep(). It is a Singularity Function and requires SourceFile-4 (level 2) to run.");
return -1;
}
}
if (!factionExists(name)) {
workerScript.scriptRef.log("ERROR: Faction specified in getFactionRep() does not exist.");
return -1;
}
return Factions[name].playerReputation;
},
createProgram(name) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run createProgram(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
return false;
}
}
if (Player.isWorking) {
var txt = Player.singularityStopWork();
workerScript.scriptRef.log(txt);
}
switch(name.toLowerCase()) {
case Programs.NukeProgram.toLowerCase():
Player.startCreateProgramWork(Programs.NukeProgram, CONSTANTS.MillisecondsPerFiveMinutes, 1);
break;
case Programs.BruteSSHProgram.toLowerCase():
if (Player.hacking_skill < 50) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create BruteSSH (level 50 req)");
return false;
}
Player.startCreateProgramWork(Programs.BruteSSHProgram, CONSTANTS.MillisecondsPerFiveMinutes * 2, 50);
break;
case Programs.FTPCrackProgram.toLowerCase():
if (Player.hacking_skill < 100) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create FTPCrack (level 100 req)");
return false;
}
Player.startCreateProgramWork(Programs.FTPCrackProgram, CONSTANTS.MillisecondsPerHalfHour, 100);
break;
case Programs.RelaySMTPProgram.toLowerCase():
if (Player.hacking_skill < 250) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create relaySMTP (level 250 req)");
return false;
}
Player.startCreateProgramWork(Programs.RelaySMTPProgram, CONSTANTS.MillisecondsPer2Hours, 250);
break;
case Programs.HTTPWormProgram.toLowerCase():
if (Player.hacking_skill < 500) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create HTTPWorm (level 500 req)");
return false;
}
Player.startCreateProgramWork(Programs.HTTPWormProgram, CONSTANTS.MillisecondsPer4Hours, 500);
break;
case Programs.SQLInjectProgram.toLowerCase():
if (Player.hacking_skill < 750) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create SQLInject (level 750 req)");
return false;
}
Player.startCreateProgramWork(Programs.SQLInjectProgram, CONSTANTS.MillisecondsPer8Hours, 750);
break;
case Programs.DeepscanV1.toLowerCase():
if (Player.hacking_skill < 75) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create DeepscanV1 (level 75 req)");
return false;
}
Player.startCreateProgramWork(Programs.DeepscanV1, CONSTANTS.MillisecondsPerQuarterHour, 75);
break;
case Programs.DeepscanV2.toLowerCase():
if (Player.hacking_skill < 400) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create DeepscanV2 (level 400 req)");
return false;
}
Player.startCreateProgramWork(Programs.DeepscanV2, CONSTANTS.MillisecondsPer2Hours, 400);
break;
case Programs.ServerProfiler.toLowerCase():
if (Player.hacking_skill < 75) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create ServerProfiler (level 75 req)");
return false;
}
Player.startCreateProgramWork(Programs.ServerProfiler, CONSTANTS.MillisecondsPerHalfHour, 75);
break;
case Programs.AutoLink.toLowerCase():
if (Player.hacking_skill < 25) {
workerScript.scriptRef.log("ERROR: createProgram() failed because hacking level is too low to create AutoLink (level 25 req)");
return false;
}
Player.startCreateProgramWork(Programs.AutoLink, CONSTANTS.MillisecondsPerQuarterHour, 25);
break;
default:
workerScript.scriptRef.log("ERROR: createProgram() failed because the specified program does not exist: " + name);
return false;
}
workerScript.scriptRef.log("Began creating program: " + name);
return true;
},
getAugmentationCost(name) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getAugmentationCost(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
return false;
}
}
if (!augmentationExists(name)) {
workerScript.scriptRef.log("ERROR: getAugmentationCost() failed. Invalid Augmentation name passed in (note: this is case-sensitive): " + name);
return [-1, -1];
}
var aug = Augmentations[name];
return [aug.baseRepRequirement, aug.baseCost];
},
purchaseAugmentation(faction, name) {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run purchaseAugmentation(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
return false;
}
}
var fac = Factions[faction];
if (fac === null || !(fac instanceof Faction)) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because of invalid faction name: " + faction);
return false;
}
if (!fac.augmentations.includes(name)) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because the faction " + faction + " does not contain the " + name + " augmentation");
return false;
}
var aug = Augmentations[name];
if (aug === null || !(aug instanceof Augmentation)) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because of invalid augmentation name: " + name);
return false;
}
for (var j = 0; j < Player.queuedAugmentations.length; ++j) {
if (Player.queuedAugmentations[j].name === aug.name) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because you already have " + name);
return false;
}
}
for (var j = 0; j < Player.augmentations.length; ++j) {
if (Player.augmentations[j].name === aug.name) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because you already have " + name);
return false;
}
}
var res = purchaseAugmentation(aug, fac, true);
workerScript.scriptRef.log(res);
if (isString(res) && res.startsWith("You purchased")) {
return true;
} else {
return false;
}
},
installAugmentations() {
if (Player.bitNodeN != 4) {
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run installAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
return false;
}
}
if (Player.queuedAugmentations.length === 0) {
workerScript.scriptRef.log("ERROR: installAugmentations() failed because you do not have any Augmentations to be installed");
return false;
}
workerScript.scriptRef.log("Installing Augmentations. This will cause this script to be killed");
installAugmentations();
return true;
}
} }
} }
export {NetscriptFunctions, initSingularitySFFlags};

@ -1,8 +1,18 @@
/* Worker code, contains Netscript scripts that are actually running */ import {addActiveScriptsItem,
deleteActiveScriptsItem,
updateActiveScriptsItems} from "./ActiveScriptsUI.js";
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {Environment} from "./NetscriptEnvironment.js";
import {evaluate, isScriptErrorMessage} from "./NetscriptEvaluator.js";
import {AllServers} from "./Server.js";
import {Settings} from "./Settings.js";
import {parse} from "../utils/acorn.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {compareArrays, printArray} from "../utils/HelperFunctions.js";
//TODO Tested For and while and generic call statements. Have not tested if statements
/* Actual Worker Code */
function WorkerScript(runningScriptObj) { function WorkerScript(runningScriptObj) {
this.name = runningScriptObj.filename; this.name = runningScriptObj.filename;
this.running = false; this.running = false;
@ -23,9 +33,9 @@ WorkerScript.prototype.getServer = function() {
} }
//Array containing all scripts that are running across all servers, to easily run them all //Array containing all scripts that are running across all servers, to easily run them all
var workerScripts = []; let workerScripts = [];
var NetscriptPorts = { let NetscriptPorts = {
Port1: [], Port1: [],
Port2: [], Port2: [],
Port3: [], Port3: [],
@ -38,6 +48,14 @@ var NetscriptPorts = {
Port10: [], Port10: [],
} }
function prestigeWorkerScripts() {
for (var i = 0; i < workerScripts.length; ++i) {
deleteActiveScriptsItem(workerScripts[i]);
workerScripts[i].env.stopFlag = true;
}
workerScripts.length = 0;
}
//Loop through workerScripts and run every script that is not currently running //Loop through workerScripts and run every script that is not currently running
function runScriptsLoop() { function runScriptsLoop() {
//Run any scripts that haven't been started //Run any scripts that haven't been started
@ -45,7 +63,7 @@ function runScriptsLoop() {
//If it isn't running, start the script //If it isn't running, start the script
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) { if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == false) {
try { try {
var ast = acorn.parse(workerScripts[i].code); var ast = parse(workerScripts[i].code);
//console.log(ast); //console.log(ast);
} catch (e) { } catch (e) {
console.log("Error parsing script: " + workerScripts[i].name); console.log("Error parsing script: " + workerScripts[i].name);
@ -64,9 +82,10 @@ function runScriptsLoop() {
w.env.stopFlag = true; w.env.stopFlag = true;
w.scriptRef.log("Script finished running"); w.scriptRef.log("Script finished running");
}, function(w) { }, function(w) {
//console.log(w);
if (w instanceof Error) { if (w instanceof Error) {
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer"); dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
console.log("ERROR: Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN"); console.log("ERROR: Evaluating workerscript returns an Error. THIS SHOULDN'T HAPPEN: " + w.toString());
return; return;
} else if (w instanceof WorkerScript) { } else if (w instanceof WorkerScript) {
if (isScriptErrorMessage(w.errorMessage)) { if (isScriptErrorMessage(w.errorMessage)) {
@ -92,7 +111,7 @@ function runScriptsLoop() {
} else if (isScriptErrorMessage(w)) { } else if (isScriptErrorMessage(w)) {
dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer"); dialogBoxCreate("Script runtime unknown error. This is a bug please contact game developer");
console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN"); console.log("ERROR: Evaluating workerscript returns only error message rather than WorkerScript object. THIS SHOULDN'T HAPPEN: " + w.toString());
return; return;
} else { } else {
dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev"); dialogBoxCreate("An unknown script died for an unknown reason. This is a bug please contact game dev");
@ -182,4 +201,6 @@ function updateOnlineScriptTimes(numCycles = 1) {
} }
} }
runScriptsLoop(); export {WorkerScript, workerScripts, NetscriptPorts, runScriptsLoop,
killWorkerScript, addWorkerScript, updateOnlineScriptTimes,
prestigeWorkerScripts};

File diff suppressed because it is too large Load Diff

@ -1,113 +1,48 @@
/* Prestige functions */ import {deleteActiveScriptsItem} from "./ActiveScriptsUI.js";
import {Augmentations, augmentationExists,
initAugmentations, AugmentationNames} from "./Augmentations.js";
import {initBitNodeMultipliers} from "./BitNode.js";
import {Companies, Company, initCompanies} from "./Company.js";
import {Programs} from "./CreateProgram.js";
import {Engine} from "./engine.js";
import {Factions, Faction, initFactions,
joinFaction} from "./Faction.js";
import {Locations} from "./Location.js";
import {initMessages, Messages, Message} from "./Message.js";
import {WorkerScript, workerScripts,
prestigeWorkerScripts} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
import {AllServers, AddToAllServers,
initForeignServers, Server,
prestigeAllServers,
prestigeHomeComputer} from "./Server.js";
import {SpecialServerIps, SpecialServerIpsMap,
prestigeSpecialServerIps,
SpecialServerNames} from "./SpecialServerIps.js";
import {initStockMarket, initSymbolToStockMap,
stockMarketContentCreated} from "./StockMarket.js";
import {Terminal, postNetburnerText} from "./Terminal.js";
import Decimal from '../utils/decimal.js';
//Prestige by purchasing augmentation //Prestige by purchasing augmentation
function prestigeAugmentation() { function prestigeAugmentation() {
initBitNodeMultipliers(); initBitNodeMultipliers();
//Crime statistics Player.prestigeAugmentation();
Player.numTimesShoplifted = 0;
Player.numPeopleMugged = 0;
Player.numTimesDealtDrugs = 0;
Player.numTimesTraffickArms = 0;
Player.numPeopleKilled = 0;
Player.numTimesGrandTheftAuto = 0;
Player.numTimesKidnapped = 0;
Player.numTimesHeist = 0;
Player.karma = 0;
//Reset stats
Player.hacking_skill = 1;
Player.strength = 1;
Player.defense = 1;
Player.dexterity = 1;
Player.agility = 1;
Player.charisma = 1;
Player.hacking_exp = 0;
Player.strength_exp = 0;
Player.defense_exp = 0;
Player.dexterity_exp = 0;
Player.agility_exp = 0;
Player.charisma_exp = 0;
Player.money = new Decimal(1000);
Player.city = Locations.Sector12;
Player.location = "";
Player.companyName = "";
Player.companyPosition = "";
Player.currentServer = "";
Player.discoveredServers = [];
Player.purchasedServers = [];
Player.factions = [];
Player.factionInvitations = [];
Player.queuedAugmentations = [];
Player.startAction = false;
Player.actionTime = 0;
Player.isWorking = false;
Player.currentWorkFactionName = "";
Player.currentWorkFactionDescription = "";
this.createProgramName = "";
this.className = "";
this.crimeType = "";
Player.workHackExpGainRate = 0;
Player.workStrExpGainRate = 0;
Player.workDefExpGainRate = 0;
Player.workDexExpGainRate = 0;
Player.workAgiExpGainRate = 0;
Player.workChaExpGainRate = 0;
Player.workRepGainRate = 0;
Player.workMoneyGainRate = 0;
Player.workHackExpGained = 0;
Player.workStrExpGained = 0;
Player.workDefExpGained = 0;
Player.workDexExpGained = 0;
Player.workAgiExpGained = 0;
Player.workChaExpGained = 0;
Player.workRepGained = 0;
Player.workMoneyGained = 0;
Player.timeWorked = 0;
Player.lastUpdate = new Date().getTime();
//Delete all Worker Scripts objects //Delete all Worker Scripts objects
for (var i = 0; i < workerScripts.length; ++i) { prestigeWorkerScripts();
deleteActiveScriptsItem(workerScripts[i]);
workerScripts[i].env.stopFlag = true;
}
workerScripts.length = 0;
var homeComp = Player.getHomeComputer(); var homeComp = Player.getHomeComputer();
//Delete all servers except home computer //Delete all servers except home computer
for (var member in AllServers) { prestigeAllServers();
delete AllServers[member];
}
AllServers = {};
//Delete Special Server IPs //Delete Special Server IPs
for (var member in SpecialServerIps) { prestigeSpecialServerIps(); //Must be done before initForeignServers()
delete SpecialServerIps[member];
}
SpecialServersIps = null;
//Reset home computer (only the programs) and add to AllServers //Reset home computer (only the programs) and add to AllServers
homeComp.programs.length = 0; prestigeHomeComputer(homeComp);
homeComp.runningScripts = [];
homeComp.serversOnNetwork = [];
homeComp.isConnectedTo = true;
homeComp.ramUsed = 0;
homeComp.programs.push(Programs.NukeProgram);
if (augmentationExists(AugmentationNames.Neurolink) && if (augmentationExists(AugmentationNames.Neurolink) &&
Augmentations[AugmentationNames.Neurolink].owned) { Augmentations[AugmentationNames.Neurolink].owned) {
homeComp.programs.push(Programs.FTPCrackProgram); homeComp.programs.push(Programs.FTPCrackProgram);
@ -115,31 +50,18 @@ function prestigeAugmentation() {
} }
if (augmentationExists(AugmentationNames.CashRoot) && if (augmentationExists(AugmentationNames.CashRoot) &&
Augmentations[AugmentationNames.CashRoot].owned) { Augmentations[AugmentationNames.CashRoot].owned) {
Player.money = new Decimal(1000000); Player.setMoney(new Decimal(1000000));
homeComp.programs.push(Programs.BruteSSHProgram); homeComp.programs.push(Programs.BruteSSHProgram);
} }
Player.currentServer = homeComp.ip;
Player.homeComputer = homeComp.ip;
AddToAllServers(homeComp); AddToAllServers(homeComp);
//Re-create foreign servers //Re-create foreign servers
SpecialServerIps = new SpecialServerIpsMap(); //Must be done before initForeignServers()
initForeignServers(); initForeignServers();
//Darkweb is purchase-able //Darkweb is purchase-able
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button"); document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
//Reset statistics of all scripts on home computer
for (var i = 0; i < homeComp.scripts.length; ++i) {
var s = homeComp.scripts[i];
}
//Delete messages on home computer
homeComp.messages.length = 0;
//Delete Hacknet Nodes
Player.hacknetNodes.length = 0;
Player.totalHacknetNodeProduction = 0;
//Gain favor for Companies //Gain favor for Companies
for (var member in Companies) { for (var member in Companies) {
if (Companies.hasOwnProperty(member)) { if (Companies.hasOwnProperty(member)) {
@ -192,8 +114,6 @@ function prestigeAugmentation() {
} }
} }
Player.playtimeSinceLastAug = 0;
var mainMenu = document.getElementById("mainmenu-container"); var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible"; mainMenu.style.visibility = "visible";
Engine.loadTerminalContent(); Engine.loadTerminalContent();
@ -216,110 +136,22 @@ function prestigeSourceFile() {
initBitNodeMultipliers(); initBitNodeMultipliers();
//Crime statistics //Crime statistics
Player.numTimesShoplifted = 0; Player.prestigeSourceFile();
Player.numPeopleMugged = 0;
Player.numTimesDealtDrugs = 0;
Player.numTimesTraffickArms = 0;
Player.numPeopleKilled = 0;
Player.numTimesGrandTheftAuto = 0;
Player.numTimesKidnapped = 0;
Player.numTimesHeist = 0;
Player.karma = 0;
//Reset stats
Player.hacking_skill = 1;
Player.strength = 1;
Player.defense = 1;
Player.dexterity = 1;
Player.agility = 1;
Player.charisma = 1;
Player.hacking_exp = 0;
Player.strength_exp = 0;
Player.defense_exp = 0;
Player.dexterity_exp = 0;
Player.agility_exp = 0;
Player.charisma_exp = 0;
Player.money = new Decimal(1000);
Player.city = Locations.Sector12;
Player.location = "";
Player.companyName = "";
Player.companyPosition = "";
Player.currentServer = "";
Player.discoveredServers = [];
Player.purchasedServers = [];
Player.factions = [];
Player.factionInvitations = [];
Player.queuedAugmentations = [];
Player.augmentations = [];
Player.startAction = false;
Player.actionTime = 0;
Player.isWorking = false;
Player.currentWorkFactionName = "";
Player.currentWorkFactionDescription = "";
this.createProgramName = "";
this.className = "";
this.crimeType = "";
Player.workHackExpGainRate = 0;
Player.workStrExpGainRate = 0;
Player.workDefExpGainRate = 0;
Player.workDexExpGainRate = 0;
Player.workAgiExpGainRate = 0;
Player.workChaExpGainRate = 0;
Player.workRepGainRate = 0;
Player.workMoneyGainRate = 0;
Player.workHackExpGained = 0;
Player.workStrExpGained = 0;
Player.workDefExpGained = 0;
Player.workDexExpGained = 0;
Player.workAgiExpGained = 0;
Player.workChaExpGained = 0;
Player.workRepGained = 0;
Player.workMoneyGained = 0;
Player.timeWorked = 0;
Player.lastUpdate = new Date().getTime();
//Delete all Worker Scripts objects //Delete all Worker Scripts objects
for (var i = 0; i < workerScripts.length; ++i) { prestigeWorkerScripts();
deleteActiveScriptsItem(workerScripts[i]);
workerScripts[i].env.stopFlag = true;
}
workerScripts.length = 0;
var homeComp = Player.getHomeComputer(); var homeComp = Player.getHomeComputer();
//Delete all servers except home computer //Delete all servers except home computer
for (var member in AllServers) { prestigeAllServers(); //Must be done before initForeignServers()
delete AllServers[member];
}
AllServers = {};
//Delete Special Server IPs //Delete Special Server IPs
for (var member in SpecialServerIps) { prestigeSpecialServerIps();
delete SpecialServerIps[member];
}
SpecialServersIps = null;
//Reset home computer (only the programs) and add to AllServers //Reset home computer (only the programs) and add to AllServers
homeComp.programs.length = 0; prestigeHomeComputer(homeComp);
homeComp.runningScripts = [];
homeComp.serversOnNetwork = [];
homeComp.isConnectedTo = true;
homeComp.ramUsed = 0;
homeComp.programs.push(Programs.NukeProgram);
var srcFile1Owned = false; var srcFile1Owned = false;
for (var i = 0; i < Player.sourceFiles.length; ++i) { for (var i = 0; i < Player.sourceFiles.length; ++i) {
if (Player.sourceFiles[i].n == 1) { if (Player.sourceFiles[i].n == 1) {
@ -327,32 +159,19 @@ function prestigeSourceFile() {
} }
} }
if (srcFile1Owned) { if (srcFile1Owned) {
homeComp.maxRam = 32; homeComp.setMaxRam(32);
} else { } else {
homeComp.maxRam = 8; homeComp.setMaxRam(8);
} }
Player.currentServer = homeComp.ip;
Player.homeComputer = homeComp.ip;
AddToAllServers(homeComp); AddToAllServers(homeComp);
//Re-create foreign servers //Re-create foreign servers
SpecialServerIps = new SpecialServerIpsMap(); //Must be done before initForeignServers()
initForeignServers(); initForeignServers();
//Darkweb is purchase-able //Darkweb is purchase-able
document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button"); document.getElementById("location-purchase-tor").setAttribute("class", "a-link-button");
//Reset statistics of all scripts on home computer
for (var i = 0; i < homeComp.scripts.length; ++i) {
var s = homeComp.scripts[i];
}
//Delete messages on home computer
homeComp.messages.length = 0;
//Delete Hacknet Nodes
Player.hacknetNodes.length = 0;
Player.totalHacknetNodeProduction = 0;
//Reset favor for Companies //Reset favor for Companies
for (var member in Companies) { for (var member in Companies) {
if (Companies.hasOwnProperty(member)) { if (Companies.hasOwnProperty(member)) {
@ -393,16 +212,9 @@ function prestigeSourceFile() {
//Messages //Messages
initMessages(); initMessages();
//Gang
Player.gang = null;
//Reset Stock market
Player.hasWseAccount = false;
Player.hasTixApiAccess = false;
Player.playtimeSinceLastAug = 0;
var mainMenu = document.getElementById("mainmenu-container"); var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible"; mainMenu.style.visibility = "visible";
Engine.loadTerminalContent(); Engine.loadTerminalContent();
} }
export {prestigeAugmentation, prestigeSourceFile};

@ -1,3 +1,15 @@
import {BitNode, BitNodes} from "./BitNode.js";
import {Engine} from "./engine.js";
import {Player} from "./Player.js";
import {prestigeSourceFile} from "./Prestige.js";
import {SourceFiles, SourceFile} from "./SourceFile.js";
import {Terminal} from "./Terminal.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {yesNoBoxCreate, yesNoBoxGetYesButton,
yesNoBoxGetNoButton, yesNoBoxClose} from "../utils/YesNoBox.js";
/* RedPill.js /* RedPill.js
* Implements what happens when you have Red Pill augmentation and then hack the world daemon */ * Implements what happens when you have Red Pill augmentation and then hack the world daemon */
@ -38,7 +50,7 @@ function writeRedPillLetter(pElem, line, i=0) {
}); });
} }
redPillFlag = false; let redPillFlag = false;
function hackWorldDaemon(currentNodeNumber) { function hackWorldDaemon(currentNodeNumber) {
redPillFlag = true; redPillFlag = true;
Engine.loadRedPillContent(); Engine.loadRedPillContent();
@ -193,7 +205,7 @@ function loadBitVerse(destroyedBitNodeNum) {
var elemId = "bitnode-" + i.toString(); var elemId = "bitnode-" + i.toString();
var elem = clearEventListeners(elemId); var elem = clearEventListeners(elemId);
if (elem == null) {return;} if (elem == null) {return;}
if (i == 1 || i == 2) { if (i === 1 || i === 2 || i === 4 || i === 11) {
elem.addEventListener("click", function() { elem.addEventListener("click", function() {
var bitNodeKey = "BitNode" + i; var bitNodeKey = "BitNode" + i;
var bitNode = BitNodes[bitNodeKey]; var bitNode = BitNodes[bitNodeKey];
@ -282,6 +294,7 @@ function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode) {
//Set new Bit Node //Set new Bit Node
Player.bitNodeN = newBitNode; Player.bitNodeN = newBitNode;
console.log("Entering Bit Node " + Player.bitNodeN);
//Reenable terminal //Reenable terminal
$("#hack-progress-bar").attr('id', "old-hack-progress-bar"); $("#hack-progress-bar").attr('id', "old-hack-progress-bar");
@ -293,7 +306,6 @@ function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode) {
prestigeSourceFile(); prestigeSourceFile();
yesNoBoxClose(); yesNoBoxClose();
//TODO Dialog box for going ot new Bit node
}); });
var noBtn = yesNoBoxGetNoButton(); var noBtn = yesNoBoxGetNoButton();
noBtn.innerHTML = "Back"; noBtn.innerHTML = "Back";
@ -302,3 +314,5 @@ function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode) {
}); });
} }
export {redPillFlag, hackWorldDaemon};

@ -1,7 +1,33 @@
import {loadAliases, loadGlobalAliases,
Aliases, GlobalAliases} from "./Alias.js";
import {loadCompanies, Companies,
CompanyPositions} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {loadFactions, Factions,
processPassiveFactionRepGain} from "./Faction.js";
import {loadAllGangs, AllGangs} from "./Gang.js";
import {processAllHacknetNodeEarnings} from "./HacknetNode.js";
import {loadMessages, initMessages, Messages} from "./Message.js";
import {Player, loadPlayer} from "./Player.js";
import {loadAllRunningScripts} from "./Script.js";
import {AllServers, loadAllServers} from "./Server.js";
import {loadSettings, initSettings, Settings} from "./Settings.js";
import {loadSpecialServerIps, SpecialServerIps} from "./SpecialServerIps.js";
import {loadStockMarket, StockMarket} from "./StockMarket.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {gameOptionsBoxClose} from "../utils/GameOptions.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
import Decimal from '../utils/decimal.js';
/* SaveObject.js /* SaveObject.js
* Defines the object used to save/load games * Defines the object used to save/load games
*/ */
var saveObject = new BitburnerSaveObject(); let saveObject = new BitburnerSaveObject();
function BitburnerSaveObject() { function BitburnerSaveObject() {
this.PlayerSave = ""; this.PlayerSave = "";
@ -53,7 +79,7 @@ BitburnerSaveObject.prototype.saveGame = function() {
Engine.createStatusText("Game saved!"); Engine.createStatusText("Game saved!");
} }
loadGame = function(saveObj) { function loadGame(saveObj) {
if (!window.localStorage.getItem("bitburnerSave")) { if (!window.localStorage.getItem("bitburnerSave")) {
console.log("No save file to load"); console.log("No save file to load");
return false; return false;
@ -61,39 +87,33 @@ loadGame = function(saveObj) {
var saveString = decodeURIComponent(escape(atob(window.localStorage.getItem("bitburnerSave")))); var saveString = decodeURIComponent(escape(atob(window.localStorage.getItem("bitburnerSave"))));
saveObj = JSON.parse(saveString, Reviver); saveObj = JSON.parse(saveString, Reviver);
Player = JSON.parse(saveObj.PlayerSave, Reviver); loadPlayer(saveObj.PlayerSave);
loadAllServers(saveObj.AllServersSave);
//Parse Decimal.js objects loadCompanies(saveObj.CompaniesSave);
Player.money = new Decimal(Player.money); loadFactions(saveObj.FactionsSave);
Player.total_money = new Decimal(Player.total_money); loadSpecialServerIps(saveObj.SpecialServerIpsSave);
Player.lifetime_money = new Decimal(Player.lifetime_money);
AllServers = JSON.parse(saveObj.AllServersSave, Reviver);
Companies = JSON.parse(saveObj.CompaniesSave, Reviver);
Factions = JSON.parse(saveObj.FactionsSave, Reviver);
SpecialServerIps = JSON.parse(saveObj.SpecialServerIpsSave, Reviver);
if (saveObj.hasOwnProperty("AliasesSave")) { if (saveObj.hasOwnProperty("AliasesSave")) {
try { try {
Aliases = JSON.parse(saveObj.AliasesSave, Reviver); loadAliases(saveObj.AliasesSave);
} catch(e) { } catch(e) {
Aliases = {}; loadAliases("");
} }
} else { } else {
Aliases = {}; loadAliases("");
} }
if (saveObj.hasOwnProperty("GlobalAliasesSave")) { if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
try { try {
GlobalAliases = JSON.parse(saveObj.GlobalAliasesSave, Reviver); loadGlobalAliases(saveObj.GlobalAliasesSave);
} catch(e) { } catch(e) {
GlobalAliases = {}; loadGlobalAliases("");
} }
} else { } else {
GlobalAliases = {}; loadGlobalAliases("");
} }
if (saveObj.hasOwnProperty("MessagesSave")) { if (saveObj.hasOwnProperty("MessagesSave")) {
try { try {
Messages = JSON.parse(saveObj.MessagesSave, Reviver); loadMessages(saveObj.MessagesSave);
} catch(e) { } catch(e) {
initMessages(); initMessages();
} }
@ -102,17 +122,18 @@ loadGame = function(saveObj) {
} }
if (saveObj.hasOwnProperty("StockMarketSave")) { if (saveObj.hasOwnProperty("StockMarketSave")) {
try { try {
StockMarket = JSON.parse(saveObj.StockMarketSave, Reviver); loadStockMarket(saveObj.StockMarketSave);
} catch(e) { } catch(e) {
StockMarket = {}; loadStockMarket("");
} }
} else { } else {
StockMarket = {}; loadStockMarket("");
} }
if (saveObj.hasOwnProperty("SettingsSave")) { if (saveObj.hasOwnProperty("SettingsSave")) {
try { try {
Settings = JSON.parse(saveObj.SettingsSave, Reviver); loadSettings(saveObj.SettingsSave);
} catch(e) { } catch(e) {
console.log("ERROR: Failed to parse Settings. Re-initing default values");
initSettings(); initSettings();
} }
} else { } else {
@ -121,13 +142,10 @@ loadGame = function(saveObj) {
if (saveObj.hasOwnProperty("VersionSave")) { if (saveObj.hasOwnProperty("VersionSave")) {
try { try {
var ver = JSON.parse(saveObj.VersionSave, Reviver); var ver = JSON.parse(saveObj.VersionSave, Reviver);
if (ver.startsWith("0.27.")) { if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
console.log("Evaluating changes needed for version compatibility"); console.log("Evaluating changes needed for version compatibility");
if (Player.bitNodeN == null || Player.bitNodeN == 0) { if (Player.bitNodeN == null || Player.bitNodeN == 0) {
Player.bitNodeN = 1; Player.setBitNodeNumber(1);
}
if (Player.sourceFiles == null) {
Player.sourceFiles = [];
} }
} }
if (ver != CONSTANTS.Version) { if (ver != CONSTANTS.Version) {
@ -141,7 +159,7 @@ loadGame = function(saveObj) {
} }
if (Player.bitNodeN == 2 && Player.inGang() && saveObj.hasOwnProperty("AllGangsSave")) { if (Player.bitNodeN == 2 && Player.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
try { try {
AllGangs = JSON.parse(saveObj.AllGangsSave, Reviver); loadAllGangs(saveObj.AllGangsSave);
} catch(e) { } catch(e) {
console.log("ERROR: Failed to parse AllGangsSave: " + e); console.log("ERROR: Failed to parse AllGangsSave: " + e);
} }
@ -150,24 +168,26 @@ loadGame = function(saveObj) {
return true; return true;
} }
loadImportedGame = function(saveObj, saveString) { function loadImportedGame(saveObj, saveString) {
var tempSaveObj = null; var tempSaveObj = null;
var tempPlayer = null; var tempPlayer = null;
var tempAllServers = null; var tempAllServers = null;
var tempCompanies = null; var tempCompanies = null;
var tempFactions = null; var tempFactions = null;
var tempSpecialServerIps = null; var tempSpecialServerIps = null;
var tempAugmentations = null;
var tempAliases = null; var tempAliases = null;
var tempGlobalAliases = null; var tempGlobalAliases = null;
var tempMessages = null; var tempMessages = null;
var tempStockMarket = null; var tempStockMarket = null;
try {
saveString = decodeURIComponent(escape(atob(saveString)));
tempSaveObj = new BitburnerSaveObject();
tempSaveObj = JSON.parse(saveString, Reviver);
tempPlayer = JSON.parse(tempSaveObj.PlayerSave, Reviver); //Check to see if the imported save file can be parsed. If any
//errors are caught it will fail
try {
var decodedSaveString = decodeURIComponent(escape(atob(saveString)));
tempSaveObj = new BitburnerSaveObject();
tempSaveObj = JSON.parse(decodedSaveString, Reviver);
tempPlayer = JSON.parse(tempSaveObj.PlayerSave, Reviver);
//Parse Decimal.js objects //Parse Decimal.js objects
tempPlayer.money = new Decimal(tempPlayer.money); tempPlayer.money = new Decimal(tempPlayer.money);
@ -178,11 +198,11 @@ loadImportedGame = function(saveObj, saveString) {
tempCompanies = JSON.parse(tempSaveObj.CompaniesSave, Reviver); tempCompanies = JSON.parse(tempSaveObj.CompaniesSave, Reviver);
tempFactions = JSON.parse(tempSaveObj.FactionsSave, Reviver); tempFactions = JSON.parse(tempSaveObj.FactionsSave, Reviver);
tempSpecialServerIps = JSON.parse(tempSaveObj.SpecialServerIpsSave, Reviver); tempSpecialServerIps = JSON.parse(tempSaveObj.SpecialServerIpsSave, Reviver);
tempAugmentations = JSON.parse(tempSaveObj.AugmentationsSave, Reviver);
if (tempSaveObj.hasOwnProperty("AliasesSave")) { if (tempSaveObj.hasOwnProperty("AliasesSave")) {
try { try {
tempAliases = JSON.parse(tempSaveObj.AliasesSave, Reviver); tempAliases = JSON.parse(tempSaveObj.AliasesSave, Reviver);
} catch(e) { } catch(e) {
console.log("Parsing Aliases save failed: " + e);
tempAliases = {}; tempAliases = {};
} }
} else { } else {
@ -192,6 +212,7 @@ loadImportedGame = function(saveObj, saveString) {
try { try {
tempGlobalAliases = JSON.parse(tempSaveObj.AliasesSave, Reviver); tempGlobalAliases = JSON.parse(tempSaveObj.AliasesSave, Reviver);
} catch(e) { } catch(e) {
console.log("Parsing Global Aliases save failed: " + e);
tempGlobalAliases = {}; tempGlobalAliases = {};
} }
} else { } else {
@ -201,6 +222,7 @@ loadImportedGame = function(saveObj, saveString) {
try { try {
tempMessages = JSON.parse(tempSaveObj.MessagesSave, Reviver); tempMessages = JSON.parse(tempSaveObj.MessagesSave, Reviver);
} catch(e) { } catch(e) {
console.log("Parsing Messages save failed: " + e);
initMessages(); initMessages();
} }
} else { } else {
@ -210,6 +232,7 @@ loadImportedGame = function(saveObj, saveString) {
try { try {
tempStockMarket = JSON.parse(saveObj.StockMarketSave, Reviver); tempStockMarket = JSON.parse(saveObj.StockMarketSave, Reviver);
} catch(e) { } catch(e) {
console.log("Parsing StockMarket save failed: " + e);
tempStockMarket = {}; tempStockMarket = {};
} }
} else { } else {
@ -218,7 +241,7 @@ loadImportedGame = function(saveObj, saveString) {
if (tempSaveObj.hasOwnProperty("VersionSave")) { if (tempSaveObj.hasOwnProperty("VersionSave")) {
try { try {
var ver = JSON.parse(tempSaveObj.VersionSave, Reviver); var ver = JSON.parse(tempSaveObj.VersionSave, Reviver);
if (ver == "0.27.0" || ver == "0.27.1") { if (ver.startsWith("0.27.") || ver.startsWith("0.28.")) {
if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) { if (tempPlayer.bitNodeN == null || tempPlayer.bitNodeN == 0) {
tempPlayer.bitNodeN = 1; tempPlayer.bitNodeN = 1;
} }
@ -227,13 +250,14 @@ loadImportedGame = function(saveObj, saveString) {
} }
} }
if (ver != CONSTANTS.Version) { if (ver != CONSTANTS.Version) {
createNewUpdateText(); //createNewUpdateText();
} }
} catch(e) { } catch(e) {
createNewUpdateText(); console.log("Parsing Version save failed: " + e);
//createNewUpdateText();
} }
} else { } else {
createNewUpdateText(); //createNewUpdateText();
} }
if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && saveObj.hasOwnProperty("AllGangsSave")) { if (tempPlayer.bitNodeN == 2 && tempPlayer.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
try { try {
@ -243,31 +267,89 @@ loadImportedGame = function(saveObj, saveString) {
} }
} }
} catch(e) { } catch(e) {
dialogBoxCreate("Error importing game"); dialogBoxCreate("Error importing game: " + e.toString());
return false; return false;
} }
saveObj = tempSaveObj; //Since the save file is valid, load everything for real
Player = tempPlayer; saveString = decodeURIComponent(escape(atob(saveString)));
AllServers = tempAllServers; saveObj = JSON.parse(saveString, Reviver);
Companies = tempCompanies;
Factions = tempFactions;
SpecialServerIps = tempSpecialServerIps;
Augmentations = tempAugmentations;
if (tempAliases) {
Aliases = tempAliases;
}
if (tempGlobalAliases) { loadPlayer(saveObj.PlayerSave);
GlobalAliases = tempGlobalAliases; loadAllServers(saveObj.AllServersSave);
} loadCompanies(saveObj.CompaniesSave);
loadFactions(saveObj.FactionsSave);
loadSpecialServerIps(saveObj.SpecialServerIpsSave);
if (tempMessages) { if (saveObj.hasOwnProperty("AliasesSave")) {
Messages = tempMessages; try {
loadAliases(saveObj.AliasesSave);
} catch(e) {
loadAliases("");
}
} else {
loadAliases("");
} }
if (saveObj.hasOwnProperty("GlobalAliasesSave")) {
if (tempStockMarket) { try {
StockMarket = tempStockMarket; loadGlobalAliases(saveObj.GlobalAliasesSave);
} catch(e) {
loadGlobalAliases("");
}
} else {
loadGlobalAliases("");
}
if (saveObj.hasOwnProperty("MessagesSave")) {
try {
loadMessages(saveObj.MessagesSave);
} catch(e) {
initMessages();
}
} else {
initMessages();
}
if (saveObj.hasOwnProperty("StockMarketSave")) {
try {
loadStockMarket(saveObj.StockMarketSave);
} catch(e) {
loadStockMarket("");
}
} else {
loadStockMarket("");
}
if (saveObj.hasOwnProperty("SettingsSave")) {
try {
loadSettings(saveObj.SettingsSave);
} catch(e) {
initSettings();
}
} else {
initSettings();
}
if (saveObj.hasOwnProperty("VersionSave")) {
try {
var ver = JSON.parse(saveObj.VersionSave, Reviver);
if (ver.startsWith("0.27.")) {
console.log("Evaluating changes needed for version compatibility");
if (Player.bitNodeN == null || Player.bitNodeN == 0) {
Player.setBitNodeNumber(1);
}
}
if (ver != CONSTANTS.Version) {
createNewUpdateText();
}
} catch(e) {
createNewUpdateText();
}
} else {
createNewUpdateText();
}
if (Player.bitNodeN == 2 && Player.inGang() && saveObj.hasOwnProperty("AllGangsSave")) {
try {
loadAllGangs(saveObj.AllGangsSave);
} catch(e) {
console.log("ERROR: Failed to parse AllGangsSave: " + e);
}
} }
dialogBoxCreate("Imported game! I would suggest saving the game and then reloading the page " + dialogBoxCreate("Imported game! I would suggest saving the game and then reloading the page " +
@ -337,7 +419,6 @@ BitburnerSaveObject.prototype.exportGame = function() {
this.CompaniesSave = JSON.stringify(Companies); this.CompaniesSave = JSON.stringify(Companies);
this.FactionsSave = JSON.stringify(Factions); this.FactionsSave = JSON.stringify(Factions);
this.SpecialServerIpsSave = JSON.stringify(SpecialServerIps); this.SpecialServerIpsSave = JSON.stringify(SpecialServerIps);
this.AugmentationsSave = JSON.stringify(Augmentations);
this.AliasesSave = JSON.stringify(Aliases); this.AliasesSave = JSON.stringify(Aliases);
this.GlobalAliasesSave = JSON.stringify(GlobalAliases); this.GlobalAliasesSave = JSON.stringify(GlobalAliases);
this.MessagesSave = JSON.stringify(Messages); this.MessagesSave = JSON.stringify(Messages);
@ -380,7 +461,7 @@ BitburnerSaveObject.prototype.deleteGame = function() {
Engine.createStatusText("Game deleted!"); Engine.createStatusText("Game deleted!");
} }
createNewUpdateText = function() { function createNewUpdateText() {
dialogBoxCreate("New update!<br>" + dialogBoxCreate("New update!<br>" +
"Please report any bugs/issues through the github repository " + "Please report any bugs/issues through the github repository " +
"or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" + "or the Bitburner subreddit (reddit.com/r/bitburner).<br><br>" +
@ -414,3 +495,5 @@ function openImportFileHandler(evt) {
}; };
reader.readAsText(file); reader.readAsText(file);
} }
export {saveObject, loadGame};

@ -1,6 +1,18 @@
/* Script.js import {CONSTANTS} from "./Constants.js";
* Script object import {Engine} from "./engine.js";
*/ import {iTutorialSteps, iTutorialNextStep,
iTutorialIsRunning, currITutorialStep} from "./InteractiveTutorial.js";
import {addWorkerScript, killWorkerScript} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
import {AllServers, processSingleServerGrowth} from "./Server.js";
import {Settings} from "./Settings.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
import {compareArrays} from "../utils/HelperFunctions.js";
import {formatNumber, numOccurrences,
numNetscriptOperators} from "../utils/StringHelperFunctions.js";
function scriptEditorInit() { function scriptEditorInit() {
//Initialize save and close button //Initialize save and close button
@ -22,7 +34,7 @@ function scriptEditorInit() {
var end = this.selectionEnd; var end = this.selectionEnd;
//Set textarea value to: text before caret + four spaces + text after caret //Set textarea value to: text before caret + four spaces + text after caret
spaces = " "; let spaces = " ";
this.value = this.value.substring(0, start) + spaces + this.value.substring(end); this.value = this.value.substring(0, start) + spaces + this.value.substring(end);
//Put caret at after the four spaces //Put caret at after the four spaces
@ -34,7 +46,7 @@ function scriptEditorInit() {
document.addEventListener("DOMContentLoaded", scriptEditorInit, false); document.addEventListener("DOMContentLoaded", scriptEditorInit, false);
//Updates line number and RAM usage in script //Updates line number and RAM usage in script
function upgradeScriptEditorContent() { function updateScriptEditorContent() {
var txt = $("#script-editor-text")[0]; var txt = $("#script-editor-text")[0];
var lineNum = txt.value.substr(0, txt.selectionStart).split("\n").length; var lineNum = txt.value.substr(0, txt.selectionStart).split("\n").length;
@ -200,6 +212,30 @@ function calculateRamUsage(codeCopy) {
var getHackTimeCount = numOccurrences(codeCopy, "getHackTime(") + var getHackTimeCount = numOccurrences(codeCopy, "getHackTime(") +
numOccurrences(codeCopy, "getGrowTime(") + numOccurrences(codeCopy, "getGrowTime(") +
numOccurrences(codeCopy, "getWeakenTime("); numOccurrences(codeCopy, "getWeakenTime(");
var singFn1Count = numOccurrences(codeCopy, "universityCourse(") +
numOccurrences(codeCopy, "gymWorkout(") +
numOccurrences(codeCopy, "travelToCity(") +
numOccurrences(codeCopy, "purchaseTor(") +
numOccurrences(codeCopy, "purchaseProgram(");
var singFn2Count = numOccurrences(codeCopy, "upgradeHomeRam(") +
numOccurrences(codeCopy, "getUpgradeHomeRamCost(") +
numOccurrences(codeCopy, "workForCompany(") +
numOccurrences(codeCopy, "applyToCompany(") +
numOccurrences(codeCopy, "getCompanyRep(") +
numOccurrences(codeCopy, "checkFactionInvitations(") +
numOccurrences(codeCopy, "joinFaction(") +
numOccurrences(codeCopy, "workForFaction(") +
numOccurrences(codeCopy, "getFactionRep(");
var singFn3Count = numOccurrences(codeCopy, "createProgram(") +
numOccurrences(codeCopy, "getAugmentationCost(") +
numOccurrences(codeCopy, "purchaseAugmentation(") +
numOccurrences(codeCopy, "installAugmentations(");
if (Player.bitNodeN != 4) {
singFn1Count *= 10;
singFn2Count *= 10;
singFn3Count *= 10;
}
return baseRam + return baseRam +
((whileCount * CONSTANTS.ScriptWhileRamCost) + ((whileCount * CONSTANTS.ScriptWhileRamCost) +
@ -238,8 +274,11 @@ function calculateRamUsage(codeCopy) {
(scriptWriteCount * CONSTANTS.ScriptReadWriteRamCost) + (scriptWriteCount * CONSTANTS.ScriptReadWriteRamCost) +
(scriptReadCount * CONSTANTS.ScriptReadWriteRamCost) + (scriptReadCount * CONSTANTS.ScriptReadWriteRamCost) +
(arbScriptCount * CONSTANTS.ScriptArbScriptRamCost) + (arbScriptCount * CONSTANTS.ScriptArbScriptRamCost) +
(getScriptCount * CONSTANTS.ScriptGetScriptCost) + (getScriptCount * CONSTANTS.ScriptGetScriptRamCost) +
(getHackTimeCount * CONSTANTS.ScriptGetHackTimeCost)); (getHackTimeCount * CONSTANTS.ScriptGetHackTimeRamCost) +
(singFn1Count * CONSTANTS.ScriptSingularityFn1RamCost) +
(singFn2Count * CONSTANTS.ScriptSingularityFn2RamCost) +
(singFn3Count * CONSTANTS.ScriptSingularityFn3RamCost));
} }
Script.prototype.toJSON = function() { Script.prototype.toJSON = function() {
@ -255,7 +294,7 @@ Reviver.constructors.Script = Script;
//Called when the game is loaded. Loads all running scripts (from all servers) //Called when the game is loaded. Loads all running scripts (from all servers)
//into worker scripts so that they will start running //into worker scripts so that they will start running
loadAllRunningScripts = function() { function loadAllRunningScripts() {
var count = 0; var count = 0;
var total = 0; var total = 0;
for (var property in AllServers) { for (var property in AllServers) {
@ -278,7 +317,7 @@ loadAllRunningScripts = function() {
console.log("Loaded " + count.toString() + " running scripts"); console.log("Loaded " + count.toString() + " running scripts");
} }
scriptCalculateOfflineProduction = function(runningScriptObj) { function scriptCalculateOfflineProduction(runningScriptObj) {
//The Player object stores the last update time from when we were online //The Player object stores the last update time from when we were online
var thisUpdate = new Date().getTime(); var thisUpdate = new Date().getTime();
var lastUpdate = Player.lastUpdate; var lastUpdate = Player.lastUpdate;
@ -473,6 +512,8 @@ RunningScript.fromJSON = function(value) {
return Generic_fromJSON(RunningScript, value.data); return Generic_fromJSON(RunningScript, value.data);
} }
Reviver.constructors.RunningScript = RunningScript;
//Creates an object that creates a map/dictionary with the IP of each existing server as //Creates an object that creates a map/dictionary with the IP of each existing server as
//a key. Initializes every key with a specified value that can either by a number or an array //a key. Initializes every key with a specified value that can either by a number or an array
function AllServersMap(arr=false) { function AllServersMap(arr=false) {
@ -517,3 +558,6 @@ AllServersMap.fromJSON = function(value) {
} }
Reviver.constructors.AllServersMap = AllServersMap; Reviver.constructors.AllServersMap = AllServersMap;
export {updateScriptEditorContent, loadAllRunningScripts, findRunningScript,
RunningScript, Script, AllServersMap};

@ -1,6 +1,14 @@
//Netburner Server class import {BitNodeMultipliers} from "./BitNode.js";
//TODO Make a map of all IPS in the game so far so that we don't accidentally import {CONSTANTS} from "./Constants.js";
// get duplicate IPs..however unlikely it is import {Programs} from "./CreateProgram.js";
import {Player} from "./Player.js";
import {RunningScript, Script} from "./Script.js";
import {SpecialServerNames, SpecialServerIps} from "./SpecialServerIps.js";
import {getRandomInt} from "../utils/HelperFunctions.js";
import {createRandomIp, isValidIPAddress, ipExists} from "../utils/IPAddress.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
function Server(ip=createRandomIp(), hostname="", organizationName="", function Server(ip=createRandomIp(), hostname="", organizationName="",
isConnectedTo=false, adminRights=false, purchasedByPlayer=false, maxRam=0) { isConnectedTo=false, adminRights=false, purchasedByPlayer=false, maxRam=0) {
/* Properties */ /* Properties */
@ -67,9 +75,9 @@ Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvai
if (isNaN(moneyAvailable)) { if (isNaN(moneyAvailable)) {
this.moneyAvailable = 1000000; this.moneyAvailable = 1000000;
} else { } else {
this.moneyAvailable = moneyAvailable; this.moneyAvailable = moneyAvailable * BitNodeMultipliers.ServerStartingMoney;
} }
this.moneyMax = 25 * moneyAvailable * BitNodeMultipliers.ServerMaxMoney; this.moneyMax = 25 * this.moneyAvailable * BitNodeMultipliers.ServerMaxMoney;
this.hackDifficulty = hackDifficulty; this.hackDifficulty = hackDifficulty;
this.baseDifficulty = hackDifficulty; this.baseDifficulty = hackDifficulty;
this.minDifficulty = Math.max(1, Math.round(hackDifficulty / 3)); this.minDifficulty = Math.max(1, Math.round(hackDifficulty / 3));
@ -82,6 +90,10 @@ Server.prototype.setPortProperties = function(numOpenPortsReq) {
this.numOpenPortsRequired = numOpenPortsReq; this.numOpenPortsRequired = numOpenPortsReq;
} }
Server.prototype.setMaxRam = function(ram) {
this.maxRam = ram;
}
//The serverOnNetwork array holds the IP of all the servers. This function //The serverOnNetwork array holds the IP of all the servers. This function
//returns the actual Server objects //returns the actual Server objects
Server.prototype.getServerOnNetwork = function(i) { Server.prototype.getServerOnNetwork = function(i) {
@ -110,7 +122,7 @@ Server.prototype.fortify = function(amt) {
} }
Server.prototype.weaken = function(amt) { Server.prototype.weaken = function(amt) {
this.hackDifficulty -= amt; this.hackDifficulty -= (amt * BitNodeMultipliers.ServerWeakenRate);
if (this.hackDifficulty < this.minDifficulty) {this.hackDifficulty = this.minDifficulty;} if (this.hackDifficulty < this.minDifficulty) {this.hackDifficulty = this.minDifficulty;}
if (this.hackDifficulty < 1) {this.hackDifficulty = 1;} if (this.hackDifficulty < 1) {this.hackDifficulty = 1;}
} }
@ -126,7 +138,7 @@ Server.fromJSON = function(value) {
Reviver.constructors.Server = Server; Reviver.constructors.Server = Server;
initForeignServers = function() { function initForeignServers() {
//MegaCorporations //MegaCorporations
var ECorpServer = new Server(createRandomIp(), "ecorp", "ECorp", false, false, false, 0); var ECorpServer = new Server(createRandomIp(), "ecorp", "ECorp", false, false, false, 0);
ECorpServer.setHackingParameters(getRandomInt(1150, 1300), getRandomInt(30000000000, 70000000000), 99, 99); ECorpServer.setHackingParameters(getRandomInt(1150, 1300), getRandomInt(30000000000, 70000000000), 99, 99);
@ -637,7 +649,7 @@ initForeignServers = function() {
} }
//Applied server growth for a single server. Returns the percentage growth //Applied server growth for a single server. Returns the percentage growth
processSingleServerGrowth = function(server, numCycles) { function processSingleServerGrowth(server, numCycles) {
//Server growth processed once every 450 game cycles //Server growth processed once every 450 game cycles
var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0); var numServerGrowthCycles = Math.max(Math.floor(numCycles / 450), 0);
@ -645,11 +657,10 @@ processSingleServerGrowth = function(server, numCycles) {
var growthRate = CONSTANTS.ServerBaseGrowthRate; var growthRate = CONSTANTS.ServerBaseGrowthRate;
var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty; var adjGrowthRate = 1 + (growthRate - 1) / server.hackDifficulty;
if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;} if (adjGrowthRate > CONSTANTS.ServerMaxGrowthRate) {adjGrowthRate = CONSTANTS.ServerMaxGrowthRate;}
//console.log("Adjusted growth rate: " + adjGrowthRate);
//Calculate adjusted server growth rate based on parameters //Calculate adjusted server growth rate based on parameters
var serverGrowthPercentage = server.serverGrowth / 100; var serverGrowthPercentage = server.serverGrowth / 100;
var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage; var numServerGrowthCyclesAdjusted = numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate;
//Apply serverGrowth for the calculated number of growth cycles //Apply serverGrowth for the calculated number of growth cycles
var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult); var serverGrowth = Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * Player.hacking_grow_mult);
@ -666,14 +677,38 @@ processSingleServerGrowth = function(server, numCycles) {
server.moneyAvailable = server.moneyMax; server.moneyAvailable = server.moneyMax;
return 1; return 1;
} }
//Growing increases server security twice as much as hacking
server.fortify(2 * CONSTANTS.ServerFortifyAmount * numServerGrowthCycles); server.fortify(2 * CONSTANTS.ServerFortifyAmount * numServerGrowthCycles);
return serverGrowth; return serverGrowth;
} }
//List of all servers that exist in the game, indexed by their ip function prestigeHomeComputer(homeComp) {
AllServers = {}; homeComp.programs.length = 0;
homeComp.runningScripts = [];
homeComp.serversOnNetwork = [];
homeComp.isConnectedTo = true;
homeComp.ramUsed = 0;
homeComp.programs.push(Programs.NukeProgram);
SizeOfAllServers = function() { homeComp.messages.length = 0;
}
//List of all servers that exist in the game, indexed by their ip
let AllServers = {};
function prestigeAllServers() {
for (var member in AllServers) {
delete AllServers[member];
}
AllServers = {};
}
function loadAllServers(saveString) {
AllServers = JSON.parse(saveString, Reviver);
}
function SizeOfAllServers() {
var size = 0, key; var size = 0, key;
for (key in AllServers) { for (key in AllServers) {
if (AllServers.hasOwnProperty(key)) size++; if (AllServers.hasOwnProperty(key)) size++;
@ -682,7 +717,7 @@ SizeOfAllServers = function() {
} }
//Add a server onto the map of all servers in the game //Add a server onto the map of all servers in the game
AddToAllServers = function(server) { function AddToAllServers(server) {
var serverIp = server.ip; var serverIp = server.ip;
if (ipExists(serverIp)) { if (ipExists(serverIp)) {
console.log("IP of server that's being added: " + serverIp); console.log("IP of server that's being added: " + serverIp);
@ -696,7 +731,7 @@ AddToAllServers = function(server) {
//Returns server object with corresponding hostname //Returns server object with corresponding hostname
// Relatively slow, would rather not use this a lot // Relatively slow, would rather not use this a lot
GetServerByHostname = function(hostname) { function GetServerByHostname(hostname) {
for (var ip in AllServers) { for (var ip in AllServers) {
if (AllServers.hasOwnProperty(ip)) { if (AllServers.hasOwnProperty(ip)) {
if (AllServers[ip].hostname == hostname) { if (AllServers[ip].hostname == hostname) {
@ -708,7 +743,7 @@ GetServerByHostname = function(hostname) {
} }
//Get server by IP or hostname. Returns null if invalid //Get server by IP or hostname. Returns null if invalid
getServer = function(s) { function getServer(s) {
if (!isValidIPAddress(s)) { if (!isValidIPAddress(s)) {
return GetServerByHostname(s); return GetServerByHostname(s);
} else { } else {
@ -717,10 +752,14 @@ getServer = function(s) {
} }
//Debugging tool //Debugging tool
PrintAllServers = function() { function PrintAllServers() {
for (var ip in AllServers) { for (var ip in AllServers) {
if (AllServers.hasOwnProperty(ip)) { if (AllServers.hasOwnProperty(ip)) {
console.log("Ip: " + ip + ", hostname: " + AllServers[ip].hostname); console.log("Ip: " + ip + ", hostname: " + AllServers[ip].hostname);
} }
} }
} }
export {Server, AllServers, getServer, GetServerByHostname, loadAllServers,
AddToAllServers, processSingleServerGrowth, initForeignServers,
prestigeAllServers, prestigeHomeComputer};

@ -1,8 +1,14 @@
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {AllServers} from "./Server.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {yesNoTxtInpBoxGetInput} from "../utils/YesNoBox.js";
/* Functions to handle any server-related purchasing: /* Functions to handle any server-related purchasing:
* Purchasing new servers * Purchasing new servers
* Purchasing more RAM for home computer * Purchasing more RAM for home computer
*/ */
purchaseServer = function(ram, cost) { function purchaseServer(ram, cost) {
//Check if player has enough money //Check if player has enough money
if (Player.money.lt(cost)) { if (Player.money.lt(cost)) {
dialogBoxCreate("You don't have enough money to purchase this server!"); dialogBoxCreate("You don't have enough money to purchase this server!");
@ -41,7 +47,7 @@ purchaseServer = function(ram, cost) {
} }
purchaseRamForHomeComputer = function(cost) { function purchaseRamForHomeComputer(cost) {
if (Player.money.lt(cost)) { if (Player.money.lt(cost)) {
dialogBoxCreate("You do not have enough money to purchase additional RAM for your home computer"); dialogBoxCreate("You do not have enough money to purchase additional RAM for your home computer");
return; return;
@ -54,3 +60,5 @@ purchaseRamForHomeComputer = function(cost) {
dialogBoxCreate("Purchased additional RAM for home computer! It now has " + homeComputer.maxRam + "GB of RAM."); dialogBoxCreate("Purchased additional RAM for home computer! It now has " + homeComputer.maxRam + "GB of RAM.");
} }
export {purchaseServer, purchaseRamForHomeComputer};

@ -1,5 +1,5 @@
/* Settings.js */ /* Settings.js */
Settings = { let Settings = {
CodeInstructionRunTime: 100, CodeInstructionRunTime: 100,
MaxLogCapacity: 50, MaxLogCapacity: 50,
MaxPortCapacity: 50, MaxPortCapacity: 50,
@ -7,6 +7,10 @@ Settings = {
SuppressFactionInvites: false, SuppressFactionInvites: false,
} }
function loadSettings(saveString) {
Settings = JSON.parse(saveString);
}
function initSettings() { function initSettings() {
Settings.CodeInstructionRunTime = 100; Settings.CodeInstructionRunTime = 100;
Settings.MaxLogCapacity = 50; Settings.MaxLogCapacity = 50;
@ -16,14 +20,42 @@ function initSettings() {
} }
function setSettingsLabels() { function setSettingsLabels() {
document.getElementById("settingsNSExecTimeRangeValLabel").innerHTML var nsExecTime = document.getElementById("settingsNSExecTimeRangeValLabel");
= Settings.CodeInstructionRunTime + "ms"; var nsLogLimit = document.getElementById("settingsNSLogRangeValLabel");
document.getElementById("settingsNSLogRangeValLabel").innerHTML var nsPortLimit = document.getElementById("settingsNSPortRangeValLabel");
= Settings.MaxLogCapacity; var suppressMsgs = document.getElementById("settingsSuppressMessages");
document.getElementById("settingsNSPortRangeValLabel").innerHTML var suppressFactionInv = document.getElementById("settingsSuppressFactionInvites")
= Settings.MaxPortCapacity;
document.getElementById("settingsSuppressMessages").checked //Initialize values on labels
= Settings.SuppressMessages; nsExecTime.innerHTML = Settings.CodeInstructionRunTime + "ms";
document.getElementById("settingsSuppressFactionInvites").checked nsLogLimit.innerHTML = Settings.MaxLogCapacity;
= Settings.SuppressFactionInvites; nsPortLimit.innerHTML = Settings.MaxPortCapacity;
suppressMsgs.checked = Settings.SuppressMessages;
suppressFactionInv.checked = Settings.SuppressFactionInvites;
//Set handlers for when input changes
document.getElementById("settingsNSExecTimeRangeVal").oninput = function() {
nsExecTime.innerHTML = this.value + 'ms';
Settings.CodeInstructionRunTime = this.value;
};
document.getElementById("settingsNSLogRangeVal").oninput = function() {
nsLogLimit.innerHTML = this.value;
Settings.MaxLogCapacity = this.value;
};
document.getElementById("settingsNSPortRangeVal").oninput = function() {
nsPortLimit.innerHTML = this.value;
Settings.MaxPortCapacity = this.value;
};
document.getElementById("settingsSuppressMessages").onclick = function() {
Settings.SuppressMessages = this.checked;
};
document.getElementById("settingsSuppressFactionInvites").onclick = function() {
Settings.SuppressFactionInvites = this.checked;
};
} }
export {Settings, initSettings, setSettingsLabels, loadSettings};

@ -1,5 +1,7 @@
/* SourceFile.js */ import {Player} from "./Player.js";
import {BitNode, BitNodes} from "./BitNode.js";
/* SourceFile.js */
//Each SourceFile corresponds to a BitNode with the same number //Each SourceFile corresponds to a BitNode with the same number
function SourceFile(number, info="") { function SourceFile(number, info="") {
var bitnodeKey = "BitNode" + number; var bitnodeKey = "BitNode" + number;
@ -15,27 +17,33 @@ function SourceFile(number, info="") {
this.owned = false; this.owned = false;
} }
SourceFiles = { let SourceFiles = {};
SourceFile1: new SourceFile(1, "This Source-File lets the player start with 32GB of RAM on his/her " + function initSourceFiles() {
SourceFiles = {};
SourceFiles["SourceFile1"] = new SourceFile(1, "This Source-File lets the player start with 32GB of RAM on his/her " +
"home computer. It also increases all of the player's multipliers by:<br><br>" + "home computer. It also increases all of the player's multipliers by:<br><br>" +
"Level 1: 16%<br>" + "Level 1: 16%<br>" +
"Level 2: 24%<br>" + "Level 2: 24%<br>" +
"Level 3: 28%"), "Level 3: 28%");
SourceFile2: new SourceFile(2, "This Source-File increases the player's crime success rate, crime money, and charisma " + SourceFiles["SourceFile2"] = new SourceFile(2, "This Source-File increases the player's crime success rate, crime money, and charisma " +
"multipliers by:<br><br>" + "multipliers by:<br><br>" +
"Level 1: 20%<br>" + "Level 1: 20%<br>" +
"Level 2: 30%<br>" + "Level 2: 30%<br>" +
"Level 3: 35%"), "Level 3: 35%");
SourceFile3: new SourceFile(3), SourceFiles["SourceFile3"] = new SourceFile(3);
SourceFile4: new SourceFile(4), SourceFiles["SourceFile4"] = new SourceFile(4, "This Source-File lets you access and use the Singularity Functions in every BitNode. Every " +
SourceFile5: new SourceFile(5), "level of this Source-File opens up more of the Singularity Functions you can use.");
SourceFile6: new SourceFile(6), SourceFiles["SourceFile5"] = new SourceFile(5);
SourceFile7: new SourceFile(7), SourceFiles["SourceFile6"] = new SourceFile(6);
SourceFile8: new SourceFile(8), SourceFiles["SourceFile7"] = new SourceFile(7);
SourceFile9: new SourceFile(9), SourceFiles["SourceFile8"] = new SourceFile(8);
SourceFile10: new SourceFile(10), SourceFiles["SourceFile9"] = new SourceFile(9);
SourceFile11: new SourceFile(11), SourceFiles["SourceFile10"] = new SourceFile(10);
SourceFile12: new SourceFile(12), SourceFiles["SourceFile11"] = new SourceFile(11, "This Source-File increases the player's company salary and reputation gain multipliers by:<br><br>" +
"Level 1: 60%<br>" +
"Level 2: 90%<br>" +
"Level 3: 105%<br>");
SourceFiles["SourceFile12"] = new SourceFile(12);
} }
function PlayerOwnedSourceFile(number, level) { function PlayerOwnedSourceFile(number, level) {
@ -97,6 +105,18 @@ function applySourceFile(srcFile) {
Player.crime_success_mult *= incMult; Player.crime_success_mult *= incMult;
Player.charisma_mult *= incMult; Player.charisma_mult *= incMult;
break; break;
case 4: //The Singularity
//No effects, just gives access to Singularity functions
break;
case 11: //The Big Crash
var mult = 0;
for (var i = 0; i < srcFile.lvl; ++i) {
mult += (60 / (Math.pow(2, i)));
}
var incMult = 1 + (mult / 100);
Player.work_money_mult *= incMult;
Player.company_rep_mult *= incMult;
break;
default: default:
console.log("ERROR: Invalid source file number: " + srcFile.n); console.log("ERROR: Invalid source file number: " + srcFile.n);
break; break;
@ -105,18 +125,4 @@ function applySourceFile(srcFile) {
sourceFileObject.owned = true; sourceFileObject.owned = true;
} }
PlayerObject.prototype.reapplyAllSourceFiles = function() { export {SourceFiles, PlayerOwnedSourceFile, applySourceFile, initSourceFiles};
console.log("Re-applying source files");
//Will always be called after reapplyAllAugmentations() so multipliers do not have to be reset
//this.resetMultipliers();
for (i = 0; i < this.sourceFiles.length; ++i) {
var srcFileKey = "SourceFile" + this.sourceFiles[i].n;
var sourceFileObject = SourceFiles[srcFileKey];
if (sourceFileObject == null) {
console.log("ERROR: Invalid source file number: " + this.sourceFiles[i].n);
continue;
}
applySourceFile(this.sourceFiles[i]);
}
}

@ -1,5 +1,8 @@
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
/* Holds IP of Special Servers */ /* Holds IP of Special Servers */
SpecialServerNames = { let SpecialServerNames = {
FulcrumSecretTechnologies: "Fulcrum Secret Technologies Server", FulcrumSecretTechnologies: "Fulcrum Secret Technologies Server",
CyberSecServer: "CyberSec Server", CyberSecServer: "CyberSec Server",
NiteSecServer: "NiteSec Server", NiteSecServer: "NiteSec Server",
@ -23,6 +26,25 @@ SpecialServerIpsMap.fromJSON = function(value) {
return Generic_fromJSON(SpecialServerIpsMap, value.data); return Generic_fromJSON(SpecialServerIpsMap, value.data);
} }
Reviver.constructors.SpecialServerIpsMap = SpecialServerIpsMap(); Reviver.constructors.SpecialServerIpsMap = SpecialServerIpsMap;
SpecialServerIps = null; let SpecialServerIps = new SpecialServerIpsMap();
function prestigeSpecialServerIps() {
for (var member in SpecialServerIps) {
delete SpecialServerIps[member];
}
SpecialServerIps = null;
SpecialServerIps = new SpecialServerIpsMap();
}
function loadSpecialServerIps(saveString) {
SpecialServerIps = JSON.parse(saveString, Reviver);
}
function initSpecialServerIps() {
SpecialServerIps = new SpecialServerIpsMap();
}
export {SpecialServerNames, SpecialServerIps, SpecialServerIpsMap, loadSpecialServerIps,
prestigeSpecialServerIps, initSpecialServerIps};

@ -1,3 +1,13 @@
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
import {Locations} from "./Location.js";
import {Player} from "./Player.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {clearEventListeners, getRandomInt} from "../utils/HelperFunctions.js";
import {Reviver} from "../utils/JSONReviver.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
/* StockMarket.js */ /* StockMarket.js */
function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) { function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
this.symbol = symbol; this.symbol = symbol;
@ -11,10 +21,27 @@ function Stock(name, symbol, mv, b, otlkMag, initPrice=10000) {
this.otlkMag = otlkMag; this.otlkMag = otlkMag;
} }
Stock.prototype.toJSON = function() {
return Generic_toJSON("Stock", this);
}
StockMarket = {} //Full name to stock object Stock.fromJSON = function(value) {
StockSymbols = {} //Full name to symbol return Generic_fromJSON(Stock, value.data);
SymbolToStockMap = {}; //Symbol to Stock object }
Reviver.constructors.Stock = Stock;
let StockMarket = {} //Full name to stock object
let StockSymbols = {} //Full name to symbol
let SymbolToStockMap = {}; //Symbol to Stock object
function loadStockMarket(saveString) {
if (saveString === "") {
StockMarket = {};
} else {
StockMarket = JSON.parse(saveString, Reviver);
}
}
function initStockSymbols() { function initStockSymbols() {
//Stocks for companies at which you can work //Stocks for companies at which you can work
@ -119,10 +146,6 @@ function initStockMarket() {
var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], 0.55, true, 10, getRandomInt(20000, 25000)); var universalenergyStk = new Stock(universalenergy, StockSymbols[universalenergy], 0.55, true, 10, getRandomInt(20000, 25000));
StockMarket[universalenergy] = universalenergyStk; StockMarket[universalenergy] = universalenergyStk;
var galactic = Locations.AevumGalacticCybersystems;
var galacticStk = new Stock(galactic, StockSymbols[galactic], 0.6, true, 5, getRandomInt(8000, 10000));
StockMarket[galactic] = galacticStk;
var aerocorp = Locations.AevumAeroCorp; var aerocorp = Locations.AevumAeroCorp;
var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], 0.6, true, 6, getRandomInt(10000, 15000)); var aerocorpStk = new Stock(aerocorp, StockSymbols[aerocorp], 0.6, true, 6, getRandomInt(10000, 15000));
StockMarket[aerocorp] = aerocorpStk; StockMarket[aerocorp] = aerocorpStk;
@ -191,10 +214,6 @@ function initStockMarket() {
var catalystStk = new Stock(catalyst, StockSymbols[catalyst], 1.25, true, 0, getRandomInt(1000, 1500)); var catalystStk = new Stock(catalyst, StockSymbols[catalyst], 1.25, true, 0, getRandomInt(1000, 1500));
StockMarket[catalyst] = catalystStk; StockMarket[catalyst] = catalystStk;
var taiyang = "Taiyang Digital";
var taiyangStk = new Stock(taiyang, StockSymbols[taiyang], 0.75, true, 12, getRandomInt(25000, 30000));
StockMarket[taiyang] = taiyangStk;
var microdyne = "Microdyne Technologies"; var microdyne = "Microdyne Technologies";
var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], 0.75, true, 8, getRandomInt(20000, 25000)); var microdyneStk = new Stock(microdyne, StockSymbols[microdyne], 0.75, true, 8, getRandomInt(20000, 25000));
StockMarket[microdyne] = microdyneStk; StockMarket[microdyne] = microdyneStk;
@ -537,9 +556,9 @@ function displayStockMarketContent() {
//'increase' argument is a boolean indicating whether the price increased or decreased //'increase' argument is a boolean indicating whether the price increased or decreased
function updateStockTicker(stock, increase) { function updateStockTicker(stock, increase) {
var tickerId = "stock-market-ticker-" + stock.symbol; var tickerId = "stock-market-ticker-" + stock.symbol;
stkName = document.getElementById(tickerId + "-name"); let stkName = document.getElementById(tickerId + "-name");
stkSym = document.getElementById(tickerId + "-sym"); let stkSym = document.getElementById(tickerId + "-sym");
stkPrice = document.getElementById(tickerId + "-price"); let stkPrice = document.getElementById(tickerId + "-price");
if (stkName == null || stkSym == null || stkPrice == null) { if (stkName == null || stkSym == null || stkPrice == null) {
console.log("ERROR, couldn't find elements with tickerId " + tickerId); console.log("ERROR, couldn't find elements with tickerId " + tickerId);
@ -584,3 +603,8 @@ function updateStockPlayerPosition(stock) {
avgPriceTxt.innerText = "$" + formatNumber(stock.playerAvgPx, 2); avgPriceTxt.innerText = "$" + formatNumber(stock.playerAvgPx, 2);
sharesTxt.innerText = stock.playerShares.toString(); sharesTxt.innerText = stock.playerShares.toString();
} }
export {StockMarket, StockSymbols, SymbolToStockMap, initStockSymbols,
initStockMarket, initSymbolToStockMap, stockMarketCycle, buyStock,
sellStock, updateStockPrices, displayStockMarketContent,
updateStockTicker, updateStockPlayerPosition, loadStockMarket};

@ -1,7 +1,35 @@
//Terminal import {substituteAliases, printAliases,
parseAliasDeclaration,
removeAlias, GlobalAliases,
Aliases} from "./Alias.js";
import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {executeDarkwebTerminalCommand,
checkIfConnectedToDarkweb} from "./DarkWeb.js";
import {Engine} from "./engine.js";
import {TerminalHelpText, HelpTexts} from "./HelpText.js";
import {iTutorialNextStep, iTutorialSteps,
iTutorialIsRunning,
currITutorialStep} from "./InteractiveTutorial.js";
import {showLiterature} from "./Literature.js";
import {showMessage, Message} from "./Message.js";
import {killWorkerScript, addWorkerScript} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
import {hackWorldDaemon} from "./RedPill.js";
import {findRunningScript, RunningScript,
AllServersMap} from "./Script.js";
import {AllServers, GetServerByHostname,
getServer, Server} from "./Server.js";
import {SpecialServerIps,
SpecialServerNames} from "./SpecialServerIps.js";
import {containsAllStrings, longestCommonStart,
formatNumber} from "../utils/StringHelperFunctions.js";
import {addOffset, printArray} from "../utils/HelperFunctions.js";
import {logBoxCreate} from "../utils/LogBox.js";
/* Write text to terminal */ /* Write text to terminal */
var post = function(input, replace=true) { function post(input, replace=true) {
if (replace) { if (replace) {
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input.replace( / /g, "&nbsp;" ) + '</td></tr>'); $("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input.replace( / /g, "&nbsp;" ) + '</td></tr>');
} else { } else {
@ -12,12 +40,12 @@ var post = function(input, replace=true) {
} }
//Same thing as post but the td cells have ids so they can be animated for the hack progress bar //Same thing as post but the td cells have ids so they can be animated for the hack progress bar
var hackProgressBarPost = function(input) { function hackProgressBarPost(input) {
$("#terminal-input").before('<tr class="posted"><td id="hack-progress-bar" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>'); $("#terminal-input").before('<tr class="posted"><td id="hack-progress-bar" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
updateTerminalScroll(); updateTerminalScroll();
} }
var hackProgressPost = function(input) { function hackProgressPost(input) {
$("#terminal-input").before('<tr class="posted"><td id="hack-progress" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>'); $("#terminal-input").before('<tr class="posted"><td id="hack-progress" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
updateTerminalScroll(); updateTerminalScroll();
} }
@ -28,7 +56,7 @@ function updateTerminalScroll() {
element.scrollTop = element.scrollHeight; element.scrollTop = element.scrollHeight;
} }
var postNetburnerText = function() { function postNetburnerText() {
post("Bitburner v" + CONSTANTS.Version); post("Bitburner v" + CONSTANTS.Version);
} }
@ -134,7 +162,7 @@ $(document).keydown(function(event) {
}); });
//Keep terminal in focus //Keep terminal in focus
terminalCtrlPressed = false; let terminalCtrlPressed = false;
$(document).ready(function() { $(document).ready(function() {
if (Engine.currentPage == Engine.Page.Terminal) { if (Engine.currentPage == Engine.Page.Terminal) {
$('.terminal-input').focus(); $('.terminal-input').focus();
@ -346,7 +374,7 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
return allPos; return allPos;
} }
var Terminal = { let Terminal = {
//Flags to determine whether the player is currently running a hack or an analyze //Flags to determine whether the player is currently running a hack or an analyze
hackFlag: false, hackFlag: false,
analyzeFlag: false, analyzeFlag: false,
@ -1592,5 +1620,6 @@ var Terminal = {
post("ERROR: No such script"); post("ERROR: No such script");
} }
}; };
export {postNetburnerText, post, Terminal};

@ -1,3 +1,58 @@
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {gameOptionsBoxOpen, gameOptionsBoxClose}from "../utils/GameOptions.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
import numeral from "../utils/numeral.min.js";
import {formatNumber,
convertTimeMsToTimeElapsedString} from "../utils/StringHelperFunctions.js";
import {loxBoxCreate, logBoxUpdateText,
logBoxOpened} from "../utils/LogBox.js";
import {setActiveScriptsClickHandlers,
updateActiveScriptsItems} from "./ActiveScriptsUI.js";
import {Augmentations, installAugmentations,
initAugmentations, AugmentationNames} from "./Augmentations.js";
import {BitNodes, initBitNodes,
initBitNodeMultipliers} from "./BitNode.js";
import {CompanyPositions, initCompanies} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
import {Programs, displayCreateProgramContent,
getNumAvailableCreateProgram,
initCreateProgramButtons} from "./CreateProgram.js";
import {displayFactionContent, joinFaction,
processPassiveFactionRepGain, Factions,
inviteToFaction, initFactions} from "./Faction.js";
import {displayGangContent, updateGangContent,
Gang} from "./Gang.js";
import {displayHacknetNodesContent, processAllHacknetNodeEarnings,
updateHacknetNodesContent} from "./HacknetNode.js";
import {iTutorialStart} from "./InteractiveTutorial.js";
import {initLiterature} from "./Literature.js";
import {Locations, displayLocationContent,
initLocationButtons} from "./Location.js";
import {checkForMessagesToSend, initMessages} from "./Message.js";
import {initSingularitySFFlags} from "./NetscriptFunctions.js";
import {updateOnlineScriptTimes,
runScriptsLoop} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
import {prestigeAugmentation,
prestigeSourceFile} from "./Prestige.js";
import {redPillFlag} from "./RedPill.js";
import {saveObject, loadGame} from "./SaveObject.js";
import {loadAllRunningScripts,
updateScriptEditorContent} from "./Script.js";
import {AllServers, Server, initForeignServers} from "./Server.js";
import {Settings, setSettingsLabels} from "./Settings.js";
import {initSourceFiles, SourceFiles} from "./SourceFile.js";
import {SpecialServerIps, initSpecialServerIps} from "./SpecialServerIps.js";
import {StockMarket, StockSymbols,
SymbolToStockMap, initStockSymbols,
initSymbolToStockMap, stockMarketCycle,
updateStockPrices,
displayStockMarketContent} from "./StockMarket.js";
import {Terminal, postNetburnerText, post} from "./Terminal.js";
/* Shortcuts to navigate through the game /* Shortcuts to navigate through the game
* Alt-t - Terminal * Alt-t - Terminal
* Alt-c - Character * Alt-c - Character
@ -60,7 +115,7 @@ $(document).keydown(function(e) {
} }
}); });
var Engine = { let Engine = {
version: "", version: "",
Debug: true, Debug: true,
@ -182,7 +237,7 @@ var Engine = {
document.getElementById("script-editor-text").value = code; document.getElementById("script-editor-text").value = code;
} }
document.getElementById("script-editor-text").focus(); document.getElementById("script-editor-text").focus();
upgradeScriptEditorContent(); updateScriptEditorContent();
Engine.currentPage = Engine.Page.ScriptEditor; Engine.currentPage = Engine.Page.ScriptEditor;
document.getElementById("create-script-menu-link").classList.add("active"); document.getElementById("create-script-menu-link").classList.add("active");
}, },
@ -324,7 +379,7 @@ var Engine = {
loadGangContent: function() { loadGangContent: function() {
Engine.hideAllContent(); Engine.hideAllContent();
if (document.getElementById("gang-container") || Player.gang) { if (document.getElementById("gang-container") || Player.inGang()) {
displayGangContent(); displayGangContent();
Engine.currentPage = Engine.Page.Gang; Engine.currentPage = Engine.Page.Gang;
} else { } else {
@ -383,7 +438,6 @@ var Engine = {
if (Player.hp == null) {Player.hp = Player.max_hp;} if (Player.hp == null) {Player.hp = Player.max_hp;}
document.getElementById("character-overview-text").innerHTML = document.getElementById("character-overview-text").innerHTML =
("Hp: " + Player.hp + " / " + Player.max_hp + "<br>" + ("Hp: " + Player.hp + " / " + Player.max_hp + "<br>" +
//"Money: $" + formatNumber(Player.money.toNumber(), 2) + "<br>" +
"Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + "<br>" + "Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + "<br>" +
"Hack: " + (Player.hacking_skill).toLocaleString() + "<br>" + "Hack: " + (Player.hacking_skill).toLocaleString() + "<br>" +
"Str: " + (Player.strength).toLocaleString() + "<br>" + "Str: " + (Player.strength).toLocaleString() + "<br>" +
@ -473,7 +527,6 @@ var Engine = {
document.getElementById("world-city-name").innerHTML = Player.city; document.getElementById("world-city-name").innerHTML = Player.city;
var cityDesc = document.getElementById("world-city-desc"); //TODO var cityDesc = document.getElementById("world-city-desc"); //TODO
switch(Player.city) { switch(Player.city) {
case Locations.Aevum: case Locations.Aevum:
Engine.aevumLocationsList.style.display = "inline"; Engine.aevumLocationsList.style.display = "inline";
break; break;
@ -891,7 +944,7 @@ var Engine = {
if (Engine.Counters.updateScriptEditorDisplay <= 0) { if (Engine.Counters.updateScriptEditorDisplay <= 0) {
if (Engine.currentPage == Engine.Page.ScriptEditor) { if (Engine.currentPage == Engine.Page.ScriptEditor) {
upgradeScriptEditorContent(); updateScriptEditorContent();
} }
Engine.Counters.updateScriptEditorDisplay = 5; Engine.Counters.updateScriptEditorDisplay = 5;
} }
@ -978,7 +1031,9 @@ var Engine = {
//Load game from save or create new game //Load game from save or create new game
if (loadGame(saveObject)) { if (loadGame(saveObject)) {
console.log("Loaded game from save"); console.log("Loaded game from save");
initBitNodes();
initBitNodeMultipliers(); initBitNodeMultipliers();
initSourceFiles();
Engine.setDisplayElements(); //Sets variables for important DOM elements Engine.setDisplayElements(); //Sets variables for important DOM elements
Engine.init(); //Initialize buttons, work, etc. Engine.init(); //Initialize buttons, work, etc.
CompanyPositions.init(); CompanyPositions.init();
@ -989,6 +1044,7 @@ var Engine = {
initSymbolToStockMap(); initSymbolToStockMap();
} }
initLiterature(); initLiterature();
initSingularitySFFlags();
//Calculate the number of cycles have elapsed while offline //Calculate the number of cycles have elapsed while offline
Engine._lastUpdate = new Date().getTime(); Engine._lastUpdate = new Date().getTime();
@ -1081,8 +1137,10 @@ var Engine = {
} else { } else {
//No save found, start new game //No save found, start new game
console.log("Initializing new game"); console.log("Initializing new game");
initBitNodes();
initBitNodeMultipliers(); initBitNodeMultipliers();
SpecialServerIps = new SpecialServerIpsMap(); initSourceFiles();
initSpecialServerIps();
Engine.setDisplayElements(); //Sets variables for important DOM elements Engine.setDisplayElements(); //Sets variables for important DOM elements
Engine.start(); //Run main game loop and Scripts loop Engine.start(); //Run main game loop and Scripts loop
Player.init(); Player.init();
@ -1094,6 +1152,7 @@ var Engine = {
initMessages(); initMessages();
initStockSymbols(); initStockSymbols();
initLiterature(); initLiterature();
initSingularitySFFlags();
//Open main menu accordions for new game //Open main menu accordions for new game
//Main menu accordions //Main menu accordions
@ -1269,6 +1328,11 @@ var Engine = {
/* Initialization */ /* Initialization */
init: function() { init: function() {
//Import game link
document.getElementById("import-game-link").onclick = function() {
saveObject.importGame();
};
//Main menu accordions //Main menu accordions
var hackingHdr = document.getElementById("hacking-menu-header"); var hackingHdr = document.getElementById("hacking-menu-header");
//hackingHdr.classList.toggle("opened"); //hackingHdr.classList.toggle("opened");
@ -1603,9 +1667,9 @@ var Engine = {
cancelButton.addEventListener("click", function() { cancelButton.addEventListener("click", function() {
if (Player.workType == CONSTANTS.WorkTypeFaction) { if (Player.workType == CONSTANTS.WorkTypeFaction) {
var fac = Factions[Player.currentWorkFactionName]; var fac = Factions[Player.currentWorkFactionName];
Player.finishFactionWork(true, fac); Player.finishFactionWork(true);
} else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) { } else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) {
Player.finishCreateProgramWork(true, Player.createProgramName); Player.finishCreateProgramWork(true);
} else if (Player.workType == CONSTANTS.WorkTypeStudyClass) { } else if (Player.workType == CONSTANTS.WorkTypeStudyClass) {
Player.finishClass(); Player.finishClass();
} else if (Player.workType == CONSTANTS.WorkTypeCrime) { } else if (Player.workType == CONSTANTS.WorkTypeCrime) {
@ -1661,3 +1725,5 @@ var Engine = {
window.onload = function() { window.onload = function() {
Engine.load(); Engine.load();
}; };
export {Engine};

@ -1,5 +1,5 @@
/* Pop up Dialog Box */ /* Pop up Dialog Box */
dialogBoxes = []; let dialogBoxes = [];
//Close dialog box when clicking outside //Close dialog box when clicking outside
$(document).click(function(event) { $(document).click(function(event) {
@ -32,7 +32,7 @@ $(document).on('click', '.dialog-box-close-button', function( event ) {
var dialogBoxOpened = false; var dialogBoxOpened = false;
dialogBoxCreate = function(txt) { function dialogBoxCreate(txt) {
var container = document.createElement("div"); var container = document.createElement("div");
container.setAttribute("class", "dialog-box-container"); container.setAttribute("class", "dialog-box-container");
@ -60,3 +60,5 @@ dialogBoxCreate = function(txt) {
dialogBoxOpened = true; dialogBoxOpened = true;
}, 400); }, 400);
} }
export {dialogBoxCreate};

@ -1,26 +1,30 @@
import {Faction, joinFaction} from "../src/Faction.js";
import {Player} from "../src/Player.js";
import {clearEventListeners} from "./HelperFunctions.js";
/* Faction Invitation Pop-up box */ /* Faction Invitation Pop-up box */
factionInvitationBoxClose = function() { function factionInvitationBoxClose() {
var factionInvitationBox = document.getElementById("faction-invitation-box-container"); var factionInvitationBox = document.getElementById("faction-invitation-box-container");
factionInvitationBox.style.display = "none"; factionInvitationBox.style.display = "none";
} }
factionInvitationBoxOpen = function() { function factionInvitationBoxOpen() {
var factionInvitationBox = document.getElementById("faction-invitation-box-container"); var factionInvitationBox = document.getElementById("faction-invitation-box-container");
factionInvitationBox.style.display = "block"; factionInvitationBox.style.display = "block";
} }
factionInvitationSetText = function(txt) { function factionInvitationSetText(txt) {
var textBox = document.getElementById("faction-invitation-box-text"); var textBox = document.getElementById("faction-invitation-box-text");
textBox.innerHTML = txt; textBox.innerHTML = txt;
} }
factionInvitationSetMessage = function(msg) { function factionInvitationSetMessage(msg) {
var msgBox = document.getElementById("faction-invitation-box-message"); var msgBox = document.getElementById("faction-invitation-box-message");
msgBox.innerHTML = msg; msgBox.innerHTML = msg;
} }
//ram argument is in GB //ram argument is in GB
factionInvitationBoxCreate = function(faction) { function factionInvitationBoxCreate(faction) {
factionInvitationSetText("You have received a faction invitation from " + faction.name); factionInvitationSetText("You have received a faction invitation from " + faction.name);
//TODO Faction invitation message //TODO Faction invitation message
@ -41,3 +45,5 @@ factionInvitationBoxCreate = function(faction) {
factionInvitationBoxOpen(); factionInvitationBoxOpen();
} }
export {factionInvitationBoxCreate};

@ -27,13 +27,13 @@ function gameOptionsBoxInit() {
document.addEventListener("DOMContentLoaded", gameOptionsBoxInit, false); document.addEventListener("DOMContentLoaded", gameOptionsBoxInit, false);
gameOptionsBoxClose = function() { function gameOptionsBoxClose() {
gameOptionsOpened = false; gameOptionsOpened = false;
var box = document.getElementById("game-options-container"); var box = document.getElementById("game-options-container");
box.style.display = "none"; box.style.display = "none";
} }
gameOptionsBoxOpen = function() { function gameOptionsBoxOpen() {
var box = document.getElementById("game-options-container"); var box = document.getElementById("game-options-container");
box.style.display = "block"; box.style.display = "block";
setTimeout(function() { setTimeout(function() {
@ -41,3 +41,5 @@ gameOptionsBoxOpen = function() {
}, 500); }, 500);
} }
export {gameOptionsBoxOpen, gameOptionsBoxClose};

@ -57,3 +57,6 @@ function powerOfTwo(n) {
if (isNaN(n)) {return false;} if (isNaN(n)) {return false;}
return n && (n & (n-1)) === 0; return n && (n & (n-1)) === 0;
} }
export {sizeOfObject, addOffset, clearEventListeners, getRandomInt,
compareArrays, printArray, powerOfTwo};

@ -1,8 +1,9 @@
import {AllServers} from "../src/Server.js";
/* Functions to deal with manipulating IP addresses*/ /* Functions to deal with manipulating IP addresses*/
//Generate a random IP address //Generate a random IP address
//Will not return an IP address that already exists in the AllServers array //Will not return an IP address that already exists in the AllServers array
createRandomIp = function() { function createRandomIp() {
var ip = createRandomByte(99) +'.' + var ip = createRandomByte(99) +'.' +
createRandomByte(9) +'.' + createRandomByte(9) +'.' +
createRandomByte(9) +'.' + createRandomByte(9) +'.' +
@ -16,7 +17,7 @@ createRandomIp = function() {
} }
//Returns true if the IP already exists in one of the game's servers //Returns true if the IP already exists in one of the game's servers
ipExists = function(ip) { function ipExists(ip) {
for (var property in AllServers) { for (var property in AllServers) {
if (AllServers.hasOwnProperty(property)) { if (AllServers.hasOwnProperty(property)) {
if (property == ip) { if (property == ip) {
@ -27,14 +28,16 @@ ipExists = function(ip) {
return false; return false;
} }
createRandomByte = function(n=9) { function createRandomByte(n=9) {
return Math.round(Math.random()*n); return Math.round(Math.random()*n);
} }
isValidIPAddress = function(ipaddress) { function isValidIPAddress(ipaddress) {
if (/^(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress)) if (/^(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-6]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress))
{ {
return true; return true;
} }
return false; return false;
} }
export {createRandomIp, ipExists, isValidIPAddress};

@ -1,21 +1,28 @@
import {CONSTANTS} from "../src/Constants.js";
import {Factions, Faction} from "../src/Faction.js";
import {Player} from "../src/Player.js";
import {dialogBoxCreate} from "./DialogBox.js";
import {clearEventListeners} from "./HelperFunctions.js";
import {formatNumber} from "./StringHelperFunctions.js";
/* InfiltrationBox.js */ /* InfiltrationBox.js */
infiltrationBoxClose = function() { function infiltrationBoxClose() {
var box = document.getElementById("infiltration-box-container"); var box = document.getElementById("infiltration-box-container");
box.style.display = "none"; box.style.display = "none";
} }
infiltrationBoxOpen = function() { function infiltrationBoxOpen() {
var box = document.getElementById("infiltration-box-container"); var box = document.getElementById("infiltration-box-container");
box.style.display = "block"; box.style.display = "block";
} }
infiltrationSetText = function(txt) { function infiltrationSetText(txt) {
var textBox = document.getElementById("infiltration-box-text"); var textBox = document.getElementById("infiltration-box-text");
textBox.innerHTML = txt; textBox.innerHTML = txt;
} }
//ram argument is in GB //ram argument is in GB
infiltrationBoxCreate = function(inst) { function infiltrationBoxCreate(inst) {
var totalValue = 0; var totalValue = 0;
for (var i = 0; i < inst.secretsStolen.length; ++i) { for (var i = 0; i < inst.secretsStolen.length; ++i) {
totalValue += inst.secretsStolen[i]; totalValue += inst.secretsStolen[i];
@ -89,3 +96,5 @@ infiltrationBoxCreate = function(inst) {
}, 750); }, 750);
infiltrationBoxOpen(); infiltrationBoxOpen();
} }
export {infiltrationBoxCreate};

@ -67,3 +67,5 @@ function Generic_fromJSON(ctor, data) {
} }
return obj; return obj;
} }
export {Reviver, Generic_toJSON, Generic_fromJSON};

@ -1,15 +1,4 @@
/* Log Box */ import {printArray} from "./HelperFunctions.js";
//Close box when clicking outside
/*
$(document).click(function(event) {
if (logBoxOpened) {
if ( $(event.target).closest("#log-box-container").get(0) == null ) {
logBoxClose();
}
}
});
*/
$(document).keydown(function(event) { $(document).keydown(function(event) {
if (logBoxOpened && event.keyCode == 27) { if (logBoxOpened && event.keyCode == 27) {
@ -30,13 +19,13 @@ function logBoxInit() {
document.addEventListener("DOMContentLoaded", logBoxInit, false); document.addEventListener("DOMContentLoaded", logBoxInit, false);
logBoxClose = function() { function logBoxClose() {
logBoxOpened = false; logBoxOpened = false;
var logBox = document.getElementById("log-box-container"); var logBox = document.getElementById("log-box-container");
logBox.style.display = "none"; logBox.style.display = "none";
} }
logBoxOpen = function() { function logBoxOpen() {
logBoxOpened = true; logBoxOpened = true;
var logBox = document.getElementById("log-box-container"); var logBox = document.getElementById("log-box-container");
@ -47,13 +36,13 @@ logBoxOpen = function() {
var logBoxOpened = false; var logBoxOpened = false;
var logBoxCurrentScript = null; var logBoxCurrentScript = null;
//ram argument is in GB //ram argument is in GB
logBoxCreate = function(script) { function logBoxCreate(script) {
logBoxCurrentScript = script; logBoxCurrentScript = script;
logBoxOpen(); logBoxOpen();
logBoxUpdateText(); logBoxUpdateText();
} }
logBoxUpdateText = function() { function logBoxUpdateText() {
var txt = document.getElementById("log-box-text"); var txt = document.getElementById("log-box-text");
if (logBoxCurrentScript && logBoxOpened && txt) { if (logBoxCurrentScript && logBoxOpened && txt) {
txt.innerHTML = logBoxCurrentScript.filename + printArray(logBoxCurrentScript.args) + ":<br><br>"; txt.innerHTML = logBoxCurrentScript.filename + printArray(logBoxCurrentScript.args) + ":<br><br>";
@ -63,3 +52,5 @@ logBoxUpdateText = function() {
} }
} }
} }
export {logBoxCreate, logBoxUpdateText, logBoxOpened, logBoxCurrentScript};

@ -1,3 +1,5 @@
import {dialogBoxCreate} from "./DialogBox.js";
//Netburner String helper functions //Netburner String helper functions
//Searches for every occurence of searchStr within str and returns an array of the indices of //Searches for every occurence of searchStr within str and returns an array of the indices of
@ -126,3 +128,7 @@ function numNetscriptOperators(string) {
} }
return total; return total;
} }
export {getIndicesOf, convertTimeMsToTimeElapsedString, longestCommonStart,
isString, isPositiveNumber, containsAllStrings, formatNumber,
numOccurrences, numNetscriptOperators};

@ -1,3 +1,4 @@
import {clearEventListeners} from "./HelperFunctions.js";
/* Generic Yes-No Pop-up box /* Generic Yes-No Pop-up box
* Can be used to create pop-up boxes that require a yes/no response from player * Can be used to create pop-up boxes that require a yes/no response from player
*/ */
@ -74,3 +75,9 @@ function yesNoTxtInpBoxCreate(txt) {
console.log("ERROR: Container not found for YesNoTextInputBox"); console.log("ERROR: Container not found for YesNoTextInputBox");
} }
} }
export {yesNoBoxCreate, yesNoTxtInpBoxCreate,
yesNoBoxGetYesButton, yesNoBoxGetNoButton,
yesNoTxtInpBoxGetYesButton, yesNoTxtInpBoxGetNoButton,
yesNoTxtInpBoxGetInput, yesNoBoxClose,
yesNoTxtInpBoxClose, yesNoBoxOpen};