mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 12:15:44 +01:00
Finished BETA version of Missions. All other changes for v0.29.1
This commit is contained in:
parent
c84417607f
commit
22a5d3b3cc
@ -34,7 +34,6 @@
|
|||||||
background-color:blue;
|
background-color:blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hack-mission-player-node:hover,
|
|
||||||
.hack-mission-player-node-active {
|
.hack-mission-player-node-active {
|
||||||
border: 2px solid white;
|
border: 2px solid white;
|
||||||
color: #6666ff;
|
color: #6666ff;
|
||||||
|
3470
dist/bundle.js
vendored
3470
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
@ -6,6 +6,7 @@ import {getServer} from "./Server.js";
|
|||||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||||
import {printArray} from "../utils/HelperFunctions.js";
|
import {printArray} from "../utils/HelperFunctions.js";
|
||||||
import {logBoxCreate} from "../utils/LogBox.js";
|
import {logBoxCreate} from "../utils/LogBox.js";
|
||||||
|
import numeral from "../utils/numeral.min.js";
|
||||||
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
import {formatNumber} from "../utils/StringHelperFunctions.js";
|
||||||
|
|
||||||
|
|
||||||
@ -183,10 +184,10 @@ function updateActiveScriptsItems() {
|
|||||||
total += updateActiveScriptsItemContent(workerScripts[i]);
|
total += updateActiveScriptsItemContent(workerScripts[i]);
|
||||||
}
|
}
|
||||||
document.getElementById("active-scripts-total-prod").innerHTML =
|
document.getElementById("active-scripts-total-prod").innerHTML =
|
||||||
"Total online production of Active Scripts: $" + formatNumber(total, 2) + " / second<br>" +
|
"Total online production of Active Scripts: " + numeral(total).format('$0.000a') + " / sec<br>" +
|
||||||
"Total online production since last Augmentation installation: $" +
|
"Total online production since last Aug installation: " +
|
||||||
formatNumber(Player.scriptProdSinceLastAug, 2) + " ($" +
|
numeral(Player.scriptProdSinceLastAug).format('$0.000a') + " (" +
|
||||||
formatNumber(Player.scriptProdSinceLastAug / Player.playtimeSinceLastAug, 2) + " / second)";
|
numeral(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000)).format('$0.000a') + " / sec)";
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,31 +124,30 @@ let CONSTANTS = {
|
|||||||
|
|
||||||
//Hacking Missions
|
//Hacking Missions
|
||||||
HackingMissionRepToDiffConversion: 5000, //Faction rep is divided by this to get mission difficulty
|
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)
|
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
|
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.<br><br>" +
|
HackingMissionHowToPlay: "Hacking missions are a minigame that, if won, will reward you with faction reputation.<br><br>" +
|
||||||
"In this game you control a set of Nodes and use them to try and defeat an enemy. Your Nodes " +
|
"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 " +
|
"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. " +
|
"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.<br><br>" +
|
"If you cannot capture all of the enemy's database nodes in the time limit, you will lose.<br><br>" +
|
||||||
"Each Node has three stats: Attack, Defense, and HP. There are five different actions that " +
|
"Each Node has three stats: Attack, Defense, and HP. There are five different actions that " +
|
||||||
"a Node can take:<br><br> " +
|
"a Node can take:<br><br> " +
|
||||||
"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.<br>" +
|
"hacking level, and the enemy's defense.<br>" +
|
||||||
"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.<br>" +
|
"enemy's defense.<br>" +
|
||||||
"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.<br>" +
|
"defense.<br>" +
|
||||||
"Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level.<br><br>" +
|
"Fortify - Raises the Node's Defense. The effectiveness is determined by your hacking level.<br>" +
|
||||||
"To capture a Node, you must lower its HP down to 0. " +
|
"Overflow - Raises the Node's Attack but lowers its Defense. The effectiveness is determined by your hacking level.<br><br>" +
|
||||||
"A Node's 'Attack' stats affects its effectiveness when attacking other Nodes. A Node's 'Defense' helps protect " +
|
"Note that when determining the effectiveness of the above actions, the TOTAL Attack or Defense of the team is used, not just the " +
|
||||||
"against the actions of enemy Nodes. One important thing to note is that, when defending, your total 'Defense' " +
|
"Attack/Defense of the individual Node that is performing the action.<br><br." +
|
||||||
"(sum of the Defense of all of your Nodes) is what's taken into account when determining the effect of offensive actions. " +
|
"To capture a Node, you must lower its HP down to 0.<br><br>" +
|
||||||
"However, when attacking, only the 'Attack' of the Node being used to attack is taken into account.<br><br>" +
|
|
||||||
"There are six different types of Nodes:<br><br>" +
|
"There are six different types of Nodes:<br><br>" +
|
||||||
"CPU Core - These are your main Nodes that are used to perform actions<br>" +
|
"CPU Core - These are your main Nodes that are used to perform actions. Capable of performing every action<br>" +
|
||||||
"Firewall - Nodes with high defense. These Nodes cannot perform any actions<br>" +
|
"Firewall - Nodes with high defense. These Nodes cannot perform any actions<br>" +
|
||||||
"Database - A special type of Node. The player's objective is to conquer all of the enemy's Database Nodes within " +
|
"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<br>" +
|
"the time limit. These Nodes cannot perform any actions<br>" +
|
||||||
@ -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. " +
|
"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<br>" +
|
"These Nodes are capable of performing every action except the 'Attack' action<br>" +
|
||||||
"Shield - Nodes with high defense. These Nodes cannot perform any actions<br><br>" +
|
"Shield - Nodes with high defense. These Nodes cannot perform any actions<br><br>" +
|
||||||
|
"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.<br><br>" +
|
||||||
"For certain actions such as attacking, scanning, and weakening, the Node performing the action must have a target. To target " +
|
"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 " +
|
"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 " +
|
"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
|
//Gang constants
|
||||||
@ -418,6 +423,9 @@ let CONSTANTS = {
|
|||||||
"args.length<br><br>" +
|
"args.length<br><br>" +
|
||||||
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
|
"Note that none of the other functions that typically work with arrays, such as remove(), insert(), clear(), etc., will work on the " +
|
||||||
"args array.<br><br>" +
|
"args array.<br><br>" +
|
||||||
|
"<u><h1>Javascript Modules</h1></u><br>" +
|
||||||
|
"Netscript supports the following Javascript Modules:<br><br>" +
|
||||||
|
"Math<br>Date (static functions only)<br><br>" +
|
||||||
"<u><h1> Functions </h1></u><br>" +
|
"<u><h1> Functions </h1></u><br>" +
|
||||||
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
|
"You can NOT define you own functions in Netscript (yet), but there are several built in functions that " +
|
||||||
"you may use: <br><br> " +
|
"you may use: <br><br> " +
|
||||||
@ -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.<br><br>" +
|
"on the server specified by the hostname/ip. The argument must be a string with the hostname/ip of the target server.<br><br>" +
|
||||||
"<i>getScriptIncome([scriptname], [hostname/ip], [args...])</i><br>" +
|
"<i>getScriptIncome([scriptname], [hostname/ip], [args...])</i><br>" +
|
||||||
"Returns the amount of income the specified script generates while online (when the game is open, does not apply for " +
|
"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 " +
|
"offline income). This function can also be called with no arguments. If called with no arguments, then this function " +
|
||||||
"with no arguments.<br><br>" +
|
"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).<br><br>" +
|
||||||
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
|
"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 " +
|
"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.<br><br>" +
|
"specify those arguments in this function call.<br><br>" +
|
||||||
@ -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 " +
|
"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 " +
|
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
|
||||||
"the arguments passed into the target script.<br><br>" +
|
"the arguments passed into the target script.<br><br>" +
|
||||||
|
"<i>getTimeSinceLastAug()</i><br>" +
|
||||||
|
"Returns the amount of time in milliseconds that have passed since you last installed Augmentations (or destroyed a BitNode).<br><br>" +
|
||||||
"<u><h1>Hacknet Nodes API</h1></u><br>" +
|
"<u><h1>Hacknet Nodes API</h1></u><br>" +
|
||||||
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.<br><br>" +
|
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.<br><br>" +
|
||||||
"<i>hacknetnodes</i><br> A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
|
"<i>hacknetnodes</i><br> A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
|
||||||
@ -998,28 +1009,24 @@ let CONSTANTS = {
|
|||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
"v0.29.1<br>" +
|
"v0.29.1<br>" +
|
||||||
|
"-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<br>" +
|
||||||
|
"-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!<br>" +
|
||||||
"-Added continue statement for for/while loops<br>" +
|
"-Added continue statement for for/while loops<br>" +
|
||||||
"-Added getServerMinSecurityLevel() Netscript function<br>" +
|
"-Added getServerMinSecurityLevel(), getPurchasedServers(), and getTimeSinceLastAug() Netscript functions<br>" +
|
||||||
|
"-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<br>" +
|
||||||
"-Added Javascript's Date module to Netscript. Since 'new' is not supported in Netscript yet, only the Date module's " +
|
"-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.).<br>" +
|
"static methods will work (now(), UTC(), parse(), etc.).<br>" +
|
||||||
"-Failing a crime now gives half the experience it did before<br>" +
|
"-Failing a crime now gives half the experience it did before<br>" +
|
||||||
"-The repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
|
"-The forced repeated 'Find The-Cave' message after installing The Red Pill Augmentation now only happens " +
|
||||||
"if you've never destroyed a BitNode before<br>" +
|
"if you've never destroyed a BitNode before, and will only popup every 15 minutes. If you have already destroyed a BitNode, " +
|
||||||
"-fileExists() function now works on literature files<br><br>" +
|
"the message will not pop up if you have messages suppressed (if you don't have messages suppressed it WILL still repeatedly popup)<br>" +
|
||||||
"v0.29.0<br>" +
|
"-fileExists() function now works on literature files<br><br>",
|
||||||
"-Added BitNode-5: Artificial Intelligence<br>" +
|
|
||||||
"-Added getIp(), getIntelligence(), getHackingMultipliers(), and getBitNodeMultipliers() Netscript functions (requires Source-File 5)<br>" +
|
|
||||||
"-Updated scan() Netscript function so that you can choose to have it print IPs rather than hostnames<br>" +
|
|
||||||
"-Refactored scp() Netscript function so that it takes an optional 'source server' argument<br>" +
|
|
||||||
"-For Infiltration, decreased the percentage by which the security level increases by " +
|
|
||||||
"about 10% for every location<br>" +
|
|
||||||
"-Using :w in the script editor's Vim keybinding mode should now save and quit to Terminal<br>" +
|
|
||||||
"-Some minor optimizations that should reduce the size of the save file<br>" +
|
|
||||||
"-scan-analyze Terminal command will no longer show your purchased servers, unless you pass a '-a' flag into the command<br>" +
|
|
||||||
"-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<br>" +
|
|
||||||
"-Various bugfixes",
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export {CONSTANTS};
|
export {CONSTANTS};
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import {Augmentations, Augmentation,
|
import {Augmentations, Augmentation,
|
||||||
AugmentationNames} from "./Augmentations.js";
|
AugmentationNames} from "./Augmentations.js";
|
||||||
import {Programs} from "./CreateProgram.js";
|
import {Programs} from "./CreateProgram.js";
|
||||||
|
import {inMission} from "./Missions.js";
|
||||||
import {Player} from "./Player.js";
|
import {Player} from "./Player.js";
|
||||||
|
import {redPillFlag} from "./RedPill.js";
|
||||||
import {GetServerByHostname} from "./Server.js";
|
import {GetServerByHostname} from "./Server.js";
|
||||||
import {Settings} from "./Settings.js";
|
import {Settings} from "./Settings.js";
|
||||||
import {dialogBoxCreate, dialogBoxOpened} from "../utils/DialogBox.js";
|
import {dialogBoxCreate, dialogBoxOpened} from "../utils/DialogBox.js";
|
||||||
@ -75,10 +77,15 @@ function checkForMessagesToSend() {
|
|||||||
redpillOwned = true;
|
redpillOwned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redpill && redpillOwned && Player.sourceFiles.length === 0) {
|
if (redpill && redpillOwned && Player.sourceFiles.length === 0 && !redPillFlag && !inMission) {
|
||||||
if (!dialogBoxOpened) {
|
if (!dialogBoxOpened) {
|
||||||
sendMessage(redpill, true);
|
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) {
|
} else if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
|
||||||
sendMessage(jumper0);
|
sendMessage(jumper0);
|
||||||
Player.getHomeComputer().programs.push(Programs.Flight);
|
Player.getHomeComputer().programs.push(Programs.Flight);
|
||||||
@ -96,8 +103,6 @@ function checkForMessagesToSend() {
|
|||||||
sendMessage(jumper4);
|
sendMessage(jumper4);
|
||||||
} else if (bitrunnersTest && !bitrunnersTest.recvd && Player.hacking_skill >= 500) {
|
} else if (bitrunnersTest && !bitrunnersTest.recvd && Player.hacking_skill >= 500) {
|
||||||
sendMessage(bitrunnersTest);
|
sendMessage(bitrunnersTest);
|
||||||
} else if (redpill && redpillOwned) {
|
|
||||||
sendMessage(redpill);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
197
src/Missions.js
197
src/Missions.js
@ -156,15 +156,17 @@ function HackingMission(rep, fac) {
|
|||||||
this.faction = fac;
|
this.faction = fac;
|
||||||
|
|
||||||
this.started = false;
|
this.started = false;
|
||||||
this.time = 120000; //2 minutes, milliseconds
|
this.time = 180000; //2 minutes, milliseconds
|
||||||
|
|
||||||
this.playerCores = [];
|
this.playerCores = [];
|
||||||
this.playerNodes = []; //Non-core nodes
|
this.playerNodes = []; //Non-core nodes
|
||||||
|
this.playerAtk = 0;
|
||||||
this.playerDef = 0;
|
this.playerDef = 0;
|
||||||
|
|
||||||
this.enemyCores = [];
|
this.enemyCores = [];
|
||||||
this.enemyDatabases = [];
|
this.enemyDatabases = [];
|
||||||
this.enemyNodes = []; //Non-core nodes
|
this.enemyNodes = []; //Non-core nodes
|
||||||
|
this.enemyAtk = 0;
|
||||||
this.enemyDef = 0;
|
this.enemyDef = 0;
|
||||||
|
|
||||||
this.miscNodes = [];
|
this.miscNodes = [];
|
||||||
@ -190,7 +192,7 @@ function HackingMission(rep, fac) {
|
|||||||
//difficulty capped at 16
|
//difficulty capped at 16
|
||||||
this.difficulty = Math.min(16, Math.round(rep / CONSTANTS.HackingMissionRepToDiffConversion) + 1);
|
this.difficulty = Math.min(16, Math.round(rep / CONSTANTS.HackingMissionRepToDiffConversion) + 1);
|
||||||
console.log("difficulty: " + this.difficulty);
|
console.log("difficulty: " + this.difficulty);
|
||||||
this.reward = 200 + (rep / CONSTANTS.HackingMissionRepToRewardConversion);
|
this.reward = 250 + (rep / CONSTANTS.HackingMissionRepToRewardConversion);
|
||||||
}
|
}
|
||||||
|
|
||||||
HackingMission.prototype.init = function() {
|
HackingMission.prototype.init = function() {
|
||||||
@ -213,7 +215,7 @@ HackingMission.prototype.init = function() {
|
|||||||
|
|
||||||
//Randomly generate enemy nodes (CPU and Firewall) based on difficulty
|
//Randomly generate enemy nodes (CPU and Firewall) based on difficulty
|
||||||
var numNodes = getRandomInt(this.difficulty, this.difficulty + 1);
|
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 numDatabases = getRandomInt(this.difficulty, this.difficulty + 1);
|
||||||
var totalNodes = numNodes + numFirewalls + numDatabases;
|
var totalNodes = numNodes + numFirewalls + numDatabases;
|
||||||
var xlimit = 7 - Math.floor(totalNodes / 8);
|
var xlimit = 7 - Math.floor(totalNodes / 8);
|
||||||
@ -254,6 +256,7 @@ HackingMission.prototype.init = function() {
|
|||||||
this.enemyDatabases.push(node);
|
this.enemyDatabases.push(node);
|
||||||
}
|
}
|
||||||
this.calculateDefenses();
|
this.calculateDefenses();
|
||||||
|
this.calculateAttacks();
|
||||||
this.createMap();
|
this.createMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,11 +300,23 @@ HackingMission.prototype.createPageDom = function() {
|
|||||||
startBtn.style.display = "inline-block";
|
startBtn.style.display = "inline-block";
|
||||||
startBtn.addEventListener("click", ()=>{
|
startBtn.addEventListener("click", ()=>{
|
||||||
this.start();
|
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");
|
var timer = document.createElement("p");
|
||||||
timer.setAttribute("id", "hacking-mission-timer");
|
timer.setAttribute("id", "hacking-mission-timer");
|
||||||
timer.style.display = "inline-block";
|
timer.style.display = "inline-block";
|
||||||
|
timer.style.margin = "6px";
|
||||||
|
|
||||||
//Create Action Buttons (Attack/Scan/Weaken/ etc...)
|
//Create Action Buttons (Attack/Scan/Weaken/ etc...)
|
||||||
var actionsContainer = document.createElement("span");
|
var actionsContainer = document.createElement("span");
|
||||||
@ -353,18 +368,18 @@ HackingMission.prototype.createPageDom = function() {
|
|||||||
this.actionButtons[5].appendChild(dropconnTooltip);
|
this.actionButtons[5].appendChild(dropconnTooltip);
|
||||||
|
|
||||||
//Player/enemy defense displays will be in action container
|
//Player/enemy defense displays will be in action container
|
||||||
var playerDefense = document.createElement("p");
|
var playerStats = document.createElement("p");
|
||||||
var enemyDefense = document.createElement("p");
|
var enemyStats = document.createElement("p");
|
||||||
playerDefense.style.display = "inline-block";
|
playerStats.style.display = "inline-block";
|
||||||
enemyDefense.style.display = "inline-block";
|
enemyStats.style.display = "inline-block";
|
||||||
playerDefense.style.color = "blue";
|
playerStats.style.color = "#00ccff";
|
||||||
enemyDefense.style.color = "red";
|
enemyStats.style.color = "red";
|
||||||
playerDefense.style.margin = "4px";
|
playerStats.style.margin = "4px";
|
||||||
enemyDefense.style.margin = "4px";
|
enemyStats.style.margin = "4px";
|
||||||
playerDefense.setAttribute("id", "hacking-mission-player-def");
|
playerStats.setAttribute("id", "hacking-mission-player-stats");
|
||||||
enemyDefense.setAttribute("id", "hacking-mission-enemy-def");
|
enemyStats.setAttribute("id", "hacking-mission-enemy-stats");
|
||||||
actionsContainer.appendChild(playerDefense);
|
actionsContainer.appendChild(playerStats);
|
||||||
actionsContainer.appendChild(enemyDefense);
|
actionsContainer.appendChild(enemyStats);
|
||||||
|
|
||||||
//Set Action Button event listeners
|
//Set Action Button event listeners
|
||||||
this.actionButtons[0].addEventListener("click", ()=>{
|
this.actionButtons[0].addEventListener("click", ()=>{
|
||||||
@ -434,6 +449,7 @@ HackingMission.prototype.createPageDom = function() {
|
|||||||
container.appendChild(inGameGuideBtn);
|
container.appendChild(inGameGuideBtn);
|
||||||
container.appendChild(wikiGuideBtn);
|
container.appendChild(wikiGuideBtn);
|
||||||
container.appendChild(startBtn);
|
container.appendChild(startBtn);
|
||||||
|
container.appendChild(forfeitMission);
|
||||||
container.appendChild(timer);
|
container.appendChild(timer);
|
||||||
container.appendChild(actionsContainer);
|
container.appendChild(actionsContainer);
|
||||||
container.appendChild(timeDisplay);
|
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) + "<br>" +
|
||||||
|
"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) + "<br>" +
|
||||||
|
"Enemy Defense: " + formatNumber(this.enemyDef, 1);
|
||||||
|
}
|
||||||
|
|
||||||
HackingMission.prototype.calculateDefenses = function() {
|
HackingMission.prototype.calculateDefenses = function() {
|
||||||
var total = 0;
|
var total = 0;
|
||||||
for (var i = 0; i < this.playerCores.length; ++i) {
|
for (var i = 0; i < this.playerCores.length; ++i) {
|
||||||
@ -495,7 +538,8 @@ HackingMission.prototype.calculateDefenses = function() {
|
|||||||
total += this.playerNodes[i].def;
|
total += this.playerNodes[i].def;
|
||||||
}
|
}
|
||||||
this.playerDef = total;
|
this.playerDef = total;
|
||||||
document.getElementById("hacking-mission-player-def").innerText =
|
document.getElementById("hacking-mission-player-stats").innerHTML =
|
||||||
|
"Player Attack: " + formatNumber(this.playerAtk, 1) + "<br>" +
|
||||||
"Player Defense: " + formatNumber(this.playerDef, 1);
|
"Player Defense: " + formatNumber(this.playerDef, 1);
|
||||||
total = 0;
|
total = 0;
|
||||||
for (var i = 0; i < this.enemyCores.length; ++i) {
|
for (var i = 0; i < this.enemyCores.length; ++i) {
|
||||||
@ -508,7 +552,8 @@ HackingMission.prototype.calculateDefenses = function() {
|
|||||||
total += this.enemyNodes[i].def;
|
total += this.enemyNodes[i].def;
|
||||||
}
|
}
|
||||||
this.enemyDef = total;
|
this.enemyDef = total;
|
||||||
document.getElementById("hacking-mission-enemy-def").innerText =
|
document.getElementById("hacking-mission-enemy-stats").innerHTML =
|
||||||
|
"Enemy Attack: " + formatNumber(this.enemyAtk, 1) + "<br>" +
|
||||||
"Enemy Defense: " + formatNumber(this.enemyDef, 1);
|
"Enemy Defense: " + formatNumber(this.enemyDef, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,16 +608,16 @@ HackingMission.prototype.createMap = function() {
|
|||||||
case 0: //Spam
|
case 0: //Spam
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: 0,
|
atk: 0,
|
||||||
def: randMult * getRandomInt(30, 40),
|
def: randMult * getRandomInt(35, 55),
|
||||||
hp: randMult * getRandomInt(70, 90)
|
hp: randMult * getRandomInt(125, 150)
|
||||||
}
|
}
|
||||||
node = new Node(NodeTypes.Spam, stats);
|
node = new Node(NodeTypes.Spam, stats);
|
||||||
break;
|
break;
|
||||||
case 1: //Transfer
|
case 1: //Transfer
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: 0,
|
atk: 0,
|
||||||
def: randMult * getRandomInt(50, 70),
|
def: randMult * getRandomInt(45, 65),
|
||||||
hp: randMult * getRandomInt(80, 95)
|
hp: randMult * getRandomInt(150, 175)
|
||||||
}
|
}
|
||||||
node = new Node(NodeTypes.Transfer, stats);
|
node = new Node(NodeTypes.Transfer, stats);
|
||||||
break;
|
break;
|
||||||
@ -580,8 +625,8 @@ HackingMission.prototype.createMap = function() {
|
|||||||
default:
|
default:
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: 0,
|
atk: 0,
|
||||||
def: randMult * getRandomInt(90, 105),
|
def: randMult * getRandomInt(60, 80),
|
||||||
hp: randMult * getRandomInt(130, 150)
|
hp: randMult * getRandomInt(200, 250)
|
||||||
}
|
}
|
||||||
node = new Node(NodeTypes.Shield, stats);
|
node = new Node(NodeTypes.Shield, stats);
|
||||||
break;
|
break;
|
||||||
@ -779,11 +824,8 @@ HackingMission.prototype.start = function() {
|
|||||||
this.started = true;
|
this.started = true;
|
||||||
this.initJsPlumb();
|
this.initJsPlumb();
|
||||||
var startBtn = clearEventListeners("hack-mission-start-btn");
|
var startBtn = clearEventListeners("hack-mission-start-btn");
|
||||||
startBtn.innerHTML = "Forfeit Mission";
|
startBtn.classList.remove("a-link-button");
|
||||||
startBtn.addEventListener("click", ()=>{
|
startBtn.classList.add("a-link-button-inactive");
|
||||||
this.finishMission(false);
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HackingMission.prototype.initJsPlumb = function() {
|
HackingMission.prototype.initJsPlumb = function() {
|
||||||
@ -806,8 +848,8 @@ HackingMission.prototype.initJsPlumb = function() {
|
|||||||
instance.makeSource(this.playerCores[i].el, {
|
instance.makeSource(this.playerCores[i].el, {
|
||||||
deleteEndpointsOnEmpty:true,
|
deleteEndpointsOnEmpty:true,
|
||||||
maxConnections:1,
|
maxConnections:1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:"Straight"
|
connector:"Flowchart"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,29 +857,29 @@ HackingMission.prototype.initJsPlumb = function() {
|
|||||||
for (var i = 0; i < this.enemyCores.length; ++i) {
|
for (var i = 0; i < this.enemyCores.length; ++i) {
|
||||||
instance.makeTarget(this.enemyCores[i].el, {
|
instance.makeTarget(this.enemyCores[i].el, {
|
||||||
maxConnections:-1,
|
maxConnections:-1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:"Straight"
|
connector:"Flowchart"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this.enemyDatabases.length; ++i) {
|
for (var i = 0; i < this.enemyDatabases.length; ++i) {
|
||||||
instance.makeTarget(this.enemyDatabases[i].el, {
|
instance.makeTarget(this.enemyDatabases[i].el, {
|
||||||
maxConnections:-1,
|
maxConnections:-1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:["Straight"]
|
connector:["Flowchart"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this.enemyNodes.length; ++i) {
|
for (var i = 0; i < this.enemyNodes.length; ++i) {
|
||||||
instance.makeTarget(this.enemyNodes[i].el, {
|
instance.makeTarget(this.enemyNodes[i].el, {
|
||||||
maxConnections:-1,
|
maxConnections:-1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:"Straight"
|
connector:"Flowchart"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (var i = 0; i < this.miscNodes.length; ++i) {
|
for (var i = 0; i < this.miscNodes.length; ++i) {
|
||||||
instance.makeTarget(this.miscNodes[i].el, {
|
instance.makeTarget(this.miscNodes[i].el, {
|
||||||
maxConnections:-1,
|
maxConnections:-1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:"Straight"
|
connector:"Flowchart"
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,45 +930,60 @@ HackingMission.prototype.dropAllConnectionsToNode = function(node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var storedCycles = 0;
|
||||||
HackingMission.prototype.process = function(numCycles=1) {
|
HackingMission.prototype.process = function(numCycles=1) {
|
||||||
if (!this.started) {return;}
|
if (!this.started) {return;}
|
||||||
|
storedCycles += numCycles;
|
||||||
|
if (storedCycles < 3) {return;} //Only process every 2 cycles minimum
|
||||||
|
|
||||||
var res = false;
|
var res = false;
|
||||||
//Process actions of all player nodes
|
//Process actions of all player nodes
|
||||||
this.playerCores.forEach((node)=>{
|
this.playerCores.forEach((node)=>{
|
||||||
res |= this.processNode(node, numCycles);
|
res |= this.processNode(node, storedCycles);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.playerNodes.forEach((node)=>{
|
this.playerNodes.forEach((node)=>{
|
||||||
if (node.type === NodeTypes.Transfer) {
|
if (node.type === NodeTypes.Transfer) {
|
||||||
res |= this.processNode(node, numCycles);
|
res |= this.processNode(node, storedCycles);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Process actions of all enemy nodes
|
//Process actions of all enemy nodes
|
||||||
this.enemyCores.forEach((node)=>{
|
this.enemyCores.forEach((node)=>{
|
||||||
res |= this.processNode(node, numCycles);
|
res |= this.processNode(node, storedCycles);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.enemyNodes.forEach((node)=>{
|
this.enemyNodes.forEach((node)=>{
|
||||||
if (node.type === NodeTypes.Transfer) {
|
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) {
|
if (this.enemyDatabases.length === 0) {
|
||||||
this.finishMission(true);
|
this.finishMission(true);
|
||||||
return;
|
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
|
//Update timer and check if player lost
|
||||||
this.time -= (numCycles * Engine._idleSpeed);
|
this.time -= (storedCycles * Engine._idleSpeed);
|
||||||
if (this.time <= 0) {
|
if (this.time <= 0) {
|
||||||
this.finishMission(false);
|
this.finishMission(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.updateTimer();
|
this.updateTimer();
|
||||||
|
|
||||||
|
storedCycles = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns a bool representing whether defenses need to be re-calculated
|
//Returns a bool representing whether defenses need to be re-calculated
|
||||||
@ -935,48 +992,52 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var targetNode = null, def;
|
var targetNode = null, def, atk;
|
||||||
if (nodeObj.conn) {
|
if (nodeObj.conn) {
|
||||||
targetNode = this.getNodeFromElement(nodeObj.conn.target);
|
targetNode = this.getNodeFromElement(nodeObj.conn.target);
|
||||||
if (targetNode.plyrCtrl) {
|
if (targetNode.plyrCtrl) {
|
||||||
def = this.playerDef;
|
def = this.playerDef;
|
||||||
|
atk = this.enemyAtk;
|
||||||
} else if (targetNode.enmyCtrl) {
|
} else if (targetNode.enmyCtrl) {
|
||||||
def = this.enemyDef;
|
def = this.enemyDef;
|
||||||
|
atk = this.playerAtk;
|
||||||
} else { //Misc Node
|
} else { //Misc Node
|
||||||
def = targetNode.def;
|
def = targetNode.def;
|
||||||
|
nodeObj.plyrCtrl ? atk = this.playerAtk : atk = this.enemyAtk;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Calculations are per second, so divide everything by 5
|
//Calculations are per second, so divide everything by 5
|
||||||
var calcDefenses = false;
|
var calcStats = false;
|
||||||
switch(nodeObj.action) {
|
switch(nodeObj.action) {
|
||||||
case NodeActions.Attack:
|
case NodeActions.Attack:
|
||||||
if (nodeObj.conn === null) {break;}
|
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);
|
targetNode.hp -= (dmg/5 * numCycles);
|
||||||
break;
|
break;
|
||||||
case NodeActions.Scan:
|
case NodeActions.Scan:
|
||||||
if (nodeObj.conn === null) {break;}
|
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);
|
targetNode.def -= (eff/5 * numCycles);
|
||||||
calcDefenses = true;
|
calcStats = true;
|
||||||
break;
|
break;
|
||||||
case NodeActions.Weaken:
|
case NodeActions.Weaken:
|
||||||
if (nodeObj.conn === null) {break;}
|
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);
|
targetNode.atk -= (eff/5 * numCycles);
|
||||||
|
calcStats = true;
|
||||||
break;
|
break;
|
||||||
case NodeActions.Fortify:
|
case NodeActions.Fortify:
|
||||||
var eff = this.calculateFortifyEffect(Player.hacking_skill);
|
var eff = this.calculateFortifyEffect(Player.hacking_skill);
|
||||||
nodeObj.def += (eff/5 * numCycles);
|
nodeObj.def += (eff/5 * numCycles);
|
||||||
calcDefenses = true;
|
calcStats = true;
|
||||||
break;
|
break;
|
||||||
case NodeActions.Overflow:
|
case NodeActions.Overflow:
|
||||||
var eff = this.calculateOverflowEffect(Player.hacking_skill);
|
var eff = this.calculateOverflowEffect(Player.hacking_skill);
|
||||||
if (nodeObj.def < eff) {break;}
|
if (nodeObj.def < eff) {break;}
|
||||||
nodeObj.def -= (eff/5 * numCycles);
|
nodeObj.def -= (eff/5 * numCycles);
|
||||||
nodeObj.atk += (eff/5 * numCycles);
|
nodeObj.atk += (eff/5 * numCycles);
|
||||||
calcDefenses = true;
|
calcStats = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.log("ERR: Invalid Node Action: " + nodeObj.action);
|
console.log("ERR: Invalid Node Action: " + nodeObj.action);
|
||||||
@ -1014,20 +1075,20 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
this.jsplumbinstance.makeSource(targetNode.el, {
|
this.jsplumbinstance.makeSource(targetNode.el, {
|
||||||
deleteEndpointsOnEmpty:true,
|
deleteEndpointsOnEmpty:true,
|
||||||
maxConnections:1,
|
maxConnections:1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:"Straight"
|
connector:"Flowchart"
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
targetNode.setControlledByEnemy();
|
targetNode.setControlledByEnemy();
|
||||||
this.jsplumbinstance.unmakeSource(targetNode.el);
|
this.jsplumbinstance.unmakeSource(targetNode.el);
|
||||||
this.jsplumbinstance.makeTarget(targetNode.el, {
|
this.jsplumbinstance.makeTarget(targetNode.el, {
|
||||||
maxConnections:-1,
|
maxConnections:-1,
|
||||||
anchor:"Center",
|
anchor:"Continuous",
|
||||||
connector:["Straight"]
|
connector:["Flowchart"]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
calcDefenses = true;
|
calcStats = true;
|
||||||
|
|
||||||
//Helper function to swap nodes between the respective enemyNodes/playerNodes arrays
|
//Helper function to swap nodes between the respective enemyNodes/playerNodes arrays
|
||||||
function swapNodes(orig, dest, targetNode) {
|
function swapNodes(orig, dest, targetNode) {
|
||||||
@ -1105,24 +1166,24 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
}
|
}
|
||||||
this.updateNodeDomElement(nodeObj);
|
this.updateNodeDomElement(nodeObj);
|
||||||
if (targetNode) {this.updateNodeDomElement(targetNode);}
|
if (targetNode) {this.updateNodeDomElement(targetNode);}
|
||||||
return calcDefenses;
|
return calcStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hackEffWeightSelf = 100; //Weight for Node actions on self
|
var hackEffWeightSelf = 150; //Weight for Node actions on self
|
||||||
var hackEffWeightTarget = 15; //Weight for Node Actions against Target
|
var hackEffWeightTarget = 25; //Weight for Node Actions against Target
|
||||||
var hackEffWeightAttack = 100; //Weight for Attack action
|
var hackEffWeightAttack = 110; //Weight for Attack action
|
||||||
|
|
||||||
//Returns damage per cycle based on stats
|
//Returns damage per cycle based on stats
|
||||||
HackingMission.prototype.calculateAttackDamage = function(atk, def, hacking = 0) {
|
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) {
|
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) {
|
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) {
|
HackingMission.prototype.calculateFortifyEffect = function(hacking=0) {
|
||||||
@ -1151,9 +1212,11 @@ HackingMission.prototype.finishMission = function(win) {
|
|||||||
currMission = null;
|
currMission = null;
|
||||||
|
|
||||||
if (win) {
|
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 {
|
} else {
|
||||||
dialogBoxCreate("Mission lost!");
|
dialogBoxCreate("Mission lost/forfeited!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clear mission container
|
//Clear mission container
|
||||||
|
@ -469,6 +469,16 @@ function NetscriptFunctions(workerScript) {
|
|||||||
if (arguments.length !== 2 && arguments.length !== 3) {
|
if (arguments.length !== 2 && arguments.length !== 3) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Error: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");
|
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")) {
|
if (!scriptname.endsWith(".lit") && !scriptname.endsWith(".script")) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Error: scp() only works for .script and .lit files");
|
throw makeRuntimeRejectMsg(workerScript, "Error: scp() only works for .script and .lit files");
|
||||||
}
|
}
|
||||||
@ -1124,7 +1134,10 @@ function NetscriptFunctions(workerScript) {
|
|||||||
getScriptIncome : function(scriptname, ip) {
|
getScriptIncome : function(scriptname, ip) {
|
||||||
if (arguments.length === 0) {
|
if (arguments.length === 0) {
|
||||||
//Get total script income
|
//Get total script income
|
||||||
return updateActiveScriptsItems();
|
var res = [];
|
||||||
|
res.push(updateActiveScriptsItems());
|
||||||
|
res.push(Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug/1000));
|
||||||
|
return res;
|
||||||
} else {
|
} else {
|
||||||
//Get income for a particular script
|
//Get income for a particular script
|
||||||
var server = getServer(ip);
|
var server = getServer(ip);
|
||||||
@ -1170,6 +1183,9 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime;
|
return runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
getTimeSinceLastAug : function() {
|
||||||
|
return Player.playtimeSinceLastAug;
|
||||||
|
},
|
||||||
|
|
||||||
/* Singularity Functions */
|
/* Singularity Functions */
|
||||||
universityCourse(universityName, className) {
|
universityCourse(universityName, className) {
|
||||||
|
@ -275,6 +275,7 @@ PlayerObject.prototype.prestigeAugmentation = function() {
|
|||||||
this.lastUpdate = new Date().getTime();
|
this.lastUpdate = new Date().getTime();
|
||||||
|
|
||||||
this.playtimeSinceLastAug = 0;
|
this.playtimeSinceLastAug = 0;
|
||||||
|
this.scriptProdSinceLastAug = 0;
|
||||||
|
|
||||||
this.hacknetNodes.length = 0;
|
this.hacknetNodes.length = 0;
|
||||||
this.totalHacknetNodeProduction = 0;
|
this.totalHacknetNodeProduction = 0;
|
||||||
@ -365,6 +366,7 @@ PlayerObject.prototype.prestigeSourceFile = function() {
|
|||||||
this.hasTixApiAccess = false;
|
this.hasTixApiAccess = false;
|
||||||
|
|
||||||
this.playtimeSinceLastAug = 0;
|
this.playtimeSinceLastAug = 0;
|
||||||
|
this.scriptProdSinceLastAug = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerObject.prototype.getCurrentServer = function() {
|
PlayerObject.prototype.getCurrentServer = function() {
|
||||||
|
@ -840,6 +840,7 @@ let Engine = {
|
|||||||
Player.gang.process(numCycles);
|
Player.gang.process(numCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Mission
|
||||||
if (inMission && currMission) {
|
if (inMission && currMission) {
|
||||||
currMission.process(numCycles);
|
currMission.process(numCycles);
|
||||||
}
|
}
|
||||||
@ -967,7 +968,7 @@ let Engine = {
|
|||||||
if (Engine.Counters.messages <= 0) {
|
if (Engine.Counters.messages <= 0) {
|
||||||
checkForMessagesToSend();
|
checkForMessagesToSend();
|
||||||
if (Augmentations[AugmentationNames.TheRedPill].owned) {
|
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 {
|
} else {
|
||||||
Engine.Counters.messages = 150;
|
Engine.Counters.messages = 150;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user