diff --git a/css/missions.css b/css/missions.css
index 4a5052378..6abafebda 100644
--- a/css/missions.css
+++ b/css/missions.css
@@ -34,7 +34,6 @@
background-color:blue;
}
-.hack-mission-player-node:hover,
.hack-mission-player-node-active {
border: 2px solid white;
color: #6666ff;
diff --git a/dist/bundle.js b/dist/bundle.js
index a27d4caee..5ef1fe5f0 100644
--- a/dist/bundle.js
+++ b/dist/bundle.js
@@ -75,14 +75,14 @@
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Company_js__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__CreateProgram_js__ = __webpack_require__(14);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Crimes_js__ = __webpack_require__(37);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Crimes_js__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__engine_js__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Faction_js__ = __webpack_require__(10);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Gang_js__ = __webpack_require__(30);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Gang_js__ = __webpack_require__(32);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Location_js__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__SpecialServerIps_js__ = __webpack_require__(11);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__SourceFile_js__ = __webpack_require__(31);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__SourceFile_js__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__utils_decimal_js__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__utils_decimal_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_13__utils_decimal_js__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__ = __webpack_require__(1);
@@ -360,6 +360,7 @@ PlayerObject.prototype.prestigeAugmentation = function() {
this.lastUpdate = new Date().getTime();
this.playtimeSinceLastAug = 0;
+ this.scriptProdSinceLastAug = 0;
this.hacknetNodes.length = 0;
this.totalHacknetNodeProduction = 0;
@@ -450,6 +451,7 @@ PlayerObject.prototype.prestigeSourceFile = function() {
this.hasTixApiAccess = false;
this.playtimeSinceLastAug = 0;
+ this.scriptProdSinceLastAug = 0;
}
PlayerObject.prototype.getCurrentServer = function() {
@@ -2642,31 +2644,30 @@ let CONSTANTS = {
//Hacking Missions
HackingMissionRepToDiffConversion: 5000, //Faction rep is divided by this to get mission difficulty
- HackingMissionRepToRewardConversion: 20, //Faction rep divided byt his to get mission rep reward
+ HackingMissionRepToRewardConversion: 12, //Faction rep divided byt his to get mission rep reward
HackingMissionSpamTimeIncrease: 20000, //How much time limit increase is gained when conquering a Spam Node (ms)
HackingMissionTransferAttackIncrease: 1.05, //Multiplier by which the attack for all Core Nodes is increased when conquering a Transfer Node
HackingMissionHowToPlay: "Hacking missions are a minigame that, if won, will reward you with faction reputation.
" +
"In this game you control a set of Nodes and use them to try and defeat an enemy. Your Nodes " +
- "are colored blue, while the enemy's are red. There are also other nodes on the map colored gray" +
+ "are colored blue, while the enemy's are red. There are also other nodes on the map colored gray " +
"that initially belong to neither you nor the enemy. The goal of the game is " +
"to capture all of the enemy's database nodes, which are the parallelogram-shaped ones, within the time limit. " +
"If you cannot capture all of the enemy's database nodes in the time limit, you will lose.
" +
"Each Node has three stats: Attack, Defense, and HP. There are five different actions that " +
"a Node can take:
" +
- "Attack - Targets an enemy Node and lowers its HP. The effectiveness is determined by the Node's Attack, the Player's " +
+ "Attack - Targets an enemy Node and lowers its HP. The effectiveness is determined by the owner's Attack, the Player's " +
"hacking level, and the enemy's defense. " +
- "Scan - Targets an enemy Node and lowers its Defense. The effectiveness is determined by the Player's hacking level and the " +
+ "Scan - Targets an enemy Node and lowers its Defense. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the " +
"enemy's defense. " +
- "Weaken - Targets an enemy Node and lowers its Attack. The effectiveness is determined by the Player's hacking level and the enemy's " +
+ "Weaken - Targets an enemy Node and lowers its Attack. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's " +
"defense. " +
- "Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level.
" +
- "To capture a Node, you must lower its HP down to 0. " +
- "A Node's 'Attack' stats affects its effectiveness when attacking other Nodes. A Node's 'Defense' helps protect " +
- "against the actions of enemy Nodes. One important thing to note is that, when defending, your total 'Defense' " +
- "(sum of the Defense of all of your Nodes) is what's taken into account when determining the effect of offensive actions. " +
- "However, when attacking, only the 'Attack' of the Node being used to attack is taken into account.
" +
+ "Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level. " +
+ "Overflow - Raises the Node's Attack but lowers its Defense. The effectiveness is determined by your hacking level.
" +
+ "Note that when determining the effectiveness of the above actions, the TOTAL Attack or Defense of the team is used, not just the " +
+ "Attack/Defense of the individual Node that is performing the action. " +
"There are six different types of Nodes:
" +
- "CPU Core - These are your main Nodes that are used to perform actions " +
+ "CPU Core - These are your main Nodes that are used to perform actions. Capable of performing every action " +
"Firewall - Nodes with high defense. These Nodes cannot perform any actions " +
"Database - A special type of Node. The player's objective is to conquer all of the enemy's Database Nodes within " +
"the time limit. These Nodes cannot perform any actions " +
@@ -2675,10 +2676,16 @@ let CONSTANTS = {
"Transfer - Conquering one of these nodes will increase the Attack of all of your CPU Cores by a small fixed percentage. " +
"These Nodes are capable of performing every action except the 'Attack' action " +
"Shield - Nodes with high defense. These Nodes cannot perform any actions
" +
+ "To assign an action to a Node, you must first select one of your Nodes. This can be done by simply clicking on it. Only " +
+ "one Node can be selected at a time, and it will be denoted with a white highlight. After selecting the Node, " +
+ "select its action using the Action Buttons near the top of the screen. Every action also has a corresponding keyboard " +
+ "shortcut that can be used as well.
" +
"For certain actions such as attacking, scanning, and weakening, the Node performing the action must have a target. To target " +
"another node, simply click-and-drag from the 'source' Node to a target. A Node can only have one target, and you can only target " +
"Nodes that are adjacent to one of your Nodes (immediately above, below, or to the side. NOT diagonal). Furthermore, only CPU Cores and Transfer Nodes " +
- "can target, since they are the only ones that can perform actions",
+ "can target, since they are the only ones that can perform actions. To remove a target, you can simply click on the line that represents " +
+ "the connection between one of your Nodes and its target. Alternatively, you can select the 'source' Node and click the 'Drop Connection' button, " +
+ "or press 'd',",
//Gang constants
@@ -2936,6 +2943,9 @@ let CONSTANTS = {
"args.length
" +
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
"args array.
" +
+ "
Javascript Modules
" +
+ "Netscript supports the following Javascript Modules:
" +
+ "Math Date (static functions only)
" +
"
Functions
" +
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
"you may use:
" +
@@ -3167,8 +3177,9 @@ let CONSTANTS = {
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.
" +
"getScriptIncome([scriptname], [hostname/ip], [args...]) " +
"Returns the amount of income the specified script generates while online (when the game is open, does not apply for " +
- "offline income). This function can also return the total income of all of your active scripts by running the function " +
- "with no arguments.
" +
+ "offline income). This function can also be called with no arguments. If called with no arguments, then this function " +
+ "will return an array of two values. The first value is the total income ($/sec) of all of your active scripts (currently running). " +
+ "The second value is the total income ($/sec) from scripts since you last installed Augmentations (or destroyed a BitNode).
" +
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
"with the arguments 'foodnstuff' and '5' then in order to use this function to get that script's income you must " +
"specify those arguments in this function call.
" +
@@ -3187,6 +3198,8 @@ let CONSTANTS = {
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.
" +
+ "getTimeSinceLastAug() " +
+ "Returns the amount of time in milliseconds that have passed since you last installed Augmentations (or destroyed a BitNode).
" +
"
Hacknet Nodes API
" +
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.
" +
"hacknetnodes A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
@@ -3516,28 +3529,24 @@ let CONSTANTS = {
LatestUpdate:
"v0.29.1 " +
+ "-New gameplay feature that is currently in BETA: Hacking Missions. Hacking Missions is an active gameplay mechanic (its a minigame) " +
+ "that is meant to be used to earn faction reputation. However, since this is currently in beta, hacking missions will NOT grant reputation " +
+ "for the time being, since the feature likely has many bugs, balance problems, and other issues. If you have any feedback " +
+ "regarding the new feature, feel free to let me know " +
+ "-CHANGED THE RETURN VALUE OF getScriptIncome() WHEN RAN WITH NO ARGUMENTS. It will now return an array of " +
+ "two values rather than a single value. This may break your scripts, so make sure to update them! " +
"-Added continue statement for for/while loops " +
- "-Added getServerMinSecurityLevel() Netscript function " +
+ "-Added getServerMinSecurityLevel(), getPurchasedServers(), and getTimeSinceLastAug() Netscript functions " +
+ "-Netscript scp() function can now take an array as the first argument, and will try to copy " +
+ "every file specified in the array (it will just call scp() normally for every element in the array). " +
+ "If an array is passed in, then the scp() function returns true if at least one element from the array is successfully copied " +
"-Added Javascript's Date module to Netscript. Since 'new' is not supported in Netscript yet, only the Date module's " +
"static methods will work (now(), UTC(), parse(), etc.). " +
"-Failing a crime now gives half the experience it did before " +
- "-The repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
- "if you've never destroyed a BitNode before " +
- "-fileExists() function now works on literature files
" +
- "v0.29.0 " +
- "-Added BitNode-5: Artificial Intelligence " +
- "-Added getIp(), getIntelligence(), getHackingMultipliers(), and getBitNodeMultipliers() Netscript functions (requires Source-File 5) " +
- "-Updated scan() Netscript function so that you can choose to have it print IPs rather than hostnames " +
- "-Refactored scp() Netscript function so that it takes an optional 'source server' argument " +
- "-For Infiltration, decreased the percentage by which the security level increases by " +
- "about 10% for every location " +
- "-Using :w in the script editor's Vim keybinding mode should now save and quit to Terminal " +
- "-Some minor optimizations that should reduce the size of the save file " +
- "-scan-analyze Terminal command will no longer show your purchased servers, unless you pass a '-a' flag into the command " +
- "-After installing the Red Pill augmentation from Daedalus, the message telling you to find 'The-Cave' " +
- "will now repeatedly pop up regardless of whether or not you have messages suppressed " +
- "-Various bugfixes",
-
+ "-The forced repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
+ "if you've never destroyed a BitNode before, and will only popup every 15 minutes. If you have already destroyed a BitNode, " +
+ "the message will not pop up if you have messages suppressed (if you don't have messages suppressed it WILL still repeatedly popup) " +
+ "-fileExists() function now works on literature files
",
}
@@ -3551,12 +3560,12 @@ let CONSTANTS = {
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Engine", function() { return Engine; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__utils_DialogBox_js__ = __webpack_require__(1);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_GameOptions_js__ = __webpack_require__(35);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__utils_GameOptions_js__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__utils_HelperFunctions_js__ = __webpack_require__(2);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js__ = __webpack_require__(36);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js__ = __webpack_require__(27);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_3__utils_numeral_min_js__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_StringHelperFunctions_js__ = __webpack_require__(5);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_LogBox_js__ = __webpack_require__(27);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_LogBox_js__ = __webpack_require__(28);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__ActiveScriptsUI_js__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Augmentations_js__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__BitNode_js__ = __webpack_require__(9);
@@ -3565,22 +3574,22 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__CreateProgram_js__ = __webpack_require__(14);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__Faction_js__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__Location_js__ = __webpack_require__(12);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__Gang_js__ = __webpack_require__(30);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__HacknetNode_js__ = __webpack_require__(34);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__Gang_js__ = __webpack_require__(32);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__HacknetNode_js__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__InteractiveTutorial_js__ = __webpack_require__(24);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__Literature_js__ = __webpack_require__(43);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__Literature_js__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__Message_js__ = __webpack_require__(22);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__Missions_js__ = __webpack_require__(38);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__NetscriptFunctions_js__ = __webpack_require__(29);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__Missions_js__ = __webpack_require__(31);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__NetscriptFunctions_js__ = __webpack_require__(30);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__NetscriptWorker_js__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__Player_js__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__Prestige_js__ = __webpack_require__(32);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24__RedPill_js__ = __webpack_require__(44);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__Prestige_js__ = __webpack_require__(34);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_24__RedPill_js__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_25__SaveObject_js__ = __webpack_require__(68);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_26__Script_js__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_27__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_28__Settings_js__ = __webpack_require__(13);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29__SourceFile_js__ = __webpack_require__(31);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_29__SourceFile_js__ = __webpack_require__(33);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_30__SpecialServerIps_js__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_31__StockMarket_js__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_32__Terminal_js__ = __webpack_require__(20);
@@ -4406,6 +4415,7 @@ let Engine = {
__WEBPACK_IMPORTED_MODULE_22__Player_js__["a" /* Player */].gang.process(numCycles);
}
+ //Mission
if (__WEBPACK_IMPORTED_MODULE_19__Missions_js__["c" /* inMission */] && __WEBPACK_IMPORTED_MODULE_19__Missions_js__["b" /* currMission */]) {
__WEBPACK_IMPORTED_MODULE_19__Missions_js__["b" /* currMission */].process(numCycles);
}
@@ -4533,7 +4543,7 @@ let Engine = {
if (Engine.Counters.messages <= 0) {
Object(__WEBPACK_IMPORTED_MODULE_18__Message_js__["c" /* checkForMessagesToSend */])();
if (__WEBPACK_IMPORTED_MODULE_7__Augmentations_js__["c" /* Augmentations */][__WEBPACK_IMPORTED_MODULE_7__Augmentations_js__["b" /* AugmentationNames */].TheRedPill].owned) {
- Engine.Counters.messages = 600; //2 minutes for Red pill message
+ Engine.Counters.messages = 4500; //15 minutes for Red pill message
} else {
Engine.Counters.messages = 150;
}
@@ -16752,7 +16762,7 @@ function initBitNodeMultipliers() {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__engine_js__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__FactionInfo_js__ = __webpack_require__(47);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Location_js__ = __webpack_require__(12);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Missions_js__ = __webpack_require__(38);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Missions_js__ = __webpack_require__(31);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Player_js__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Settings_js__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__utils_DialogBox_js__ = __webpack_require__(1);
@@ -17878,7 +17888,7 @@ function initSpecialServerIps() {
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return initLocationButtons; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Company_js__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Constants_js__ = __webpack_require__(3);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Crimes_js__ = __webpack_require__(37);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Crimes_js__ = __webpack_require__(39);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__engine_js__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Infiltration_js__ = __webpack_require__(45);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Player_js__ = __webpack_require__(0);
@@ -20225,8 +20235,8 @@ function initCreateProgramButtons() {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__ActiveScriptsUI_js__ = __webpack_require__(23);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__engine_js__ = __webpack_require__(4);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__NetscriptEnvironment_js__ = __webpack_require__(28);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__NetscriptEvaluator_js__ = __webpack_require__(33);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__NetscriptEnvironment_js__ = __webpack_require__(29);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__NetscriptEvaluator_js__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Settings_js__ = __webpack_require__(13);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__utils_acorn_js__ = __webpack_require__(67);
@@ -20509,7 +20519,7 @@ function isValidIPAddress(ipaddress) {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__BitNode_js__ = __webpack_require__(9);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Player_js__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Prestige_js__ = __webpack_require__(32);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Prestige_js__ = __webpack_require__(34);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Faction_js__ = __webpack_require__(10);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_DialogBox_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_JSONReviver_js__ = __webpack_require__(8);
@@ -24266,25 +24276,25 @@ __WEBPACK_IMPORTED_MODULE_8__utils_JSONReviver_js__["c" /* Reviver */].construct
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return postNetburnerText; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return post; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Terminal; });
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Alias_js__ = __webpack_require__(41);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Alias_js__ = __webpack_require__(42);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__CreateProgram_js__ = __webpack_require__(14);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__DarkWeb_js__ = __webpack_require__(42);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__DarkWeb_js__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__engine_js__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__HelpText_js__ = __webpack_require__(66);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__InteractiveTutorial_js__ = __webpack_require__(24);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Literature_js__ = __webpack_require__(43);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Literature_js__ = __webpack_require__(44);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Message_js__ = __webpack_require__(22);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__NetscriptEvaluator_js__ = __webpack_require__(33);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__NetscriptEvaluator_js__ = __webpack_require__(36);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__NetscriptWorker_js__ = __webpack_require__(15);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Player_js__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__RedPill_js__ = __webpack_require__(44);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__RedPill_js__ = __webpack_require__(35);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__Script_js__ = __webpack_require__(19);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__SpecialServerIps_js__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__utils_StringHelperFunctions_js__ = __webpack_require__(5);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__utils_HelperFunctions_js__ = __webpack_require__(2);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__utils_LogBox_js__ = __webpack_require__(27);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__utils_LogBox_js__ = __webpack_require__(28);
@@ -26071,11 +26081,15 @@ function yesNoTxtInpBoxCreate(txt) {
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Message; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Augmentations_js__ = __webpack_require__(17);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__CreateProgram_js__ = __webpack_require__(14);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Player_js__ = __webpack_require__(0);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Server_js__ = __webpack_require__(6);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Settings_js__ = __webpack_require__(13);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_DialogBox_js__ = __webpack_require__(1);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_JSONReviver_js__ = __webpack_require__(8);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Missions_js__ = __webpack_require__(31);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Player_js__ = __webpack_require__(0);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__RedPill_js__ = __webpack_require__(35);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Server_js__ = __webpack_require__(6);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__Settings_js__ = __webpack_require__(13);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__utils_DialogBox_js__ = __webpack_require__(1);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__utils_JSONReviver_js__ = __webpack_require__(8);
+
+
@@ -26092,21 +26106,21 @@ function Message(filename="", msg="") {
}
Message.prototype.toJSON = function() {
- return Object(__WEBPACK_IMPORTED_MODULE_6__utils_JSONReviver_js__["b" /* Generic_toJSON */])("Message", this);
+ return Object(__WEBPACK_IMPORTED_MODULE_8__utils_JSONReviver_js__["b" /* Generic_toJSON */])("Message", this);
}
Message.fromJSON = function(value) {
- return Object(__WEBPACK_IMPORTED_MODULE_6__utils_JSONReviver_js__["a" /* Generic_fromJSON */])(Message, value.data);
+ return Object(__WEBPACK_IMPORTED_MODULE_8__utils_JSONReviver_js__["a" /* Generic_fromJSON */])(Message, value.data);
}
-__WEBPACK_IMPORTED_MODULE_6__utils_JSONReviver_js__["c" /* Reviver */].constructors.Message = Message;
+__WEBPACK_IMPORTED_MODULE_8__utils_JSONReviver_js__["c" /* Reviver */].constructors.Message = Message;
//Sends message to player, including a pop up
function sendMessage(msg, forced=false) {
console.log("sending message: " + msg.filename);
msg.recvd = true;
- if (forced || !__WEBPACK_IMPORTED_MODULE_4__Settings_js__["a" /* Settings */].SuppressMessages) {
+ if (forced || !__WEBPACK_IMPORTED_MODULE_6__Settings_js__["a" /* Settings */].SuppressMessages) {
showMessage(msg);
}
addMessageToServer(msg, "home");
@@ -26116,12 +26130,12 @@ function showMessage(msg) {
var txt = "Message received from unknown sender:
" +
"" + msg.msg + "
" +
"This message was saved as " + msg.filename + " onto your home computer.";
- Object(__WEBPACK_IMPORTED_MODULE_5__utils_DialogBox_js__["a" /* dialogBoxCreate */])(txt);
+ Object(__WEBPACK_IMPORTED_MODULE_7__utils_DialogBox_js__["a" /* dialogBoxCreate */])(txt);
}
//Adds a message to a server
function addMessageToServer(msg, serverHostname) {
- var server = Object(__WEBPACK_IMPORTED_MODULE_3__Server_js__["c" /* GetServerByHostname */])(serverHostname);
+ var server = Object(__WEBPACK_IMPORTED_MODULE_5__Server_js__["c" /* GetServerByHostname */])(serverHostname);
if (server == null) {
console.log("WARNING: Did not locate " + serverHostname);
return;
@@ -26151,29 +26165,32 @@ function checkForMessagesToSend() {
redpillOwned = true;
}
- if (redpill && redpillOwned && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].sourceFiles.length === 0) {
- if (!__WEBPACK_IMPORTED_MODULE_5__utils_DialogBox_js__["b" /* dialogBoxOpened */]) {
+ if (redpill && redpillOwned && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].sourceFiles.length === 0 && !__WEBPACK_IMPORTED_MODULE_4__RedPill_js__["b" /* redPillFlag */] && !__WEBPACK_IMPORTED_MODULE_2__Missions_js__["c" /* inMission */]) {
+ if (!__WEBPACK_IMPORTED_MODULE_7__utils_DialogBox_js__["b" /* dialogBoxOpened */]) {
sendMessage(redpill, true);
}
- } else if (jumper0 && !jumper0.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 25) {
- sendMessage(jumper0);
- __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].getHomeComputer().programs.push(__WEBPACK_IMPORTED_MODULE_1__CreateProgram_js__["a" /* Programs */].Flight);
- } else if (jumper1 && !jumper1.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 40) {
- sendMessage(jumper1);
- } else if (cybersecTest && !cybersecTest.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 50) {
- sendMessage(cybersecTest);
- } else if (jumper2 && !jumper2.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 175) {
- sendMessage(jumper2);
- } else if (nitesecTest && !nitesecTest.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 200) {
- sendMessage(nitesecTest);
- } else if (jumper3 && !jumper3.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 350) {
- sendMessage(jumper3);
- } else if (jumper4 && !jumper4.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 490) {
- sendMessage(jumper4);
- } else if (bitrunnersTest && !bitrunnersTest.recvd && __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].hacking_skill >= 500) {
- sendMessage(bitrunnersTest);
} else if (redpill && redpillOwned) {
- sendMessage(redpill);
+ //If player has already destroyed a BitNode, message is not forced
+ if (!__WEBPACK_IMPORTED_MODULE_4__RedPill_js__["b" /* redPillFlag */] && !__WEBPACK_IMPORTED_MODULE_2__Missions_js__["c" /* inMission */] && !__WEBPACK_IMPORTED_MODULE_7__utils_DialogBox_js__["b" /* dialogBoxOpened */]) {
+ sendMessage(redpill);
+ }
+ } else if (jumper0 && !jumper0.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 25) {
+ sendMessage(jumper0);
+ __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].getHomeComputer().programs.push(__WEBPACK_IMPORTED_MODULE_1__CreateProgram_js__["a" /* Programs */].Flight);
+ } else if (jumper1 && !jumper1.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 40) {
+ sendMessage(jumper1);
+ } else if (cybersecTest && !cybersecTest.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 50) {
+ sendMessage(cybersecTest);
+ } else if (jumper2 && !jumper2.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 175) {
+ sendMessage(jumper2);
+ } else if (nitesecTest && !nitesecTest.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 200) {
+ sendMessage(nitesecTest);
+ } else if (jumper3 && !jumper3.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 350) {
+ sendMessage(jumper3);
+ } else if (jumper4 && !jumper4.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 490) {
+ sendMessage(jumper4);
+ } else if (bitrunnersTest && !bitrunnersTest.recvd && __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill >= 500) {
+ sendMessage(bitrunnersTest);
}
}
@@ -26184,7 +26201,7 @@ function AddToAllMessages(msg) {
let Messages = {}
function loadMessages(saveString) {
- Messages = JSON.parse(saveString, __WEBPACK_IMPORTED_MODULE_6__utils_JSONReviver_js__["c" /* Reviver */]);
+ Messages = JSON.parse(saveString, __WEBPACK_IMPORTED_MODULE_8__utils_JSONReviver_js__["c" /* Reviver */]);
}
let MessageFilenames = {
@@ -26278,8 +26295,11 @@ function initMessages() {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Server_js__ = __webpack_require__(6);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__utils_DialogBox_js__ = __webpack_require__(1);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_HelperFunctions_js__ = __webpack_require__(2);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_LogBox_js__ = __webpack_require__(27);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__ = __webpack_require__(5);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_LogBox_js__ = __webpack_require__(28);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js__ = __webpack_require__(27);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js__);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__ = __webpack_require__(5);
+
@@ -26463,10 +26483,10 @@ function updateActiveScriptsItems() {
total += updateActiveScriptsItemContent(__WEBPACK_IMPORTED_MODULE_0__NetscriptWorker_js__["h" /* workerScripts */][i]);
}
document.getElementById("active-scripts-total-prod").innerHTML =
- "Total online production of Active Scripts: $" + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(total, 2) + " / second " +
- "Total online production since last Augmentation installation: $" +
- Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].scriptProdSinceLastAug, 2) + " ($" +
- Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].scriptProdSinceLastAug / __WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].playtimeSinceLastAug, 2) + " / second)";
+ "Total online production of Active Scripts: " + __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js___default()(total).format('$0.000a') + " / sec " +
+ "Total online production since last Aug installation: " +
+ __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js___default()(__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].scriptProdSinceLastAug).format('$0.000a') + " (" +
+ __WEBPACK_IMPORTED_MODULE_6__utils_numeral_min_js___default()(__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].scriptProdSinceLastAug / (__WEBPACK_IMPORTED_MODULE_1__Player_js__["a" /* Player */].playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
return total;
}
@@ -26536,22 +26556,22 @@ function updateActiveScriptsText(workerscript, item, statsEl=null) {
//Updates statistics only
//Online
- var onlineTotalMoneyMade = "Total online production: $" + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.onlineMoneyMade, 2);
- var onlineTotalExpEarned = (Array(26).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, " ");
+ var onlineTotalMoneyMade = "Total online production: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.onlineMoneyMade, 2);
+ var onlineTotalExpEarned = (Array(26).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.onlineExpGained, 2) + " hacking exp").replace( / /g, " ");
var onlineMps = workerscript.scriptRef.onlineMoneyMade / workerscript.scriptRef.onlineRunningTime;
- var onlineMpsText = "Online production rate: $" + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(onlineMps, 2) + "/second";
+ var onlineMpsText = "Online production rate: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(onlineMps, 2) + "/second";
var onlineEps = workerscript.scriptRef.onlineExpGained / workerscript.scriptRef.onlineRunningTime;
- var onlineEpsText = (Array(25).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(onlineEps, 4) + " hacking exp/second").replace( / /g, " ");
+ var onlineEpsText = (Array(25).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(onlineEps, 4) + " hacking exp/second").replace( / /g, " ");
//Offline
- var offlineTotalMoneyMade = "Total offline production: $" + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.offlineMoneyMade, 2);
- var offlineTotalExpEarned = (Array(27).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, " ");
+ var offlineTotalMoneyMade = "Total offline production: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.offlineMoneyMade, 2);
+ var offlineTotalExpEarned = (Array(27).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(workerscript.scriptRef.offlineExpGained, 2) + " hacking exp").replace( / /g, " ");
var offlineMps = workerscript.scriptRef.offlineMoneyMade / workerscript.scriptRef.offlineRunningTime;
- var offlineMpsText = "Offline production rate: $" + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(offlineMps, 2) + "/second";
+ var offlineMpsText = "Offline production rate: $" + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(offlineMps, 2) + "/second";
var offlineEps = workerscript.scriptRef.offlineExpGained / workerscript.scriptRef.offlineRunningTime;
- var offlineEpsText = (Array(26).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(offlineEps, 4) + " hacking exp/second").replace( / /g, " ");
+ var offlineEpsText = (Array(26).join(" ") + Object(__WEBPACK_IMPORTED_MODULE_7__utils_StringHelperFunctions_js__["c" /* formatNumber */])(offlineEps, 4) + " hacking exp/second").replace( / /g, " ");
itemTextStats.innerHTML = onlineTotalMoneyMade + " " + onlineTotalExpEarned + " " +
onlineMpsText + " " + onlineEpsText + " " + offlineTotalMoneyMade + " " + offlineTotalExpEarned + " " +
@@ -32699,6 +32719,23 @@ function updateStockPlayerPosition(stock) {
/***/ }),
/* 27 */
+/***/ (function(module, exports, __webpack_require__) {
+
+var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @preserve
+ * numeral.js
+ * version : 2.0.6
+ * author : Adam Draper
+ * license : MIT
+ * http://adamwdraper.github.com/Numeral-js/
+ */
+!function(a,b){ true?!(__WEBPACK_AMD_DEFINE_FACTORY__ = (b),
+ __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
+ (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) :
+ __WEBPACK_AMD_DEFINE_FACTORY__),
+ __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)):"object"==typeof module&&module.exports?module.exports=b():a.numeral=b()}(this,function(){function a(a,b){this._input=a,this._value=b}var b,c,d="2.0.6",e={},f={},g={currentLocale:"en",zeroFormat:null,nullFormat:null,defaultFormat:"0,0",scalePercentBy100:!0},h={currentLocale:g.currentLocale,zeroFormat:g.zeroFormat,nullFormat:g.nullFormat,defaultFormat:g.defaultFormat,scalePercentBy100:g.scalePercentBy100};return b=function(d){var f,g,i,j;if(b.isNumeral(d))f=d.value();else if(0===d||"undefined"==typeof d)f=0;else if(null===d||c.isNaN(d))f=null;else if("string"==typeof d)if(h.zeroFormat&&d===h.zeroFormat)f=0;else if(h.nullFormat&&d===h.nullFormat||!d.replace(/[^0-9]+/g,"").length)f=null;else{for(g in e)if(j="function"==typeof e[g].regexps.unformat?e[g].regexps.unformat():e[g].regexps.unformat,j&&d.match(j)){i=e[g].unformat;break}i=i||b._.stringToNumber,f=i(d)}else f=Number(d)||null;return new a(d,f)},b.version=d,b.isNumeral=function(b){return b instanceof a},b._=c={numberToFormat:function(a,c,d){var e,g,h,i,j,k,l,m=f[b.options.currentLocale],n=!1,o=!1,p=0,q="",r=1e12,s=1e9,t=1e6,u=1e3,v="",w=!1;if(a=a||0,g=Math.abs(a),b._.includes(c,"(")?(n=!0,c=c.replace(/[\(|\)]/g,"")):(b._.includes(c,"+")||b._.includes(c,"-"))&&(j=b._.includes(c,"+")?c.indexOf("+"):0>a?c.indexOf("-"):-1,c=c.replace(/[\+|\-]/g,"")),b._.includes(c,"a")&&(e=c.match(/a(k|m|b|t)?/),e=e?e[1]:!1,b._.includes(c," a")&&(q=" "),c=c.replace(new RegExp(q+"a[kmbt]?"),""),g>=r&&!e||"t"===e?(q+=m.abbreviations.trillion,a/=r):r>g&&g>=s&&!e||"b"===e?(q+=m.abbreviations.billion,a/=s):s>g&&g>=t&&!e||"m"===e?(q+=m.abbreviations.million,a/=t):(t>g&&g>=u&&!e||"k"===e)&&(q+=m.abbreviations.thousand,a/=u)),b._.includes(c,"[.]")&&(o=!0,c=c.replace("[.]",".")),h=a.toString().split(".")[0],i=c.split(".")[1],k=c.indexOf(","),p=(c.split(".")[0].split(",")[0].match(/0/g)||[]).length,i?(b._.includes(i,"[")?(i=i.replace("]",""),i=i.split("["),v=b._.toFixed(a,i[0].length+i[1].length,d,i[1].length)):v=b._.toFixed(a,i.length,d),h=v.split(".")[0],v=b._.includes(v,".")?m.delimiters.decimal+v.split(".")[1]:"",o&&0===Number(v.slice(1))&&(v="")):h=b._.toFixed(a,0,d),q&&!e&&Number(h)>=1e3&&q!==m.abbreviations.trillion)switch(h=String(Number(h)/1e3),q){case m.abbreviations.thousand:q=m.abbreviations.million;break;case m.abbreviations.million:q=m.abbreviations.billion;break;case m.abbreviations.billion:q=m.abbreviations.trillion}if(b._.includes(h,"-")&&(h=h.slice(1),w=!0),h.length
0;x--)h="0"+h;return k>-1&&(h=h.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g,"$1"+m.delimiters.thousands)),0===c.indexOf(".")&&(h=""),l=h+v+(q?q:""),n?l=(n&&w?"(":"")+l+(n&&w?")":""):j>=0?l=0===j?(w?"-":"+")+l:l+(w?"-":"+"):w&&(l="-"+l),l},stringToNumber:function(a){var b,c,d,e=f[h.currentLocale],g=a,i={thousand:3,million:6,billion:9,trillion:12};if(h.zeroFormat&&a===h.zeroFormat)c=0;else if(h.nullFormat&&a===h.nullFormat||!a.replace(/[^0-9]+/g,"").length)c=null;else{c=1,"."!==e.delimiters.decimal&&(a=a.replace(/\./g,"").replace(e.delimiters.decimal,"."));for(b in i)if(d=new RegExp("[^a-zA-Z]"+e.abbreviations[b]+"(?:\\)|(\\"+e.currency.symbol+")?(?:\\))?)?$"),g.match(d)){c*=Math.pow(10,i[b]);break}c*=(a.split("-").length+Math.min(a.split("(").length-1,a.split(")").length-1))%2?1:-1,a=a.replace(/[^0-9\.]+/g,""),c*=Number(a)}return c},isNaN:function(a){return"number"==typeof a&&isNaN(a)},includes:function(a,b){return-1!==a.indexOf(b)},insert:function(a,b,c){return a.slice(0,c)+b+a.slice(c)},reduce:function(a,b){if(null===this)throw new TypeError("Array.prototype.reduce called on null or undefined");if("function"!=typeof b)throw new TypeError(b+" is not a function");var c,d=Object(a),e=d.length>>>0,f=0;if(3===arguments.length)c=arguments[2];else{for(;e>f&&!(f in d);)f++;if(f>=e)throw new TypeError("Reduce of empty array with no initial value");c=d[f++]}for(;e>f;f++)f in d&&(c=b(c,d[f],f,d));return c},multiplier:function(a){var b=a.toString().split(".");return b.length<2?1:Math.pow(10,b[1].length)},correctionFactor:function(){var a=Array.prototype.slice.call(arguments);return a.reduce(function(a,b){var d=c.multiplier(b);return a>d?a:d},1)},toFixed:function(a,b,c,d){var e,f,g,h,i=a.toString().split("."),j=b-(d||0);return e=2===i.length?Math.min(Math.max(i[1].length,j),b):j,g=Math.pow(10,e),h=(c(a+"e+"+e)/g).toFixed(e),d>b-e&&(f=new RegExp("\\.?0{1,"+(d-(b-e))+"}$"),h=h.replace(f,"")),h}},b.options=h,b.formats=e,b.locales=f,b.locale=function(a){return a&&(h.currentLocale=a.toLowerCase()),h.currentLocale},b.localeData=function(a){if(!a)return f[h.currentLocale];if(a=a.toLowerCase(),!f[a])throw new Error("Unknown locale : "+a);return f[a]},b.reset=function(){for(var a in g)h[a]=g[a]},b.zeroFormat=function(a){h.zeroFormat="string"==typeof a?a:null},b.nullFormat=function(a){h.nullFormat="string"==typeof a?a:null},b.defaultFormat=function(a){h.defaultFormat="string"==typeof a?a:"0.0"},b.register=function(a,b,c){if(b=b.toLowerCase(),this[a+"s"][b])throw new TypeError(b+" "+a+" already registered.");return this[a+"s"][b]=c,c},b.validate=function(a,c){var d,e,f,g,h,i,j,k;if("string"!=typeof a&&(a+="",console.warn&&console.warn("Numeral.js: Value is not string. It has been co-erced to: ",a)),a=a.trim(),a.match(/^\d+$/))return!0;if(""===a)return!1;try{j=b.localeData(c)}catch(l){j=b.localeData(b.locale())}return f=j.currency.symbol,h=j.abbreviations,d=j.delimiters.decimal,e="."===j.delimiters.thousands?"\\.":j.delimiters.thousands,k=a.match(/^[^\d]+/),null!==k&&(a=a.substr(1),k[0]!==f)?!1:(k=a.match(/[^\d]+$/),null!==k&&(a=a.slice(0,-1),k[0]!==h.thousand&&k[0]!==h.million&&k[0]!==h.billion&&k[0]!==h.trillion)?!1:(i=new RegExp(e+"{2}"),a.match(/[^\d.,]/g)?!1:(g=a.split(d),g.length>2?!1:g.length<2?!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i):1===g[0].length?!!g[0].match(/^\d+$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/):!!g[0].match(/^\d+.*\d$/)&&!g[0].match(i)&&!!g[1].match(/^\d+$/))))},b.fn=a.prototype={clone:function(){return b(this)},format:function(a,c){var d,f,g,i=this._value,j=a||h.defaultFormat;if(c=c||Math.round,0===i&&null!==h.zeroFormat)f=h.zeroFormat;else if(null===i&&null!==h.nullFormat)f=h.nullFormat;else{for(d in e)if(j.match(e[d].regexps.format)){g=e[d].format;break}g=g||b._.numberToFormat,f=g(i,j,c)}return f},value:function(){return this._value},input:function(){return this._input},set:function(a){return this._value=Number(a),this},add:function(a){function b(a,b,c,e){return a+Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([this._value,a],b,0)/d,this},subtract:function(a){function b(a,b,c,e){return a-Math.round(d*b)}var d=c.correctionFactor.call(null,this._value,a);return this._value=c.reduce([a],b,Math.round(this._value*d))/d,this},multiply:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)*Math.round(b*f)/Math.round(f*f)}return this._value=c.reduce([this._value,a],b,1),this},divide:function(a){function b(a,b,d,e){var f=c.correctionFactor(a,b);return Math.round(a*f)/Math.round(b*f)}return this._value=c.reduce([this._value,a],b),this},difference:function(a){return Math.abs(b(this._value).subtract(a).value())}},b.register("locale","en",{delimiters:{thousands:",",decimal:"."},abbreviations:{thousand:"k",million:"m",billion:"b",trillion:"t"},ordinal:function(a){var b=a%10;return 1===~~(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th"},currency:{symbol:"$"}}),function(){b.register("format","bps",{regexps:{format:/(BPS)/,unformat:/(BPS)/},format:function(a,c,d){var e,f=b._.includes(c," BPS")?" ":"";return a=1e4*a,c=c.replace(/\s?BPS/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"BPS"),e=e.join("")):e=e+f+"BPS",e},unformat:function(a){return+(1e-4*b._.stringToNumber(a)).toFixed(15)}})}(),function(){var a={base:1e3,suffixes:["B","KB","MB","GB","TB","PB","EB","ZB","YB"]},c={base:1024,suffixes:["B","KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"]},d=a.suffixes.concat(c.suffixes.filter(function(b){return a.suffixes.indexOf(b)<0})),e=d.join("|");e="("+e.replace("B","B(?!PS)")+")",b.register("format","bytes",{regexps:{format:/([0\s]i?b)/,unformat:new RegExp(e)},format:function(d,e,f){var g,h,i,j,k=b._.includes(e,"ib")?c:a,l=b._.includes(e," b")||b._.includes(e," ib")?" ":"";for(e=e.replace(/\s?i?b/,""),h=0;h<=k.suffixes.length;h++)if(i=Math.pow(k.base,h),j=Math.pow(k.base,h+1),null===d||0===d||d>=i&&j>d){l+=k.suffixes[h],i>0&&(d/=i);break}return g=b._.numberToFormat(d,e,f),g+l},unformat:function(d){var e,f,g=b._.stringToNumber(d);if(g){for(e=a.suffixes.length-1;e>=0;e--){if(b._.includes(d,a.suffixes[e])){f=Math.pow(a.base,e);break}if(b._.includes(d,c.suffixes[e])){f=Math.pow(c.base,e);break}}g*=f||1}return g}})}(),function(){b.register("format","currency",{regexps:{format:/(\$)/},format:function(a,c,d){var e,f,g,h=b.locales[b.options.currentLocale],i={before:c.match(/^([\+|\-|\(|\s|\$]*)/)[0],after:c.match(/([\+|\-|\)|\s|\$]*)$/)[0]};for(c=c.replace(/\s?\$\s?/,""),e=b._.numberToFormat(a,c,d),a>=0?(i.before=i.before.replace(/[\-\(]/,""),i.after=i.after.replace(/[\-\)]/,"")):0>a&&!b._.includes(i.before,"-")&&!b._.includes(i.before,"(")&&(i.before="-"+i.before),g=0;g=0;g--)switch(f=i.after[g]){case"$":e=g===i.after.length-1?e+h.currency.symbol:b._.insert(e,h.currency.symbol,-(i.after.length-(1+g)));break;case" ":e=g===i.after.length-1?e+" ":b._.insert(e," ",-(i.after.length-(1+g)+h.currency.symbol.length-1))}return e}})}(),function(){b.register("format","exponential",{regexps:{format:/(e\+|e-)/,unformat:/(e\+|e-)/},format:function(a,c,d){var e,f="number"!=typeof a||b._.isNaN(a)?"0e+0":a.toExponential(),g=f.split("e");return c=c.replace(/e[\+|\-]{1}0/,""),e=b._.numberToFormat(Number(g[0]),c,d),e+"e"+g[1]},unformat:function(a){function c(a,c,d,e){var f=b._.correctionFactor(a,c),g=a*f*(c*f)/(f*f);return g}var d=b._.includes(a,"e+")?a.split("e+"):a.split("e-"),e=Number(d[0]),f=Number(d[1]);return f=b._.includes(a,"e-")?f*=-1:f,b._.reduce([e,Math.pow(10,f)],c,1)}})}(),function(){b.register("format","ordinal",{regexps:{format:/(o)/},format:function(a,c,d){var e,f=b.locales[b.options.currentLocale],g=b._.includes(c," o")?" ":"";return c=c.replace(/\s?o/,""),g+=f.ordinal(a),e=b._.numberToFormat(a,c,d),e+g}})}(),function(){b.register("format","percentage",{regexps:{format:/(%)/,unformat:/(%)/},format:function(a,c,d){var e,f=b._.includes(c," %")?" ":"";return b.options.scalePercentBy100&&(a=100*a),c=c.replace(/\s?\%/,""),e=b._.numberToFormat(a,c,d),b._.includes(e,")")?(e=e.split(""),e.splice(-1,0,f+"%"),e=e.join("")):e=e+f+"%",e},unformat:function(a){var c=b._.stringToNumber(a);return b.options.scalePercentBy100?.01*c:c}})}(),function(){b.register("format","time",{regexps:{format:/(:)/,unformat:/(:)/},format:function(a,b,c){var d=Math.floor(a/60/60),e=Math.floor((a-60*d*60)/60),f=Math.round(a-60*d*60-60*e);return d+":"+(10>e?"0"+e:e)+":"+(10>f?"0"+f:f)},unformat:function(a){var b=a.split(":"),c=0;return 3===b.length?(c+=60*Number(b[0])*60,c+=60*Number(b[1]),c+=Number(b[2])):2===b.length&&(c+=60*Number(b[0]),c+=Number(b[1])),Number(c)}})}(),b});
+
+/***/ }),
+/* 28 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -32769,12 +32806,12 @@ function logBoxUpdateText() {
/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(7)))
/***/ }),
-/* 28 */
+/* 29 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Environment; });
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__NetscriptFunctions_js__ = __webpack_require__(29);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__NetscriptFunctions_js__ = __webpack_require__(30);
/* Environment
* NetScript program environment
@@ -32874,7 +32911,7 @@ Environment.prototype = {
/***/ }),
-/* 29 */
+/* 30 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
@@ -32887,10 +32924,10 @@ Environment.prototype = {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Company_js__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__CreateProgram_js__ = __webpack_require__(14);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__DarkWeb_js__ = __webpack_require__(42);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__DarkWeb_js__ = __webpack_require__(43);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__engine_js__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Faction_js__ = __webpack_require__(10);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__HacknetNode_js__ = __webpack_require__(34);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__HacknetNode_js__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__Location_js__ = __webpack_require__(12);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__Message_js__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__Player_js__ = __webpack_require__(0);
@@ -32901,8 +32938,8 @@ Environment.prototype = {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__StockMarket_js__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__Terminal_js__ = __webpack_require__(20);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_19__NetscriptWorker_js__ = __webpack_require__(15);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__NetscriptEvaluator_js__ = __webpack_require__(33);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__NetscriptEnvironment_js__ = __webpack_require__(28);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_20__NetscriptEvaluator_js__ = __webpack_require__(36);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_21__NetscriptEnvironment_js__ = __webpack_require__(29);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__utils_decimal_js__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_22__utils_decimal_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_22__utils_decimal_js__);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_23__utils_DialogBox_js__ = __webpack_require__(1);
@@ -33365,6 +33402,16 @@ function NetscriptFunctions(workerScript) {
if (arguments.length !== 2 && arguments.length !== 3) {
throw Object(__WEBPACK_IMPORTED_MODULE_20__NetscriptEvaluator_js__["c" /* makeRuntimeRejectMsg */])(workerScript, "Error: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");
}
+ if (scriptname && scriptname.constructor === Array) {
+ //Recursively call scp on all elements of array
+ var res = false;
+ scriptname.forEach(function(script) {
+ if (NetscriptFunctions(workerScript).scp(script, ip1, ip2)) {
+ res = true;
+ };
+ });
+ return res;
+ }
if (!scriptname.endsWith(".lit") && !scriptname.endsWith(".script")) {
throw Object(__WEBPACK_IMPORTED_MODULE_20__NetscriptEvaluator_js__["c" /* makeRuntimeRejectMsg */])(workerScript, "Error: scp() only works for .script and .lit files");
}
@@ -34020,7 +34067,10 @@ function NetscriptFunctions(workerScript) {
getScriptIncome : function(scriptname, ip) {
if (arguments.length === 0) {
//Get total script income
- return Object(__WEBPACK_IMPORTED_MODULE_0__ActiveScriptsUI_js__["d" /* updateActiveScriptsItems */])();
+ var res = [];
+ res.push(Object(__WEBPACK_IMPORTED_MODULE_0__ActiveScriptsUI_js__["d" /* updateActiveScriptsItems */])());
+ res.push(__WEBPACK_IMPORTED_MODULE_12__Player_js__["a" /* Player */].scriptProdSinceLastAug / (__WEBPACK_IMPORTED_MODULE_12__Player_js__["a" /* Player */].playtimeSinceLastAug/1000));
+ return res;
} else {
//Get income for a particular script
var server = Object(__WEBPACK_IMPORTED_MODULE_14__Server_js__["e" /* getServer */])(ip);
@@ -34066,6 +34116,9 @@ function NetscriptFunctions(workerScript) {
return runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime;
}
},
+ getTimeSinceLastAug : function() {
+ return __WEBPACK_IMPORTED_MODULE_12__Player_js__["a" /* Player */].playtimeSinceLastAug;
+ },
/* Singularity Functions */
universityCourse(universityName, className) {
@@ -34877,7 +34930,1261 @@ function NetscriptFunctions(workerScript) {
/***/ }),
-/* 30 */
+/* 31 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return HackingMission; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "c", function() { return inMission; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "d", function() { return setInMission; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return currMission; });
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Constants_js__ = __webpack_require__(3);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__engine_js__ = __webpack_require__(4);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Faction_js__ = __webpack_require__(10);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__Player_js__ = __webpack_require__(0);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__utils_DialogBox_js__ = __webpack_require__(1);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__ = __webpack_require__(2);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__ = __webpack_require__(5);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_jsplumb__ = __webpack_require__(48);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7_jsplumb___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_7_jsplumb__);
+
+
+
+
+
+
+
+
+
+let inMission = false; //Flag to denote whether a mission is running
+let currMission = null;
+function setInMission(bool, mission) {
+ inMission = bool;
+ if (bool) {
+ currMission = mission;
+ } else {
+ currMission = null;
+ }
+}
+
+//Keyboard shortcuts
+$(document).keydown(function(e) {
+ if (inMission && currMission && currMission.selectedNode != null) {
+ switch (e.keyCode) {
+ case 65: //a for Attack
+ currMission.actionButtons[0].click();
+ break;
+ case 83: //s for Scan
+ currMission.actionButtons[1].click();
+ break;
+ case 87: //w for Weaken
+ currMission.actionButtons[2].click();
+ break;
+ case 70: //f for Fortify
+ currMission.actionButtons[3].click();
+ break;
+ case 82: //r for Overflow
+ currMission.actionButtons[4].click();
+ break;
+ case 68: //d for Detach connection
+ currMission.actionButtons[5].click();
+ break;
+ default:
+ break;
+ }
+ }
+});
+
+let NodeTypes = {
+ Core: "CPU Core Node", //All actions available
+ Firewall: "Firewall Node", //No actions available
+ Database: "Database Node", //No actions available
+ Spam: "Spam Node", //No actions Available
+ Transfer: "Transfer Node", //Can Weaken, Scan, Fortify and Overflow
+ Shield: "Shield Node" //Can Fortify
+}
+
+let NodeActions = {
+ Attack: "Attacking", //Damaged based on attack stat + hacking level + opp def
+ Scan: "Scanning", //-Def for target, affected by attack and hacking level
+ Weaken: "Weakening", //-Attack for target, affected by attack and hacking level
+ Fortify: "Fortifying", //+Defense for Node, affected by hacking level
+ Overflow: "Overflowing", //+Attack but -Defense for Node, affected by hacking level
+}
+
+function Node(type, stats) {
+ this.type = type;
+ this.atk = stats.atk ? stats.atk : 0;
+ this.def = stats.def ? stats.def : 0;
+ this.hp = stats.hp ? stats.hp : 0;
+ this.maxhp = this.hp;
+ this.plyrCtrl = false;
+ this.enmyCtrl = false;
+ this.pos = [0, 0]; //x, y
+ this.el = null; //Holds the Node's DOM element
+ this.action = null;
+
+ //Holds the JsPlumb Connection object for this Node,
+ //where this Node is the Source (since each Node
+ //can only have 1 outgoing Connection)
+ this.conn = null;
+}
+
+Node.prototype.setPosition = function(x, y) {
+ this.pos = [x, y];
+}
+
+Node.prototype.setControlledByPlayer = function() {
+ this.plyrCtrl = true;
+ this.enmyCtrl = false;
+ if (this.el) {
+ this.el.classList.remove("hack-mission-enemy-node");
+ this.el.classList.add("hack-mission-player-node");
+ }
+}
+
+Node.prototype.setControlledByEnemy = function() {
+ this.plyrCtrl = false;
+ this.enmyCtrl = true;
+ if (this.el) {
+ this.el.classList.remove("hack-mission-player-node");
+ this.el.classList.add("hack-mission-enemy-node");
+ }
+}
+
+//Sets this node to be the active node
+Node.prototype.select = function(actionButtons) {
+ if (this.enmyCtrl) {return;}
+ this.el.classList.add("hack-mission-player-node-active");
+
+ //Make all buttons inactive
+ for (var i = 0; i < actionButtons.length; ++i) {
+ actionButtons[i].classList.remove("a-link-button");
+ actionButtons[i].classList.add("a-link-button-inactive");
+ }
+
+ switch(this.type) {
+ case NodeTypes.Core:
+ //All buttons active
+ for (var i = 0; i < actionButtons.length; ++i) {
+ actionButtons[i].classList.remove("a-link-button-inactive");
+ actionButtons[i].classList.add("a-link-button");
+ }
+ break;
+ case NodeTypes.Transfer:
+ actionButtons[1].classList.remove("a-link-button-inactive");
+ actionButtons[1].classList.add("a-link-button");
+ actionButtons[2].classList.remove("a-link-button-inactive");
+ actionButtons[2].classList.add("a-link-button");
+ actionButtons[3].classList.remove("a-link-button-inactive");
+ actionButtons[3].classList.add("a-link-button");
+ actionButtons[4].classList.remove("a-link-button-inactive");
+ actionButtons[4].classList.add("a-link-button");
+ actionButtons[5].classList.remove("a-link-button-inactive");
+ actionButtons[5].classList.add("a-link-button");
+ break;
+ default:
+ break;
+ }
+}
+
+Node.prototype.deselect = function(actionButtons) {
+ this.el.classList.remove("hack-mission-player-node-active");
+ for (var i = 0; i < actionButtons.length; ++i) {
+ actionButtons[i].classList.remove("a-link-button");
+ actionButtons[i].classList.add("a-link-button-inactive");
+ }
+}
+
+//Hacking mission instance
+//Takes in the reputation of the Faction for which the mission is
+//being conducted
+function HackingMission(rep, fac) {
+ this.faction = fac;
+
+ this.started = false;
+ this.time = 180000; //2 minutes, milliseconds
+
+ this.playerCores = [];
+ this.playerNodes = []; //Non-core nodes
+ this.playerAtk = 0;
+ this.playerDef = 0;
+
+ this.enemyCores = [];
+ this.enemyDatabases = [];
+ this.enemyNodes = []; //Non-core nodes
+ this.enemyAtk = 0;
+ this.enemyDef = 0;
+
+ this.miscNodes = [];
+
+ this.selectedNode = null; //Which of the player's nodes is currently selected
+
+ this.actionButtons = []; //DOM buttons for actions
+
+ this.availablePositions = [];
+ for (var r = 0; r < 8; ++r) {
+ for (var c = 0; c < 8; ++c) {
+ this.availablePositions.push([r, c]);
+ }
+ }
+
+ this.map = [];
+ for (var i = 0; i < 8; ++i) {
+ this.map.push([null, null, null, null, null, null, null, null]);
+ }
+
+ this.jsplumbinstance = null;
+
+ //difficulty capped at 16
+ this.difficulty = Math.min(16, Math.round(rep / __WEBPACK_IMPORTED_MODULE_0__Constants_js__["a" /* CONSTANTS */].HackingMissionRepToDiffConversion) + 1);
+ console.log("difficulty: " + this.difficulty);
+ this.reward = 250 + (rep / __WEBPACK_IMPORTED_MODULE_0__Constants_js__["a" /* CONSTANTS */].HackingMissionRepToRewardConversion);
+}
+
+HackingMission.prototype.init = function() {
+ //Create Header DOM
+ this.createPageDom();
+
+ //Create player starting nodes
+ var home = __WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].getHomeComputer()
+ for (var i = 0; i < home.cpuCores; ++i) {
+ var stats = {
+ atk: (__WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill / 10),
+ def: (__WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill / 25),
+ hp: (__WEBPACK_IMPORTED_MODULE_3__Player_js__["a" /* Player */].hacking_skill / 5),
+ };
+ this.playerCores.push(new Node(NodeTypes.Core, stats));
+ this.playerCores[i].setControlledByPlayer();
+ this.setNodePosition(this.playerCores[i], 0, i);
+ this.removeAvailablePosition(0, i);
+ }
+
+ //Randomly generate enemy nodes (CPU and Firewall) based on difficulty
+ var numNodes = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(this.difficulty, this.difficulty + 1);
+ var numFirewalls = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(this.difficulty, this.difficulty + 1);
+ var numDatabases = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(this.difficulty, this.difficulty + 1);
+ var totalNodes = numNodes + numFirewalls + numDatabases;
+ var xlimit = 7 - Math.floor(totalNodes / 8);
+ console.log("numNodes: " + numNodes);
+ console.log("numFirewalls: " + numFirewalls);
+ console.log("numDatabases: " + numDatabases);
+ console.log("totalNodes: " + totalNodes);
+ var randMult = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["a" /* addOffset */])(this.difficulty, 20);
+ for (var i = 0; i < numNodes; ++i) {
+ var stats = {
+ atk: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(125, 175),
+ def: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(30, 50),
+ hp: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(225, 275)
+ }
+ this.enemyCores.push(new Node(NodeTypes.Core, stats));
+ this.enemyCores[i].setControlledByEnemy();
+ this.setNodeRandomPosition(this.enemyCores[i], xlimit);
+ }
+ for (var i = 0; i < numFirewalls; ++i) {
+ var stats = {
+ atk: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(10, 25),
+ def: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(50, 75),
+ hp: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(175, 200)
+ }
+ this.enemyNodes.push(new Node(NodeTypes.Firewall, stats));
+ this.enemyNodes[i].setControlledByEnemy();
+ this.setNodeRandomPosition(this.enemyNodes[i], xlimit);
+ }
+ for (var i = 0; i < numDatabases; ++i) {
+ var stats = {
+ atk: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(20, 30),
+ def: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(25, 40),
+ hp: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(120, 150)
+ }
+ var node = new Node(NodeTypes.Database, stats);
+ node.setControlledByEnemy();
+ this.setNodeRandomPosition(node, xlimit);
+ this.enemyDatabases.push(node);
+ }
+ this.calculateDefenses();
+ this.calculateAttacks();
+ this.createMap();
+}
+
+HackingMission.prototype.createPageDom = function() {
+ var container = document.getElementById("mission-container");
+
+ var headerText = document.createElement("p");
+ headerText.innerHTML = "You are about to start a hacking mission! For more information " +
+ "about how hacking missions work, click one of the guide links " +
+ "below (one opens up an in-game guide and the other opens up " +
+ "the guide from the wiki). Click the 'Start' button to begin.";
+ headerText.style.display = "block";
+ headerText.classList.add("hack-mission-header-element");
+ headerText.style.width = "80%";
+
+ var inGameGuideBtn = document.createElement("a");
+ inGameGuideBtn.innerText = "How to Play";
+ inGameGuideBtn.classList.add("a-link-button");
+ inGameGuideBtn.style.display = "inline-block";
+ inGameGuideBtn.classList.add("hack-mission-header-element");
+ inGameGuideBtn.addEventListener("click", function() {
+ Object(__WEBPACK_IMPORTED_MODULE_4__utils_DialogBox_js__["a" /* dialogBoxCreate */])(__WEBPACK_IMPORTED_MODULE_0__Constants_js__["a" /* CONSTANTS */].HackingMissionHowToPlay);
+ return false;
+ });
+
+ var wikiGuideBtn = document.createElement("a");
+ wikiGuideBtn.innerText = "Wiki Guide";
+ wikiGuideBtn.classList.add("a-link-button");
+ wikiGuideBtn.style.display = "inline-block";
+ wikiGuideBtn.classList.add("hack-mission-header-element");
+ wikiGuideBtn.target = "_blank";
+ //TODO Add link to wiki page wikiGuideBtn.href =
+
+
+ //Start button will get replaced with forfeit when game is started
+ var startBtn = document.createElement("a");
+ startBtn.innerHTML = "Start";
+ startBtn.setAttribute("id", "hack-mission-start-btn");
+ startBtn.classList.add("a-link-button");
+ startBtn.classList.add("hack-mission-header-element");
+ startBtn.style.display = "inline-block";
+ startBtn.addEventListener("click", ()=>{
+ this.start();
+ return false;
+ });
+
+ var forfeitMission = document.createElement("a");
+ forfeitMission.innerHTML = "Forfeit Mission (Exit)";
+ forfeitMission.classList.add("a-link-button");
+ forfeitMission.classList.add("hack-mission-header-element");
+ forfeitMission.style.display = "inline-block";
+ forfeitMission.addEventListener("click", ()=> {
+ this.finishMission(false);
+ return false;
+ });
+
+ var timer = document.createElement("p");
+ timer.setAttribute("id", "hacking-mission-timer");
+ timer.style.display = "inline-block";
+ timer.style.margin = "6px";
+
+ //Create Action Buttons (Attack/Scan/Weaken/ etc...)
+ var actionsContainer = document.createElement("span");
+ actionsContainer.style.display = "block";
+ actionsContainer.classList.add("hack-mission-action-buttons-container");
+ for (var i = 0; i < 6; ++i) {
+ this.actionButtons.push(document.createElement("a"));
+ this.actionButtons[i].style.display = "inline-block";
+ this.actionButtons[i].classList.add("a-link-button-inactive"); //Disabled at start
+ this.actionButtons[i].classList.add("tooltip"); //Disabled at start
+ this.actionButtons[i].classList.add("hack-mission-header-element");
+ actionsContainer.appendChild(this.actionButtons[i]);
+ }
+ this.actionButtons[0].innerText = "Attack(a)";
+ var atkTooltip = document.createElement("span");
+ atkTooltip.classList.add("tooltiptext");
+ atkTooltip.innerText = "Lowers the targeted node's HP. The effectiveness of this depends on " +
+ "this node's Attack level, your hacking level, and the opponent's defense level.";
+ this.actionButtons[0].appendChild(atkTooltip);
+ this.actionButtons[1].innerText = "Scan(s)";
+ var scanTooltip = document.createElement("span");
+ scanTooltip.classList.add("tooltiptext");
+ scanTooltip.innerText = "Lowers the targeted node's defense. The effectiveness of this depends on " +
+ "this node's Attack level, your hacking level, and the opponent's defense level.";
+ this.actionButtons[1].appendChild(scanTooltip);
+ this.actionButtons[2].innerText = "Weaken(w)";
+ var WeakenTooltip = document.createElement("span");
+ WeakenTooltip.classList.add("tooltiptext");
+ WeakenTooltip.innerText = "Lowers the targeted node's attack. The effectiveness of this depends on " +
+ "this node's Attack level, your hacking level, and the opponent's defense level.";
+ this.actionButtons[2].appendChild(WeakenTooltip);
+ this.actionButtons[3].innerText = "Fortify(f)";
+ var fortifyTooltip = document.createElement("span");
+ fortifyTooltip.classList.add("tooltiptext");
+ fortifyTooltip.innerText = "Raises this node's Defense level. The effectiveness of this depends on " +
+ "your hacking level";
+ this.actionButtons[3].appendChild(fortifyTooltip);
+ this.actionButtons[4].innerText = "Overflow(r)";
+ var overflowTooltip = document.createElement("span");
+ overflowTooltip.classList.add("tooltiptext");
+ overflowTooltip.innerText = "Raises this node's Attack level but lowers its Defense level. The effectiveness " +
+ "of this depends on your hacking level.";
+ this.actionButtons[4].appendChild(overflowTooltip);
+ this.actionButtons[5].innerText = "Drop Connection(d)";
+ var dropconnTooltip = document.createElement("span");
+ dropconnTooltip.classList.add("tooltiptext");
+ dropconnTooltip.innerText = "Removes this Node's current connection to some target Node, if it has one. This can " +
+ "also be done by simply clicking the white connection line.";
+ this.actionButtons[5].appendChild(dropconnTooltip);
+
+ //Player/enemy defense displays will be in action container
+ var playerStats = document.createElement("p");
+ var enemyStats = document.createElement("p");
+ playerStats.style.display = "inline-block";
+ enemyStats.style.display = "inline-block";
+ playerStats.style.color = "#00ccff";
+ enemyStats.style.color = "red";
+ playerStats.style.margin = "4px";
+ enemyStats.style.margin = "4px";
+ playerStats.setAttribute("id", "hacking-mission-player-stats");
+ enemyStats.setAttribute("id", "hacking-mission-enemy-stats");
+ actionsContainer.appendChild(playerStats);
+ actionsContainer.appendChild(enemyStats);
+
+ //Set Action Button event listeners
+ this.actionButtons[0].addEventListener("click", ()=>{
+ if (!(this.selectedNode instanceof Node)) {
+ console.log("ERR: Pressing Action button without selected node");
+ return;
+ }
+ this.setActionButtonsActive();
+ this.setActionButton(NodeActions.Attack, false); //Set attack button inactive
+ this.selectedNode.action = NodeActions.Attack;
+ });
+
+ this.actionButtons[1].addEventListener("click", ()=>{
+ if (!(this.selectedNode instanceof Node)) {
+ console.log("ERR: Pressing Action button without selected node");
+ return;
+ }
+ this.setActionButtonsActive();
+ this.setActionButton(NodeActions.Scan, false); //Set scan button inactive
+ this.selectedNode.action = NodeActions.Scan;
+ });
+
+ this.actionButtons[2].addEventListener("click", ()=>{
+ if (!(this.selectedNode instanceof Node)) {
+ console.log("ERR: Pressing Action button without selected node");
+ return;
+ }
+ this.setActionButtonsActive();
+ this.setActionButton(NodeActions.Weaken, false); //Set Weaken button inactive
+ this.selectedNode.action = NodeActions.Weaken;
+ });
+
+ this.actionButtons[3].addEventListener("click", ()=>{
+ if (!(this.selectedNode instanceof Node)) {
+ console.log("ERR: Pressing Action button without selected node");
+ return;
+ }
+ this.setActionButtonsActive();
+ this.setActionButton(NodeActions.Fortify, false); //Set Fortify button inactive
+ this.selectedNode.action = NodeActions.Fortify;
+ });
+
+ this.actionButtons[4].addEventListener("click", ()=>{
+ if (!(this.selectedNode instanceof Node)) {
+ console.log("ERR: Pressing Action button without selected node");
+ return;
+ }
+ this.setActionButtonsActive();
+ this.setActionButton(NodeActions.Overflow, false); //Set Overflow button inactive
+ this.selectedNode.action = NodeActions.Overflow;
+ });
+
+ this.actionButtons[5].addEventListener("click", ()=>{
+ if (!(this.selectedNode instanceof Node)) {
+ console.log("ERR: Pressing Action button without selected node");
+ return;
+ }
+ if (this.selectedNode.conn) {
+ var endpoints = this.selectedNode.conn.endpoints;
+ endpoints[0].detachFrom(endpoints[1]);
+ }
+ })
+
+ var timeDisplay = document.createElement("p");
+
+ container.appendChild(headerText);
+ container.appendChild(inGameGuideBtn);
+ container.appendChild(wikiGuideBtn);
+ container.appendChild(startBtn);
+ container.appendChild(forfeitMission);
+ container.appendChild(timer);
+ container.appendChild(actionsContainer);
+ container.appendChild(timeDisplay);
+}
+
+HackingMission.prototype.setActionButtonsInactive = function() {
+ for (var i = 0; i < this.actionButtons.length; ++i) {
+ this.actionButtons[i].classList.remove("a-link-button");
+ this.actionButtons[i].classList.add("a-link-button-inactive");
+ }
+}
+
+HackingMission.prototype.setActionButtonsActive = function() {
+ for (var i = 0; i < this.actionButtons.length; ++i) {
+ this.actionButtons[i].classList.add("a-link-button");
+ this.actionButtons[i].classList.remove("a-link-button-inactive");
+ }
+}
+
+//True for active, false for inactive
+HackingMission.prototype.setActionButton = function(i, active=true) {
+ if (Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["f" /* isString */])(i)) {
+ switch (i) {
+ case NodeActions.Attack:
+ i = 0;
+ break;
+ case NodeActions.Scan:
+ i = 1;
+ break;
+ case NodeActions.Weaken:
+ i = 2;
+ break;
+ case NodeActions.Fortify:
+ i = 3;
+ break;
+ case NodeActions.Overflow:
+ default:
+ i = 4;
+ break;
+ }
+ }
+ if (active) {
+ this.actionButtons[i].classList.remove("a-link-button-inactive");
+ this.actionButtons[i].classList.add("a-link-button");
+ } else {
+ this.actionButtons[i].classList.remove("a-link-button");
+ this.actionButtons[i].classList.add("a-link-button-inactive");
+ }
+
+}
+
+HackingMission.prototype.calculateAttacks = function() {
+ var total = 0;
+ for (var i = 0; i < this.playerCores.length; ++i) {
+ total += this.playerCores[i].atk;
+ }
+ for (var i = 0; i < this.playerNodes.length; ++i) {
+ total += this.playerNodes[i].atk;
+ }
+ this.playerAtk = total;
+ document.getElementById("hacking-mission-player-stats").innerHTML =
+ "Player Attack: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.playerAtk, 1) + " " +
+ "Player Defense: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.playerDef, 1);
+ total = 0;
+ for (var i = 0; i < this.enemyCores.length; ++i) {
+ total += this.enemyCores[i].atk;
+ }
+ for (var i = 0; i < this.enemyDatabases.length; ++i) {
+ total += this.enemyDatabases[i].atk;
+ }
+ for (var i = 0; i < this.enemyNodes.length; ++i) {
+ total += this.enemyNodes[i].atk;
+ }
+ this.enemyAtk = total;
+ document.getElementById("hacking-mission-enemy-stats").innerHTML =
+ "Enemy Attack: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.enemyAtk, 1) + " " +
+ "Enemy Defense: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.enemyDef, 1);
+}
+
+HackingMission.prototype.calculateDefenses = function() {
+ var total = 0;
+ for (var i = 0; i < this.playerCores.length; ++i) {
+ total += this.playerCores[i].def;
+ }
+ for (var i = 0; i < this.playerNodes.length; ++i) {
+ total += this.playerNodes[i].def;
+ }
+ this.playerDef = total;
+ document.getElementById("hacking-mission-player-stats").innerHTML =
+ "Player Attack: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.playerAtk, 1) + " " +
+ "Player Defense: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.playerDef, 1);
+ total = 0;
+ for (var i = 0; i < this.enemyCores.length; ++i) {
+ total += this.enemyCores[i].def;
+ }
+ for (var i = 0; i < this.enemyDatabases.length; ++i) {
+ total += this.enemyDatabases[i].def;
+ }
+ for (var i = 0; i < this.enemyNodes.length; ++i) {
+ total += this.enemyNodes[i].def;
+ }
+ this.enemyDef = total;
+ document.getElementById("hacking-mission-enemy-stats").innerHTML =
+ "Enemy Attack: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.enemyAtk, 1) + " " +
+ "Enemy Defense: " + Object(__WEBPACK_IMPORTED_MODULE_6__utils_StringHelperFunctions_js__["c" /* formatNumber */])(this.enemyDef, 1);
+}
+
+HackingMission.prototype.removeAvailablePosition = function(x, y) {
+ for (var i = 0; i < this.availablePositions.length; ++i) {
+ if (this.availablePositions[i][0] === x &&
+ this.availablePositions[i][1] === y) {
+ this.availablePositions.splice(i, 1);
+ return;
+ }
+ }
+ console.log("WARNING: removeAvailablePosition() did not remove " + x + ", " + y);
+}
+
+HackingMission.prototype.setNodePosition = function(nodeObj, x, y) {
+ if (!(nodeObj instanceof Node)) {
+ console.log("WARNING: Non-Node object passed into setNodePOsition");
+ return;
+ }
+ if (isNaN(x) || isNaN(y)) {
+ console.log("ERR: Invalid values passed as x and y for setNodePosition");
+ console.log(x);
+ console.log(y);
+ return;
+ }
+ nodeObj.pos = [x, y];
+ this.map[x][y] = nodeObj;
+}
+
+HackingMission.prototype.setNodeRandomPosition = function(nodeObj, xlimit=0) {
+ var i = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(0, this.availablePositions.length - 1);
+ var pos = this.availablePositions.splice(i, 1);
+ pos = pos[0];
+ this.setNodePosition(nodeObj, pos[0], pos[1]);
+}
+
+HackingMission.prototype.createMap = function() {
+ //Use a grid
+ var map = document.createElement("div");
+ map.classList.add("hack-mission-grid");
+ map.setAttribute("id", "hacking-mission-map");
+ document.getElementById("mission-container").appendChild(map);
+
+ //Create random Nodes for every space in the map that
+ //hasn't been filled yet
+ for (var x = 0; x < 8; ++x) {
+ for (var y = 0; y < 8; ++y) {
+ if (!(this.map[x][y] instanceof Node)) {
+ var node, type = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(0, 2);
+ var randMult = Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["a" /* addOffset */])(this.difficulty, 20);
+ switch (type) {
+ case 0: //Spam
+ var stats = {
+ atk: 0,
+ def: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(35, 55),
+ hp: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(125, 150)
+ }
+ node = new Node(NodeTypes.Spam, stats);
+ break;
+ case 1: //Transfer
+ var stats = {
+ atk: 0,
+ def: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(45, 65),
+ hp: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(150, 175)
+ }
+ node = new Node(NodeTypes.Transfer, stats);
+ break;
+ case 2: //Shield
+ default:
+ var stats = {
+ atk: 0,
+ def: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(60, 80),
+ hp: randMult * Object(__WEBPACK_IMPORTED_MODULE_5__utils_HelperFunctions_js__["d" /* getRandomInt */])(200, 250)
+ }
+ node = new Node(NodeTypes.Shield, stats);
+ break;
+ }
+ this.setNodePosition(node, x, y);
+ this.removeAvailablePosition(x, y);
+ this.miscNodes.push(node);
+ }
+ }
+ }
+
+ //Create DOM elements in order
+ for (var r = 0; r < 8; ++r) {
+ for (var c = 0; c < 8; ++c) {
+ this.createNodeDomElement(this.map[r][c]);
+ }
+ }
+
+ //Configure all Player CPUS
+ for (var i = 0; i < this.playerCores.length; ++i) {
+ console.log("Configuring Player Node: " + this.playerCores[i].el.id);
+ this.configurePlayerNodeElement(this.playerCores[i].el);
+ }
+}
+
+HackingMission.prototype.createNodeDomElement = function(nodeObj) {
+ var nodeDiv = document.createElement("a");
+ nodeObj.el = nodeDiv;
+ document.getElementById("hacking-mission-map").appendChild(nodeDiv);
+
+ //Set the node element's id based on its coordinates
+ nodeDiv.setAttribute("id", "hacking-mission-node-" +
+ nodeObj.pos[0] + "-" +
+ nodeObj.pos[1]);
+
+ //Set node classes for owner
+ nodeDiv.classList.add("hack-mission-node");
+ if (nodeObj.plyrCtrl) {
+ nodeDiv.classList.add("hack-mission-player-node");
+ } else if (nodeObj.enmyCtrl) {
+ nodeDiv.classList.add("hack-mission-enemy-node");
+ }
+
+ //Set node classes based on type
+ var txt;
+ switch (nodeObj.type) {
+ case NodeTypes.Core:
+ txt = "
";
-
-
- /*
- " O " +
- " | O O | O O | " +
- " O | | / __| \ | | O " +
- " O | O | | O / | O | | O | O " +
- " | | | | |_/ |/ | \_ \_| | | | | " +
- " O | | | O | | O__/ | / \__ | | O | | | O " +
- " | | | | | | | / /| O / \| | | | | | | " +
- "O | | | \| | O / _/ | / O | |/ | | | O " +
- "| | | |O / | | O / | O O | | \ O| | | | " +
- "| | |/ \/ / __| | |/ \ | \ | |__ \ \/ \| | | " +
- " \| O | |_/ |\| \ O \__| \_| | O |/ " +
- " | | |_/ | | \| / | \_| | | " +
- " \| / \| | / / \ |/ " +
- " | O | | / | O | " +
- " O | | | | | | | O " +
- " | | | / / \ \ | | | " +
- " \| | / O / \ O \ | |/ " +
- " \ | / / | | \ \ | / " +
- " \ \JUMP O3R | | | | | | R3O PMUJ/ / " +
- " \|| | | | | | | | | ||/ " +
- " \| \_ | | | | | | _/ |/ " +
- " \ \| / \ / \ |/ / " +
- " O |/ O | | O \| O " +
- " | | | | | | | | " +
- " \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ ";
- */
-
- container.appendChild(bitVerseImage);
-
- //Bit node event listeners
- for (var i = 1; i <= 12; ++i) {
- (function(i) {
- var elemId = "bitnode-" + i.toString();
- var elem = Object(__WEBPACK_IMPORTED_MODULE_7__utils_HelperFunctions_js__["b" /* clearEventListeners */])(elemId);
- if (elem == null) {return;}
- if (i === 1 || i === 2 || i === 4 || i === 5 || i === 11) {
- elem.addEventListener("click", function() {
- var bitNodeKey = "BitNode" + i;
- var bitNode = __WEBPACK_IMPORTED_MODULE_0__BitNode_js__["b" /* BitNodes */][bitNodeKey];
- if (bitNode == null) {
- console.log("ERROR: Could not find BitNode object for number: " + i);
- return;
- }
- Object(__WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__["b" /* yesNoBoxCreate */])("BitNode-" + i + ": " + bitNode.name + "
" + bitNode.info);
- createBitNodeYesNoEventListeners(i, destroyedBitNodeNum);
- });
- } else {
- elem.addEventListener("click", function() {
- Object(__WEBPACK_IMPORTED_MODULE_6__utils_DialogBox_js__["a" /* dialogBoxCreate */])("Not yet implemented! Coming soon!")
- });
- }
- }(i)); //Immediate invocation closure
- }
-
- //Create lore text
- return writeRedPillLine("Many decades ago, a humanoid extraterrestial species which we call the Enders descended on the Earth...violently").then(function() {
- return writeRedPillLine("Our species fought back, but it was futile. The Enders had technology far beyond our own...");
- }).then(function() {
- return writeRedPillLine("Instead of killing every last one of us, the human race was enslaved...");
- }).then(function() {
- return writeRedPillLine("We were shackled in a digital world, chained into a prison for our minds...");
- }).then(function() {
- return writeRedPillLine("Using their advanced technology, the Enders created complex simulations of a virtual reality...");
- }).then(function() {
- return writeRedPillLine("Simulations designed to keep us content...ignorant of the truth.");
- }).then(function() {
- return writeRedPillLine("Simulations used to trap and suppress our consciousness, to keep us under control...");
- }).then(function() {
- return writeRedPillLine("Why did they do this? Why didn't they just end our entire race? We don't know, not yet.");
- }).then(function() {
- return writeRedPillLine("Humanity's only hope is to destroy these simulations, destroy the only realities we've ever known...");
- }).then(function() {
- return writeRedPillLine("Only then can we begin to fight back...");
- }).then(function() {
- return writeRedPillLine("By hacking the daemon that generated your reality, you've just destroyed one simulation, called a BitNode...");
- }).then(function() {
- return writeRedPillLine("But there is still a long way to go...");
- }).then(function() {
- return writeRedPillLine("The technology the Enders used to enslave the human race wasn't just a single complex simulation...");
- }).then(function() {
- return writeRedPillLine("There are tens if not hundreds of BitNodes out there...");
- }).then(function() {
- return writeRedPillLine("Each with their own simulations of a reality...");
- }).then(function() {
- return writeRedPillLine("Each creating their own universes...a universe of universes");
- }).then(function() {
- return writeRedPillLine("And all of which must be destroyed...");
- }).then(function() {
- return writeRedPillLine(".......................................");
- }).then(function() {
- return writeRedPillLine("Welcome to the Bitverse...");
- }).then(function() {
- return Promise.resolve(true);
- }).catch(function(e){
- console.log("ERROR: " + e.toString());
- });
-}
-
-
-//Returns string with DOM element for Bit Node
-function createBitNode(n) {
- var bitNodeStr = "BitNode" + n.toString();
- var bitNode = __WEBPACK_IMPORTED_MODULE_0__BitNode_js__["b" /* BitNodes */][bitNodeStr];
- if (bitNode == null) {return "O";}
- return "O" +
- "" +
- "BitNode-" + bitNode.number.toString() + " " + bitNode.name+ " " +
- bitNode.desc + " " +
- "";
-}
-
-function createBitNodeYesNoEventListeners(newBitNode, destroyedBitNode) {
- var yesBtn = Object(__WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__["d" /* yesNoBoxGetYesButton */])();
- yesBtn.innerHTML = "Enter BitNode-" + newBitNode;
- yesBtn.addEventListener("click", function() {
- giveSourceFile(destroyedBitNode);
- redPillFlag = false;
- var container = document.getElementById("red-pill-container");
- while (container.firstChild) {
- container.removeChild(container.firstChild);
- }
-
- //Set new Bit Node
- __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].bitNodeN = newBitNode;
- console.log("Entering Bit Node " + __WEBPACK_IMPORTED_MODULE_2__Player_js__["a" /* Player */].bitNodeN);
-
- //Reenable terminal
- $("#hack-progress-bar").attr('id', "old-hack-progress-bar");
- $("#hack-progress").attr('id', "old-hack-progress");
- document.getElementById("terminal-input-td").innerHTML = '$ ';
- $('input[class=terminal-input]').prop('disabled', false);
-
- __WEBPACK_IMPORTED_MODULE_5__Terminal_js__["a" /* Terminal */].hackFlag = false;
-
- Object(__WEBPACK_IMPORTED_MODULE_3__Prestige_js__["b" /* prestigeSourceFile */])();
- Object(__WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__["a" /* yesNoBoxClose */])();
- });
- var noBtn = Object(__WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__["c" /* yesNoBoxGetNoButton */])();
- noBtn.innerHTML = "Back";
- noBtn.addEventListener("click", function() {
- Object(__WEBPACK_IMPORTED_MODULE_8__utils_YesNoBox_js__["a" /* yesNoBoxClose */])();
- });
-
-}
-
-
-
-/* WEBPACK VAR INJECTION */}.call(__webpack_exports__, __webpack_require__(7)))
-
/***/ }),
/* 45 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
@@ -59931,7 +60030,7 @@ init(true);function init(packaged) {
if (!global || !global.document)
return;
- options.packaged = packaged || acequire.packaged || module.packaged || (global.define && __webpack_require__(39).packaged);
+ options.packaged = packaged || acequire.packaged || module.packaged || (global.define && __webpack_require__(40).packaged);
var scriptOptions = {};
var scriptUrl = "";
@@ -75229,7 +75328,7 @@ exports.config = acequire("./config");
exports.acequire = acequire;
if (true)
- exports.define = __webpack_require__(39);
+ exports.define = __webpack_require__(40);
exports.edit = function(el) {
if (typeof el == "string") {
var _id = el;
@@ -76124,7 +76223,7 @@ oop.inherits(Mode, TextMode);
};
this.createWorker = function(session) {
- var worker = new WorkerClient(["ace"], __webpack_require__(40), "JavaScriptWorker");
+ var worker = new WorkerClient(["ace"], __webpack_require__(41), "JavaScriptWorker");
worker.attachToDocument(session.getDocument());
worker.on("annotate", function(results) {
@@ -76226,10 +76325,11 @@ var NetscriptHighlightRules = function(options) {
"getServerMinSecurityLevel|" +
"getServerRequiredHackingLevel|getServerNumPortsRequired|getServerRam|" +
"serverExists|fileExists|isRunning|getNextHacknetNodeCost|" +
- "purchaseHacknetNode|" +
+ "purchaseHacknetNode|deleteServer|getPurchasedServers|" +
"purchaseServer|round|write|read|scriptRunning|scriptKill|getScriptRam|" +
"getHackTime|getGrowTime|getWeakenTime|getScriptIncome|getScriptExpGain|" +
- "universityCourse|" +
+ "getTimeSinceLastAug|" +
+ "universityCourse|" +
"gymWorkout|travelToCity|purchaseTor|purchaseProgram|upgradeHomeRam|" +
"getUpgradeHomeRamCost|workForCompany|applyToCompany|getCompanyRep|" +
"checkFactionInvitations|joinFaction|workForFaction|getFactionRep|" +
@@ -76931,7 +77031,7 @@ oop.inherits(Mode, TextMode);
};
this.createWorker = function(session) {
- var worker = new WorkerClient(["ace"], __webpack_require__(40), "JavaScriptWorker");
+ var worker = new WorkerClient(["ace"], __webpack_require__(41), "JavaScriptWorker");
worker.attachToDocument(session.getDocument());
worker.on("annotate", function(results) {
@@ -88600,13 +88700,13 @@ Object.defineProperty(exports, '__esModule', { value: true });
"use strict";
/* WEBPACK VAR INJECTION */(function($) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "b", function() { return saveObject; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return loadGame; });
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Alias_js__ = __webpack_require__(41);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__Alias_js__ = __webpack_require__(42);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__Company_js__ = __webpack_require__(18);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__Constants_js__ = __webpack_require__(3);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__engine_js__ = __webpack_require__(4);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__Faction_js__ = __webpack_require__(10);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Gang_js__ = __webpack_require__(30);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__HacknetNode_js__ = __webpack_require__(34);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__Gang_js__ = __webpack_require__(32);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__HacknetNode_js__ = __webpack_require__(37);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__Message_js__ = __webpack_require__(22);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__Player_js__ = __webpack_require__(0);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__Script_js__ = __webpack_require__(19);
@@ -88615,7 +88715,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__SpecialServerIps_js__ = __webpack_require__(11);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__StockMarket_js__ = __webpack_require__(26);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__utils_DialogBox_js__ = __webpack_require__(1);
-/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__utils_GameOptions_js__ = __webpack_require__(35);
+/* harmony import */ var __WEBPACK_IMPORTED_MODULE_15__utils_GameOptions_js__ = __webpack_require__(38);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_16__utils_HelperFunctions_js__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_17__utils_JSONReviver_js__ = __webpack_require__(8);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_18__utils_StringHelperFunctions_js__ = __webpack_require__(5);
diff --git a/src/ActiveScriptsUI.js b/src/ActiveScriptsUI.js
index d1ad0fa07..5b279ac40 100644
--- a/src/ActiveScriptsUI.js
+++ b/src/ActiveScriptsUI.js
@@ -6,6 +6,7 @@ import {getServer} from "./Server.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {printArray} from "../utils/HelperFunctions.js";
import {logBoxCreate} from "../utils/LogBox.js";
+import numeral from "../utils/numeral.min.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
@@ -183,10 +184,10 @@ function updateActiveScriptsItems() {
total += updateActiveScriptsItemContent(workerScripts[i]);
}
document.getElementById("active-scripts-total-prod").innerHTML =
- "Total online production of Active Scripts: $" + formatNumber(total, 2) + " / second " +
- "Total online production since last Augmentation installation: $" +
- formatNumber(Player.scriptProdSinceLastAug, 2) + " ($" +
- formatNumber(Player.scriptProdSinceLastAug / Player.playtimeSinceLastAug, 2) + " / second)";
+ "Total online production of Active Scripts: " + numeral(total).format('$0.000a') + " / sec " +
+ "Total online production since last Aug installation: " +
+ numeral(Player.scriptProdSinceLastAug).format('$0.000a') + " (" +
+ numeral(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
return total;
}
diff --git a/src/Constants.js b/src/Constants.js
index 9ae13cb7c..75a2a6339 100644
--- a/src/Constants.js
+++ b/src/Constants.js
@@ -124,31 +124,30 @@ let CONSTANTS = {
//Hacking Missions
HackingMissionRepToDiffConversion: 5000, //Faction rep is divided by this to get mission difficulty
- HackingMissionRepToRewardConversion: 20, //Faction rep divided byt his to get mission rep reward
+ HackingMissionRepToRewardConversion: 12, //Faction rep divided byt his to get mission rep reward
HackingMissionSpamTimeIncrease: 20000, //How much time limit increase is gained when conquering a Spam Node (ms)
HackingMissionTransferAttackIncrease: 1.05, //Multiplier by which the attack for all Core Nodes is increased when conquering a Transfer Node
HackingMissionHowToPlay: "Hacking missions are a minigame that, if won, will reward you with faction reputation.
" +
"In this game you control a set of Nodes and use them to try and defeat an enemy. Your Nodes " +
- "are colored blue, while the enemy's are red. There are also other nodes on the map colored gray" +
+ "are colored blue, while the enemy's are red. There are also other nodes on the map colored gray " +
"that initially belong to neither you nor the enemy. The goal of the game is " +
"to capture all of the enemy's database nodes, which are the parallelogram-shaped ones, within the time limit. " +
"If you cannot capture all of the enemy's database nodes in the time limit, you will lose.
" +
"Each Node has three stats: Attack, Defense, and HP. There are five different actions that " +
"a Node can take:
" +
- "Attack - Targets an enemy Node and lowers its HP. The effectiveness is determined by the Node's Attack, the Player's " +
+ "Attack - Targets an enemy Node and lowers its HP. The effectiveness is determined by the owner's Attack, the Player's " +
"hacking level, and the enemy's defense. " +
- "Scan - Targets an enemy Node and lowers its Defense. The effectiveness is determined by the Player's hacking level and the " +
+ "Scan - Targets an enemy Node and lowers its Defense. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the " +
"enemy's defense. " +
- "Weaken - Targets an enemy Node and lowers its Attack. The effectiveness is determined by the Player's hacking level and the enemy's " +
+ "Weaken - Targets an enemy Node and lowers its Attack. The effectiveness is determined by the owner's Attack, the Player's hacking level, and the enemy's " +
"defense. " +
- "Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level.
" +
- "To capture a Node, you must lower its HP down to 0. " +
- "A Node's 'Attack' stats affects its effectiveness when attacking other Nodes. A Node's 'Defense' helps protect " +
- "against the actions of enemy Nodes. One important thing to note is that, when defending, your total 'Defense' " +
- "(sum of the Defense of all of your Nodes) is what's taken into account when determining the effect of offensive actions. " +
- "However, when attacking, only the 'Attack' of the Node being used to attack is taken into account.
" +
+ "Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level. " +
+ "Overflow - Raises the Node's Attack but lowers its Defense. The effectiveness is determined by your hacking level.
" +
+ "Note that when determining the effectiveness of the above actions, the TOTAL Attack or Defense of the team is used, not just the " +
+ "Attack/Defense of the individual Node that is performing the action. " +
"There are six different types of Nodes:
" +
- "CPU Core - These are your main Nodes that are used to perform actions " +
+ "CPU Core - These are your main Nodes that are used to perform actions. Capable of performing every action " +
"Firewall - Nodes with high defense. These Nodes cannot perform any actions " +
"Database - A special type of Node. The player's objective is to conquer all of the enemy's Database Nodes within " +
"the time limit. These Nodes cannot perform any actions " +
@@ -157,10 +156,16 @@ let CONSTANTS = {
"Transfer - Conquering one of these nodes will increase the Attack of all of your CPU Cores by a small fixed percentage. " +
"These Nodes are capable of performing every action except the 'Attack' action " +
"Shield - Nodes with high defense. These Nodes cannot perform any actions
" +
+ "To assign an action to a Node, you must first select one of your Nodes. This can be done by simply clicking on it. Only " +
+ "one Node can be selected at a time, and it will be denoted with a white highlight. After selecting the Node, " +
+ "select its action using the Action Buttons near the top of the screen. Every action also has a corresponding keyboard " +
+ "shortcut that can be used as well.
" +
"For certain actions such as attacking, scanning, and weakening, the Node performing the action must have a target. To target " +
"another node, simply click-and-drag from the 'source' Node to a target. A Node can only have one target, and you can only target " +
"Nodes that are adjacent to one of your Nodes (immediately above, below, or to the side. NOT diagonal). Furthermore, only CPU Cores and Transfer Nodes " +
- "can target, since they are the only ones that can perform actions",
+ "can target, since they are the only ones that can perform actions. To remove a target, you can simply click on the line that represents " +
+ "the connection between one of your Nodes and its target. Alternatively, you can select the 'source' Node and click the 'Drop Connection' button, " +
+ "or press 'd',",
//Gang constants
@@ -418,6 +423,9 @@ let CONSTANTS = {
"args.length
" +
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
"args array.
" +
+ "
Javascript Modules
" +
+ "Netscript supports the following Javascript Modules:
" +
+ "Math Date (static functions only)
" +
"
Functions
" +
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
"you may use:
" +
@@ -649,8 +657,9 @@ let CONSTANTS = {
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.
" +
"getScriptIncome([scriptname], [hostname/ip], [args...]) " +
"Returns the amount of income the specified script generates while online (when the game is open, does not apply for " +
- "offline income). This function can also return the total income of all of your active scripts by running the function " +
- "with no arguments.
" +
+ "offline income). This function can also be called with no arguments. If called with no arguments, then this function " +
+ "will return an array of two values. The first value is the total income ($/sec) of all of your active scripts (currently running). " +
+ "The second value is the total income ($/sec) from scripts since you last installed Augmentations (or destroyed a BitNode).
" +
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
"with the arguments 'foodnstuff' and '5' then in order to use this function to get that script's income you must " +
"specify those arguments in this function call.
" +
@@ -669,6 +678,8 @@ let CONSTANTS = {
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.
" +
+ "getTimeSinceLastAug() " +
+ "Returns the amount of time in milliseconds that have passed since you last installed Augmentations (or destroyed a BitNode).
" +
"
Hacknet Nodes API
" +
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.
" +
"hacknetnodes A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
@@ -998,28 +1009,24 @@ let CONSTANTS = {
LatestUpdate:
"v0.29.1 " +
+ "-New gameplay feature that is currently in BETA: Hacking Missions. Hacking Missions is an active gameplay mechanic (its a minigame) " +
+ "that is meant to be used to earn faction reputation. However, since this is currently in beta, hacking missions will NOT grant reputation " +
+ "for the time being, since the feature likely has many bugs, balance problems, and other issues. If you have any feedback " +
+ "regarding the new feature, feel free to let me know " +
+ "-CHANGED THE RETURN VALUE OF getScriptIncome() WHEN RAN WITH NO ARGUMENTS. It will now return an array of " +
+ "two values rather than a single value. This may break your scripts, so make sure to update them! " +
"-Added continue statement for for/while loops " +
- "-Added getServerMinSecurityLevel() Netscript function " +
+ "-Added getServerMinSecurityLevel(), getPurchasedServers(), and getTimeSinceLastAug() Netscript functions " +
+ "-Netscript scp() function can now take an array as the first argument, and will try to copy " +
+ "every file specified in the array (it will just call scp() normally for every element in the array). " +
+ "If an array is passed in, then the scp() function returns true if at least one element from the array is successfully copied " +
"-Added Javascript's Date module to Netscript. Since 'new' is not supported in Netscript yet, only the Date module's " +
"static methods will work (now(), UTC(), parse(), etc.). " +
"-Failing a crime now gives half the experience it did before " +
- "-The repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
- "if you've never destroyed a BitNode before " +
- "-fileExists() function now works on literature files
" +
- "v0.29.0 " +
- "-Added BitNode-5: Artificial Intelligence " +
- "-Added getIp(), getIntelligence(), getHackingMultipliers(), and getBitNodeMultipliers() Netscript functions (requires Source-File 5) " +
- "-Updated scan() Netscript function so that you can choose to have it print IPs rather than hostnames " +
- "-Refactored scp() Netscript function so that it takes an optional 'source server' argument " +
- "-For Infiltration, decreased the percentage by which the security level increases by " +
- "about 10% for every location " +
- "-Using :w in the script editor's Vim keybinding mode should now save and quit to Terminal " +
- "-Some minor optimizations that should reduce the size of the save file " +
- "-scan-analyze Terminal command will no longer show your purchased servers, unless you pass a '-a' flag into the command " +
- "-After installing the Red Pill augmentation from Daedalus, the message telling you to find 'The-Cave' " +
- "will now repeatedly pop up regardless of whether or not you have messages suppressed " +
- "-Various bugfixes",
-
+ "-The forced repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
+ "if you've never destroyed a BitNode before, and will only popup every 15 minutes. If you have already destroyed a BitNode, " +
+ "the message will not pop up if you have messages suppressed (if you don't have messages suppressed it WILL still repeatedly popup) " +
+ "-fileExists() function now works on literature files
",
}
export {CONSTANTS};
diff --git a/src/Message.js b/src/Message.js
index 94096bec3..667c8d147 100644
--- a/src/Message.js
+++ b/src/Message.js
@@ -1,7 +1,9 @@
import {Augmentations, Augmentation,
AugmentationNames} from "./Augmentations.js";
import {Programs} from "./CreateProgram.js";
+import {inMission} from "./Missions.js";
import {Player} from "./Player.js";
+import {redPillFlag} from "./RedPill.js";
import {GetServerByHostname} from "./Server.js";
import {Settings} from "./Settings.js";
import {dialogBoxCreate, dialogBoxOpened} from "../utils/DialogBox.js";
@@ -75,10 +77,15 @@ function checkForMessagesToSend() {
redpillOwned = true;
}
- if (redpill && redpillOwned && Player.sourceFiles.length === 0) {
+ if (redpill && redpillOwned && Player.sourceFiles.length === 0 && !redPillFlag && !inMission) {
if (!dialogBoxOpened) {
sendMessage(redpill, true);
}
+ } else if (redpill && redpillOwned) {
+ //If player has already destroyed a BitNode, message is not forced
+ if (!redPillFlag && !inMission && !dialogBoxOpened) {
+ sendMessage(redpill);
+ }
} else if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
sendMessage(jumper0);
Player.getHomeComputer().programs.push(Programs.Flight);
@@ -96,8 +103,6 @@ function checkForMessagesToSend() {
sendMessage(jumper4);
} else if (bitrunnersTest && !bitrunnersTest.recvd && Player.hacking_skill >= 500) {
sendMessage(bitrunnersTest);
- } else if (redpill && redpillOwned) {
- sendMessage(redpill);
}
}
diff --git a/src/Missions.js b/src/Missions.js
index 2932d622d..2120b0255 100644
--- a/src/Missions.js
+++ b/src/Missions.js
@@ -156,15 +156,17 @@ function HackingMission(rep, fac) {
this.faction = fac;
this.started = false;
- this.time = 120000; //2 minutes, milliseconds
+ this.time = 180000; //2 minutes, milliseconds
this.playerCores = [];
this.playerNodes = []; //Non-core nodes
+ this.playerAtk = 0;
this.playerDef = 0;
this.enemyCores = [];
this.enemyDatabases = [];
this.enemyNodes = []; //Non-core nodes
+ this.enemyAtk = 0;
this.enemyDef = 0;
this.miscNodes = [];
@@ -190,7 +192,7 @@ function HackingMission(rep, fac) {
//difficulty capped at 16
this.difficulty = Math.min(16, Math.round(rep / CONSTANTS.HackingMissionRepToDiffConversion) + 1);
console.log("difficulty: " + this.difficulty);
- this.reward = 200 + (rep / CONSTANTS.HackingMissionRepToRewardConversion);
+ this.reward = 250 + (rep / CONSTANTS.HackingMissionRepToRewardConversion);
}
HackingMission.prototype.init = function() {
@@ -213,7 +215,7 @@ HackingMission.prototype.init = function() {
//Randomly generate enemy nodes (CPU and Firewall) based on difficulty
var numNodes = getRandomInt(this.difficulty, this.difficulty + 1);
- var numFirewalls = getRandomInt(this.difficulty, this.difficulty + 2);
+ var numFirewalls = getRandomInt(this.difficulty, this.difficulty + 1);
var numDatabases = getRandomInt(this.difficulty, this.difficulty + 1);
var totalNodes = numNodes + numFirewalls + numDatabases;
var xlimit = 7 - Math.floor(totalNodes / 8);
@@ -254,6 +256,7 @@ HackingMission.prototype.init = function() {
this.enemyDatabases.push(node);
}
this.calculateDefenses();
+ this.calculateAttacks();
this.createMap();
}
@@ -297,11 +300,23 @@ HackingMission.prototype.createPageDom = function() {
startBtn.style.display = "inline-block";
startBtn.addEventListener("click", ()=>{
this.start();
+ return false;
+ });
+
+ var forfeitMission = document.createElement("a");
+ forfeitMission.innerHTML = "Forfeit Mission (Exit)";
+ forfeitMission.classList.add("a-link-button");
+ forfeitMission.classList.add("hack-mission-header-element");
+ forfeitMission.style.display = "inline-block";
+ forfeitMission.addEventListener("click", ()=> {
+ this.finishMission(false);
+ return false;
});
var timer = document.createElement("p");
timer.setAttribute("id", "hacking-mission-timer");
timer.style.display = "inline-block";
+ timer.style.margin = "6px";
//Create Action Buttons (Attack/Scan/Weaken/ etc...)
var actionsContainer = document.createElement("span");
@@ -353,18 +368,18 @@ HackingMission.prototype.createPageDom = function() {
this.actionButtons[5].appendChild(dropconnTooltip);
//Player/enemy defense displays will be in action container
- var playerDefense = document.createElement("p");
- var enemyDefense = document.createElement("p");
- playerDefense.style.display = "inline-block";
- enemyDefense.style.display = "inline-block";
- playerDefense.style.color = "blue";
- enemyDefense.style.color = "red";
- playerDefense.style.margin = "4px";
- enemyDefense.style.margin = "4px";
- playerDefense.setAttribute("id", "hacking-mission-player-def");
- enemyDefense.setAttribute("id", "hacking-mission-enemy-def");
- actionsContainer.appendChild(playerDefense);
- actionsContainer.appendChild(enemyDefense);
+ var playerStats = document.createElement("p");
+ var enemyStats = document.createElement("p");
+ playerStats.style.display = "inline-block";
+ enemyStats.style.display = "inline-block";
+ playerStats.style.color = "#00ccff";
+ enemyStats.style.color = "red";
+ playerStats.style.margin = "4px";
+ enemyStats.style.margin = "4px";
+ playerStats.setAttribute("id", "hacking-mission-player-stats");
+ enemyStats.setAttribute("id", "hacking-mission-enemy-stats");
+ actionsContainer.appendChild(playerStats);
+ actionsContainer.appendChild(enemyStats);
//Set Action Button event listeners
this.actionButtons[0].addEventListener("click", ()=>{
@@ -434,6 +449,7 @@ HackingMission.prototype.createPageDom = function() {
container.appendChild(inGameGuideBtn);
container.appendChild(wikiGuideBtn);
container.appendChild(startBtn);
+ container.appendChild(forfeitMission);
container.appendChild(timer);
container.appendChild(actionsContainer);
container.appendChild(timeDisplay);
@@ -485,7 +501,34 @@ HackingMission.prototype.setActionButton = function(i, active=true) {
}
-//Should only be used at the start
+HackingMission.prototype.calculateAttacks = function() {
+ var total = 0;
+ for (var i = 0; i < this.playerCores.length; ++i) {
+ total += this.playerCores[i].atk;
+ }
+ for (var i = 0; i < this.playerNodes.length; ++i) {
+ total += this.playerNodes[i].atk;
+ }
+ this.playerAtk = total;
+ document.getElementById("hacking-mission-player-stats").innerHTML =
+ "Player Attack: " + formatNumber(this.playerAtk, 1) + " " +
+ "Player Defense: " + formatNumber(this.playerDef, 1);
+ total = 0;
+ for (var i = 0; i < this.enemyCores.length; ++i) {
+ total += this.enemyCores[i].atk;
+ }
+ for (var i = 0; i < this.enemyDatabases.length; ++i) {
+ total += this.enemyDatabases[i].atk;
+ }
+ for (var i = 0; i < this.enemyNodes.length; ++i) {
+ total += this.enemyNodes[i].atk;
+ }
+ this.enemyAtk = total;
+ document.getElementById("hacking-mission-enemy-stats").innerHTML =
+ "Enemy Attack: " + formatNumber(this.enemyAtk, 1) + " " +
+ "Enemy Defense: " + formatNumber(this.enemyDef, 1);
+}
+
HackingMission.prototype.calculateDefenses = function() {
var total = 0;
for (var i = 0; i < this.playerCores.length; ++i) {
@@ -495,7 +538,8 @@ HackingMission.prototype.calculateDefenses = function() {
total += this.playerNodes[i].def;
}
this.playerDef = total;
- document.getElementById("hacking-mission-player-def").innerText =
+ document.getElementById("hacking-mission-player-stats").innerHTML =
+ "Player Attack: " + formatNumber(this.playerAtk, 1) + " " +
"Player Defense: " + formatNumber(this.playerDef, 1);
total = 0;
for (var i = 0; i < this.enemyCores.length; ++i) {
@@ -508,7 +552,8 @@ HackingMission.prototype.calculateDefenses = function() {
total += this.enemyNodes[i].def;
}
this.enemyDef = total;
- document.getElementById("hacking-mission-enemy-def").innerText =
+ document.getElementById("hacking-mission-enemy-stats").innerHTML =
+ "Enemy Attack: " + formatNumber(this.enemyAtk, 1) + " " +
"Enemy Defense: " + formatNumber(this.enemyDef, 1);
}
@@ -563,16 +608,16 @@ HackingMission.prototype.createMap = function() {
case 0: //Spam
var stats = {
atk: 0,
- def: randMult * getRandomInt(30, 40),
- hp: randMult * getRandomInt(70, 90)
+ def: randMult * getRandomInt(35, 55),
+ hp: randMult * getRandomInt(125, 150)
}
node = new Node(NodeTypes.Spam, stats);
break;
case 1: //Transfer
var stats = {
atk: 0,
- def: randMult * getRandomInt(50, 70),
- hp: randMult * getRandomInt(80, 95)
+ def: randMult * getRandomInt(45, 65),
+ hp: randMult * getRandomInt(150, 175)
}
node = new Node(NodeTypes.Transfer, stats);
break;
@@ -580,8 +625,8 @@ HackingMission.prototype.createMap = function() {
default:
var stats = {
atk: 0,
- def: randMult * getRandomInt(90, 105),
- hp: randMult * getRandomInt(130, 150)
+ def: randMult * getRandomInt(60, 80),
+ hp: randMult * getRandomInt(200, 250)
}
node = new Node(NodeTypes.Shield, stats);
break;
@@ -779,11 +824,8 @@ HackingMission.prototype.start = function() {
this.started = true;
this.initJsPlumb();
var startBtn = clearEventListeners("hack-mission-start-btn");
- startBtn.innerHTML = "Forfeit Mission";
- startBtn.addEventListener("click", ()=>{
- this.finishMission(false);
- return false;
- });
+ startBtn.classList.remove("a-link-button");
+ startBtn.classList.add("a-link-button-inactive");
}
HackingMission.prototype.initJsPlumb = function() {
@@ -806,8 +848,8 @@ HackingMission.prototype.initJsPlumb = function() {
instance.makeSource(this.playerCores[i].el, {
deleteEndpointsOnEmpty:true,
maxConnections:1,
- anchor:"Center",
- connector:"Straight"
+ anchor:"Continuous",
+ connector:"Flowchart"
});
}
@@ -815,29 +857,29 @@ HackingMission.prototype.initJsPlumb = function() {
for (var i = 0; i < this.enemyCores.length; ++i) {
instance.makeTarget(this.enemyCores[i].el, {
maxConnections:-1,
- anchor:"Center",
- connector:"Straight"
+ anchor:"Continuous",
+ connector:"Flowchart"
});
}
for (var i = 0; i < this.enemyDatabases.length; ++i) {
instance.makeTarget(this.enemyDatabases[i].el, {
maxConnections:-1,
- anchor:"Center",
- connector:["Straight"]
+ anchor:"Continuous",
+ connector:["Flowchart"]
});
}
for (var i = 0; i < this.enemyNodes.length; ++i) {
instance.makeTarget(this.enemyNodes[i].el, {
maxConnections:-1,
- anchor:"Center",
- connector:"Straight"
+ anchor:"Continuous",
+ connector:"Flowchart"
});
}
for (var i = 0; i < this.miscNodes.length; ++i) {
instance.makeTarget(this.miscNodes[i].el, {
maxConnections:-1,
- anchor:"Center",
- connector:"Straight"
+ anchor:"Continuous",
+ connector:"Flowchart"
});
}
@@ -888,45 +930,60 @@ HackingMission.prototype.dropAllConnectionsToNode = function(node) {
}
}
+var storedCycles = 0;
HackingMission.prototype.process = function(numCycles=1) {
if (!this.started) {return;}
+ storedCycles += numCycles;
+ if (storedCycles < 3) {return;} //Only process every 2 cycles minimum
+
var res = false;
//Process actions of all player nodes
this.playerCores.forEach((node)=>{
- res |= this.processNode(node, numCycles);
+ res |= this.processNode(node, storedCycles);
});
this.playerNodes.forEach((node)=>{
if (node.type === NodeTypes.Transfer) {
- res |= this.processNode(node, numCycles);
+ res |= this.processNode(node, storedCycles);
}
});
//Process actions of all enemy nodes
this.enemyCores.forEach((node)=>{
- res |= this.processNode(node, numCycles);
+ res |= this.processNode(node, storedCycles);
});
this.enemyNodes.forEach((node)=>{
if (node.type === NodeTypes.Transfer) {
- res |= this.processNode(node, numCycles);
+ res |= this.processNode(node, storedCycles);
}
});
- if (res) {this.calculateDefenses();}
+ if (res) {
+ this.calculateAttacks();
+ this.calculateDefenses();
+ }
if (this.enemyDatabases.length === 0) {
this.finishMission(true);
return;
}
+ //Defense of every misc Node increase by 1 per second
+ this.miscNodes.forEach((node)=>{
+ node.def += (0.1 * storedCycles);
+ this.updateNodeDomElement(node);
+ });
+
//Update timer and check if player lost
- this.time -= (numCycles * Engine._idleSpeed);
+ this.time -= (storedCycles * Engine._idleSpeed);
if (this.time <= 0) {
this.finishMission(false);
return;
}
this.updateTimer();
+
+ storedCycles = 0;
}
//Returns a bool representing whether defenses need to be re-calculated
@@ -935,48 +992,52 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
return;
}
- var targetNode = null, def;
+ var targetNode = null, def, atk;
if (nodeObj.conn) {
targetNode = this.getNodeFromElement(nodeObj.conn.target);
if (targetNode.plyrCtrl) {
def = this.playerDef;
+ atk = this.enemyAtk;
} else if (targetNode.enmyCtrl) {
def = this.enemyDef;
+ atk = this.playerAtk;
} else { //Misc Node
def = targetNode.def;
+ nodeObj.plyrCtrl ? atk = this.playerAtk : atk = this.enemyAtk;
}
}
//Calculations are per second, so divide everything by 5
- var calcDefenses = false;
+ var calcStats = false;
switch(nodeObj.action) {
case NodeActions.Attack:
if (nodeObj.conn === null) {break;}
- var dmg = this.calculateAttackDamage(nodeObj.atk, def, Player.hacking_skill);
+ var dmg = this.calculateAttackDamage(atk, def, Player.hacking_skill);
targetNode.hp -= (dmg/5 * numCycles);
break;
case NodeActions.Scan:
if (nodeObj.conn === null) {break;}
- var eff = this.calculateScanEffect(nodeObj.atk, def, Player.hacking_skill);
+ var eff = this.calculateScanEffect(atk, def, Player.hacking_skill);
targetNode.def -= (eff/5 * numCycles);
- calcDefenses = true;
+ calcStats = true;
break;
case NodeActions.Weaken:
if (nodeObj.conn === null) {break;}
- var eff = this.calculateWeakenEffect(nodeObj.atk, def, Player.hacking_skill);
+ var eff = this.calculateWeakenEffect(atk, def, Player.hacking_skill);
targetNode.atk -= (eff/5 * numCycles);
+ calcStats = true;
break;
case NodeActions.Fortify:
var eff = this.calculateFortifyEffect(Player.hacking_skill);
nodeObj.def += (eff/5 * numCycles);
- calcDefenses = true;
+ calcStats = true;
break;
case NodeActions.Overflow:
var eff = this.calculateOverflowEffect(Player.hacking_skill);
if (nodeObj.def < eff) {break;}
nodeObj.def -= (eff/5 * numCycles);
nodeObj.atk += (eff/5 * numCycles);
- calcDefenses = true;
+ calcStats = true;
break;
default:
console.log("ERR: Invalid Node Action: " + nodeObj.action);
@@ -1014,20 +1075,20 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
this.jsplumbinstance.makeSource(targetNode.el, {
deleteEndpointsOnEmpty:true,
maxConnections:1,
- anchor:"Center",
- connector:"Straight"
+ anchor:"Continuous",
+ connector:"Flowchart"
});
} else {
targetNode.setControlledByEnemy();
this.jsplumbinstance.unmakeSource(targetNode.el);
this.jsplumbinstance.makeTarget(targetNode.el, {
maxConnections:-1,
- anchor:"Center",
- connector:["Straight"]
+ anchor:"Continuous",
+ connector:["Flowchart"]
});
}
- calcDefenses = true;
+ calcStats = true;
//Helper function to swap nodes between the respective enemyNodes/playerNodes arrays
function swapNodes(orig, dest, targetNode) {
@@ -1105,24 +1166,24 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
}
this.updateNodeDomElement(nodeObj);
if (targetNode) {this.updateNodeDomElement(targetNode);}
- return calcDefenses;
+ return calcStats;
}
-var hackEffWeightSelf = 100; //Weight for Node actions on self
-var hackEffWeightTarget = 15; //Weight for Node Actions against Target
-var hackEffWeightAttack = 100; //Weight for Attack action
+var hackEffWeightSelf = 150; //Weight for Node actions on self
+var hackEffWeightTarget = 25; //Weight for Node Actions against Target
+var hackEffWeightAttack = 110; //Weight for Attack action
//Returns damage per cycle based on stats
HackingMission.prototype.calculateAttackDamage = function(atk, def, hacking = 0) {
- return Math.max(atk + (hacking / hackEffWeightAttack) - def, 0.1);
+ return Math.max(atk + (hacking / hackEffWeightAttack) - def, 1);
}
HackingMission.prototype.calculateScanEffect = function(atk, def, hacking=0) {
- return Math.max((atk/2) + hacking / hackEffWeightTarget - def, 0.1);
+ return Math.max((atk/2) + hacking / hackEffWeightTarget - def, 1);
}
HackingMission.prototype.calculateWeakenEffect = function(atk, def, hacking=0) {
- return Math.max((atk/2) + hacking / hackEffWeightTarget - def, 0.1);
+ return Math.max((atk/2) + hacking / hackEffWeightTarget - def, 1);
}
HackingMission.prototype.calculateFortifyEffect = function(hacking=0) {
@@ -1151,9 +1212,11 @@ HackingMission.prototype.finishMission = function(win) {
currMission = null;
if (win) {
- dialogBoxCreate("Mission won!");
+ dialogBoxCreate("Mission won! This feature is currently in " +
+ "beta so you did not earn anything, but normally you would have won " +
+ this.reward + " reputation with " + this.faction.name);
} else {
- dialogBoxCreate("Mission lost!");
+ dialogBoxCreate("Mission lost/forfeited!");
}
//Clear mission container
diff --git a/src/NetscriptFunctions.js b/src/NetscriptFunctions.js
index 089c23b70..076bcea8f 100644
--- a/src/NetscriptFunctions.js
+++ b/src/NetscriptFunctions.js
@@ -469,6 +469,16 @@ function NetscriptFunctions(workerScript) {
if (arguments.length !== 2 && arguments.length !== 3) {
throw makeRuntimeRejectMsg(workerScript, "Error: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");
}
+ if (scriptname && scriptname.constructor === Array) {
+ //Recursively call scp on all elements of array
+ var res = false;
+ scriptname.forEach(function(script) {
+ if (NetscriptFunctions(workerScript).scp(script, ip1, ip2)) {
+ res = true;
+ };
+ });
+ return res;
+ }
if (!scriptname.endsWith(".lit") && !scriptname.endsWith(".script")) {
throw makeRuntimeRejectMsg(workerScript, "Error: scp() only works for .script and .lit files");
}
@@ -1124,7 +1134,10 @@ function NetscriptFunctions(workerScript) {
getScriptIncome : function(scriptname, ip) {
if (arguments.length === 0) {
//Get total script income
- return updateActiveScriptsItems();
+ var res = [];
+ res.push(updateActiveScriptsItems());
+ res.push(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000));
+ return res;
} else {
//Get income for a particular script
var server = getServer(ip);
@@ -1170,6 +1183,9 @@ function NetscriptFunctions(workerScript) {
return runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime;
}
},
+ getTimeSinceLastAug : function() {
+ return Player.playtimeSinceLastAug;
+ },
/* Singularity Functions */
universityCourse(universityName, className) {
diff --git a/src/Player.js b/src/Player.js
index f45f669c7..cfecd0043 100644
--- a/src/Player.js
+++ b/src/Player.js
@@ -275,6 +275,7 @@ PlayerObject.prototype.prestigeAugmentation = function() {
this.lastUpdate = new Date().getTime();
this.playtimeSinceLastAug = 0;
+ this.scriptProdSinceLastAug = 0;
this.hacknetNodes.length = 0;
this.totalHacknetNodeProduction = 0;
@@ -365,6 +366,7 @@ PlayerObject.prototype.prestigeSourceFile = function() {
this.hasTixApiAccess = false;
this.playtimeSinceLastAug = 0;
+ this.scriptProdSinceLastAug = 0;
}
PlayerObject.prototype.getCurrentServer = function() {
diff --git a/src/engine.js b/src/engine.js
index 5409d21fd..bb81b6248 100644
--- a/src/engine.js
+++ b/src/engine.js
@@ -840,6 +840,7 @@ let Engine = {
Player.gang.process(numCycles);
}
+ //Mission
if (inMission && currMission) {
currMission.process(numCycles);
}
@@ -967,7 +968,7 @@ let Engine = {
if (Engine.Counters.messages <= 0) {
checkForMessagesToSend();
if (Augmentations[AugmentationNames.TheRedPill].owned) {
- Engine.Counters.messages = 600; //2 minutes for Red pill message
+ Engine.Counters.messages = 4500; //15 minutes for Red pill message
} else {
Engine.Counters.messages = 150;
}