mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-23 22:52:29 +01:00
commit
13105e33ad
@ -1,16 +1,26 @@
|
|||||||
/* css for Missions */
|
/* css for Missions */
|
||||||
|
|
||||||
/* Hacking missions */
|
/* Hacking missions */
|
||||||
|
#mission-container {
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.hack-mission-grid {
|
.hack-mission-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 10% 10% 10% 10% 10% 10% 10% 10%;
|
/*grid-template-columns: 11% 11% 11% 11% 11% 11% 11% 11%;*/
|
||||||
grid-template-rows: 8% 8% 8% 8% 8% 8% 8% 8%;
|
grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
|
/*grid-template-rows: 10% 10% 10% 10% 10% 10% 10% 10%;*/
|
||||||
|
grid-template-rows: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
|
||||||
grid-gap: 2.5%;
|
grid-gap: 2.5%;
|
||||||
height: 100%;
|
height: 90%;
|
||||||
position:fixed;
|
position:absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow-y:auto;
|
overflow-y:auto;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hack-mission-grid::-webkit-scrollbar {
|
||||||
|
display:none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hack-mission-node {
|
.hack-mission-node {
|
||||||
|
@ -209,7 +209,24 @@ a:link, a:visited {
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tooltip:hover .tooltiptext {
|
/* Same thing as a normal tooltip except its a bit higher */
|
||||||
|
.tooltip .tooltiptexthigh {
|
||||||
|
visibility: hidden;
|
||||||
|
width: 300px;
|
||||||
|
background-color: var(--my-background-color);
|
||||||
|
border: 2px solid var(--my-highlight-color);;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 4px;
|
||||||
|
left: 101%;
|
||||||
|
bottom:-25%;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip:hover .tooltiptext,
|
||||||
|
.tooltip:hover .tooltiptexthigh {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
.generic-fullscreen-container {
|
.generic-fullscreen-container {
|
||||||
color: var(--my-font-color);
|
color: var(--my-font-color);
|
||||||
width: 99%;
|
width: 99%;
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#work-in-progress-container {
|
#work-in-progress-container {
|
||||||
|
10485
dist/bundle.js
vendored
10485
dist/bundle.js
vendored
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,15 @@
|
|||||||
import {BitNodeMultipliers} from "./BitNode.js";
|
import {BitNodeMultipliers} from "./BitNode.js";
|
||||||
import {CONSTANTS} from "./Constants.js";
|
import {CONSTANTS} from "./Constants.js";
|
||||||
|
import {Factions, getNextNeurofluxLevel} from "./Faction.js";
|
||||||
|
import {addWorkerScript} from "./NetscriptWorker.js";
|
||||||
import {Player} from "./Player.js";
|
import {Player} from "./Player.js";
|
||||||
import {prestigeAugmentation} from "./Prestige.js";
|
import {prestigeAugmentation} from "./Prestige.js";
|
||||||
import {Factions, getNextNeurofluxLevel} from "./Faction.js";
|
import {Script, RunningScript} from "./Script.js";
|
||||||
|
import {Server} from "./Server.js";
|
||||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||||
import {Reviver, Generic_toJSON,
|
import {Reviver, Generic_toJSON,
|
||||||
Generic_fromJSON} from "../utils/JSONReviver.js";
|
Generic_fromJSON} from "../utils/JSONReviver.js";
|
||||||
|
import {isString} from "../utils/StringHelperFunctions.js";
|
||||||
|
|
||||||
//Augmentations
|
//Augmentations
|
||||||
function Augmentation(name) {
|
function Augmentation(name) {
|
||||||
@ -121,6 +125,7 @@ let AugmentationNames = {
|
|||||||
PCDNIOptimizer: "PC Direct-Neural Interface Optimization Submodule",
|
PCDNIOptimizer: "PC Direct-Neural Interface Optimization Submodule",
|
||||||
PCDNINeuralNetwork: "PC Direct-Neural Interface NeuroNet Injector",
|
PCDNINeuralNetwork: "PC Direct-Neural Interface NeuroNet Injector",
|
||||||
ADRPheromone1: "ADR-V1 Pheromone Gene",
|
ADRPheromone1: "ADR-V1 Pheromone Gene",
|
||||||
|
ADRPheromone2: "ADR-V2 Pheromone Gene",
|
||||||
HacknetNodeCPUUpload: "Hacknet Node CPU Architecture Neural-Upload",
|
HacknetNodeCPUUpload: "Hacknet Node CPU Architecture Neural-Upload",
|
||||||
HacknetNodeCacheUpload: "Hacknet Node Cache Architecture Neural-Upload",
|
HacknetNodeCacheUpload: "Hacknet Node Cache Architecture Neural-Upload",
|
||||||
HacknetNodeNICUpload: "HacknetNode NIC Architecture Neural-Upload",
|
HacknetNodeNICUpload: "HacknetNode NIC Architecture Neural-Upload",
|
||||||
@ -827,6 +832,19 @@ function initAugmentations() {
|
|||||||
}
|
}
|
||||||
AddToAugmentations(ADRPheromone1);
|
AddToAugmentations(ADRPheromone1);
|
||||||
|
|
||||||
|
var ADRPheromone2 = new Augmentation(AugmentationNames.ADRPheromone2);
|
||||||
|
ADRPheromone2.setRequirements(25000, 90000000000);
|
||||||
|
ADRPheromone2.setInfo("The body is genetically re-engineered so that it produces the ADR-V2 pheromone, " +
|
||||||
|
"which is similar to but more potent than ADR-V1. This pheromone, when excreted, " +
|
||||||
|
"triggers feelings of admiration, approval, and respect in others.<br><br>" +
|
||||||
|
"This augmentation:<br>" +
|
||||||
|
"Increases the amount of reputation the player gains for a faction and company by 20%.");
|
||||||
|
ADRPheromone2.addToFactions(["Silhouette", "Four Sigma", "Bachman & Associates", "Clarke Incorporated"]);
|
||||||
|
if (augmentationExists(AugmentationNames.ADRPheromone2)) {
|
||||||
|
delete Augmentations[AugmentationNames.ADRPheromone2];
|
||||||
|
}
|
||||||
|
AddToAugmentations(ADRPheromone2);
|
||||||
|
|
||||||
//HacknetNode Augmentations
|
//HacknetNode Augmentations
|
||||||
var HacknetNodeCPUUpload = new Augmentation(AugmentationNames.HacknetNodeCPUUpload);
|
var HacknetNodeCPUUpload = new Augmentation(AugmentationNames.HacknetNodeCPUUpload);
|
||||||
HacknetNodeCPUUpload.setRequirements(1500, 2200000);
|
HacknetNodeCPUUpload.setRequirements(1500, 2200000);
|
||||||
@ -1626,6 +1644,10 @@ function applyAugmentation(aug, reapply=false) {
|
|||||||
Player.company_rep_mult *= 1.1;
|
Player.company_rep_mult *= 1.1;
|
||||||
Player.faction_rep_mult *= 1.1;
|
Player.faction_rep_mult *= 1.1;
|
||||||
break;
|
break;
|
||||||
|
case AugmentationNames.ADRPheromone2:
|
||||||
|
Player.company_rep_mult *= 1.2;
|
||||||
|
Player.faction_rep_mult *= 1.2;
|
||||||
|
break;
|
||||||
|
|
||||||
//Hacknet Node Augmentations
|
//Hacknet Node Augmentations
|
||||||
case AugmentationNames.HacknetNodeCPUUpload:
|
case AugmentationNames.HacknetNodeCPUUpload:
|
||||||
@ -1910,7 +1932,7 @@ function PlayerOwnedAugmentation(name) {
|
|||||||
this.level = 1;
|
this.level = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function installAugmentations() {
|
function installAugmentations(cbScript=null) {
|
||||||
if (Player.queuedAugmentations.length == 0) {
|
if (Player.queuedAugmentations.length == 0) {
|
||||||
dialogBoxCreate("You have not purchased any Augmentations to install!");
|
dialogBoxCreate("You have not purchased any Augmentations to install!");
|
||||||
return false;
|
return false;
|
||||||
@ -1930,6 +1952,25 @@ function installAugmentations() {
|
|||||||
"to install the following Augmentations:<br>" + augmentationList +
|
"to install the following Augmentations:<br>" + augmentationList +
|
||||||
"<br>You wake up in your home...you feel different...");
|
"<br>You wake up in your home...you feel different...");
|
||||||
prestigeAugmentation();
|
prestigeAugmentation();
|
||||||
|
|
||||||
|
//Run a script after prestiging
|
||||||
|
if (cbScript && isString(cbScript)) {
|
||||||
|
var home = Player.getHomeComputer();
|
||||||
|
for (var i = 0; i < home.scripts.length; ++i) {
|
||||||
|
if (home.scripts[i].filename === cbScript) {
|
||||||
|
var script = home.scripts[i];
|
||||||
|
var ramUsage = script.ramUsage;
|
||||||
|
var ramAvailable = home.maxRam - home.ramUsed;
|
||||||
|
if (ramUsage > ramAvailable) {
|
||||||
|
return; //Not enough RAM
|
||||||
|
}
|
||||||
|
var runningScriptObj = new RunningScript(script, []); //No args
|
||||||
|
runningScriptObj.threads = 1; //Only 1 thread
|
||||||
|
home.runningScripts.push(runningScriptObj);
|
||||||
|
addWorkerScript(runningScriptObj, home);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function augmentationExists(name) {
|
function augmentationExists(name) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
let CONSTANTS = {
|
let CONSTANTS = {
|
||||||
Version: "0.29.1",
|
Version: "0.29.2",
|
||||||
|
|
||||||
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
|
||||||
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
|
||||||
@ -34,7 +34,6 @@ let CONSTANTS = {
|
|||||||
CompanyReputationToFavorBase: 500,
|
CompanyReputationToFavorBase: 500,
|
||||||
CompanyReputationToFavorMult: 1.02,
|
CompanyReputationToFavorMult: 1.02,
|
||||||
|
|
||||||
|
|
||||||
/* Augmentation */
|
/* Augmentation */
|
||||||
//NeuroFlux Governor cost multiplier as you level up
|
//NeuroFlux Governor cost multiplier as you level up
|
||||||
NeuroFluxGovernorLevelMult: 1.14,
|
NeuroFluxGovernorLevelMult: 1.14,
|
||||||
@ -116,17 +115,18 @@ let CONSTANTS = {
|
|||||||
//Intelligence-related constants
|
//Intelligence-related constants
|
||||||
IntelligenceCrimeWeight: 0.05, //Weight for how much int affects crime success rates
|
IntelligenceCrimeWeight: 0.05, //Weight for how much int affects crime success rates
|
||||||
IntelligenceInfiltrationWeight: 0.1, //Weight for how much int affects infiltration success rates
|
IntelligenceInfiltrationWeight: 0.1, //Weight for how much int affects infiltration success rates
|
||||||
IntelligenceCrimeBaseExpGain: 0.0002,
|
IntelligenceCrimeBaseExpGain: 0.001,
|
||||||
IntelligenceProgramBaseExpGain: 1000, //Program required hack level divided by this to determine int exp gain
|
IntelligenceProgramBaseExpGain: 1000, //Program required hack level divided by this to determine int exp gain
|
||||||
IntelligenceTerminalHackBaseExpGain: 200, //Hacking exp divided by this to determine int exp gain
|
IntelligenceTerminalHackBaseExpGain: 200, //Hacking exp divided by this to determine int exp gain
|
||||||
IntelligenceSingFnBaseExpGain: 0.0005,
|
IntelligenceSingFnBaseExpGain: 0.0005,
|
||||||
IntelligenceClassBaseExpGain: 0.0000001,
|
IntelligenceClassBaseExpGain: 0.0000001,
|
||||||
|
|
||||||
//Hacking Missions
|
//Hacking Missions
|
||||||
HackingMissionRepToDiffConversion: 5000, //Faction rep is divided by this to get mission difficulty
|
HackingMissionRepToDiffConversion: 10000, //Faction rep is divided by this to get mission difficulty
|
||||||
HackingMissionRepToRewardConversion: 12, //Faction rep divided byt his to get mission rep reward
|
HackingMissionRepToRewardConversion: 10, //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
|
||||||
|
HackingMissionMiscDefenseIncrease: 5, //The amount by which every misc node's defense increases when one is conquered
|
||||||
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 " +
|
||||||
@ -161,8 +161,8 @@ let CONSTANTS = {
|
|||||||
"select its action using the Action Buttons near the top of the screen. Every action also has a corresponding keyboard " +
|
"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>" +
|
"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 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 " +
|
"any Node that is 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. To remove a target, you can simply click on the line that represents " +
|
"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, " +
|
"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',",
|
"or press 'd',",
|
||||||
@ -515,11 +515,12 @@ let CONSTANTS = {
|
|||||||
"must be a string containing the hostname or IP of the target server. This function will always return true. <br><br>" +
|
"must be a string containing the hostname or IP of the target server. This function will always return true. <br><br>" +
|
||||||
"<i>scp(script, [source], destination)</i><br>Copies a script or literature (.lit) file to another server. The first argument is a string with " +
|
"<i>scp(script, [source], destination)</i><br>Copies a script or literature (.lit) file to another server. The first argument is a string with " +
|
||||||
"the filename of the script or literature file " +
|
"the filename of the script or literature file " +
|
||||||
"to be copied. The next two arguments are strings containing the hostname/IPs of the source and target server. " +
|
"to be copied, or an array of filenames to be copied. The next two arguments are strings containing the hostname/IPs of the source and target server. " +
|
||||||
"The source refers to the server from which the script/literature file will be copied, while the destination " +
|
"The source refers to the server from which the script/literature file will be copied, while the destination " +
|
||||||
"refers to the server to which it will be copied. The source server argument is optional, and if ommitted the source " +
|
"refers to the server to which it will be copied. The source server argument is optional, and if ommitted the source " +
|
||||||
"will be the current server (the server on which the script is running). Returns true if the script/literature file is " +
|
"will be the current server (the server on which the script is running). Returns true if the script/literature file is " +
|
||||||
"successfully copied over and false otherwise. <br><br>" +
|
"successfully copied over and false otherwise. If the first argument passed in is an array, then the function " +
|
||||||
|
"will return if at least one of the files in the array is successfully copied over.<br><br>" +
|
||||||
"Example: scp('hack-template.script', 'foodnstuff'); //Copies hack-template.script from the current server to foodnstuff<br>" +
|
"Example: scp('hack-template.script', 'foodnstuff'); //Copies hack-template.script from the current server to foodnstuff<br>" +
|
||||||
"Example: scp('foo.lit', 'helios', 'home'); //Copies foo.lit from the helios server to the home computer<br><br>" +
|
"Example: scp('foo.lit', 'helios', 'home'); //Copies foo.lit from the helios server to the home computer<br><br>" +
|
||||||
"<i>ls(hostname/ip)</i><br>Returns an array containing the names of all files on the specified server. The argument must be a " +
|
"<i>ls(hostname/ip)</i><br>Returns an array containing the names of all files on the specified server. The argument must be a " +
|
||||||
@ -632,6 +633,9 @@ let CONSTANTS = {
|
|||||||
"an empty string. The function will fail if the arguments passed in are invalid or if the player does not have enough money to purchase the specified server.<br><br>" +
|
"an empty string. The function will fail if the arguments passed in are invalid or if the player does not have enough money to purchase the specified server.<br><br>" +
|
||||||
"<i>deleteServer(hostname)</i><br>Deletes one of the servers you've purchased with the specified hostname. The function will fail if " +
|
"<i>deleteServer(hostname)</i><br>Deletes one of the servers you've purchased with the specified hostname. The function will fail if " +
|
||||||
"there are any scripts running on the specified server. Returns true if successful and false otherwise<br><br>" +
|
"there are any scripts running on the specified server. Returns true if successful and false otherwise<br><br>" +
|
||||||
|
"<i>getPurchasedServers([hostname=true])</i><br>Returns an array with either the hostname or IPs of all of the servers you " +
|
||||||
|
"have purchased. It takes an optional parameter specifying whether the hostname or IP addresses will be returned. If this " +
|
||||||
|
"parameter is not specified, it is true by default and hostnames will be returned<br><br>" +
|
||||||
"<i>round(n)</i><br>Rounds the number n to the nearest integer. If the argument passed in is not a number, then the function will return 0.<br><br>" +
|
"<i>round(n)</i><br>Rounds the number n to the nearest integer. If the argument passed in is not a number, then the function will return 0.<br><br>" +
|
||||||
"<i>write(port, data)</i><br>Writes data to a port. The first argument must be a number between 1 and 10 that specifies the port. The second " +
|
"<i>write(port, data)</i><br>Writes data to a port. The first argument must be a number between 1 and 10 that specifies the port. The second " +
|
||||||
"argument defines the data to write to the port. If the second argument is not specified then it will write an empty string to the port.<br><br>" +
|
"argument defines the data to write to the port. If the second argument is not specified then it will write an empty string to the port.<br><br>" +
|
||||||
@ -905,10 +909,14 @@ let CONSTANTS = {
|
|||||||
"This function will try to purchase the specified Augmentation through the given Faction.<br><br>" +
|
"This function will try to purchase the specified Augmentation through the given Faction.<br><br>" +
|
||||||
"The two arguments must be strings specifying the name of the Faction and Augmentation, respectively. These arguments are both CASE-SENSITIVE.<br><br>" +
|
"The two arguments must be strings specifying the name of the Faction and Augmentation, respectively. These arguments are both CASE-SENSITIVE.<br><br>" +
|
||||||
"This function will return true if the Augmentation is successfully purchased, and false otherwise.<br><br>" +
|
"This function will return true if the Augmentation is successfully purchased, and false otherwise.<br><br>" +
|
||||||
"<i>installAugmentations()</i><br>" +
|
"<i>installAugmentations(cbScript)</i><br>" +
|
||||||
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
"If you are not in BitNode-4, then you must have Level 3 of Source-File 4 in order to use this function.<br><br>" +
|
||||||
"This function will automatically install your Augmentations, resetting the game as usual.<br><br>" +
|
"This function will automatically install your Augmentations, resetting the game as usual.<br><br>" +
|
||||||
"It will return true if successful, and false otherwise.",
|
"It will return true if successful, and false otherwise.<br><br>" +
|
||||||
|
"This function takes a single optional parameter that specifies a callback script. This is " +
|
||||||
|
"a script that will automatically be run after Augmentations are installed (after the reset). " +
|
||||||
|
"This script will be run with no arguments and 1 thread. It must be located on your home computer. This argument, if used, " +
|
||||||
|
"must be a string with the name of the script.",
|
||||||
|
|
||||||
TutorialTravelingText:"There are six major cities in the world that you are able to travel to: <br><br> " +
|
TutorialTravelingText:"There are six major cities in the world that you are able to travel to: <br><br> " +
|
||||||
" Aevum<br>" +
|
" Aevum<br>" +
|
||||||
@ -1008,6 +1016,17 @@ let CONSTANTS = {
|
|||||||
"World Stock Exchange account and TIX API Access<br>",
|
"World Stock Exchange account and TIX API Access<br>",
|
||||||
|
|
||||||
LatestUpdate:
|
LatestUpdate:
|
||||||
|
"v0.29.2<br>" +
|
||||||
|
"-installAugmentations() Singularity Function now takes a callback script as an argument. This is a script " +
|
||||||
|
"that gets ran automatically after Augmentations are installed. The script is run with no arguments and only a single thread, " +
|
||||||
|
"and must be found on your home computer.<br>" +
|
||||||
|
"-Added the ability to create your own functions in Netscript. See <a href='http://bitburner.wikia.com/wiki/Netscript_Functions' target='_blank'>this link</a> for details<br>" +
|
||||||
|
"-Added :q, :x, and :wq Vim Ex Commands when using the Vim script editor keybindings. :w, :x, and :wq will all save the script and return to Terminal. " +
|
||||||
|
":q will quit (return to Terminal) WITHOUT saving. If anyone thinks theres an issue with this please let me know, I don't use Vim<br>" +
|
||||||
|
"-Added a new Augmentation: ADR-V2 Pheromone Gene<br>" +
|
||||||
|
"-In Hacking Missions, enemy nodes will now automatically target Nodes and perform actions.<br>" +
|
||||||
|
"-Re-balanced Hacking Missions through minor tweaking of many numbers<br>" +
|
||||||
|
"-The faction reputation reward for Hacking Missions was slightly increased<br><br>" +
|
||||||
"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) " +
|
"-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 " +
|
"that is meant to be used to earn faction reputation. However, since this is currently in beta, hacking missions will NOT grant reputation " +
|
||||||
|
177
src/Missions.js
177
src/Missions.js
@ -156,7 +156,7 @@ function HackingMission(rep, fac) {
|
|||||||
this.faction = fac;
|
this.faction = fac;
|
||||||
|
|
||||||
this.started = false;
|
this.started = false;
|
||||||
this.time = 180000; //2 minutes, milliseconds
|
this.time = 300000; //5 minutes to start, milliseconds
|
||||||
|
|
||||||
this.playerCores = [];
|
this.playerCores = [];
|
||||||
this.playerNodes = []; //Non-core nodes
|
this.playerNodes = []; //Non-core nodes
|
||||||
@ -203,8 +203,8 @@ HackingMission.prototype.init = function() {
|
|||||||
var home = Player.getHomeComputer()
|
var home = Player.getHomeComputer()
|
||||||
for (var i = 0; i < home.cpuCores; ++i) {
|
for (var i = 0; i < home.cpuCores; ++i) {
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: (Player.hacking_skill / 10),
|
atk: (Player.hacking_skill / 6),
|
||||||
def: (Player.hacking_skill / 25),
|
def: (Player.hacking_skill / 20),
|
||||||
hp: (Player.hacking_skill / 5),
|
hp: (Player.hacking_skill / 5),
|
||||||
};
|
};
|
||||||
this.playerCores.push(new Node(NodeTypes.Core, stats));
|
this.playerCores.push(new Node(NodeTypes.Core, stats));
|
||||||
@ -226,9 +226,9 @@ HackingMission.prototype.init = function() {
|
|||||||
var randMult = addOffset(this.difficulty, 20);
|
var randMult = addOffset(this.difficulty, 20);
|
||||||
for (var i = 0; i < numNodes; ++i) {
|
for (var i = 0; i < numNodes; ++i) {
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: randMult * getRandomInt(125, 175),
|
atk: randMult * getRandomInt(30, 50),
|
||||||
def: randMult * getRandomInt(30, 50),
|
def: randMult * getRandomInt(20, 40),
|
||||||
hp: randMult * getRandomInt(225, 275)
|
hp: randMult * getRandomInt(100, 120)
|
||||||
}
|
}
|
||||||
this.enemyCores.push(new Node(NodeTypes.Core, stats));
|
this.enemyCores.push(new Node(NodeTypes.Core, stats));
|
||||||
this.enemyCores[i].setControlledByEnemy();
|
this.enemyCores[i].setControlledByEnemy();
|
||||||
@ -236,9 +236,9 @@ HackingMission.prototype.init = function() {
|
|||||||
}
|
}
|
||||||
for (var i = 0; i < numFirewalls; ++i) {
|
for (var i = 0; i < numFirewalls; ++i) {
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: randMult * getRandomInt(10, 25),
|
atk: 0,
|
||||||
def: randMult * getRandomInt(50, 75),
|
def: randMult * getRandomInt(50, 75),
|
||||||
hp: randMult * getRandomInt(175, 200)
|
hp: randMult * getRandomInt(150, 200)
|
||||||
}
|
}
|
||||||
this.enemyNodes.push(new Node(NodeTypes.Firewall, stats));
|
this.enemyNodes.push(new Node(NodeTypes.Firewall, stats));
|
||||||
this.enemyNodes[i].setControlledByEnemy();
|
this.enemyNodes[i].setControlledByEnemy();
|
||||||
@ -246,8 +246,8 @@ HackingMission.prototype.init = function() {
|
|||||||
}
|
}
|
||||||
for (var i = 0; i < numDatabases; ++i) {
|
for (var i = 0; i < numDatabases; ++i) {
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: randMult * getRandomInt(20, 30),
|
atk: 0,
|
||||||
def: randMult * getRandomInt(25, 40),
|
def: randMult * getRandomInt(20, 30),
|
||||||
hp: randMult * getRandomInt(120, 150)
|
hp: randMult * getRandomInt(120, 150)
|
||||||
}
|
}
|
||||||
var node = new Node(NodeTypes.Database, stats);
|
var node = new Node(NodeTypes.Database, stats);
|
||||||
@ -332,37 +332,37 @@ HackingMission.prototype.createPageDom = function() {
|
|||||||
}
|
}
|
||||||
this.actionButtons[0].innerText = "Attack(a)";
|
this.actionButtons[0].innerText = "Attack(a)";
|
||||||
var atkTooltip = document.createElement("span");
|
var atkTooltip = document.createElement("span");
|
||||||
atkTooltip.classList.add("tooltiptext");
|
atkTooltip.classList.add("tooltiptexthigh");
|
||||||
atkTooltip.innerText = "Lowers the targeted node's HP. The effectiveness of this depends on " +
|
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 node's Attack level, your hacking level, and the opponent's defense level.";
|
||||||
this.actionButtons[0].appendChild(atkTooltip);
|
this.actionButtons[0].appendChild(atkTooltip);
|
||||||
this.actionButtons[1].innerText = "Scan(s)";
|
this.actionButtons[1].innerText = "Scan(s)";
|
||||||
var scanTooltip = document.createElement("span");
|
var scanTooltip = document.createElement("span");
|
||||||
scanTooltip.classList.add("tooltiptext");
|
scanTooltip.classList.add("tooltiptexthigh");
|
||||||
scanTooltip.innerText = "Lowers the targeted node's defense. The effectiveness of this depends on " +
|
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 node's Attack level, your hacking level, and the opponent's defense level.";
|
||||||
this.actionButtons[1].appendChild(scanTooltip);
|
this.actionButtons[1].appendChild(scanTooltip);
|
||||||
this.actionButtons[2].innerText = "Weaken(w)";
|
this.actionButtons[2].innerText = "Weaken(w)";
|
||||||
var WeakenTooltip = document.createElement("span");
|
var WeakenTooltip = document.createElement("span");
|
||||||
WeakenTooltip.classList.add("tooltiptext");
|
WeakenTooltip.classList.add("tooltiptexthigh");
|
||||||
WeakenTooltip.innerText = "Lowers the targeted node's attack. The effectiveness of this depends on " +
|
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 node's Attack level, your hacking level, and the opponent's defense level.";
|
||||||
this.actionButtons[2].appendChild(WeakenTooltip);
|
this.actionButtons[2].appendChild(WeakenTooltip);
|
||||||
this.actionButtons[3].innerText = "Fortify(f)";
|
this.actionButtons[3].innerText = "Fortify(f)";
|
||||||
var fortifyTooltip = document.createElement("span");
|
var fortifyTooltip = document.createElement("span");
|
||||||
fortifyTooltip.classList.add("tooltiptext");
|
fortifyTooltip.classList.add("tooltiptexthigh");
|
||||||
fortifyTooltip.innerText = "Raises this node's Defense level. The effectiveness of this depends on " +
|
fortifyTooltip.innerText = "Raises this node's Defense level. The effectiveness of this depends on " +
|
||||||
"your hacking level";
|
"your hacking level";
|
||||||
this.actionButtons[3].appendChild(fortifyTooltip);
|
this.actionButtons[3].appendChild(fortifyTooltip);
|
||||||
this.actionButtons[4].innerText = "Overflow(r)";
|
this.actionButtons[4].innerText = "Overflow(r)";
|
||||||
var overflowTooltip = document.createElement("span");
|
var overflowTooltip = document.createElement("span");
|
||||||
overflowTooltip.classList.add("tooltiptext");
|
overflowTooltip.classList.add("tooltiptexthigh");
|
||||||
overflowTooltip.innerText = "Raises this node's Attack level but lowers its Defense level. The effectiveness " +
|
overflowTooltip.innerText = "Raises this node's Attack level but lowers its Defense level. The effectiveness " +
|
||||||
"of this depends on your hacking level.";
|
"of this depends on your hacking level.";
|
||||||
this.actionButtons[4].appendChild(overflowTooltip);
|
this.actionButtons[4].appendChild(overflowTooltip);
|
||||||
this.actionButtons[5].innerText = "Drop Connection(d)";
|
this.actionButtons[5].innerText = "Drop Connection(d)";
|
||||||
var dropconnTooltip = document.createElement("span");
|
var dropconnTooltip = document.createElement("span");
|
||||||
dropconnTooltip.classList.add("tooltiptext");
|
dropconnTooltip.classList.add("tooltiptexthigh");
|
||||||
dropconnTooltip.innerText = "Removes this Node's current connection to some target Node, if it has one. This can " +
|
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.";
|
"also be done by simply clicking the white connection line.";
|
||||||
this.actionButtons[5].appendChild(dropconnTooltip);
|
this.actionButtons[5].appendChild(dropconnTooltip);
|
||||||
@ -387,6 +387,7 @@ HackingMission.prototype.createPageDom = function() {
|
|||||||
console.log("ERR: Pressing Action button without selected node");
|
console.log("ERR: Pressing Action button without selected node");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this.selectedNode.type !== NodeTypes.Core) {return;}
|
||||||
this.setActionButtonsActive();
|
this.setActionButtonsActive();
|
||||||
this.setActionButton(NodeActions.Attack, false); //Set attack button inactive
|
this.setActionButton(NodeActions.Attack, false); //Set attack button inactive
|
||||||
this.selectedNode.action = NodeActions.Attack;
|
this.selectedNode.action = NodeActions.Attack;
|
||||||
@ -608,7 +609,7 @@ HackingMission.prototype.createMap = function() {
|
|||||||
case 0: //Spam
|
case 0: //Spam
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: 0,
|
atk: 0,
|
||||||
def: randMult * getRandomInt(35, 55),
|
def: randMult * getRandomInt(30, 50),
|
||||||
hp: randMult * getRandomInt(125, 150)
|
hp: randMult * getRandomInt(125, 150)
|
||||||
}
|
}
|
||||||
node = new Node(NodeTypes.Spam, stats);
|
node = new Node(NodeTypes.Spam, stats);
|
||||||
@ -616,7 +617,7 @@ HackingMission.prototype.createMap = function() {
|
|||||||
case 1: //Transfer
|
case 1: //Transfer
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: 0,
|
atk: 0,
|
||||||
def: randMult * getRandomInt(45, 65),
|
def: randMult * getRandomInt(40, 60),
|
||||||
hp: randMult * getRandomInt(150, 175)
|
hp: randMult * getRandomInt(150, 175)
|
||||||
}
|
}
|
||||||
node = new Node(NodeTypes.Transfer, stats);
|
node = new Node(NodeTypes.Transfer, stats);
|
||||||
@ -625,7 +626,7 @@ HackingMission.prototype.createMap = function() {
|
|||||||
default:
|
default:
|
||||||
var stats = {
|
var stats = {
|
||||||
atk: 0,
|
atk: 0,
|
||||||
def: randMult * getRandomInt(60, 80),
|
def: randMult * getRandomInt(50, 75),
|
||||||
hp: randMult * getRandomInt(200, 250)
|
hp: randMult * getRandomInt(200, 250)
|
||||||
}
|
}
|
||||||
node = new Node(NodeTypes.Shield, stats);
|
node = new Node(NodeTypes.Shield, stats);
|
||||||
@ -761,9 +762,15 @@ HackingMission.prototype.updateNodeDomElement = function(nodeObj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Gets a Node DOM element's corresponding Node object using its
|
//Gets a Node DOM element's corresponding Node object using its
|
||||||
//element id
|
//element id. Function accepts either the DOM element object or the ID as
|
||||||
|
//an argument
|
||||||
HackingMission.prototype.getNodeFromElement = function(el) {
|
HackingMission.prototype.getNodeFromElement = function(el) {
|
||||||
var id = el.id;
|
var id;
|
||||||
|
if (isString(el)) {
|
||||||
|
id = el;
|
||||||
|
} else {
|
||||||
|
id = el.id;
|
||||||
|
}
|
||||||
id = id.replace("hacking-mission-node-", "");
|
id = id.replace("hacking-mission-node-", "");
|
||||||
var res = id.split('-');
|
var res = id.split('-');
|
||||||
if (res.length != 2) {
|
if (res.length != 2) {
|
||||||
@ -820,6 +827,15 @@ HackingMission.prototype.nodeReachable = function(node) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HackingMission.prototype.nodeReachableByEnemy = function(node) {
|
||||||
|
var x = node.pos[0], y = node.pos[1];
|
||||||
|
if (x > 0 && this.map[x-1][y].enmyCtrl) {return true;}
|
||||||
|
if (x < 7 && this.map[x+1][y].enmyCtrl) {return true;}
|
||||||
|
if (y > 0 && this.map[x][y-1].enmyCtrl) {return true;}
|
||||||
|
if (y < 7 && this.map[x][y+1].enmyCtrl) {return true;}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
HackingMission.prototype.start = function() {
|
HackingMission.prototype.start = function() {
|
||||||
this.started = true;
|
this.started = true;
|
||||||
this.initJsPlumb();
|
this.initJsPlumb();
|
||||||
@ -908,6 +924,15 @@ HackingMission.prototype.initJsPlumb = function() {
|
|||||||
var sourceNode = this.getNodeFromElement(info.source);
|
var sourceNode = this.getNodeFromElement(info.source);
|
||||||
sourceNode.conn = null;
|
sourceNode.conn = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Set connection type for enemy connections
|
||||||
|
instance.registerConnectionTypes({
|
||||||
|
"basic": {
|
||||||
|
paintStyle:{ stroke:"red", strokeWidth:5 },
|
||||||
|
hoverPaintStyle:{ stroke:"red", strokeWidth:7 },
|
||||||
|
anchor:"Continuous",
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
//Drops all connections where the specified node is the source
|
//Drops all connections where the specified node is the source
|
||||||
@ -950,11 +975,13 @@ HackingMission.prototype.process = function(numCycles=1) {
|
|||||||
|
|
||||||
//Process actions of all enemy nodes
|
//Process actions of all enemy nodes
|
||||||
this.enemyCores.forEach((node)=>{
|
this.enemyCores.forEach((node)=>{
|
||||||
|
this.enemyAISelectAction(node);
|
||||||
res |= this.processNode(node, storedCycles);
|
res |= this.processNode(node, storedCycles);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.enemyNodes.forEach((node)=>{
|
this.enemyNodes.forEach((node)=>{
|
||||||
if (node.type === NodeTypes.Transfer) {
|
if (node.type === NodeTypes.Transfer) {
|
||||||
|
this.enemyAISelectAction(node);
|
||||||
res |= this.processNode(node, storedCycles);
|
res |= this.processNode(node, storedCycles);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -969,7 +996,7 @@ HackingMission.prototype.process = function(numCycles=1) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Defense of every misc Node increase by 1 per second
|
//Defense of every misc Node increase by 0.5 per second
|
||||||
this.miscNodes.forEach((node)=>{
|
this.miscNodes.forEach((node)=>{
|
||||||
node.def += (0.1 * storedCycles);
|
node.def += (0.1 * storedCycles);
|
||||||
this.updateNodeDomElement(node);
|
this.updateNodeDomElement(node);
|
||||||
@ -994,7 +1021,13 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
|
|
||||||
var targetNode = null, def, atk;
|
var targetNode = null, def, atk;
|
||||||
if (nodeObj.conn) {
|
if (nodeObj.conn) {
|
||||||
|
var targetNode;
|
||||||
|
if (nodeObj.conn.target) {
|
||||||
targetNode = this.getNodeFromElement(nodeObj.conn.target);
|
targetNode = this.getNodeFromElement(nodeObj.conn.target);
|
||||||
|
} else {
|
||||||
|
targetNode = this.getNodeFromElement(nodeObj.conn.targetId);
|
||||||
|
}
|
||||||
|
|
||||||
if (targetNode.plyrCtrl) {
|
if (targetNode.plyrCtrl) {
|
||||||
def = this.playerDef;
|
def = this.playerDef;
|
||||||
atk = this.enemyAtk;
|
atk = this.enemyAtk;
|
||||||
@ -1062,7 +1095,6 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
|
|
||||||
//Flag for whether the target node was a misc node
|
//Flag for whether the target node was a misc node
|
||||||
var isMiscNode = !targetNode.plyrCtrl && !targetNode.enmyCtrl;
|
var isMiscNode = !targetNode.plyrCtrl && !targetNode.enmyCtrl;
|
||||||
console.log("isMiscNode: " + isMiscNode);
|
|
||||||
|
|
||||||
//Remove all connections from Node
|
//Remove all connections from Node
|
||||||
this.dropAllConnectionsToNode(targetNode);
|
this.dropAllConnectionsToNode(targetNode);
|
||||||
@ -1080,6 +1112,7 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
targetNode.setControlledByEnemy();
|
targetNode.setControlledByEnemy();
|
||||||
|
nodeObj.conn = null; //Clear connection
|
||||||
this.jsplumbinstance.unmakeSource(targetNode.el);
|
this.jsplumbinstance.unmakeSource(targetNode.el);
|
||||||
this.jsplumbinstance.makeTarget(targetNode.el, {
|
this.jsplumbinstance.makeTarget(targetNode.el, {
|
||||||
maxConnections:-1,
|
maxConnections:-1,
|
||||||
@ -1092,10 +1125,8 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
|
|
||||||
//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) {
|
||||||
console.log("swapNodes called");
|
|
||||||
for (var i = 0; i < orig.length; ++i) {
|
for (var i = 0; i < orig.length; ++i) {
|
||||||
if (orig[i] == targetNode) {
|
if (orig[i] == targetNode) {
|
||||||
console.log("Swapping nodes");
|
|
||||||
var node = orig.splice(i, 1);
|
var node = orig.splice(i, 1);
|
||||||
node = node[0];
|
node = node[0];
|
||||||
dest.push(node);
|
dest.push(node);
|
||||||
@ -1104,7 +1135,6 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Whether conquered node was a misc node
|
|
||||||
switch(targetNode.type) {
|
switch(targetNode.type) {
|
||||||
case NodeTypes.Core:
|
case NodeTypes.Core:
|
||||||
if (conqueredByPlayer) {
|
if (conqueredByPlayer) {
|
||||||
@ -1132,12 +1162,12 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
case NodeTypes.Spam:
|
case NodeTypes.Spam:
|
||||||
if (conqueredByPlayer) {
|
if (conqueredByPlayer) {
|
||||||
swapNodes(isMiscNode ? this.miscNodes : this.enemyNodes, this.playerNodes, targetNode);
|
swapNodes(isMiscNode ? this.miscNodes : this.enemyNodes, this.playerNodes, targetNode);
|
||||||
|
//Conquering spam node increases time limit
|
||||||
|
this.time += CONSTANTS.HackingMissionSpamTimeIncrease;
|
||||||
} else {
|
} else {
|
||||||
swapNodes(isMiscNode ? this.miscNodes : this.playerNodes, this.enemyNodes, targetNode);
|
swapNodes(isMiscNode ? this.miscNodes : this.playerNodes, this.enemyNodes, targetNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Conquering spam node increases time limit
|
|
||||||
this.time += CONSTANTS.HackingMissionSpamTimeIncrease;
|
|
||||||
break;
|
break;
|
||||||
case NodeTypes.Transfer:
|
case NodeTypes.Transfer:
|
||||||
//Conquering a Transfer node increases the attack of all cores by some percentages
|
//Conquering a Transfer node increases the attack of all cores by some percentages
|
||||||
@ -1163,15 +1193,102 @@ HackingMission.prototype.processNode = function(nodeObj, numCycles=1) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//If a misc node was conquered, the defense for all misc nodes increases by some fixed amount
|
||||||
|
this.miscNodes.forEach((node)=>{
|
||||||
|
node.def += CONSTANTS.HackingMissionMiscDefenseIncrease;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Update node DOMs
|
||||||
this.updateNodeDomElement(nodeObj);
|
this.updateNodeDomElement(nodeObj);
|
||||||
if (targetNode) {this.updateNodeDomElement(targetNode);}
|
if (targetNode) {this.updateNodeDomElement(targetNode);}
|
||||||
return calcStats;
|
return calcStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
var hackEffWeightSelf = 150; //Weight for Node actions on self
|
//Enemy "AI" for CPU Cor eand Transfer Nodes
|
||||||
|
HackingMission.prototype.enemyAISelectAction = function(nodeObj) {
|
||||||
|
if (nodeObj === null) {return;}
|
||||||
|
switch(nodeObj.type) {
|
||||||
|
case NodeTypes.Core:
|
||||||
|
//Select a single RANDOM target from miscNodes and player's Nodes
|
||||||
|
//If it is reachable, it will target it. If not, no target will
|
||||||
|
//be selected for now, and the next time process() gets called this will repeat
|
||||||
|
if (nodeObj.conn === null) {
|
||||||
|
if (this.miscNodes.length === 0) {
|
||||||
|
//Randomly pick a player node and attack it if its reachable
|
||||||
|
var rand = getRandomInt(0, this.playerNodes.length-1);
|
||||||
|
var node = this.playerNodes[rand];
|
||||||
|
if (this.nodeReachableByEnemy(node)) {
|
||||||
|
//Create connection
|
||||||
|
console.log("Enemy core selected a Player Node as target");
|
||||||
|
nodeObj.conn = this.jsplumbinstance.connect({
|
||||||
|
source:nodeObj.el,
|
||||||
|
target:node.el
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
//Randomly pick a player core and attack it if its reachable
|
||||||
|
rand = getRandomInt(0, this.playerCores.length-1);
|
||||||
|
node = this.playerCores[rand];
|
||||||
|
if (this.nodeReachableByEnemy(node)) {
|
||||||
|
//Create connection
|
||||||
|
console.log("Enemy core selected a Player Core as target");
|
||||||
|
nodeObj.conn = this.jsplumbinstance.connect({
|
||||||
|
source:nodeObj.el,
|
||||||
|
target:node.el
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Randomly pick a misc node and attack it if its reachable
|
||||||
|
var rand = getRandomInt(0, this.miscNodes.length-1);
|
||||||
|
var node = this.miscNodes[rand];
|
||||||
|
if (this.nodeReachableByEnemy(node)) {
|
||||||
|
console.log("Enemy core selected a Misc Node as target: " + node.el.id);
|
||||||
|
nodeObj.conn = this.jsplumbinstance.connect({
|
||||||
|
source:nodeObj.el,
|
||||||
|
target:node.el,
|
||||||
|
type:"basic"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//If no connection was made, set the Core to Fortify
|
||||||
|
nodeObj.action = NodeActions.Fortify;
|
||||||
|
} else {
|
||||||
|
var targetNode;
|
||||||
|
if (nodeObj.conn.target) {
|
||||||
|
targetNode = this.getNodeFromElement(nodeObj.conn.target);
|
||||||
|
} else {
|
||||||
|
targetNode = this.getNodeFromElement(nodeObj.conn.targetId);
|
||||||
|
}
|
||||||
|
if (targetNode === null) {
|
||||||
|
console.log("Error getting Target node Object in enemyAISelectAction()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetNode.def > this.enemyAtk - 25) {
|
||||||
|
nodeObj.action = NodeActions.Scan;
|
||||||
|
} else {
|
||||||
|
nodeObj.action = NodeActions.Attack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NodeTypes.Transfer:
|
||||||
|
//Switch between fortifying and overflowing as necessary
|
||||||
|
if (nodeObj.def < 125) {
|
||||||
|
nodeObj.action = NodeActions.Fortify;
|
||||||
|
} else {
|
||||||
|
nodeObj.action = NodeActions.Overflow;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var hackEffWeightSelf = 130; //Weight for Node actions on self
|
||||||
var hackEffWeightTarget = 25; //Weight for Node Actions against Target
|
var hackEffWeightTarget = 25; //Weight for Node Actions against Target
|
||||||
var hackEffWeightAttack = 110; //Weight for Attack action
|
var hackEffWeightAttack = 80; //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) {
|
||||||
|
@ -4,7 +4,9 @@ import {NetscriptFunctions} from "./NetscriptFunctions.js";
|
|||||||
*/
|
*/
|
||||||
function Environment(workerScript,parent) {
|
function Environment(workerScript,parent) {
|
||||||
if (parent){
|
if (parent){
|
||||||
this.vars = parent.vars;
|
//Create a copy of parent's variables
|
||||||
|
//this.vars = parent.vars;
|
||||||
|
this.vars = Object.assign({}, parent.vars);
|
||||||
} else {
|
} else {
|
||||||
this.vars = NetscriptFunctions(workerScript);
|
this.vars = NetscriptFunctions(workerScript);
|
||||||
}
|
}
|
||||||
@ -15,17 +17,19 @@ Environment.prototype = {
|
|||||||
//Create a "subscope", which is a new new "sub-environment"
|
//Create a "subscope", which is a new new "sub-environment"
|
||||||
//The subscope is linked to this through its parent variable
|
//The subscope is linked to this through its parent variable
|
||||||
extend: function() {
|
extend: function() {
|
||||||
return new Environment(this);
|
return new Environment(null, this);
|
||||||
},
|
},
|
||||||
|
|
||||||
//Finds the scope where the variable with the given name is defined
|
//Finds the scope where the variable with the given name is defined
|
||||||
lookup: function(name) {
|
lookup: function(name) {
|
||||||
var scope = this;
|
var scope = this;
|
||||||
while (scope) {
|
while (scope) {
|
||||||
if (Object.prototype.hasOwnProperty.call(scope.vars, name))
|
if (Object.prototype.hasOwnProperty.call(scope.vars, name)) {
|
||||||
return scope;
|
return scope;
|
||||||
|
}
|
||||||
scope = scope.parent;
|
scope = scope.parent;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
//Get the current value of a variable
|
//Get the current value of a variable
|
||||||
@ -39,15 +43,14 @@ Environment.prototype = {
|
|||||||
//Sets the value of a variable in any scope
|
//Sets the value of a variable in any scope
|
||||||
set: function(name, value) {
|
set: function(name, value) {
|
||||||
var scope = this.lookup(name);
|
var scope = this.lookup(name);
|
||||||
// let's not allow defining globals from a nested environment
|
|
||||||
//
|
//If scope has a value, then this variable is already set in a higher scope, so
|
||||||
// If scope is null (aka existing variable with name could not be found)
|
//set is there. Otherwise, create a new variable in the local scope
|
||||||
// and this is NOT the global scope, throw error
|
if (scope !== null) {
|
||||||
if (!scope && this.parent) {
|
return scope.vars[name] = value;
|
||||||
console.log("Here");
|
} else {
|
||||||
throw new Error("Undefined variable " + name);
|
return this.vars[name] = value;
|
||||||
}
|
}
|
||||||
return (scope || this).vars[name] = value;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setArrayElement: function(name, idx, value) {
|
setArrayElement: function(name, idx, value) {
|
||||||
@ -56,7 +59,6 @@ Environment.prototype = {
|
|||||||
}
|
}
|
||||||
var scope = this.lookup(name);
|
var scope = this.lookup(name);
|
||||||
if (!scope && this.parent) {
|
if (!scope && this.parent) {
|
||||||
console.log("Here");
|
|
||||||
throw new Error("Undefined variable " + name);
|
throw new Error("Undefined variable " + name);
|
||||||
}
|
}
|
||||||
var arr = (scope || this).vars[name];
|
var arr = (scope || this).vars[name];
|
||||||
|
@ -8,6 +8,7 @@ import {Settings} from "./Settings.js";
|
|||||||
import {Script, findRunningScript,
|
import {Script, findRunningScript,
|
||||||
RunningScript} from "./Script.js";
|
RunningScript} from "./Script.js";
|
||||||
|
|
||||||
|
import {Node} from "../utils/acorn.js";
|
||||||
import {printArray} from "../utils/HelperFunctions.js";
|
import {printArray} from "../utils/HelperFunctions.js";
|
||||||
import {isValidIPAddress} from "../utils/IPAddress.js";
|
import {isValidIPAddress} from "../utils/IPAddress.js";
|
||||||
import {isString} from "../utils/StringHelperFunctions.js";
|
import {isString} from "../utils/StringHelperFunctions.js";
|
||||||
@ -33,7 +34,10 @@ function evaluate(exp, workerScript) {
|
|||||||
evaluateProgPromise.then(function(w) {
|
evaluateProgPromise.then(function(w) {
|
||||||
resolve(workerScript);
|
resolve(workerScript);
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
if (isString(e)) {
|
if (e.constructor === Array && e.length === 2 && e[0] === "RETURNSTATEMENT") {
|
||||||
|
//Returning from a Player-defined function
|
||||||
|
resolve(e[1]);
|
||||||
|
} else if (isString(e)) {
|
||||||
workerScript.errorMessage = e;
|
workerScript.errorMessage = e;
|
||||||
reject(workerScript);
|
reject(workerScript);
|
||||||
} else if (e instanceof WorkerScript) {
|
} else if (e instanceof WorkerScript) {
|
||||||
@ -55,7 +59,7 @@ function evaluate(exp, workerScript) {
|
|||||||
case "ExpressionStatement":
|
case "ExpressionStatement":
|
||||||
var e = evaluate(exp.expression, workerScript);
|
var e = evaluate(exp.expression, workerScript);
|
||||||
e.then(function(res) {
|
e.then(function(res) {
|
||||||
resolve("expression done");
|
resolve(res);
|
||||||
}, function(e) {
|
}, function(e) {
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
@ -76,7 +80,34 @@ function evaluate(exp, workerScript) {
|
|||||||
return evaluate(arg, workerScript);
|
return evaluate(arg, workerScript);
|
||||||
});
|
});
|
||||||
Promise.all(argPromises).then(function(args) {
|
Promise.all(argPromises).then(function(args) {
|
||||||
if (exp.callee.type == "MemberExpression"){
|
if (func instanceof Node) { //Player-defined function
|
||||||
|
//Create new Environment for the function
|
||||||
|
//Should be automatically garbage collected...
|
||||||
|
var funcEnv = env.extend();
|
||||||
|
console.log("Printing new environment for function:");
|
||||||
|
console.log(funcEnv);
|
||||||
|
|
||||||
|
//Define function arguments in this new environment
|
||||||
|
for (var i = 0; i < func.params.length; ++i) {
|
||||||
|
var arg;
|
||||||
|
if (i >= args.length) {
|
||||||
|
arg = null;
|
||||||
|
} else {
|
||||||
|
arg = args[i];
|
||||||
|
}
|
||||||
|
funcEnv.def(func.params[i].name, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create a new WorkerScript for this function evaluation
|
||||||
|
var funcWorkerScript = new WorkerScript(workerScript.scriptRef);
|
||||||
|
funcWorkerScript.env = funcEnv;
|
||||||
|
|
||||||
|
evaluate(func.body, funcWorkerScript).then(function(res) {
|
||||||
|
resolve(res);
|
||||||
|
}).catch(function(e) {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
|
} else if (exp.callee.type == "MemberExpression"){
|
||||||
evaluate(exp.callee.object, workerScript).then(function(object) {
|
evaluate(exp.callee.object, workerScript).then(function(object) {
|
||||||
try {
|
try {
|
||||||
var res = func.apply(object,args);
|
var res = func.apply(object,args);
|
||||||
@ -125,7 +156,6 @@ function evaluate(exp, workerScript) {
|
|||||||
}
|
}
|
||||||
resolve(object[index]);
|
resolve(object[index]);
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
console.log("here");
|
|
||||||
reject(makeRuntimeRejectMsg(workerScript, "Invalid MemberExpression"));
|
reject(makeRuntimeRejectMsg(workerScript, "Invalid MemberExpression"));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -195,8 +225,14 @@ function evaluate(exp, workerScript) {
|
|||||||
resolve(false);
|
resolve(false);
|
||||||
break;
|
break;
|
||||||
case "ReturnStatement":
|
case "ReturnStatement":
|
||||||
var lineNum = getErrorLineNumber(exp, workerScript);
|
console.log("Evaluating Return Statement");
|
||||||
reject(makeRuntimeRejectMsg(workerScript, "Return statements are not yet implemented in Netscript (line " + (lineNum+1) + ")"));
|
//var lineNum = getErrorLineNumber(exp, workerScript);
|
||||||
|
//reject(makeRuntimeRejectMsg(workerScript, "Return statements are not yet implemented in Netscript (line " + (lineNum+1) + ")"));
|
||||||
|
evaluate(exp.argument, workerScript).then(function(res) {
|
||||||
|
reject(["RETURNSTATEMENT", res]);
|
||||||
|
}).catch(function(e) {
|
||||||
|
reject(e);
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
case "BreakStatement":
|
case "BreakStatement":
|
||||||
reject("BREAKSTATEMENT");
|
reject("BREAKSTATEMENT");
|
||||||
@ -206,7 +242,7 @@ function evaluate(exp, workerScript) {
|
|||||||
break;
|
break;
|
||||||
case "IfStatement":
|
case "IfStatement":
|
||||||
evaluateIf(exp, workerScript).then(function(forLoopRes) {
|
evaluateIf(exp, workerScript).then(function(forLoopRes) {
|
||||||
resolve("forLoopDone");
|
resolve(forLoopRes);
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
reject(e);
|
reject(e);
|
||||||
});
|
});
|
||||||
@ -217,7 +253,7 @@ function evaluate(exp, workerScript) {
|
|||||||
break;e
|
break;e
|
||||||
case "WhileStatement":
|
case "WhileStatement":
|
||||||
evaluateWhile(exp, workerScript).then(function(forLoopRes) {
|
evaluateWhile(exp, workerScript).then(function(forLoopRes) {
|
||||||
resolve("forLoopDone");
|
resolve(forLoopRes);
|
||||||
}).catch(function(e) {
|
}).catch(function(e) {
|
||||||
if (e == "BREAKSTATEMENT" ||
|
if (e == "BREAKSTATEMENT" ||
|
||||||
(e instanceof WorkerScript && e.errorMessage == "BREAKSTATEMENT")) {
|
(e instanceof WorkerScript && e.errorMessage == "BREAKSTATEMENT")) {
|
||||||
@ -241,6 +277,15 @@ function evaluate(exp, workerScript) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case "FunctionDeclaration":
|
||||||
|
if (exp.id && exp.id.name) {
|
||||||
|
env.set(exp.id.name, exp);
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
var lineNum = getErrorLineNumber(exp, workerScript);
|
||||||
|
reject(makeRuntimeRejectMsg(workerScript, "Invalid function declaration at line " + lineNum+1));
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
var lineNum = getErrorLineNumber(exp, workerScript);
|
var lineNum = getErrorLineNumber(exp, workerScript);
|
||||||
reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + " (line " + (lineNum+1) + "). This is currently unsupported in Netscript"));
|
reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + " (line " + (lineNum+1) + "). This is currently unsupported in Netscript"));
|
||||||
|
@ -1973,7 +1973,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
installAugmentations() {
|
installAugmentations(cbScript) {
|
||||||
if (Player.bitNodeN != 4) {
|
if (Player.bitNodeN != 4) {
|
||||||
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
|
if (!(hasSingularitySF && singularitySFLvl >= 3)) {
|
||||||
throw makeRuntimeRejectMsg(workerScript, "Cannot run installAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
|
throw makeRuntimeRejectMsg(workerScript, "Cannot run installAugmentations(). It is a Singularity Function and requires SourceFile-4 (level 3) to run.");
|
||||||
@ -1987,7 +1987,7 @@ function NetscriptFunctions(workerScript) {
|
|||||||
}
|
}
|
||||||
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
|
||||||
workerScript.scriptRef.log("Installing Augmentations. This will cause this script to be killed");
|
workerScript.scriptRef.log("Installing Augmentations. This will cause this script to be killed");
|
||||||
installAugmentations();
|
installAugmentations(cbScript);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,6 @@ import {parse} from "../utils/acorn.js";
|
|||||||
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
import {dialogBoxCreate} from "../utils/DialogBox.js";
|
||||||
import {compareArrays, printArray} from "../utils/HelperFunctions.js";
|
import {compareArrays, printArray} from "../utils/HelperFunctions.js";
|
||||||
|
|
||||||
|
|
||||||
function WorkerScript(runningScriptObj) {
|
function WorkerScript(runningScriptObj) {
|
||||||
this.name = runningScriptObj.filename;
|
this.name = runningScriptObj.filename;
|
||||||
this.running = false;
|
this.running = false;
|
||||||
@ -180,6 +179,14 @@ function addWorkerScript(runningScriptObj, server) {
|
|||||||
}
|
}
|
||||||
var ramUsage = runningScriptObj.scriptRef.ramUsage * threads
|
var ramUsage = runningScriptObj.scriptRef.ramUsage * threads
|
||||||
* Math.pow(CONSTANTS.MultithreadingRAMCost, threads-1);
|
* Math.pow(CONSTANTS.MultithreadingRAMCost, threads-1);
|
||||||
|
var ramAvailable = server.maxRam - server.ramUsed;
|
||||||
|
if (ramUsage > ramAvailable) {
|
||||||
|
dialogBoxCreate("Not enough RAM to run script " + runningScriptObj.filename + " with args " +
|
||||||
|
printArray(runningScriptObj.args) + ". This likely occurred because you re-loaded " +
|
||||||
|
"the game and the script's RAM usage increased (either because of an update to the game or " +
|
||||||
|
"your changes to the script.)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
server.ramUsed += ramUsage;
|
server.ramUsed += ramUsage;
|
||||||
|
|
||||||
//Create the WorkerScript
|
//Create the WorkerScript
|
||||||
|
@ -1483,6 +1483,7 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
|
|||||||
break;
|
break;
|
||||||
case CONSTANTS.CrimeKidnap:
|
case CONSTANTS.CrimeKidnap:
|
||||||
this.karma -= 6;
|
this.karma -= 6;
|
||||||
|
this.gainIntelligenceExp(CONSTANTS.IntelligenceCrimeBaseExpGain);
|
||||||
break;
|
break;
|
||||||
case CONSTANTS.CrimeAssassination:
|
case CONSTANTS.CrimeAssassination:
|
||||||
++this.numPeopleKilled;
|
++this.numPeopleKilled;
|
||||||
|
@ -94,6 +94,12 @@ function scriptEditorInit() {
|
|||||||
VimApi.defineEx('quit', 'q', function(cm, input) {
|
VimApi.defineEx('quit', 'q', function(cm, input) {
|
||||||
Engine.loadTerminalContent();
|
Engine.loadTerminalContent();
|
||||||
});
|
});
|
||||||
|
VimApi.defineEx('xwritequit', 'x', function(cm, input) {
|
||||||
|
saveAndCloseScriptEditor();
|
||||||
|
});
|
||||||
|
VimApi.defineEx('wqwritequit', 'wq', function(cm, input) {
|
||||||
|
saveAndCloseScriptEditor();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
document.addEventListener("DOMContentLoaded", scriptEditorInit, false);
|
document.addEventListener("DOMContentLoaded", scriptEditorInit, false);
|
||||||
@ -243,6 +249,7 @@ function calculateRamUsage(codeCopy) {
|
|||||||
numOccurrences(codeCopy, "getServerMaxMoney(") +
|
numOccurrences(codeCopy, "getServerMaxMoney(") +
|
||||||
numOccurrences(codeCopy, "getServerSecurityLevel(") +
|
numOccurrences(codeCopy, "getServerSecurityLevel(") +
|
||||||
numOccurrences(codeCopy, "getServerBaseSecurityLevel(") +
|
numOccurrences(codeCopy, "getServerBaseSecurityLevel(") +
|
||||||
|
numOccurrences(codeCopy, "getServerMinSecurityLevel(") +
|
||||||
numOccurrences(codeCopy, "getServerGrowth(") +
|
numOccurrences(codeCopy, "getServerGrowth(") +
|
||||||
numOccurrences(codeCopy, "getServerRequiredHackingLevel(") +
|
numOccurrences(codeCopy, "getServerRequiredHackingLevel(") +
|
||||||
numOccurrences(codeCopy, "getServerNumPortsRequired(") +
|
numOccurrences(codeCopy, "getServerNumPortsRequired(") +
|
||||||
@ -260,7 +267,8 @@ function calculateRamUsage(codeCopy) {
|
|||||||
var scriptBuySellStockCount = numOccurrences(codeCopy, "buyStock(") +
|
var scriptBuySellStockCount = numOccurrences(codeCopy, "buyStock(") +
|
||||||
numOccurrences(codeCopy, "sellStock(");
|
numOccurrences(codeCopy, "sellStock(");
|
||||||
var scriptPurchaseServerCount = numOccurrences(codeCopy, "purchaseServer(") +
|
var scriptPurchaseServerCount = numOccurrences(codeCopy, "purchaseServer(") +
|
||||||
numOccurrences(codeCopy, "deleteServer(");
|
numOccurrences(codeCopy, "deleteServer(") +
|
||||||
|
numOccurrences(codeCopy, "getPurchasedServers(");
|
||||||
var scriptRoundCount = numOccurrences(codeCopy, "round(");
|
var scriptRoundCount = numOccurrences(codeCopy, "round(");
|
||||||
var scriptWriteCount = numOccurrences(codeCopy, "write(");
|
var scriptWriteCount = numOccurrences(codeCopy, "write(");
|
||||||
var scriptReadCount = numOccurrences(codeCopy, "read(");
|
var scriptReadCount = numOccurrences(codeCopy, "read(");
|
||||||
@ -271,7 +279,8 @@ function calculateRamUsage(codeCopy) {
|
|||||||
numOccurrences(codeCopy, "getScriptExpGain(");
|
numOccurrences(codeCopy, "getScriptExpGain(");
|
||||||
var getHackTimeCount = numOccurrences(codeCopy, "getHackTime(") +
|
var getHackTimeCount = numOccurrences(codeCopy, "getHackTime(") +
|
||||||
numOccurrences(codeCopy, "getGrowTime(") +
|
numOccurrences(codeCopy, "getGrowTime(") +
|
||||||
numOccurrences(codeCopy, "getWeakenTime(");
|
numOccurrences(codeCopy, "getWeakenTime(") +
|
||||||
|
numOccurrences(codeCopy, "getTimeSinceLastAug(");
|
||||||
var singFn1Count = numOccurrences(codeCopy, "universityCourse(") +
|
var singFn1Count = numOccurrences(codeCopy, "universityCourse(") +
|
||||||
numOccurrences(codeCopy, "gymWorkout(") +
|
numOccurrences(codeCopy, "gymWorkout(") +
|
||||||
numOccurrences(codeCopy, "travelToCity(") +
|
numOccurrences(codeCopy, "travelToCity(") +
|
||||||
|
@ -33,7 +33,15 @@ function initSourceFiles() {
|
|||||||
SourceFiles["SourceFile3"] = new SourceFile(3);
|
SourceFiles["SourceFile3"] = new SourceFile(3);
|
||||||
SourceFiles["SourceFile4"] = new SourceFile(4, "This Source-File lets you access and use the Singularity Functions in every BitNode. Every " +
|
SourceFiles["SourceFile4"] = new SourceFile(4, "This Source-File lets you access and use the Singularity Functions in every BitNode. Every " +
|
||||||
"level of this Source-File opens up more of the Singularity Functions you can use.");
|
"level of this Source-File opens up more of the Singularity Functions you can use.");
|
||||||
SourceFiles["SourceFile5"] = new SourceFile(5);
|
SourceFiles["SourceFile5"] = new SourceFile(5, "This Source-File grants a special new stat called Intelligence. Intelligence " +
|
||||||
|
"is unique because it is permanent and persistent (it never gets reset back to 1). However, " +
|
||||||
|
"gaining Intelligence experience is much slower than other stats, and it is also hidden (you won't " +
|
||||||
|
"know when you gain experience and how much). Higher Intelligence levels will boost your production " +
|
||||||
|
"for many actions in the game. In addition, this Source-File will unlock the getBitNodeMultipliers() " +
|
||||||
|
"Netscript function, and will raise all of your hacking-related multipliers by:<br><br> " +
|
||||||
|
"Level 1: 4%<br>" +
|
||||||
|
"Level 2: 6%<br>" +
|
||||||
|
"Level 3: 7%");
|
||||||
SourceFiles["SourceFile6"] = new SourceFile(6);
|
SourceFiles["SourceFile6"] = new SourceFile(6);
|
||||||
SourceFiles["SourceFile7"] = new SourceFile(7);
|
SourceFiles["SourceFile7"] = new SourceFile(7);
|
||||||
SourceFiles["SourceFile8"] = new SourceFile(8);
|
SourceFiles["SourceFile8"] = new SourceFile(8);
|
||||||
@ -108,6 +116,17 @@ function applySourceFile(srcFile) {
|
|||||||
case 4: //The Singularity
|
case 4: //The Singularity
|
||||||
//No effects, just gives access to Singularity functions
|
//No effects, just gives access to Singularity functions
|
||||||
break;
|
break;
|
||||||
|
case 5: //Artificial Intelligence
|
||||||
|
var mult = 0;
|
||||||
|
for (var i = 0; i < srcFile.lvl; ++i) {
|
||||||
|
mult += (4 / (Math.pow(2, i)));
|
||||||
|
}
|
||||||
|
var incMult = 1 + (mult / 100);
|
||||||
|
Player.hacking_chance_mult *= incMult;
|
||||||
|
Player.hacking_speed_mult *= incMult;
|
||||||
|
Player.hacking_money_mult *= incMult;
|
||||||
|
Player.hacking_grow_mult *= incMult;
|
||||||
|
break;
|
||||||
case 11: //The Big Crash
|
case 11: //The Big Crash
|
||||||
var mult = 0;
|
var mult = 0;
|
||||||
for (var i = 0; i < srcFile.lvl; ++i) {
|
for (var i = 0; i < srcFile.lvl; ++i) {
|
||||||
|
@ -484,6 +484,11 @@ let Engine = {
|
|||||||
if (Player.sourceFiles.length !== 0) {
|
if (Player.sourceFiles.length !== 0) {
|
||||||
bnText = "<br>Current BitNode: " + Player.bitNodeN;
|
bnText = "<br>Current BitNode: " + Player.bitNodeN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var intText = "";
|
||||||
|
if (Player.intelligence > 0) {
|
||||||
|
intText = 'Intelligence: ' + (Player.intelligence).toLocaleString() + "<br><br><br>";
|
||||||
|
}
|
||||||
Engine.Display.characterInfo.innerHTML =
|
Engine.Display.characterInfo.innerHTML =
|
||||||
('<b>General</b><br><br>' +
|
('<b>General</b><br><br>' +
|
||||||
'Current City: ' + Player.city + '<br><br>' +
|
'Current City: ' + Player.city + '<br><br>' +
|
||||||
@ -502,7 +507,8 @@ let Engine = {
|
|||||||
'Agility: ' + (Player.agility).toLocaleString() +
|
'Agility: ' + (Player.agility).toLocaleString() +
|
||||||
" (" + numeral(Player.agility_exp).format('(0.000a)') + ' experience)<br>' +
|
" (" + numeral(Player.agility_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
'Charisma: ' + (Player.charisma).toLocaleString() +
|
'Charisma: ' + (Player.charisma).toLocaleString() +
|
||||||
" (" + numeral(Player.charisma_exp).format('(0.000a)') + ' experience)<br><br><br>' +
|
" (" + numeral(Player.charisma_exp).format('(0.000a)') + ' experience)<br>' +
|
||||||
|
intText +
|
||||||
'<b>Multipliers</b><br><br>' +
|
'<b>Multipliers</b><br><br>' +
|
||||||
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
|
'Hacking Chance multiplier: ' + formatNumber(Player.hacking_chance_mult * 100, 2) + '%<br>' +
|
||||||
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
|
'Hacking Speed multiplier: ' + formatNumber(Player.hacking_speed_mult * 100, 2) + '%<br>' +
|
||||||
|
Loading…
Reference in New Issue
Block a user