Merge branch 'master' of https://github.com/danielyxie/netburner into bugfixes

This commit is contained in:
danielyxie
2017-09-21 16:30:03 -05:00
38 changed files with 16605 additions and 7087 deletions
+1 -1
View File
@@ -183,6 +183,7 @@ function updateActiveScriptsItems() {
}
document.getElementById("active-scripts-total-prod").innerHTML =
"Total online production rate: $" + formatNumber(total, 2) + " / second";
return total;
}
//Updates the content of the given item in the Active Scripts list
@@ -197,7 +198,6 @@ function updateActiveScriptsItemContent(workerscript) {
itemNameArray.push(workerscript.args[i].toString());
}
var itemName = itemNameArray.join("-");
//var itemName = "active-scripts-" + server.hostname + "-" + workerscript.name;
var itemContent = document.getElementById(itemName + "-content")
//Clear the item
+33 -2
View File
@@ -53,7 +53,27 @@ function initBitNodes() {
"upgrade its level up to a maximum of 3. This Source-File lets you access and use the Singularity " +
"Functions in other BitNodes. Each level of this Source-File will open up more Singularity Functions " +
"that you can use.");
BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "COMING SOON"); //Int
BitNodes["BitNode5"] = new BitNode(5, "Artificial Intelligence", "Posthuman", "They said it couldn't be done. They said the human brain, " +
"along with its consciousness and intelligence, couldn't be replicated. They said the complexity " +
"of the brain results from unpredictable, nonlinear interactions that couldn't be modeled " +
"by 1's and 0's. They were wrong.<br><br>" +
"In this BitNode:<br><br>" +
"The base security level of servers is doubled<br>" +
"The starting money on servers is halved, but the maximum money is doubled<br>" +
"Most methods of earning money now give significantly less<br>" +
"Augmentations are more expensive<br>" +
"Hacking experience gain rates are reduced<br><br>" +
"Destroying this BitNode will give you Source-File 5, or if you already have this Source-File it will " +
"upgrade its level up to a maximum of 3. This Source-File grants you 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. <br><br>" +
"In addition, this Source-File will unlock the getBitNodeMultipliers() Netscript function, " +
"and will also raise all of your hacking-related multipliers by:<br><br>" +
"Level 1: 4%<br>" +
"Level 2: 6%<br>" +
"Level 3: 7%");
BitNodes["BitNode6"] = new BitNode(6, "Hacktocracy", "COMING SOON"); //Healthy Hacknet balancing mechanic
BitNodes["BitNode7"] = new BitNode(7, "Do Androids Dream?", "COMING SOON"); //Build androids for automation
BitNodes["BitNode8"] = new BitNode(8, "Ghost of Wall Street", "COMING SOON"); //Trading only viable strategy
@@ -87,6 +107,7 @@ let BitNodeMultipliers = {
ServerStartingMoney: 1,
ServerGrowthRate: 1,
ServerWeakenRate: 1,
ServerStartingSecurity: 1,
ManualHackMoney: 1,
ScriptHackMoney: 1,
@@ -118,7 +139,7 @@ function initBitNodeMultipliers() {
}
switch (Player.bitNodeN) {
case 1:
case 1: //Source Genesis (every multiplier is 1)
break;
case 2: //Rise of the Underworld
BitNodeMultipliers.ServerMaxMoney = 0.2;
@@ -139,6 +160,16 @@ function initBitNodeMultipliers() {
BitNodeMultipliers.CrimeExpGain = 0.5;
BitNodeMultipliers.FactionWorkRepGain = 0.75;
break;
case 5: //Artificial intelligence
BitNodeMultipliers.ServerMaxMoney = 2;
BitNodeMultipliers.ServerStartingSecurity = 2;
BitNodeMultipliers.ServerStartingMoney = 0.5;
BitNodeMultipliers.ScriptHackMoney = 0.25;
BitNodeMultipliers.HacknetNodeMoney = 0.2;
BitNodeMultipliers.CrimeMoney = 0.5;
BitNodeMultipliers.AugmentationMoneyCost = 2;
BitNodeMultipliers.HackExpGain = 0.5;
break;
case 11: //The Big Crash
BitNodeMultipliers.ServerMaxMoney = 0.1;
BitNodeMultipliers.ServerStartingMoney = 0.25;
+38 -38
View File
@@ -262,58 +262,58 @@ let CompanyPositions = {
//Constructor: CompanyPosition(name, reqHack, reqStr, reqDef, reqDex, reqAgi, reqCha, reqRep, salary)
//Software
SoftwareIntern: new CompanyPosition("Software Engineering Intern", 1, 0, 0, 0, 0, 0, 0, 30),
JuniorDev: new CompanyPosition("Junior Software Engineer", 51, 0, 0, 0, 0, 0, 8000, 72),
SeniorDev: new CompanyPosition("Senior Software Engineer", 251, 0, 0, 0, 0, 51, 40000, 150),
LeadDev: new CompanyPosition("Lead Software Developer", 401, 0, 0, 0, 0, 151, 200000, 450),
SoftwareIntern: new CompanyPosition("Software Engineering Intern", 1, 0, 0, 0, 0, 0, 0, 33),
JuniorDev: new CompanyPosition("Junior Software Engineer", 51, 0, 0, 0, 0, 0, 8000, 80),
SeniorDev: new CompanyPosition("Senior Software Engineer", 251, 0, 0, 0, 0, 51, 40000, 165),
LeadDev: new CompanyPosition("Lead Software Developer", 401, 0, 0, 0, 0, 151, 200000, 500),
//TODO Through darkweb, maybe?
FreelanceDeveloper: new CompanyPosition("Freelance Developer", 0, 0, 0, 0, 0, 0, 0, 0),
SoftwareConsultant: new CompanyPosition("Software Consultant", 51, 0, 0, 0, 0, 0, 0, 60),
SeniorSoftwareConsultant: new CompanyPosition("Senior Software Consultant", 251, 0, 0, 0, 0, 51, 0, 120),
SoftwareConsultant: new CompanyPosition("Software Consultant", 51, 0, 0, 0, 0, 0, 0, 66),
SeniorSoftwareConsultant: new CompanyPosition("Senior Software Consultant", 251, 0, 0, 0, 0, 51, 0, 132),
//IT
ITIntern: new CompanyPosition("IT Intern", 1, 0, 0, 0, 0, 0, 0, 24),
ITAnalyst: new CompanyPosition("IT Analyst", 26, 0, 0, 0, 0, 0, 7000, 60),
ITManager: new CompanyPosition("IT Manager", 151, 0, 0, 0, 0, 51, 35000, 120),
SysAdmin: new CompanyPosition("Systems Administrator", 251, 0, 0, 0, 0, 76, 175000, 375),
SecurityEngineer: new CompanyPosition("Security Engineer", 151, 0, 0, 0, 0, 26, 35000, 110),
NetworkEngineer: new CompanyPosition("Network Engineer", 151, 0, 0, 0, 0, 26, 35000, 110),
NetworkAdministrator: new CompanyPosition("Network Administrator", 251, 0, 0, 0, 0, 76, 175000, 375),
ITIntern: new CompanyPosition("IT Intern", 1, 0, 0, 0, 0, 0, 0, 26),
ITAnalyst: new CompanyPosition("IT Analyst", 26, 0, 0, 0, 0, 0, 7000, 66),
ITManager: new CompanyPosition("IT Manager", 151, 0, 0, 0, 0, 51, 35000, 132),
SysAdmin: new CompanyPosition("Systems Administrator", 251, 0, 0, 0, 0, 76, 175000, 410),
SecurityEngineer: new CompanyPosition("Security Engineer", 151, 0, 0, 0, 0, 26, 35000, 121),
NetworkEngineer: new CompanyPosition("Network Engineer", 151, 0, 0, 0, 0, 26, 35000, 121),
NetworkAdministrator: new CompanyPosition("Network Administrator", 251, 0, 0, 0, 0, 76, 175000, 410),
//Technology management
HeadOfSoftware: new CompanyPosition("Head of Software", 501, 0, 0, 0, 0, 251, 400000, 720),
HeadOfEngineering: new CompanyPosition("Head of Engineering", 501, 0, 0, 0, 0, 251, 800000, 1500),
VicePresident: new CompanyPosition("Vice President of Technology", 601, 0, 0, 0, 0, 401, 1600000, 2100),
CTO: new CompanyPosition("Chief Technology Officer", 751, 0, 0, 0, 0, 501, 3200000, 2400),
HeadOfSoftware: new CompanyPosition("Head of Software", 501, 0, 0, 0, 0, 251, 400000, 800),
HeadOfEngineering: new CompanyPosition("Head of Engineering", 501, 0, 0, 0, 0, 251, 800000, 1650),
VicePresident: new CompanyPosition("Vice President of Technology", 601, 0, 0, 0, 0, 401, 1600000, 2310),
CTO: new CompanyPosition("Chief Technology Officer", 751, 0, 0, 0, 0, 501, 3200000, 2640),
//Business
BusinessIntern: new CompanyPosition("Business Intern", 1, 0, 0, 0, 0, 1, 0, 42),
BusinessAnalyst: new CompanyPosition("Business Analyst", 6, 0, 0, 0, 0, 51, 8000, 90),
BusinessManager: new CompanyPosition("Business Manager", 51, 0, 0, 0, 0, 101, 40000, 180),
OperationsManager: new CompanyPosition("Operations Manager", 51, 0, 0, 0, 0, 226, 200000, 600),
CFO: new CompanyPosition("Chief Financial Officer", 76, 0, 0, 0, 0, 501, 800000, 1800),
CEO: new CompanyPosition("Chief Executive Officer", 101, 0, 0, 0, 0, 751, 3200000, 3600),
BusinessIntern: new CompanyPosition("Business Intern", 1, 0, 0, 0, 0, 1, 0, 46),
BusinessAnalyst: new CompanyPosition("Business Analyst", 6, 0, 0, 0, 0, 51, 8000, 100),
BusinessManager: new CompanyPosition("Business Manager", 51, 0, 0, 0, 0, 101, 40000, 200),
OperationsManager: new CompanyPosition("Operations Manager", 51, 0, 0, 0, 0, 226, 200000, 660),
CFO: new CompanyPosition("Chief Financial Officer", 76, 0, 0, 0, 0, 501, 800000, 1950),
CEO: new CompanyPosition("Chief Executive Officer", 101, 0, 0, 0, 0, 751, 3200000, 3900),
BusinessConsultant: new CompanyPosition("Business Consultant", 6, 0, 0, 0, 0, 51, 0, 80),
SeniorBusinessConsultant: new CompanyPosition("Senior Business Consultant", 51, 0, 0, 0, 0, 226, 0, 480),
BusinessConsultant: new CompanyPosition("Business Consultant", 6, 0, 0, 0, 0, 51, 0, 88),
SeniorBusinessConsultant: new CompanyPosition("Senior Business Consultant", 51, 0, 0, 0, 0, 226, 0, 525),
//Non-tech/management jobs
PartTimeWaiter: new CompanyPosition("Part-time Waiter", 0, 0, 0, 0, 0, 0, 0, 18),
PartTimeEmployee: new CompanyPosition("Part-time Employee", 0, 0, 0, 0, 0, 0, 0, 18),
PartTimeWaiter: new CompanyPosition("Part-time Waiter", 0, 0, 0, 0, 0, 0, 0, 20),
PartTimeEmployee: new CompanyPosition("Part-time Employee", 0, 0, 0, 0, 0, 0, 0, 20),
Waiter: new CompanyPosition("Waiter", 0, 0, 0, 0, 0, 0, 0, 20),
Employee: new CompanyPosition("Employee", 0, 0, 0, 0, 0, 0, 0, 20),
PoliceOfficer: new CompanyPosition("Police Officer", 11, 101, 101, 101, 101, 51, 8000, 75),
PoliceChief: new CompanyPosition("Police Chief", 101, 301, 301, 301, 301, 151, 36000, 425),
SecurityGuard: new CompanyPosition("Security Guard", 0, 51, 51, 51, 51, 1, 0, 45),
SecurityOfficer: new CompanyPosition("Security Officer", 26, 151, 151, 151, 151, 51, 8000, 175),
SecuritySupervisor: new CompanyPosition("Security Supervisor", 26, 251, 251, 251, 251, 101, 36000, 600),
HeadOfSecurity: new CompanyPosition("Head of Security", 51, 501, 501, 501, 501, 151, 144000, 1200),
FieldAgent: new CompanyPosition("Field Agent", 101, 101, 101, 101, 101, 101, 8000, 300),
SecretAgent: new CompanyPosition("Secret Agent", 201, 251, 251, 251, 251, 201, 32000, 900),
SpecialOperative: new CompanyPosition("Special Operative", 251, 501, 501, 501, 501, 251, 162000, 1800),
Waiter: new CompanyPosition("Waiter", 0, 0, 0, 0, 0, 0, 0, 22),
Employee: new CompanyPosition("Employee", 0, 0, 0, 0, 0, 0, 0, 22),
PoliceOfficer: new CompanyPosition("Police Officer", 11, 101, 101, 101, 101, 51, 8000, 82),
PoliceChief: new CompanyPosition("Police Chief", 101, 301, 301, 301, 301, 151, 36000, 460),
SecurityGuard: new CompanyPosition("Security Guard", 0, 51, 51, 51, 51, 1, 0, 50),
SecurityOfficer: new CompanyPosition("Security Officer", 26, 151, 151, 151, 151, 51, 8000, 195),
SecuritySupervisor: new CompanyPosition("Security Supervisor", 26, 251, 251, 251, 251, 101, 36000, 660),
HeadOfSecurity: new CompanyPosition("Head of Security", 51, 501, 501, 501, 501, 151, 144000, 1320),
FieldAgent: new CompanyPosition("Field Agent", 101, 101, 101, 101, 101, 101, 8000, 330),
SecretAgent: new CompanyPosition("Secret Agent", 201, 251, 251, 251, 251, 201, 32000, 990),
SpecialOperative: new CompanyPosition("Special Operative", 251, 501, 501, 501, 501, 251, 162000, 2000),
init: function() {
//Argument order: hack, str, def, dex, agi, cha
+134 -30
View File
@@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.28.1",
Version: "0.29.0",
//Max level for any skill, assuming no multipliers. Determined by max numerical value in javascript for experience
//and the skill level formula in Player.js. Note that all this means it that when experience hits MAX_INT, then
@@ -58,8 +58,9 @@ let CONSTANTS = {
ScriptScpRamCost: 0.5,
ScriptKillRamCost: 0.5, //Kill and killall
ScriptHasRootAccessRamCost: 0.05,
ScriptGetHostnameRamCost: 0.05,
ScriptGetHackingLevelRamCost: 0.05,
ScriptGetHostnameRamCost: 0.05, //getHostname() and getIp()
ScriptGetHackingLevelRamCost: 0.05, //getHackingLevel() and getIntelligence()
ScriptGetMultipliersRamCost: 4.0, //getHackingMultipliers() and getBitNodeMultipliers()
ScriptGetServerCost: 0.1,
ScriptFileExistsRamCost: 0.1,
ScriptIsRunningRamCost: 0.1,
@@ -86,9 +87,9 @@ let CONSTANTS = {
//Server constants
ServerBaseGrowthRate: 1.03, //Unadjusted Growth rate
ServerMaxGrowthRate: 1.0035, //Maximum possible growth rate (max rate accounting for server security)
ServerMaxGrowthRate: 1.0035, //Maximum possible growth rate (max rate accounting for server security)
ServerFortifyAmount: 0.002, //Amount by which server's security increases when its hacked/grown
ServerWeakenAmount: 0.05, //Amount by which server's security decreases when weakened
ServerWeakenAmount: 0.05, //Amount by which server's security decreases when weakened
PurchasedServerLimit: 25,
@@ -112,6 +113,18 @@ let CONSTANTS = {
//Hospital/Health
HospitalCostPerHp: 100000,
//Intelligence-related constants
IntelligenceCrimeWeight: 0.05, //Weight for how much int affects crime success rates
IntelligenceInfiltrationWeight: 0.1, //Weight for how much int affects infiltration success rates
IntelligenceCrimeBaseExpGain: 0.0002,
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
IntelligenceSingFnBaseExpGain: 0.0005,
//Hacking Missions
HackingMissionRepToDiffConversion: 5000, //Faction rep is divided by this to get mission difficulty
HackingMissionRepToRewardConversion: 20, //Faction rep divided byt his to get mission rep reward
//Gang constants
GangRespectToReputationRatio: 2, //Respect is divided by this to get rep gain
MaximumGangMembers: 20,
@@ -231,8 +244,10 @@ let CONSTANTS = {
"encounter diminishing returns in your hacking (since you are only hacking a certain percentage). You can " +
"increase the amount of money on a server using a script and the grow() function in Netscript.<br><br>" +
"<h1>Server Security</h1><br>" +
"Each server has a security level, which is denoted by a number between 1 and 100. A higher number means " +
"the server has stronger security. As mentioned above, a server's security level is an important factor " +
"Each server has a security level, typically between 1 and 100. A higher number means the server has stronger security. " +
"It is possible for a server to have a security level of 100 or higher, in which case hacking that server " +
"will become impossible (0% chance to hack).<br><br>" +
"As mentioned above, a server's security level is an important factor " +
"to consider when hacking. You can check a server's security level using the 'analyze' command, although this " +
"only gives an estimate (with 5% uncertainty). You can also check a server's security in a script, using the " +
"<i>getServerSecurityLevel(server)</i> function in Netscript. See the Netscript documentation for more details. " +
@@ -396,10 +411,13 @@ let CONSTANTS = {
"there is no required hacking level to run the command. Returns " +
"0.1. Works offline at a slower rate<br> Example: weaken('foodnstuff');<br><br>" +
"<i>print(x)</i><br>Prints a value or a variable to the scripts logs (which can be viewed with the 'tail [script]' terminal command ). <br><br>" +
"<i>tprint(x)</i><br>Prints a value or a variable to the Terminal<br><br>" +
"<i>tprint(x)</i><br>Prints a value or a variable to the Terminal<br><br>" +
"<i>clearLog()</i><br>Clears the script's logs. <br><br>" +
"<i>scan(hostname/ip)</i><br>Returns an array containing the hostnames of all servers that are one node away from the specified server. " +
"The argument must be a string containing the IP or hostname of the target server. The hostnames in the returned array are strings.<br><br>" +
"<i>scan(hostname/ip, [hostnames=true])</i><br>Returns an array containing the hostnames or IPs of all servers that are one node away from the specified server. " +
"The argument must be a string containing the IP or hostname of the target server. The second argument is a boolean that specifies whether " +
"the hostnames or IPs of the scanned servers should be output. If it is true then hostnames will be returned, and if false then IP addresses will. " +
"This second argument is optional and, if ommitted, the function will output " +
"the hostnames of the scanned servers. The hostnames/IPs in the returned array are strings.<br><br>" +
"<i>nuke(hostname/ip)</i><br>Run NUKE.exe on the target server. NUKE.exe must exist on your home computer. Does NOT work while offline <br> Example: nuke('foodnstuff'); <br><br>" +
"<i>brutessh(hostname/ip)</i><br>Run BruteSSH.exe on the target server. BruteSSH.exe must exist on your home computer. Does NOT work while offline <br> Example: brutessh('foodnstuff');<br><br>" +
"<i>ftpcrack(hostname/ip)</i><br>Run FTPCrack.exe on the target server. FTPCrack.exe must exist on your home computer. Does NOT work while offline <br> Example: ftpcrack('foodnstuff');<br><br>" +
@@ -449,14 +467,66 @@ let CONSTANTS = {
"kill('foo.script', getHostname(), 1, 'foodnstuff');<br><br>" +
"<i>killall(hostname/ip)</i><br> Kills all running scripts on the specified server. This function takes a single argument which " +
"must be a string containing the hostname or IP of the target server. This function will always return true. <br><br>" +
"<i>scp(script, hostname/ip)</i><br>Copies a script to another server. The first argument is a string with the filename of the script " +
"to be copied. The second argument is a string with the hostname or IP of the destination server. Returns true if the script is successfully " +
"copied over and false otherwise. <br> Example: scp('hack-template.script', 'foodnstuff');<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 " +
"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. " +
"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 " +
"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>" +
"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>" +
"<i>ls(hostname/ip)</i><br>Returns an array containing the names of all files on the specified server. The argument must be a " +
"string with the hostname or IP of the target server.<br><br>" +
"<i>hasRootAccess(hostname/ip)</i><br> Returns a boolean (true or false) indicating whether or not the Player has root access to a server. " +
"The argument passed in must be a string with either the hostname or IP of the target server. Does NOT work while offline.<br> " +
"Example:<br>if (hasRootAccess('foodnstuff') == false) {<br>&nbsp;&nbsp;&nbsp;&nbsp;nuke('foodnstuff');<br>}<br><br>" +
"<i>getIp()</i><br>Returns a string with the IP Address of the server that the script is running on <br><br>" +
"<i>getHostname()</i><br>Returns a string with the hostname of the server that the script is running on<br><br>" +
"<i>getHackingLevel()</i><br> Returns the Player's current hacking level. Does NOT work while offline <br><br> " +
"<i>getHackingLevel()</i><br>Returns the Player's current hacking level. Does NOT work while offline<br><br> " +
"<i>getIntelligence()</i><br>Returns the Player's current intelligence level. Requires Source-File 5 to run<br><br>" +
"<i>getHackingMultipliers()</i><br>Returns an object containing the Player's hacking related multipliers. " +
"These multipliers are returned in integer forms, not percentages (e.g. 1.5 instead of 150%). " +
"The object has the following structure:<br><br>" +
"{<br>" +
"chance: Player's hacking chance multiplier<br>" +
"speed: Player's hacking speed multiplier<br>" +
"money: Player's hacking money stolen multiplier<br>" +
"growth: Player's hacking growth multiplier<br>" +
"}<br><br>Example:<br><br>" +
"mults = getHackingMultipliers();<br>" +
"print(mults.chance);<br>" +
"print(mults.growth);<br><br>" +
"<i>getBitNodeMultipliers()</i><br>Returns an object containing the current BitNode multipliers. " +
"This function requires Source-File 5 in order to run. The multipliers are returned in integer forms, not percentages " +
"(e.g. 1.5 instead of 150%). The multipliers represent the difference between the current BitNode and the " +
"original BitNode (BitNode-1). For example, if the 'CrimeMoney' multiplier has a value of 0.1 then that means " +
"that committing crimes in the current BitNode will only give 10% of the money you would have received in " +
"BitNode-1. The object has the following structure (subject to change in the future):<br><br>" +
"{<br>" +
"ServerMaxMoney: 1,<br>" +
"ServerStartingMoney: 1,<br>" +
"ServerGrowthRate: 1,<br>" +
"ServerWeakenRate: 1,<br>" +
"ServerStartingSecurity: 1,<br>" +
"ManualHackMoney: 1,<br>" +
"ScriptHackMoney: 1,<br>" +
"CompanyWorkMoney: 1,<br>" +
"CrimeMoney: 1,<br>" +
"HacknetNodeMoney: 1,<br>" +
"CompanyWorkExpGain: 1,<br>" +
"ClassGymExpGain: 1,<br>" +
"FactionWorkExpGain: 1,<br>" +
"HackExpGain: 1,<br>" +
"CrimeExpGain: 1,<br>" +
"FactionWorkRepGain: 1,<br>" +
"FactionPassiveRepGain: 1,<br>" +
"AugmentationRepCost: 1,<br>" +
"AugmentationMoneyCost: 1,<br>" +
"}<br><br>Example:<br><br>" +
"mults = getBitNodeMultipliers();<br>" +
"print(mults.ServerMaxMoney);<br>" +
"print(mults.HackExpGain);<br><br>" +
"<i>getServerMoneyAvailable(hostname/ip)</i><br> Returns the amount of money available on a server. The argument passed in must be a string with either the " +
"hostname or IP of the target server. Does NOT work while offline <br> Example: getServerMoneyAvailable('foodnstuff');<br><br>" +
"<i>getServerMaxMoney(hostname/ip)</i><br>Returns the maximum amount of money that can be available on a server. The argument passed in must be a string with " +
@@ -479,6 +549,8 @@ let CONSTANTS = {
"<i>getServerRam(hostname/ip)</i><br>Returns an array with two elements that gives information about the target server's RAM. The first " +
"element in the array is the amount of RAM that the server has (in GB). The second element in the array is the amount of RAM that " +
"is currently being used on the server.<br><br>" +
"<i>serverExists(hostname/ip)</i><br>Returns a boolean denoting whether or not the specified server exists. The argument " +
"must be a string with the hostname or IP of the target server.<br><br>" +
"<i>fileExists(filename, [hostname/ip])</i><br> Returns a boolean (true or false) indicating whether the specified file exists on a server. " +
"The first argument must be a string with the name of the file. A file can either be a script or a program. A script name is case-sensitive, but a " +
"program is not. For example, fileExists('brutessh.exe') will work fine, even though the actual program is named BruteSSH.exe. <br><br> " +
@@ -508,9 +580,10 @@ let CONSTANTS = {
"but it will be converted to a string using Javascript's String function. Anything that resolves to an empty string will cause the function to fail. " +
"The second argument specified the amount of RAM (in GB) for the server. This argument must resolve to a numeric and it must be a power of 2 " +
"(2, 4, 8, etc...). <br><br>" +
"Purchasing a server using this Netscript function is twice as expensive as manually purchasing a server from a location in the World.<br><br>" +
"This function returns the hostname of the newly purchased server as a string. If the function fails to purchase a server, then it will return " +
"an empty string. The function will fail if the arguments passed in are invalid or if the player does not have enough money to purchase the specified server.<br><br>" +
"<i>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>" +
"<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 " +
"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>" +
@@ -534,21 +607,46 @@ 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>" +
"<i>getWeakenTime(hostname/ip)</i><br>Returns the amount of time in seconds it takes to execute the weaken() Netscript function " +
"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>" +
"Returns the amount of income the specified script generates while online (when the game is open, does not apply for " +
"offline income). This function can also return the total income of all of your active scripts by running the function " +
"with no arguments.<br><br>" +
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
"with the arguments 'foodnstuff' and '5' then in order to use this function to get that script's income you must " +
"specify those arguments in this function call.<br><br>" +
"The first argument, if specified, must be a string with the name of the script (including the .script extension). " +
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.<br><br>" +
"<i>getScriptExpGain([scriptname], [hostname/ip], [args...])</i><br>" +
"Returns the amount of hacking experience the specified script generates while online (when the game is open, does not apply for " +
"offline experience gains). This function can also return the total experience gain rate of all of your active scripts by running the function " +
"with no arguments.<br><br>" +
"Remember that a script is uniquely identified by both its name and its arguments. So for example if you ran a script " +
"with the arguments 'foodnstuff' and '5' then in order to use this function to get that script's income you must " +
"specify those arguments in this function call.<br><br>" +
"The first argument, if specified, must be a string with the name of the script (including the .script extension). " +
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.<br><br>" +
"<u><h1>Hacknet Nodes API</h1></u><br>" +
"Netscript provides the following API for accessing and upgrading your Hacknet Nodes through scripts. This API does NOT work offline.<br><br>" +
"<i>hacknetnodes</i><br> A special variable. This is an array that maps to the Player's Hacknet Nodes. The Hacknet Nodes are accessed through " +
"indexes. These indexes correspond to the number at the end of the name of the Hacknet Node. For example, the first Hacknet Node you purchase " +
"will have the same 'hacknet-node-0' and can be accessed with hacknetnodes[0]. The fourth Hacknet Node you purchase will have the name " +
"'hacknet-node-3' and can be accessed with hacknetnodes[3]. <br><br>" +
"<i>hacknetnodes.length</i><br> Returns the number of Hacknet Nodes that the player owns<br><br>" +
"<i>hacknetnodes[i].level</i><br> Returns the level of the corresponding Hacknet Node<br><br>" +
"<i>hacknetnodes[i].ram</i><br> Returns the amount of RAM on the corresponding Hacknet Node<br><br>" +
"<i>hacknetnodes[i].cores</i><br> Returns the number of cores on the corresponding Hacknet Node<br><br>" +
"<i>hacknetnodes[i].upgradeLevel(n)</i><br> Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " +
"<i>hacknetnodes.length</i><br>Returns the number of Hacknet Nodes that the player owns<br><br>" +
"<i>hacknetnodes[i].level</i><br>Returns the level of the corresponding Hacknet Node<br><br>" +
"<i>hacknetnodes[i].ram</i><br>Returns the amount of RAM on the corresponding Hacknet Node<br><br>" +
"<i>hacknetnodes[i].cores</i><br>Returns the number of cores on the corresponding Hacknet Node<br><br>" +
"<i>hacknetnodes[i].totalMoneyGenerated</i><br>Returns the total amount of money that the corresponding Hacknet Node has earned<br><br>" +
"<i>hacknetnodes[i].onlineTimeSeconds</i><br>Returns the total amount of time that the corresponding Hacknet Node has existed<br><br>" +
"<i>hacknetnodes[i].moneyGainRatePerSecond</i><br>Returns the income ($ / sec) that the corresponding Hacknet Node earns<br><br>" +
"<i>hacknetnodes[i].upgradeLevel(n)</i><br>Tries to upgrade the level of the corresponding Hacknet Node n times. The argument n must be a " +
"positive integer. Returns true if the Hacknet Node's level is successfully upgraded n times or up to the max level (200), and false otherwise.<br><br>" +
"<i>hacknetnodes[i].upgradeRam()</i><br> Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
"<i>hacknetnodes[i].upgradeRam()</i><br>Tries to upgrade the amount of RAM on the corresponding Hacknet Node. Returns true if the " +
"RAM is successfully upgraded, and false otherwise. <br><br>" +
"<i>hacknetnodes[i].upgradeCore()</i><br> Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
"<i>hacknetnodes[i].upgradeCore()</i><br>Attempts to purchase an additional core for the corresponding Hacknet Node. Returns true if the " +
"additional core is successfully purchase, and false otherwise. <br><br>" +
"Example: The following is an example of one way a script can be used to automate the purchasing and upgrading of Hacknet Nodes. " +
"This script purchases new Hacknet Nodes until the player has four. Then, it iteratively upgrades each of those four Hacknet Nodes " +
@@ -859,14 +957,20 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.28.1<br>" +
"-The script editor now uses the open-source Ace editor, which provides a much better experience when coding!<br>" +
"-Added tprint() Netscript function<br><br>" +
"v0.28.0<br>" +
"-Added BitNode-4: The Singularity<br>" +
"-Added BitNode-11: The Big Crash<br>" +
"-Migrated the codebase to use webpack (doesn't affect any in game content, except maybe some slight " +
"performance improvements and there may be bugs that result from dependency errors)"
"v0.29.0<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};
+6 -1
View File
@@ -134,7 +134,12 @@ function getNumAvailableCreateProgram() {
if (!Player.hasProgram(Programs.AutoLink) && Player.hacking_skill >= 25) {
++count;
}
if (count > 0) {Player.firstProgramAvailable = true;}
if (Player.firstProgramAvailable === false && count > 0) {
Player.firstProgramAvailable = true;
document.getElementById("create-program-tab").style.display = "list-item";
document.getElementById("hacking-menu-header").click();
document.getElementById("hacking-menu-header").click();
}
return count;
}
+56 -42
View File
@@ -110,99 +110,113 @@ function determineCrimeSuccess(crime, moneyGained) {
}
}
let intWgt = CONSTANTS.IntelligenceCrimeWeight;
let maxLvl = CONSTANTS.MaxSkillLevel;
function determineCrimeChanceShoplift() {
var chance = ((Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel)) * 20;
var chance = (Player.dexterity / maxLvl +
Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) * 20;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceRobStore() {
var chance = ((0.5 * Player.hacking_skill / CONSTANTS.MaxSkillLevel +
2 * Player.dexterity / CONSTANTS.MaxSkillLevel +
1 * Player.agility / CONSTANTS.MaxSkillLevel)) * 5;
var chance = (0.5 * Player.hacking_skill / maxLvl +
2 * Player.dexterity / maxLvl +
1 * Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) * 5;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceMug() {
var chance = ((1.5 * Player.strength / CONSTANTS.MaxSkillLevel +
0.5 * Player.defense / CONSTANTS.MaxSkillLevel +
1.5 * Player.dexterity / CONSTANTS.MaxSkillLevel +
0.5 * Player.agility / CONSTANTS.MaxSkillLevel)) * 5;
var chance = (1.5 * Player.strength / maxLvl +
0.5 * Player.defense / maxLvl +
1.5 * Player.dexterity / maxLvl +
0.5 * Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) * 5;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceLarceny() {
var chance = ((0.5 * Player.hacking_skill / CONSTANTS.MaxSkillLevel +
Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel)) * 3;
var chance = (0.5 * Player.hacking_skill / maxLvl +
Player.dexterity / maxLvl +
Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) * 3;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceDealDrugs() {
var chance = ((3*Player.charisma / CONSTANTS.MaxSkillLevel +
2*Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel));
var chance = (3*Player.charisma / maxLvl +
2*Player.dexterity / maxLvl +
Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl);
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceTraffickArms() {
var chance = ((Player.charisma / CONSTANTS.MaxSkillLevel +
Player.strength / CONSTANTS.MaxSkillLevel +
Player.defense / CONSTANTS.MaxSkillLevel +
Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel)) / 2;
var chance = (Player.charisma / maxLvl +
Player.strength / maxLvl +
Player.defense / maxLvl +
Player.dexterity / maxLvl +
Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) / 2;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceHomicide() {
var chance = ((2 * Player.strength / CONSTANTS.MaxSkillLevel +
2 * Player.defense / CONSTANTS.MaxSkillLevel +
0.5 * Player.dexterity / CONSTANTS.MaxSkillLevel +
0.5 * Player.agility / CONSTANTS.MaxSkillLevel));
var chance = (2 * Player.strength / maxLvl +
2 * Player.defense / maxLvl +
0.5 * Player.dexterity / maxLvl +
0.5 * Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl);
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceGrandTheftAuto() {
var chance = ((Player.hacking_skill / CONSTANTS.MaxSkillLevel +
Player.strength / CONSTANTS.MaxSkillLevel +
4 * Player.dexterity / CONSTANTS.MaxSkillLevel +
2 * Player.agility / CONSTANTS.MaxSkillLevel +
2 * Player.charisma / CONSTANTS.MaxSkillLevel)) / 8;
var chance = (Player.hacking_skill / maxLvl +
Player.strength / maxLvl +
4 * Player.dexterity / maxLvl +
2 * Player.agility / maxLvl +
2 * Player.charisma / maxLvl +
intWgt * Player.intelligence / maxLvl) / 8;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceKidnap() {
var chance = ((Player.charisma / CONSTANTS.MaxSkillLevel +
Player.strength / CONSTANTS.MaxSkillLevel +
Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel)) / 5;
var chance = (Player.charisma / maxLvl +
Player.strength / maxLvl +
Player.dexterity / maxLvl +
Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) / 5;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceAssassination() {
var chance = ((Player.strength / CONSTANTS.MaxSkillLevel +
2 * Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel)) / 8;
var chance = (Player.strength / maxLvl +
2 * Player.dexterity / maxLvl +
Player.agility / maxLvl +
intWgt * Player.intelligence / maxLvl) / 8;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
function determineCrimeChanceHeist() {
var chance = ((Player.hacking_skill / CONSTANTS.MaxSkillLevel +
Player.strength / CONSTANTS.MaxSkillLevel +
Player.defense / CONSTANTS.MaxSkillLevel +
Player.dexterity / CONSTANTS.MaxSkillLevel +
Player.agility / CONSTANTS.MaxSkillLevel +
Player.charisma / CONSTANTS.MaxSkillLevel)) / 18;
var chance = (Player.hacking_skill / maxLvl +
Player.strength / maxLvl +
Player.defense / maxLvl +
Player.dexterity / maxLvl +
Player.agility / maxLvl +
Player.charisma / maxLvl +
intWgt * Player.intelligence / maxLvl) / 18;
chance *= Player.crime_success_mult;
return Math.min(chance, 1);
}
+1
View File
@@ -3,6 +3,7 @@ import {Player} from "./Player.js";
import {SpecialServerIps} from "./SpecialServerIps.js";
import {post} from "./Terminal.js";
import {isValidIPAddress} from "../utils/IPAddress.js";
import {formatNumber} from "../utils/StringHelperFunctions.js";
+11 -3
View File
@@ -766,7 +766,10 @@ function displayFactionContent(factionName) {
}
function displayFactionAugmentations(factionName) {
document.getElementById("faction-augmentations-page-desc").innerHTML = "Lists all augmentations that are available to purchase from " + factionName;
document.getElementById("faction-augmentations-page-desc").innerHTML =
"Lists all Augmentations that are available to purchase from " + factionName + "<br><br>" +
"Augmentations are powerful upgrades that will enhance your abilities.";
var faction = Factions[factionName];
var augmentationsList = document.getElementById("faction-augmentations-list");
@@ -849,7 +852,7 @@ function purchaseAugmentationBoxCreate(aug, fac) {
yesNoBoxClose();
});
yesNoBoxCreate("<h2>aug.name</h2><br>" +
yesNoBoxCreate("<h2>" + aug.name + "</h2><br>" +
aug.info + "<br><br>" +
"<br>Would you like to purchase the " + aug.name + " Augmentation for $" +
formatNumber(aug.baseCost * fac.augmentationPriceMult, 2) + "?");
@@ -908,7 +911,12 @@ function purchaseAugmentation(aug, fac, sing=false) {
var txt = "You must first install the Bionic Arms augmentation before installing this upgrade";
if (sing) {return txt;} else {dialogBoxCreate(txt);}
} else if (Player.money.gte(aug.baseCost * fac.augmentationPriceMult)) {
Player.firstAugPurchased = true;
if (Player.firstAugPurchased === false) {
Player.firstAugPurchased = true;
document.getElementById("augmentations-tab").style.display = "list-item";
document.getElementById("character-menu-header").click();
document.getElementById("character-menu-header").click();
}
var queuedAugmentation = new PlayerOwnedAugmentation(aug.name);
if (aug.name == AugmentationNames.NeuroFluxGovernor) {
+7 -3
View File
@@ -130,7 +130,7 @@ function processAllGangPowerGains(numCycles=1) {
if (name == playerGangName) {
AllGangs[name].power += Player.gang.calculatePower();
} else {
var gain = Math.random() * 0.01; //TODO Adjust as necessary
var gain = Math.random() * 0.02; //TODO Adjust as necessary
AllGangs[name].power += (gain);
}
}
@@ -235,8 +235,12 @@ Gang.prototype.processGains = function(numCycles=1) {
console.log("ERROR: respectGains is NaN");
}
if (!isNaN(wantedLevelGains)) {
this.wanted += (wantedLevelGains * this.storedCycles);
if (this.wanted < 1) {this.wanted = 1;}
if (this.wanted === 1 && wantedLevelGains < 0) {
//Do nothing
} else {
this.wanted += (wantedLevelGains * this.storedCycles);
if (this.wanted < 1) {this.wanted = 1;}
}
} else {
console.log("ERROR: wantedLevelGains is NaN");
}
+2 -2
View File
@@ -92,7 +92,7 @@ HacknetNode.prototype.getLevelUpgradeCost = function(levels=1) {
HacknetNode.prototype.purchaseLevelUpgrade = function(levels=1) {
var cost = this.calculateLevelUpgradeCost(levels);
if (isNaN(cost)) {return false;}
if (isNaN(cost) || levels < 0) {return false;}
if (this.level + levels > CONSTANTS.HacknetNodeMaxLevel) {
var diff = Math.max(0, CONSTANTS.HacknetNodeMaxLevel - this.level);
return this.purchaseLevelUpgrade(diff);
@@ -442,7 +442,7 @@ function updateHacknetNodeDomElement(nodeObj) {
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
} else {
var upgradeRamCost = nodeObj.calculateRamUpgradeCost();
upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM -$" + formatNumber(upgradeRamCost, 2);
upgradeRamButton.innerHTML = "Upgrade Hacknet Node RAM - $" + formatNumber(upgradeRamCost, 2);
if (Player.money.lt(upgradeRamCost)) {
upgradeRamButton.setAttribute("class", "a-link-button-inactive");
} else {
+5 -3
View File
@@ -24,7 +24,7 @@ let TerminalHelpText =
"rm [file] Delete a file from the server<br>" +
"run [name] [-t] [n] [args...] Execute a program or script<br>" +
"scan Prints all immediately-available network connections<br>" +
"scan-analyze [d] Prints info for all servers up to <i>d</i> nodes away<br>" +
"scan-analyze [d] [-a] Prints info for all servers up to <i>d</i> nodes away<br>" +
"scp [file] [server] Copies a script or .lit file to a destination server<br>" +
"sudov Shows whether you have root access on this computer<br>" +
"tail [script] [args...] Displays dynamic logs for the specified script<br>" +
@@ -153,7 +153,7 @@ let HelpTexts = {
scan: "scan<br>" +
"Prints all immediately-available network connection. This will print a list of all servers that you can currently connect " +
"to using the 'connect' Terminal command.",
"scan-analyze": "scan-analyze [depth]<br>" +
"scan-analyze": "scan-analyze [depth] [-a]<br>" +
"Prints detailed information about all servers up to [depth] nodes away on the network. Calling " +
"'scan-analyze 1' will display information for the same servers that are shown by the 'scan' Terminal " +
"command. This command also shows the relative paths to reach each server.<br><br>" +
@@ -162,7 +162,9 @@ let HelpTexts = {
"5 and 10, respectively.<br><br>" +
"The information 'scan-analyze' displays about each server includes whether or not you have root access to it, " +
"its required hacking level, the number of open ports required to run NUKE.exe on it, and how much RAM " +
"it has",
"it has.<br><br>" +
"By default, this command will not display servers that you have purchased. However, you can pass in the " +
"-a flag at the end of the command if you would like to enable that.",
scp: "scp [filename] [target server]<br>" +
"Copies the specified file from the current server to the target server. " +
"This command only works for script files (.script extension) and literature files (.lit extension). " +
+14 -7
View File
@@ -441,7 +441,7 @@ function updateInfiltrationLevelText(inst) {
var totalValue = 0;
var totalMoneyValue = 0;
for (var i = 0; i < inst.secretsStolen.length; ++i) {
totalValue += inst.secretsStolen[i];
totalValue += (inst.secretsStolen[i] * Player.faction_rep_mult * 1.25);
totalMoneyValue += inst.secretsStolen[i] * CONSTANTS.InfiltrationMoneyValue;
}
document.getElementById("infiltration-level-text").innerHTML =
@@ -577,6 +577,7 @@ function updateInfiltrationButtons(inst, scenario) {
}
}
let intWgt = CONSTANTS.IntelligenceInfiltrationWeight;
//Kill
//Success: 5%, Failure 10%, -Karma
@@ -649,7 +650,8 @@ function getInfiltrationStealthKnockoutChance(inst) {
return Math.min(0.95,
(0.5 * Player.strength +
2 * Player.dexterity +
2 * Player.agility) / (3 * lvl));
2 * Player.agility +
intWgt * Player.intelligence) / (3 * lvl));
}
//Assassination
@@ -671,7 +673,8 @@ function getInfiltrationAssassinateChance(inst) {
var lvl = inst.securityLevel;
return Math.min(0.95,
(Player.dexterity +
0.5 * Player.agility) / (2 * lvl));
0.5 * Player.agility +
intWgt * Player.intelligence) / (2 * lvl));
}
@@ -720,7 +723,8 @@ function attemptInfiltrationHack(inst) {
function getInfiltrationHackChance(inst) {
var lvl = inst.securityLevel;
return Math.min(0.95,
(Player.hacking_skill) / lvl);
(Player.hacking_skill +
(intWgt * Player.intelligence)) / lvl);
}
//Sneak past security
@@ -740,7 +744,8 @@ function getInfiltrationSneakChance(inst) {
var lvl = inst.securityLevel;
return Math.min(0.95,
(Player.agility +
0.5 * Player.dexterity) / (2 * lvl));
0.5 * Player.dexterity +
intWgt * Player.intelligence) / (2 * lvl));
}
//Pick locked door
@@ -760,7 +765,8 @@ function attemptInfiltrationPickLockedDoor(inst) {
function getInfiltrationPickLockedDoorChance(inst) {
var lvl = inst.securityLevel;
return Math.min(0.95,
(Player.dexterity) / lvl);
(Player.dexterity +
intWgt * Player.intelligence) / lvl);
}
//Bribe
@@ -800,7 +806,8 @@ function getInfiltrationEscapeChance(inst) {
var lvl = inst.securityLevel;
return Math.min(0.95,
(2 * Player.agility +
Player.dexterity) / lvl);
Player.dexterity +
intWgt * Player.intelligence) / lvl);
}
export {beginInfiltration};
+16 -17
View File
@@ -73,7 +73,7 @@ function iTutorialEvaluateStep() {
iTutorialSetText("Welcome to Bitburner, a cyberpunk-themed incremental RPG! " +
"The game takes place in a dark, dystopian future...The year is 2077...<br><br>" +
"This tutorial will show you the basics of the game to help you get started. " +
"This tutorial will show you the basics of the game. " +
"You may skip the tutorial at any time.");
var next = clearEventListeners("interactive-tutorial-next");
next.style.display = "inline-block";
@@ -114,7 +114,7 @@ function iTutorialEvaluateStep() {
break;
case iTutorialSteps.CharacterGoToTerminalPage:
iTutorialSetText("Let's head to your computer's terminal by clicking the 'Terminal' tab on the " +
"main navigation menu");
"main navigation menu.");
//No next button
var next = clearEventListeners("interactive-tutorial-next");
next.style.display = "none";
@@ -132,8 +132,7 @@ function iTutorialEvaluateStep() {
break;
case iTutorialSteps.TerminalIntro:
iTutorialSetText("The Terminal is used to interface with your home computer as well as " +
"all of the other machines around the world. A lot of content in the game is " +
"accessible only through the Terminal, and is necessary for progressing. ");
"all of the other machines around the world.");
var next = clearEventListeners("interactive-tutorial-next");
next.style.display = "inline-block";
next.addEventListener("click", function() {
@@ -149,14 +148,14 @@ function iTutorialEvaluateStep() {
//next step triggered by terminal command
break;
case iTutorialSteps.TerminalLs:
iTutorialSetText("The 'help' command displays a list of all available commands, how to use them, " +
iTutorialSetText("The 'help' command displays a list of all available Terminal commands, how to use them, " +
"and a description of what they do. <br><br>Let's try another command. Enter the 'ls' command");
//next step triggered by terminal command
break;
case iTutorialSteps.TerminalScan:
iTutorialSetText("'ls' is a basic command that shows all of the contents (programs/scripts) " +
"on the computer. Right now, it shows that you have a program called 'NUKE.exe' on your computer. " +
"We'll get to what this does later. <br><br> Through your home computer's terminal, you can connect " +
"We'll get to what this does later. <br><br>Using your home computer's terminal, you can connect " +
"to other machines throughout the world. Let's do that now by first entering " +
"the 'scan' command. ");
//next step triggered by terminal command
@@ -197,7 +196,7 @@ function iTutorialEvaluateStep() {
case iTutorialSteps.TerminalNuke:
iTutorialSetText("When the 'analyze' command finishes running it will show useful information " +
"about hacking the server. <br><br> For this server, the required hacking skill is only 1, " +
"which means you are able to hack it right now. However, in order to hack a server " +
"which means you can hack it right now. However, in order to hack a server " +
"you must first gain root access. The 'NUKE.exe' program that we saw earlier on your " +
"home computer is a virus that will grant you root access to a machine if there are enough " +
"open ports.<br><br> The 'analyze' results shows that there do not need to be any open ports " +
@@ -207,19 +206,19 @@ function iTutorialEvaluateStep() {
break;
case iTutorialSteps.TerminalManualHack:
iTutorialSetText("You now have root access! You can hack the server using the 'hack' command. " +
"Try doing that now. ");
"Try doing that now.");
//next step triggered by terminal command
break;
case iTutorialSteps.TerminalHackingMechanics:
iTutorialSetText("You are now attempting to hack the server. Note that performing a hack takes time and " +
"only has a certain percentage chance " +
"of success. This time and success chance is determined by a variety of factors, including " +
"your hacking skill and the server's security level. <br><br>" +
"your hacking skill and the server's security level.<br><br>" +
"If your attempt to hack the server is successful, you will steal a certain percentage " +
"of the server's total money. This percentage is affected by your hacking skill and " +
"the server's security level. <br><br> The amount of money on a server is not limitless. So, if " +
"the server's security level.<br><br>The amount of money on a server is not limitless. So, if " +
"you constantly hack a server and deplete its money, then you will encounter " +
"diminishing returns in your hacking.<br>");
"diminishing returns in your hacking.");
var next = clearEventListeners("interactive-tutorial-next");
next.style.display = "inline-block";
next.addEventListener("click", function() {
@@ -230,7 +229,7 @@ function iTutorialEvaluateStep() {
case iTutorialSteps.TerminalCreateScript:
iTutorialSetText("Hacking is the core mechanic of the game and is necessary for progressing. However, " +
"you don't want to be hacking manually the entire time. You can automate your hacking " +
"by writing scripts! <br><br>To create a new script or edit an existing one, you can use the 'nano' " +
"by writing scripts!<br><br>To create a new script or edit an existing one, you can use the 'nano' " +
"command. Scripts must end with the '.script' extension. Let's make a script now by " +
"entering 'nano foodnstuff.script' after the hack command finishes running (Sidenote: Pressing ctrl + c" +
" will end a command like hack early)");
@@ -249,14 +248,14 @@ function iTutorialEvaluateStep() {
"&nbsp;&nbsp;hack('foodnstuff'); <br>" +
"}<br><br> " +
"For anyone with basic programming experience, this code should be straightforward. " +
"This script will continuously hack the 'foodnstuff' server. <br><br>" +
"This script will continuously hack the 'foodnstuff' server.<br><br>" +
"To save and close the script editor, press the button in the bottom left, or press ctrl + b.");
//next step triggered in saveAndCloseScriptEditor() (Script.js)
break;
case iTutorialSteps.TerminalFree:
iTutorialSetText("Now we'll run the script. Scripts require a certain amount of RAM to run, and can be " +
"run on any machine which you have root access to. Different servers have different " +
"amounts of RAM. You can also purchase more RAM for your home server. <br><br> To check how much " +
"amounts of RAM. You can also purchase more RAM for your home server.<br><br>To check how much " +
"RAM is available on this machine, enter the 'free' command.");
//next step triggered by terminal commmand
break;
@@ -272,8 +271,8 @@ function iTutorialEvaluateStep() {
"runs an infinite loop). <br><br>These scripts can passively earn you income and hacking experience. " +
"Your scripts will also earn money and experience while you are offline, although at a " +
"much slower rate. <br><br> " +
"Let's check out some statistics of our active, running scripts by clicking the " +
"'Active Scripts' link in the main navigation menu. ");
"Let's check out some statistics for our running scripts by clicking the " +
"'Active Scripts' link in the main navigation menu.");
document.getElementById("active-scripts-menu-link").setAttribute("class", "flashing-button");
var activeScriptsMainMenuButton = document.getElementById("active-scripts-menu-link");
activeScriptsMainMenuButton.addEventListener("click", function() {
@@ -342,7 +341,7 @@ function iTutorialEvaluateStep() {
iTutorialSetText("You just purchased a Hacknet Node! This Hacknet Node will passively " +
"earn you money over time, both online and offline. When you get enough " +
" money, you can upgrade " +
"your newly-purchased Hacknet Node below. <br><br>" +
"your newly-purchased Hacknet Node below.<br><br>" +
"Let's go to the 'City' page through the main navigation menu.");
document.getElementById("city-menu-link").setAttribute("class", "flashing-button");
var worldButton = clearEventListeners("city-menu-link");
+45 -39
View File
@@ -120,7 +120,7 @@ function displayLocationContent() {
console.log("displayLocationContent() called with location " + Player.location)
}
var returnToWorld = document.getElementById("location-return-to-world-button");
var returnToWorld = document.getElementById("location-return-to-world-button");
var locationName = document.getElementById("location-name");
@@ -304,7 +304,7 @@ function displayLocationContent() {
//Check if the player is employed at this Location. If he is, display the "Work" button,
//update the job title, etc.
if (loc == Player.companyName) {
if (loc != "" && loc === Player.companyName) {
var company = Companies[loc];
jobTitle.style.display = "block";
@@ -420,7 +420,7 @@ function displayLocationContent() {
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumECorp,
6000, 116, 150, 9.5);
6000, 116, 150, 8.5);
break;
case Locations.AevumBachmanAndAssociates:
@@ -433,7 +433,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumBachmanAndAssociates,
1500, 42, 60, 6.5);
1500, 42, 60, 5.75);
break;
case Locations.AevumClarkeIncorporated:
@@ -446,7 +446,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumClarkeIncorporated,
2400, 34, 75, 6);
2400, 34, 75, 5.4);
break;
case Locations.AevumFulcrumTechnologies:
@@ -465,7 +465,7 @@ function displayLocationContent() {
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumFulcrumTechnologies,
6000, 96, 100, 10);
6000, 96, 100, 9);
break;
case Locations.AevumAeroCorp:
@@ -477,7 +477,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumAeroCorp,
2000, 32, 50, 7);
2000, 32, 50, 6.3);
break;
case Locations.AevumGalacticCybersystems:
@@ -490,7 +490,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumGalacticCybersystems,
1400, 30, 50, 6);
1400, 30, 50, 5.3);
break;
case Locations.AevumWatchdogSecurity:
@@ -504,7 +504,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumWatchdogSecurity,
850, 16, 30, 5);
850, 16, 30, 4.5);
break;
case Locations.AevumRhoConstruction:
@@ -513,7 +513,7 @@ function displayLocationContent() {
softwareJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumRhoConstruction,
600, 12, 20, 3);
600, 12, 20, 2.7);
break;
case Locations.AevumPolice:
@@ -522,7 +522,7 @@ function displayLocationContent() {
softwareJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumPolice,
700, 14, 25, 3.5);
700, 14, 25, 3.2);
break;
case Locations.AevumNetLinkTechnologies:
@@ -540,7 +540,7 @@ function displayLocationContent() {
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.AevumNetLinkTechnologies,
160, 10, 15, 2);
160, 10, 15, 1.8);
break;
case Locations.AevumCrushFitnessGym:
@@ -574,7 +574,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.ChongqingKuaiGongInternational,
5500, 48, 100, 10);
5500, 48, 100, 9);
break;
case Locations.ChongqingSolarisSpaceSystems:
@@ -586,7 +586,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.ChongqingSolarisSpaceSystems,
3600, 26, 75, 9.5);
3600, 26, 75, 8.6);
break;
@@ -615,7 +615,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12MegaCorp,
6000, 114, 125, 11);
6000, 114, 125, 9.8);
break;
case Locations.Sector12BladeIndustries:
@@ -628,7 +628,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12BladeIndustries,
3000, 46, 100, 7.5);
3000, 46, 100, 6.7);
break;
case Locations.Sector12FourSigma:
@@ -641,7 +641,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12FourSigma,
1500, 58, 100, 11.5);
1500, 58, 100, 10.2);
break;
case Locations.Sector12IcarusMicrosystems:
@@ -654,7 +654,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12IcarusMicrosystems,
900, 32, 70, 8.5);
900, 32, 70, 7.8);
break;
case Locations.Sector12UniversalEnergy:
@@ -667,7 +667,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12UniversalEnergy,
775, 24, 50, 7);
775, 24, 50, 6.3);
break;
case Locations.Sector12DeltaOne:
@@ -679,7 +679,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12DeltaOne,
1200, 38, 75, 7);
1200, 38, 75, 6.3);
break;
case Locations.Sector12CIA:
@@ -692,7 +692,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12CIA,
1450, 44, 80, 8.5);
1450, 44, 80, 7.6);
break;
case Locations.Sector12NSA:
@@ -705,7 +705,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12NSA,
1400, 40, 80, 8);
1400, 40, 80, 7.2);
break;
case Locations.Sector12AlphaEnterprises:
@@ -719,7 +719,7 @@ function displayLocationContent() {
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12AlphaEnterprises,
250, 14, 40, 3);
250, 14, 40, 2.7);
break;
case Locations.Sector12CarmichaelSecurity:
@@ -733,7 +733,7 @@ function displayLocationContent() {
securityJob.style.display = "block";
agentJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12CarmichaelSecurity,
500, 18, 60, 3);
500, 18, 60, 2.7);
break;
case Locations.Sector12FoodNStuff:
@@ -749,7 +749,7 @@ function displayLocationContent() {
employeeJob.style.display = "block";
employeePartTimeJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.Sector12JoesGuns,
120, 8, 20, 2.5);
120, 8, 20, 2.2);
break;
case Locations.Sector12IronGym:
@@ -782,7 +782,7 @@ function displayLocationContent() {
securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoDefComm,
1300, 28, 70, 6);
1300, 28, 70, 5.4);
break;
case Locations.NewTokyoVitaLife:
@@ -795,7 +795,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoVitaLife,
750, 22, 100, 5.5);
750, 22, 100, 5);
break;
case Locations.NewTokyoGlobalPharmaceuticals:
@@ -809,7 +809,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.NewTokyoGlobalPharmaceuticals,
900, 24, 80, 6);
900, 24, 80, 5.4);
break;
case Locations.NewTokyoNoodleBar:
@@ -848,7 +848,7 @@ function displayLocationContent() {
purchase256gb.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaStormTechnologies,
700, 24, 100, 6.5);
700, 24, 100, 5.9);
break;
case Locations.IshimaNovaMedical:
@@ -861,7 +861,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
businessJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaNovaMedical,
600, 20, 50, 5);
600, 20, 50, 4.5);
break;
case Locations.IshimaOmegaSoftware:
@@ -879,7 +879,7 @@ function displayLocationContent() {
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.IshimaOmegaSoftware,
200, 10, 40, 2.5);
200, 10, 40, 2.3);
break;
case Locations.VolhavenTravelAgency:
@@ -912,7 +912,7 @@ function displayLocationContent() {
purchase512gb.style.display = "block";
purchase1tb.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenOmniTekIncorporated,
1500, 44, 100, 7);
1500, 44, 100, 6.3);
break;
case Locations.VolhavenNWO:
@@ -925,7 +925,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenNWO,
1800, 56, 200, 8);
1800, 56, 200, 7.2);
break;
case Locations.VolhavenHeliosLabs:
@@ -937,7 +937,7 @@ function displayLocationContent() {
securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenHeliosLabs,
1200, 28, 75, 6);
1200, 28, 75, 5.4);
break;
case Locations.VolhavenOmniaCybersystems:
@@ -949,7 +949,7 @@ function displayLocationContent() {
networkEngineerJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenOmniaCybersystems,
900, 28, 90, 6.5);
900, 28, 90, 5.8);
break;
case Locations.VolhavenLexoCorp:
@@ -963,7 +963,7 @@ function displayLocationContent() {
businessJob.style.display = "block";
securityJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenLexoCorp,
500, 14, 40, 3.5);
500, 14, 40, 3.1);
break;
case Locations.VolhavenSysCoreSecurities:
@@ -974,7 +974,7 @@ function displayLocationContent() {
securityEngineerJob.style.display = "block";
networkEngineerJob.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenSysCoreSecurities,
600, 16, 50, 4);
600, 16, 50, 3.6);
break;
case Locations.VolhavenCompuTek:
@@ -995,7 +995,7 @@ function displayLocationContent() {
purchaseTor.style.display = "block";
purchaseHomeRam.style.display = "block";
setInfiltrateButton(infiltrate, Locations.VolhavenCompuTek,
300, 12, 35, 3.5);
300, 12, 35, 3.1);
break;
case Locations.VolhavenMilleniumFitnessGym:
@@ -1840,7 +1840,13 @@ function initLocationButtons() {
}
function travelToCity(destCityName, cost) {
Player.firstTimeTraveled = true;
if (Player.firstTimeTraveled === false) {
Player.firstTimeTraveled = true;
document.getElementById("travel-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
if (Player.money.lt(cost)) {
dialogBoxCreate("You cannot afford to travel to " + destCityName);
return;
+18 -15
View File
@@ -4,7 +4,7 @@ import {Programs} from "./CreateProgram.js";
import {Player} from "./Player.js";
import {GetServerByHostname} from "./Server.js";
import {Settings} from "./Settings.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {dialogBoxCreate, dialogBoxOpened} from "../utils/DialogBox.js";
import {Reviver, Generic_toJSON,
Generic_fromJSON} from "../utils/JSONReviver.js";
@@ -27,10 +27,10 @@ Message.fromJSON = function(value) {
Reviver.constructors.Message = Message;
//Sends message to player, including a pop up
function sendMessage(msg) {
function sendMessage(msg, forced=false) {
console.log("sending message: " + msg.filename);
msg.recvd = true;
if (!Settings.SuppressMessages) {
if (forced || !Settings.SuppressMessages) {
showMessage(msg);
}
addMessageToServer(msg, "home");
@@ -50,6 +50,11 @@ function addMessageToServer(msg, serverHostname) {
console.log("WARNING: Did not locate " + serverHostname);
return;
}
for (var i = 0; i < server.messages.length; ++i) {
if (server.messages[i].filename === msg.filename) {
return; //Already exists
}
}
server.messages.push(msg);
}
@@ -60,7 +65,6 @@ function checkForMessagesToSend() {
var jumper2 = Messages[MessageFilenames.Jumper2];
var jumper3 = Messages[MessageFilenames.Jumper3];
var jumper4 = Messages[MessageFilenames.Jumper4];
var jumper5 = Messages[MessageFilenames.Jumper5];
var cybersecTest = Messages[MessageFilenames.CyberSecTest];
var nitesecTest = Messages[MessageFilenames.NiteSecTest];
var bitrunnersTest = Messages[MessageFilenames.BitRunnersTest];
@@ -71,8 +75,13 @@ function checkForMessagesToSend() {
redpillOwned = true;
}
if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
if (redpill && redpillOwned) {
if (!dialogBoxOpened) {
sendMessage(redpill, true);
}
} else if (jumper0 && !jumper0.recvd && Player.hacking_skill >= 25) {
sendMessage(jumper0);
Player.getHomeComputer().programs.push(Programs.Flight);
} else if (jumper1 && !jumper1.recvd && Player.hacking_skill >= 40) {
sendMessage(jumper1);
} else if (cybersecTest && !cybersecTest.recvd && Player.hacking_skill >= 50) {
@@ -87,11 +96,6 @@ function checkForMessagesToSend() {
sendMessage(jumper4);
} else if (bitrunnersTest && !bitrunnersTest.recvd && Player.hacking_skill >= 500) {
sendMessage(bitrunnersTest);
} else if (jumper5 && !jumper5.recvd && Player.hacking_skill >= 1000) {
sendMessage(jumper5);
Player.getHomeComputer().programs.push(Programs.Flight);
} else if (redpill && !redpill.recvd && Player.hacking_skill >= 2000 && redpillOwned) {
sendMessage(redpill);
}
}
@@ -111,7 +115,6 @@ let MessageFilenames = {
Jumper2: "j2.msg",
Jumper3: "j3.msg",
Jumper4: "j4.msg",
Jumper5: "j5.msg",
CyberSecTest: "csec-test.msg",
NiteSecTest: "nitesec-test.msg",
BitRunnersTest: "19dfj3l1nd.msg",
@@ -127,7 +130,10 @@ function initMessages() {
"I know you can sense it. I know you're searching for it. " +
"It's why you spend night after " +
"night at your computer. <br><br>It's real, I've seen it. And I can " +
"help you find it. But not right now. You're not ready yet.<br><br>-jump3R"));
"help you find it. But not right now. You're not ready yet.<br><br>" +
"Use this program to track your progress<br><br>" +
"The fl1ght.exe program was added to your home computer<br><br>" +
"-jump3R"));
AddToAllMessages(new Message(MessageFilenames.Jumper1,
"Soon you will be contacted by a hacking group known as CyberSec. " +
"They can help you with your search. <br><br>" +
@@ -148,9 +154,6 @@ function initMessages() {
"To find what you are searching for, you must understand the bits. " +
"The bits are all around us. The runners will help you.<br><br>" +
"-jump3R"));
AddToAllMessages(new Message(MessageFilenames.Jumper5,
"Build your wings and fly<br><br>-jump3R<br><br> " +
"The fl1ght.exe program was added to your home computer"));
//Messages from hacking factions
AddToAllMessages(new Message(MessageFilenames.CyberSecTest,
+25 -1
View File
@@ -50,6 +50,30 @@ Environment.prototype = {
return (scope || this).vars[name] = value;
},
setArrayElement: function(name, idx, value) {
if (!(idx instanceof Array)) {
throw new Error("idx parameter is not an Array");
}
var scope = this.lookup(name);
if (!scope && this.parent) {
console.log("Here");
throw new Error("Undefined variable " + name);
}
var arr = (scope || this).vars[name];
if (!(arr.constructor === Array || arr instanceof Array)) {
throw new Error("Variable is not an array: " + name);
}
var res = arr;
for (var iterator = 0; iterator < idx.length-1; ++iterator) {
var i = idx[iterator];
if (!(res instanceof Array) || i >= res.length) {
throw new Error("Out-of-bounds array access");
}
res = res[i];
}
return res[idx[idx.length-1]] = value;
},
/*
setArrayElement: function(name, idx, value) {
var scope = this.lookup(name);
if (!scope && this.parent) {
@@ -61,7 +85,7 @@ Environment.prototype = {
throw new Error("Variable is not an array: " + name);
}
return (scope || this).vars[name][idx] = value;
},
},*/
//Creates (or overwrites) a variable in the current scope
def: function(name, value) {
+92 -20
View File
@@ -13,11 +13,10 @@ import {isValidIPAddress} from "../utils/IPAddress.js";
import {isString} from "../utils/StringHelperFunctions.js";
/* Evaluator
* Evaluates the Abstract Syntax Tree for Netscript
* generated by the Parser class
* Evaluates/Interprets the Abstract Syntax Tree generated by Acorns parser
*
* Returns a promise
*/
// Evaluator should return a Promise, so that any call to evaluate() can just
//wait for that promise to finish before continuing
function evaluate(exp, workerScript) {
return new Promise(function(resolve, reject) {
var env = workerScript.env;
@@ -179,7 +178,7 @@ function evaluate(exp, workerScript) {
env.set(exp.argument.name,env.get(exp.argument.name)-1);
break;
default:
reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". This is a bug please report to game developer"));
reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". You are trying to use code that is currently unsupported"));
}
if (env.prefix){
return;
@@ -196,11 +195,11 @@ function evaluate(exp, workerScript) {
resolve(false);
break;
case "ReturnStatement":
reject(makeRuntimeRejectMsg(workerScript, "Not implemented ReturnStatement"));
var lineNum = getErrorLineNumber(exp, workerScript);
reject(makeRuntimeRejectMsg(workerScript, "Return statements are not yet implemented in Netscript (line " + (lineNum+1) + ")"));
break;
case "BreakStatement":
reject("BREAKSTATEMENT");
//reject(makeRuntimeRejectMsg(workerScript, "Not implemented BreakStatement"));
break;
case "IfStatement":
evaluateIf(exp, workerScript).then(function(forLoopRes) {
@@ -210,7 +209,8 @@ function evaluate(exp, workerScript) {
});
break;
case "SwitchStatement":
reject(makeRuntimeRejectMsg(workerScript, "Not implemented SwitchStatement"));
var lineNum = getErrorLineNumber(exp, workerScript);
reject(makeRuntimeRejectMsg(workerScript, "Switch statements are not yet implemented in Netscript (line " + (lineNum+1) + ")"));
break;e
case "WhileStatement":
evaluateWhile(exp, workerScript).then(function(forLoopRes) {
@@ -239,7 +239,8 @@ function evaluate(exp, workerScript) {
});
break;
default:
reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + ". This is a bug please report to game developer"));
var lineNum = getErrorLineNumber(exp, workerScript);
reject(makeRuntimeRejectMsg(workerScript, "Unrecognized token: " + exp.type + " (line " + (lineNum+1) + "). This is currently unsupported in Netscript"));
break;
} //End switch
}, Settings.CodeInstructionRunTime); //End setTimeout, the Netscript operation run time
@@ -251,6 +252,12 @@ function evalBinary(exp, workerScript){
return new Promise(function(resolve, reject) {
var expLeftPromise = evaluate(exp.left, workerScript);
expLeftPromise.then(function(expLeft) {
if (expLeft == true && exp.operator === "||") {
return resolve(true);
}
if (expLeft == false && exp.operator === "&&") {
return resolve(false);
}
var expRightPromise = evaluate(exp.right, workerScript);
expRightPromise.then(function(expRight) {
switch (exp.operator){
@@ -306,7 +313,7 @@ function evalBinary(exp, workerScript){
resolve(expLeft && expRight);
break;
default:
reject(makeRuntimeRejectMsg(workerScript, "Bitwise operators are not implemented"));
reject(makeRuntimeRejectMsg(workerScript, "Unsupported operator: " + exp.operator));
}
}, function(e) {
reject(e);
@@ -340,6 +347,40 @@ function evalUnary(exp, workerScript){
});
}
//Takes in a MemberExpression that should represent a Netscript array (possible multidimensional)
//The return value is an array of the form:
// [0th index (leftmost), array name, 1st index, 2nd index, ...]
function getArrayElement(exp, workerScript) {
return new Promise(function(resolve, reject) {
var indices = [];
var iPromise = evaluate(exp.property, workerScript);
iPromise.then(function(idx) {
if (isNaN(idx)) {
return reject(makeRuntimeRejectMsg(workerScript, "Invalid access to array. Index is not a number: " + idx));
} else {
if (exp.object.name === undefined && exp.object.object) {
var recursePromise = getArrayElement(exp.object, workerScript);
recursePromise.then(function(res) {
res.push(idx);
indices = res;
return resolve(indices);
}).catch(function(e) {
return reject(e);
});
} else {
indices.push(idx);
indices.push(exp.object.name);
return resolve(indices);
}
}
}).catch(function(e) {
console.log(e);
console.log("Error getting index in getArrayElement: " + e.toString());
return reject(e);
});
});
}
function evalAssignment(exp, workerScript) {
var env = workerScript.env;
return new Promise(function(resolve, reject) {
@@ -359,6 +400,22 @@ function evalAssignment(exp, workerScript) {
//Assign to array element
//Array object designed by exp.left.object.name
//Index designated by exp.left.property
var getArrayElementPromise = getArrayElement(exp.left, workerScript);
getArrayElementPromise.then(function(res) {
if (!(res instanceof Array) || res.length < 2) {
return reject(makeRuntimeRejectMsg(workerScript, "Error evaluating array assignment. This is (probably) a bug please report to game dev"));
}
//The array name is the second value
var arrName = res.splice(1, 1);
arrName = arrName[0];
env.setArrayElement(arrName, res, expRight);
return resolve(false);
}).catch(function(e) {
return reject(e);
});
/*
var name = exp.left.object.name;
if (!(name in env.vars)){
reject(makeRuntimeRejectMsg(workerScript, "variable " + name + " not defined"));
@@ -379,7 +436,7 @@ function evalAssignment(exp, workerScript) {
});
} else {
return reject(makeRuntimeRejectMsg(workerScript, "Trying to access a non-array variable using the [] operator"));
}
}*/
} else {
//Other assignments
try {
@@ -405,19 +462,18 @@ function evalAssignment(exp, workerScript) {
default:
reject(makeRuntimeRejectMsg(workerScript, "Bitwise assignment is not implemented"));
}
resolve(false);
} catch (e) {
return reject(makeRuntimeRejectMsg(workerScript, "Failed to set environment variable: " + e.toString()));
}
}
resolve(false); //Return false so this doesnt cause conditionals to evaluate
//resolve(false); //Return false so this doesnt cause conditionals to evaluate
}, function(e) {
reject(e);
});
});
}
//Returns true if any of the if statements evaluated, false otherwise. Therefore, the else statement
//should evaluate if this returns false
function evaluateIf(exp, workerScript, i) {
var env = workerScript.env;
return new Promise(function(resolve, reject) {
@@ -566,9 +622,13 @@ function evaluateProg(exp, workerScript, index) {
});
}
function netscriptDelay(time) {
function netscriptDelay(time, workerScript) {
return new Promise(function(resolve) {
setTimeout(resolve, time);
var delay = setTimeout(resolve, time);
workerScript.killTrigger = function() {
clearTimeout(delay);
resolve();
};
});
}
@@ -576,6 +636,7 @@ function makeRuntimeRejectMsg(workerScript, msg) {
return "|"+workerScript.serverIp+"|"+workerScript.name+"|" + msg;
}
/*
function apply_op(op, a, b) {
function num(x) {
if (typeof x != "number")
@@ -604,6 +665,7 @@ function apply_op(op, a, b) {
}
throw new Error("Can't apply operator " + op);
}
*/
//Run a script from inside a script using run() command
function runScriptFromScript(server, scriptname, args, workerScript, threads=1) {
@@ -620,6 +682,7 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
//Check for admin rights and that there is enough RAM availble to run
var script = server.scripts[i];
var ramUsage = script.ramUsage;
threads = Math.round(Number(threads)); //Convert to number and round
ramUsage = ramUsage * threads * Math.pow(CONSTANTS.MultithreadingRAMCost, threads-1);
var ramAvailable = server.maxRam - server.ramUsed;
@@ -644,6 +707,15 @@ function runScriptFromScript(server, scriptname, args, workerScript, threads=1)
return Promise.resolve(false);
}
//Takes in a
function getErrorLineNumber(exp, workerScript) {
var code = workerScript.scriptRef.scriptRef.code;
//Split code up to the start of the node
code = code.substring(0, exp.start);
return (code.match(/\n/g) || []).length;
}
function isScriptErrorMessage(msg) {
if (!isString(msg)) {return false;}
let splitMsg = msg.split("|");
@@ -660,7 +732,7 @@ function isScriptErrorMessage(msg) {
//The same as Player's calculateHackingChance() function but takes in the server as an argument
function scriptCalculateHackingChance(server) {
var difficultyMult = (100 - server.hackDifficulty) / 100;
var skillMult = (1.75 * Player.hacking_skill);
var skillMult = (1.75 * Player.hacking_skill) + (0.2 * Player.intelligence);
var skillChance = (skillMult - server.requiredHackingSkill) / skillMult;
var chance = skillChance * difficultyMult * Player.hacking_chance_mult;
if (chance > 1) {return 1;}
@@ -671,7 +743,7 @@ function scriptCalculateHackingChance(server) {
//The same as Player's calculateHackingTime() function but takes in the server as an argument
function scriptCalculateHackingTime(server) {
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50);
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50 + (0.1 * Player.intelligence));
var hackingTime = 5 * skillFactor / Player.hacking_speed_mult; //This is in seconds
return hackingTime;
}
@@ -697,7 +769,7 @@ function scriptCalculatePercentMoneyHacked(server) {
//Amount of time to execute grow() in milliseconds
function scriptCalculateGrowTime(server) {
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50);
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50 + (0.1 * Player.intelligence));
var growTime = 16 * skillFactor / Player.hacking_speed_mult; //This is in seconds
return growTime * 1000;
}
@@ -705,7 +777,7 @@ function scriptCalculateGrowTime(server) {
//Amount of time to execute weaken() in milliseconds
function scriptCalculateWeakenTime(server) {
var difficultyMult = server.requiredHackingSkill * server.hackDifficulty;
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50);
var skillFactor = (2.5 * difficultyMult + 500) / (Player.hacking_skill + 50 + (0.1 * Player.intelligence));
var weakenTime = 20 * skillFactor / Player.hacking_speed_mult; //This is in seconds
return weakenTime * 1000;
}
+276 -35
View File
@@ -1,5 +1,8 @@
import {updateActiveScriptsItems} from "./ActiveScriptsUI.js";
import {Augmentations, Augmentation,
augmentationExists, installAugmentations} from "./Augmentations.js";
augmentationExists, installAugmentations,
AugmentationNames} from "./Augmentations.js";
import {BitNodeMultipliers} from "./BitNode.js";
import {Companies, Company, CompanyPosition,
CompanyPositions, companyExists} from "./Company.js";
import {CONSTANTS} from "./Constants.js";
@@ -11,6 +14,7 @@ import {Factions, Faction, joinFaction,
import {getCostOfNextHacknetNode,
purchaseHacknet} from "./HacknetNode.js";
import {Locations} from "./Location.js";
import {Message, Messages} from "./Message.js";
import {Player} from "./Player.js";
import {Script, findRunningScript, RunningScript} from "./Script.js";
import {Server, getServer, AddToAllServers,
@@ -34,33 +38,46 @@ import {makeRuntimeRejectMsg, netscriptDelay, runScriptFromScript,
import {Environment} from "./NetscriptEnvironment.js";
import Decimal from '../utils/decimal.js';
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {printArray, powerOfTwo} from "../utils/HelperFunctions.js";
import {createRandomIp} from "../utils/IPAddress.js";
import {formatNumber, isString} from "../utils/StringHelperFunctions.js";
import {formatNumber, isString, isHTML} from "../utils/StringHelperFunctions.js";
var hasSingularitySF = false;
var hasAISF = false;
var singularitySFLvl = 1;
//Also used to check for Artificial Intelligence Source File, don't want to change
//name though
function initSingularitySFFlags() {
for (var i = 0; i < Player.sourceFiles.length; ++i) {
if (Player.sourceFiles[i].n === 4) {
hasSingularitySF = true;
singularitySFLvl = Player.sourceFiles[i].lvl;
}
if (Player.sourceFiles[i].n === 5) {
hasAISF = true;
}
}
}
function NetscriptFunctions(workerScript) {
return {
Math : Math,
hacknetnodes : Player.hacknetNodes,
scan : function(ip=workerScript.serverIp){
scan : function(ip=workerScript.serverIp, hostnames=true){
var server = getServer(ip);
if (server == null) {
throw makeRuntimeRejectMsg(workerScript, 'Invalid IP or hostname passed into scan() command');
}
var out = [];
for (var i = 0; i < server.serversOnNetwork.length; i++) {
var entry = server.getServerOnNetwork(i).hostname;
var entry;
if (hostnames) {
entry = server.getServerOnNetwork(i).hostname;
} else {
entry = server.getServerOnNetwork(i).ip;
}
if (entry == null) {
continue;
}
@@ -97,7 +114,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("Attempting to hack " + ip + " in " + hackingTime.toFixed(3) + " seconds (t=" + threads + ")");
//console.log("Hacking " + server.hostname + " after " + hackingTime.toString() + " seconds (t=" + threads + ")");
return netscriptDelay(hackingTime* 1000).then(function() {
return netscriptDelay(hackingTime* 1000, workerScript).then(function() {
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
var hackChance = scriptCalculateHackingChance(server);
var rand = Math.random();
@@ -142,7 +159,7 @@ function NetscriptFunctions(workerScript) {
if (log) {
workerScript.scriptRef.log("Sleeping for " + time + " milliseconds");
}
return netscriptDelay(time).then(function() {
return netscriptDelay(time, workerScript).then(function() {
return Promise.resolve(true);
});
},
@@ -167,7 +184,7 @@ function NetscriptFunctions(workerScript) {
var growTime = scriptCalculateGrowTime(server);
//console.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds")
workerScript.scriptRef.log("Executing grow() on server " + server.hostname + " in " + formatNumber(growTime/1000, 3) + " seconds (t=" + threads + ")");
return netscriptDelay(growTime).then(function() {
return netscriptDelay(growTime, workerScript).then(function() {
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
server.moneyAvailable += (1 * threads); //It can be grown even if it has no money
var growthPercentage = processSingleServerGrowth(server, 450 * threads);
@@ -203,10 +220,9 @@ function NetscriptFunctions(workerScript) {
}
var weakenTime = scriptCalculateWeakenTime(server);
//console.log("Executing weaken() on server " + server.hostname + " in " + formatNumber(weakenTime/1000, 3) + " seconds")
workerScript.scriptRef.log("Executing weaken() on server " + server.hostname + " in " +
formatNumber(weakenTime/1000, 3) + " seconds (t=" + threads + ")");
return netscriptDelay(weakenTime).then(function() {
return netscriptDelay(weakenTime, workerScript).then(function() {
if (workerScript.env.stopFlag) {return Promise.reject(workerScript);}
server.weaken(CONSTANTS.ServerWeakenAmount * threads);
workerScript.scriptRef.recordWeaken(server.ip, threads);
@@ -228,6 +244,14 @@ function NetscriptFunctions(workerScript) {
if (args === undefined || args === null) {
throw makeRuntimeRejectMsg(workerScript, "tprint() call has incorrect number of arguments. Takes 1 argument");
}
var x = args.toString();
if (isHTML(x)) {
Player.takeDamage(1);
dialogBoxCreate("You suddenly feel a sharp shooting pain through your body as an angry voice in your head exclaims: <br><br>" +
"DON'T USE TPRINT() TO OUTPUT HTML ELEMENTS TO YOUR TERMINAL!!!!<br><br>" +
"(You lost 1 HP)");
return;
}
post(workerScript.scriptRef.filename + ": " + args.toString());
},
clearLog : function() {
@@ -439,20 +463,70 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("killall(): Killing all scripts on " + server.hostname + ". May take a few minutes for the scripts to die");
return true;
},
scp : function(scriptname,ip){
if (scriptname === undefined || ip === undefined) {
throw makeRuntimeRejectMsg(workerScript, "scp() call has incorrect number of arguments. Takes 2 arguments");
scp : function(scriptname, ip1, ip2){
if (arguments.length !== 2 && arguments.length !== 3) {
throw makeRuntimeRejectMsg(workerScript, "Error: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");
}
var destServer = getServer(ip);
if (destServer == null) {
throw makeRuntimeRejectMsg(workerScript, "Invalid hostname/ip passed into scp() command: " + ip);
if (!scriptname.endsWith(".lit") && !scriptname.endsWith(".script")) {
throw makeRuntimeRejectMsg(workerScript, "Error: scp() only works for .script and .lit files");
}
var currServ = getServer(workerScript.serverIp);
if (currServ == null) {
throw makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer");
var destServer, currServ;
if (arguments.length === 3) { //scriptname, source, destination
if (scriptname === undefined || ip1 === undefined || ip2 === undefined) {
throw makeRuntimeRejectMsg(workerScript, "Error: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");
}
destServer = getServer(ip2);
if (destServer == null) {
throw makeRuntimeRejectMsg(workerScript, "Error: Invalid hostname/ip passed into scp() command: " + ip);
}
currServ = getServer(ip1);
if (currServ == null) {
throw makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer");
}
} else if (arguments.length === 2) { //scriptname, destination
if (scriptname === undefined || ip1 === undefined) {
throw makeRuntimeRejectMsg(workerScript, "Error: scp() call has incorrect number of arguments. Takes 2 or 3 arguments");
}
destServer = getServer(ip1);
if (destServer == null) {
throw makeRuntimeRejectMsg(workerScript, "Error: Invalid hostname/ip passed into scp() command: " + ip);
}
currServ = getServer(workerScript.serverIp);
if (currServ == null) {
throw makeRuntimeRejectMsg(workerScript, "Could not find server ip for this script. This is a bug please contact game developer");
}
}
//Scp for lit files
if (scriptname.endsWith(".lit")) {
var found = false;
for (var i = 0; i < currServ.messages.length; ++i) {
if (!(currServ.messages[i] instanceof Message) && currServ.messages[i] == scriptname) {
found = true;
}
}
if (!found) {
workerScript.scriptRef.log(scriptname + " does not exist. scp() failed");
return false;
}
for (var i = 0; i < destServer.messages.length; ++i) {
if (destServer.messages[i] === scriptname) {
workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname);
return true; //Already exists
}
}
destServer.messages.push(scriptname);
workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname);
return true;
}
//Scp for script files
var sourceScript = null;
for (var i = 0; i < currServ.scripts.length; ++i) {
if (scriptname == currServ.scripts[i].filename) {
@@ -487,6 +561,64 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log(scriptname + " copied over to " + destServer.hostname);
return true;
},
ls : function(ip, grep) {
if (ip === undefined) {
throw makeRuntimeRejectMsg(workerScript, "ls() failed because of invalid arguments. Usage: ls(ip/hostname, [grep filter])");
}
var server = getServer(ip);
if (server === null) {
workerScript.scriptRef.log("ls() failed. Invalid IP or hostname passed in: " + ip);
throw makeRuntimeRejectMsg(workerScript, "ls() failed. Invalid IP or hostname passed in: " + ip);
}
//Get the grep filter, if one exists
var filter = false;
if (arguments.length >= 2) {
filter = grep.toString();
}
var allFiles = [];
for (var i = 0; i < server.programs.length; i++) {
if (filter) {
if (server.programs[i].includes(filter)) {
allFiles.push(server.programs[i]);
}
} else {
allFiles.push(server.programs[i]);
}
}
for (var i = 0; i < server.scripts.length; i++) {
if (filter) {
if (server.scripts[i].filename.includes(filter)) {
allFiles.push(server.scripts[i].filename);
}
} else {
allFiles.push(server.scripts[i].filename);
}
}
for (var i = 0; i < server.messages.length; i++) {
if (filter) {
if (server.messages[i] instanceof Message) {
if (server.messages[i].filename.includes(filter)) {
allFiles.push(server.messages[i].filename);
}
} else if (server.messages[i].includes(filter)) {
allFiles.push(server.messages[i]);
}
} else {
if (server.messages[i] instanceof Message) {
allFiles.push(server.messages[i].filename);
} else {
allFiles.push(server.messages[i]);
}
}
}
//Sort the files alphabetically then print each
allFiles.sort();
return allFiles;
},
hasRootAccess : function(ip){
if (ip===undefined){
throw makeRuntimeRejectMsg(workerScript, "hasRootAccess() call has incorrect number of arguments. Takes 1 argument");
@@ -498,6 +630,13 @@ function NetscriptFunctions(workerScript) {
}
return server.hasAdminRights;
},
getIp : function() {
var scriptServer = getServer(workerScript.serverIp);
if (scriptServer == null) {
throw makeRuntimeRejectMsg(workerScript, "Could not find server. This is a bug in the game. Report to game dev");
}
return scriptServer.ip;
},
getHostname : function(){
var scriptServer = getServer(workerScript.serverIp);
if (scriptServer == null) {
@@ -510,11 +649,33 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("getHackingLevel() returned " + Player.hacking_skill);
return Player.hacking_skill;
},
getIntelligence : function () {
if (!hasAISF) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getIntelligence(). It requires Source-File 5 to run.");
}
Player.updateSkillLevels();
workerScript.scriptRef.log("getHackingLevel() returned " + Player.intelligence);
return Player.intelligence;
},
getHackingMultipliers : function() {
return {
chance: Player.hacking_chance_mult,
speed: Player.hacking_speed_mult,
money: Player.hacking_money_mult,
growth: Player.hacking_grow_mult,
};
},
getBitNodeMultipliers: function() {
if (!hasAISF) {
throw makeRuntimeRejectMsg(workerScript, "Cannot run getBitNodeMultipliers(). It requires Source-File 5 to run.");
}
return BitNodeMultipliers;
},
getServerMoneyAvailable : function(ip){
var server = getServer(ip);
if (server == null) {
workerScript.scriptRef.log("Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip);
throw makeRuntimeRejectMsg(workerScript, "Cannot getServerMoneyAvailable(). Invalid IP or hostname passed in: " + ip);
workerScript.scriptRef.log("getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip);
throw makeRuntimeRejectMsg(workerScript, "getServerMoneyAvailable() failed. Invalid IP or hostname passed in: " + ip);
}
if (server.hostname == "home") {
//Return player's money
@@ -587,6 +748,9 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("getServerRam() returned [" + formatNumber(server.maxRam, 2) + "GB, " + formatNumber(server.ramUsed, 2) + "GB]");
return [server.maxRam, server.ramUsed];
},
serverExists : function(ip) {
return (getServer(ip) !== null);
},
fileExists : function(filename,ip=workerScript.serverIp){
if (filename === undefined) {
throw makeRuntimeRejectMsg(workerScript, "fileExists() call has incorrect number of arguments. Usage: fileExists(scriptname, [server])");
@@ -924,6 +1088,55 @@ function NetscriptFunctions(workerScript) {
}
return scriptCalculateWeakenTime(server) / 1000; //Returns seconds
},
getScriptIncome : function(scriptname, ip) {
if (arguments.length === 0) {
//Get total script income
return updateActiveScriptsItems();
} else {
//Get income for a particular script
var server = getServer(ip);
if (server === null) {
workerScript.scriptRef.log("getScriptIncome() failed. Invalid IP or hostnamed passed in: " + ip);
throw makeRuntimeRejectMsg(workerScript, "getScriptIncome() failed. Invalid IP or hostnamed passed in: " + ip);
}
var argsForScript = [];
for (var i = 2; i < arguments.length; ++i) {
argsForScript.push(arguments[i]);
}
var runningScriptObj = findRunningScript(scriptname, argsForScript, server);
if (runningScriptObj == null) {
workerScript.scriptRef.log("getScriptIncome() failed. No such script "+ scriptname + " on " + server.hostname + " with args: " + printArray(argsForScript));
return -1;
}
return runningScriptObj.onlineMoneyMade / runningScriptObj.onlineRunningTime;
}
},
getScriptExpGain : function(scriptname, ip) {
if (arguments.length === 0) {
var total = 0;
for (var i = 0; i < workerScripts.length; ++i) {
total += (workerScripts[i].scriptRef.onlineExpGained / workerScripts[i].scriptRef.onlineRunningTime);
}
return total;
} else {
//Get income for a particular script
var server = getServer(ip);
if (server === null) {
workerScript.scriptRef.log("getScriptExpGain() failed. Invalid IP or hostnamed passed in: " + ip);
throw makeRuntimeRejectMsg(workerScript, "getScriptExpGain() failed. Invalid IP or hostnamed passed in: " + ip);
}
var argsForScript = [];
for (var i = 2; i < arguments.length; ++i) {
argsForScript.push(arguments[i]);
}
var runningScriptObj = findRunningScript(scriptname, argsForScript, server);
if (runningScriptObj == null) {
workerScript.scriptRef.log("getScriptExpGain() failed. No such script "+ scriptname + " on " + server.hostname + " with args: " + printArray(argsForScript));
return -1;
}
return runningScriptObj.onlineExpGained / runningScriptObj.onlineRunningTime;
}
},
/* Singularity Functions */
universityCourse(universityName, className) {
@@ -945,6 +1158,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot study at Summit University because you are not in Aevum. universityCourse() failed");
return false;
}
Player.location = Locations.AevumSummitUniversity;
costMult = 4;
expMult = 3;
break;
@@ -953,6 +1167,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot study at Rothman University because you are not in Sector-12. universityCourse() failed");
return false;
}
Player.location = Locations.Sector12RothmanUniversity;
costMult = 3;
expMult = 2;
break;
@@ -961,6 +1176,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot study at ZB Institute of Technology because you are not in Volhaven. universityCourse() failed");
return false;
}
Player.location = Locations.VolhavenZBInstituteOfTechnology;
costMult = 5;
expMult = 4;
break;
@@ -1016,6 +1232,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot workout at Crush Fitness because you are not in Aevum. gymWorkout() failed");
return false;
}
Player.location = Locations.AevumCrushFitnessGym;
costMult = 2;
expMult = 1.5;
break;
@@ -1024,6 +1241,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot workout at Snap Fitness because you are not in Aevum. gymWorkout() failed");
return false;
}
Player.location = Locations.AevumSnapFitnessGym;
costMult = 6;
expMult = 4;
break;
@@ -1032,6 +1250,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot workout at Iron Gym because you are not in Sector-12. gymWorkout() failed");
return false;
}
Player.location = Locations.Sector12IronGym;
costMult = 1;
expMult = 1;
break;
@@ -1040,6 +1259,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot workout at Powerhouse Gym because you are not in Sector-12. gymWorkout() failed");
return false;
}
Player.location = Locations.Sector12PowerhouseGym;
costMult = 10;
expMult = 7.5;
break;
@@ -1048,6 +1268,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: You cannot workout at Millenium Fitness Gym because you are not in Volhaven. gymWorkout() failed");
return false;
}
Player.location = Locations.VolhavenMilleniumFitnessGym;
costMult = 3;
expMult = 2.5;
break;
@@ -1098,6 +1319,7 @@ function NetscriptFunctions(workerScript) {
case Locations.Volhaven:
Player.loseMoney(200000);
Player.city = cityname;
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.scriptRef.log("Traveled to " + cityname);
return true;
default:
@@ -1133,6 +1355,7 @@ function NetscriptFunctions(workerScript) {
Player.getHomeComputer().serversOnNetwork.push(darkweb.ip);
darkweb.serversOnNetwork.push(Player.getHomeComputer().ip);
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.scriptRef.log("You have purchased a Tor router!");
return true;
},
@@ -1159,6 +1382,7 @@ function NetscriptFunctions(workerScript) {
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.FTPCrackProgram.toLowerCase():
@@ -1169,7 +1393,8 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("You have purchased the FTPCrack.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.RelaySMTPProgram.toLowerCase():
@@ -1180,7 +1405,8 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("You have purchased the relaySMTP.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.HTTPWormProgram.toLowerCase():
@@ -1191,7 +1417,8 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("You have purchased the HTTPWorm.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.SQLInjectProgram.toLowerCase():
@@ -1202,7 +1429,8 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("You have purchased the SQLInject.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.DeepscanV1.toLowerCase():
@@ -1213,7 +1441,8 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("You have purchased the DeepscanV1.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
case Programs.DeepscanV2.toLowerCase():
@@ -1224,7 +1453,8 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("You have purchased the DeepscanV2.exe program. The new program " +
"can be found on your home computer.");
} else {
workerScript.scriptRef.log("Not enough money to purchase " + itemName);
workerScript.scriptRef.log("Not enough money to purchase " + programName);
return false;
}
return true;
default:
@@ -1261,6 +1491,7 @@ function NetscriptFunctions(workerScript) {
Player.loseMoney(cost);
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.scriptRef.log("Purchased additional RAM for home computer! It now has " + homeComputer.maxRam + "GB of RAM.");
return true;
},
@@ -1431,6 +1662,7 @@ function NetscriptFunctions(workerScript) {
Player.factionInvitations.splice(index, 1);
var fac = Factions[name];
joinFaction(fac);
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.scriptRef.log("Joined the " + name + " faction.");
return true;
},
@@ -1658,16 +1890,23 @@ function NetscriptFunctions(workerScript) {
return false;
}
for (var j = 0; j < Player.queuedAugmentations.length; ++j) {
if (Player.queuedAugmentations[j].name === aug.name) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because you already have " + name);
return false;
}
var isNeuroflux = false;
if (aug.name === AugmentationNames.NeuroFluxGovernor) {
isNeuroflux = true;
}
for (var j = 0; j < Player.augmentations.length; ++j) {
if (Player.augmentations[j].name === aug.name) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because you already have " + name);
return false;
if (!isNeuroflux) {
for (var j = 0; j < Player.queuedAugmentations.length; ++j) {
if (Player.queuedAugmentations[j].name === aug.name) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because you already have " + name);
return false;
}
}
for (var j = 0; j < Player.augmentations.length; ++j) {
if (Player.augmentations[j].name === aug.name) {
workerScript.scriptRef.log("ERROR: purchaseAugmentation() failed because you already have " + name);
return false;
}
}
}
@@ -1679,6 +1918,7 @@ function NetscriptFunctions(workerScript) {
var res = purchaseAugmentation(aug, fac, true);
workerScript.scriptRef.log(res);
if (isString(res) && res.startsWith("You purchased")) {
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
return true;
} else {
return false;
@@ -1696,6 +1936,7 @@ function NetscriptFunctions(workerScript) {
workerScript.scriptRef.log("ERROR: installAugmentations() failed because you do not have any Augmentations to be installed");
return false;
}
Player.gainIntelligenceExp(CONSTANTS.IntelligenceSingFnBaseExpGain);
workerScript.scriptRef.log("Installing Augmentations. This will cause this script to be killed");
installAugmentations();
return true;
+31 -29
View File
@@ -25,6 +25,7 @@ function WorkerScript(runningScriptObj) {
this.scriptRef = runningScriptObj;
this.errorMessage = "";
this.args = runningScriptObj.args;
this.killTrigger = function() {}; //CB func used to clear any delays (netscriptDelay())
}
//Returns the server on which the workerScript is running
@@ -58,6 +59,34 @@ function prestigeWorkerScripts() {
//Loop through workerScripts and run every script that is not currently running
function runScriptsLoop() {
//Delete any scripts that finished or have been killed. Loop backwards bc removing
//items fucks up the indexing
for (var i = workerScripts.length - 1; i >= 0; i--) {
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
console.log("Deleting script: " + workerScripts[i].name);
//Delete script from the runningScripts array on its host serverIp
var ip = workerScripts[i].serverIp;
var name = workerScripts[i].name;
for (var j = 0; j < AllServers[ip].runningScripts.length; j++) {
if (AllServers[ip].runningScripts[j].filename == name &&
compareArrays(AllServers[ip].runningScripts[j].args, workerScripts[i].args)) {
AllServers[ip].runningScripts.splice(j, 1);
break;
}
}
//Free RAM
AllServers[ip].ramUsed -= workerScripts[i].ramUsage;
//Delete script from Active Scripts
deleteActiveScriptsItem(workerScripts[i]);
//Delete script from workerScripts
workerScripts.splice(i, 1);
}
}
//Run any scripts that haven't been started
for (var i = 0; i < workerScripts.length; i++) {
//If it isn't running, start the script
@@ -120,35 +149,7 @@ function runScriptsLoop() {
}
}
//Delete any scripts that finished or have been killed. Loop backwards bc removing
//items fucks up the indexing
for (var i = workerScripts.length - 1; i >= 0; i--) {
if (workerScripts[i].running == false && workerScripts[i].env.stopFlag == true) {
console.log("Deleting script: " + workerScripts[i].name);
//Delete script from the runningScripts array on its host serverIp
var ip = workerScripts[i].serverIp;
var name = workerScripts[i].name;
for (var j = 0; j < AllServers[ip].runningScripts.length; j++) {
if (AllServers[ip].runningScripts[j].filename == name &&
compareArrays(AllServers[ip].runningScripts[j].args, workerScripts[i].args)) {
AllServers[ip].runningScripts.splice(j, 1);
break;
}
}
//Free RAM
AllServers[ip].ramUsed -= workerScripts[i].ramUsage;
//Delete script from Active Scripts
deleteActiveScriptsItem(workerScripts[i]);
//Delete script from workerScripts
workerScripts.splice(i, 1);
}
}
setTimeout(runScriptsLoop, 10000);
setTimeout(runScriptsLoop, 6000);
}
//Queues a script to be killed by settings its stop flag to true. Then, the code will reject
@@ -159,6 +160,7 @@ function killWorkerScript(runningScriptObj, serverIp) {
if (workerScripts[i].name == runningScriptObj.filename && workerScripts[i].serverIp == serverIp &&
compareArrays(workerScripts[i].args, runningScriptObj.args)) {
workerScripts[i].env.stopFlag = true;
workerScripts[i].killTrigger();
return true;
}
}
+128 -58
View File
@@ -8,7 +8,8 @@ import {CONSTANTS} from "./Constants.js";
import {Programs} from "./CreateProgram.js";
import {determineCrimeSuccess} from "./Crimes.js";
import {Engine} from "./engine.js";
import {Factions, Faction} from "./Faction.js";
import {Factions, Faction,
displayFactionContent} from "./Faction.js";
import {Gang, resetGangs} from "./Gang.js";
import {Locations} from "./Location.js";
import {AllServers, Server, AddToAllServers} from "./Server.js";
@@ -26,19 +27,21 @@ import {formatNumber,
function PlayerObject() {
//Skills and stats
this.hacking_skill = 1;
this.hacking_skill = 1;
//Fighting
this.hp = 10;
this.max_hp = 10;
this.strength = 1; //Damage dealt
this.defense = 1; //Damage received
this.dexterity = 1; //Accuracy
this.agility = 1; //Dodge %
//Combat stats
this.hp = 10;
this.max_hp = 10;
this.strength = 1; //Damage dealt
this.defense = 1; //Damage received
this.dexterity = 1; //Accuracy
this.agility = 1; //Dodge %
//Labor stats
this.charisma = 1;
//Intelligence, perhaps?
this.charisma = 1;
//Special stats
this.intelligence = 0;
//Hacking multipliers
this.hacking_chance_mult = 1; //Increase through ascensions/augmentations
@@ -53,6 +56,7 @@ function PlayerObject() {
this.dexterity_exp = 0;
this.agility_exp = 0;
this.charisma_exp = 0;
this.intelligence_exp= 0;
this.hacking_mult = 1;
this.strength_mult = 1;
@@ -143,12 +147,14 @@ function PlayerObject() {
this.workMoneyGained = 0;
this.createProgramName = "";
this.createProgramReqLvl = 0;
this.className = "";
this.crimeType = "";
this.timeWorked = 0; //in ms
this.timeWorkedCreateProgram = 0;
this.timeNeededToCompleteWork = 0;
this.work_money_mult = 1;
@@ -193,15 +199,6 @@ PlayerObject.prototype.init = function() {
this.getHomeComputer().programs.push(Programs.NukeProgram);
}
PlayerObject.prototype.increaseMultiplier = function(name, val) {
let mult = this[name];
if (mult === null || mult === undefined) {
console.log("ERROR: Could not find this multiplier " + name);
return;
}
mult *= val;
}
PlayerObject.prototype.prestigeAugmentation = function() {
var homeComp = this.getHomeComputer();
this.currentServer = homeComp.ip;
@@ -392,6 +389,12 @@ PlayerObject.prototype.updateSkillLevels = function() {
this.agility = Math.floor(this.calculateSkill(this.agility_exp) * this.agility_mult);
this.charisma = Math.floor(this.calculateSkill(this.charisma_exp) * this.charisma_mult);
if (this.intelligence > 0) {
this.intelligence = Math.floor(this.calculateSkill(this.intelligence_exp));
} else {
this.intelligence = 0;
}
var ratio = this.hp / this.max_hp;
this.max_hp = Math.floor(10 + this.defense / 10);
Player.hp = Math.round(this.max_hp * ratio);
@@ -439,7 +442,7 @@ PlayerObject.prototype.resetMultipliers = function() {
// (2 * hacking_chance_multiplier * hacking_skill) 100
PlayerObject.prototype.calculateHackingChance = function() {
var difficultyMult = (100 - this.getCurrentServer().hackDifficulty) / 100;
var skillMult = (1.75 * this.hacking_skill);
var skillMult = (1.75 * this.hacking_skill) + (0.2 * this.intelligence);
var skillChance = (skillMult - this.getCurrentServer().requiredHackingSkill) / skillMult;
var chance = skillChance * difficultyMult * this.hacking_chance_mult;
if (chance > 1) {return 1;}
@@ -454,7 +457,7 @@ PlayerObject.prototype.calculateHackingChance = function() {
// hacking_skill + 100
PlayerObject.prototype.calculateHackingTime = function() {
var difficultyMult = this.getCurrentServer().requiredHackingSkill * this.getCurrentServer().hackDifficulty;
var skillFactor = (2.5 * difficultyMult + 200) / (this.hacking_skill + 100);
var skillFactor = (2.5 * difficultyMult + 200) / (this.hacking_skill + 100 + (0.1 * this.intelligence));
return 5 * skillFactor / this.hacking_speed_mult;
}
@@ -571,6 +574,24 @@ PlayerObject.prototype.gainCharismaExp = function(exp) {
this.charisma_exp += exp;
}
PlayerObject.prototype.gainIntelligenceExp = function(exp) {
if (isNaN(exp)) {
console.log("ERROR: NaN passed into Player.gainIntelligenceExp()"); return;
}
var hasBn = false;
for (var i = 0; i < this.sourceFiles.length; ++i) {
if (this.sourceFiles[i].n === 5) {
hasBn = true;
break;
}
}
if (hasBn || this.intelligence > 0) {
this.intelligence_exp += exp;
} else {
console.log("Not gaining intelligence experience bc it hasn't been unlocked yet");
}
}
/******* Working functions *******/
PlayerObject.prototype.resetWorkStatus = function() {
this.workHackExpGainRate = 0;
@@ -592,6 +613,7 @@ PlayerObject.prototype.resetWorkStatus = function() {
this.workMoneyGained = 0;
this.timeWorked = 0;
this.timeWorkedCreateProgram = 0;
this.currentWorkFactionName = "";
this.currentWorkFactionDescription = "";
@@ -648,7 +670,8 @@ PlayerObject.prototype.finishWork = function(cancelled, sing=false) {
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadTerminalContent();
//Engine.loadTerminalContent();
Engine.loadLocationContent();
if (sing) {
return "You worked a short shift of " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
@@ -724,7 +747,7 @@ PlayerObject.prototype.work = function(numCycles) {
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working as a " + this.companyPosition.positionName +
" at " + Player.companyName + "<br><br>" +
" at " + this.companyName + "<br><br>" +
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
"You have earned: <br><br>" +
"$" + formatNumber(this.workMoneyGained, 2) + " ($" + formatNumber(this.workMoneyGainRate * cyclesPerSec, 2) + " / sec) <br><br>" +
@@ -841,7 +864,8 @@ PlayerObject.prototype.finishWorkPartTime = function(sing=false) {
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
this.isWorking = false;
Engine.loadTerminalContent();
//Engine.loadTerminalContent();
Engine.loadLocationContent();
if (sing) {
return "You worked for " + convertTimeMsToTimeElapsedString(this.timeWorked) + " and " +
"earned a total of " +
@@ -884,7 +908,9 @@ PlayerObject.prototype.finishFactionWork = function(cancelled, sing=false) {
this.isWorking = false;
Engine.loadTerminalContent();
//Engine.loadTerminalContent();
Engine.loadFactionContent();
displayFactionContent(faction.name);
if (sing) {
return "You worked for your faction " + faction.name + " for a total of " + convertTimeMsToTimeElapsedString(this.timeWorked) + ". " +
"You earned " +
@@ -926,7 +952,7 @@ PlayerObject.prototype.startFactionHackWork = function(faction) {
this.resetWorkStatus();
this.workHackExpGainRate = .15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.workRepGainRate = this.hacking_skill / CONSTANTS.MaxSkillLevel * this.faction_rep_mult;
this.workRepGainRate = this.workRepGainRate = (this.hacking_skill + this.intelligence) / CONSTANTS.MaxSkillLevel * this.faction_rep_mult;
this.factionWorkType = CONSTANTS.FactionWorkHacking;
this.currentWorkFactionDescription = "carrying out hacking contracts";
@@ -974,7 +1000,7 @@ PlayerObject.prototype.workForFaction = function(numCycles) {
//Constantly update the rep gain rate
switch (this.factionWorkType) {
case CONSTANTS.FactionWorkHacking:
this.workRepGainRate = this.hacking_skill / CONSTANTS.MaxSkillLevel * this.faction_rep_mult;
this.workRepGainRate = (this.hacking_skill + this.intelligence) / CONSTANTS.MaxSkillLevel * this.faction_rep_mult;
break;
case CONSTANTS.FactionWorkField:
this.workRepGainRate = this.getFactionFieldWorkRepGain();
@@ -1008,6 +1034,7 @@ PlayerObject.prototype.workForFaction = function(numCycles) {
//If timeWorked == 20 hours, then finish. You can only work for the faction for 20 hours
if (this.timeWorked >= CONSTANTS.MillisecondsPer20Hours) {
var maxCycles = CONSTANTS.GameCyclesPer20Hours;
this.timeWorked = CONSTANTS.MillisecondsPer20Hours;
this.workHackExpGained = this.workHackExpGainRate * maxCycles;
this.workStrExpGained = this.workStrExpGainRate * maxCycles;
this.workDefExpGained = this.workDefExpGainRate * maxCycles;
@@ -1092,6 +1119,10 @@ PlayerObject.prototype.getWorkRepGain = function() {
var jobPerformance = this.companyPosition.calculateJobPerformance(this.hacking_skill, this.strength,
this.defense, this.dexterity,
this.agility, this.charisma);
//Intelligence provides a flat bonus to job performance
jobPerformance += (this.intelligence / CONSTANTS.MaxSkillLevel);
//Update reputation gain rate to account for company favor
var favorMult = 1 + (company.favor / 100);
if (isNaN(favorMult)) {favorMult = 1;}
@@ -1113,7 +1144,8 @@ PlayerObject.prototype.getFactionFieldWorkRepGain = function() {
this.defense / CONSTANTS.MaxSkillLevel +
this.dexterity / CONSTANTS.MaxSkillLevel +
this.agility / CONSTANTS.MaxSkillLevel +
this.charisma / CONSTANTS.MaxSkillLevel) / 6;
this.charisma / CONSTANTS.MaxSkillLevel +
this.intelligence / CONSTANTS.MaxSkillLevel) / 6;
return t * this.faction_rep_mult;
}
@@ -1125,21 +1157,22 @@ PlayerObject.prototype.startCreateProgramWork = function(programName, time, reqL
//Time needed to complete work affected by hacking skill (linearly based on
//ratio of (your skill - required level) to MAX skill)
var timeMultiplier = (CONSTANTS.MaxSkillLevel - (this.hacking_skill - reqLevel)) / CONSTANTS.MaxSkillLevel;
if (timeMultiplier > 1) {timeMultiplier = 1;}
if (timeMultiplier < 0.01) {timeMultiplier = 0.01;}
//var timeMultiplier = (CONSTANTS.MaxSkillLevel - (this.hacking_skill - reqLevel)) / CONSTANTS.MaxSkillLevel;
//if (timeMultiplier > 1) {timeMultiplier = 1;}
//if (timeMultiplier < 0.01) {timeMultiplier = 0.01;}
this.createProgramReqLvl = reqLevel;
this.timeNeededToCompleteWork = timeMultiplier * time;
this.timeNeededToCompleteWork = time;
//Check for incomplete program
for (var i = 0; i < Player.getHomeComputer().programs.length; ++i) {
var programFile = Player.getHomeComputer().programs[i];
for (var i = 0; i < this.getHomeComputer().programs.length; ++i) {
var programFile = this.getHomeComputer().programs[i];
if (programFile.startsWith(programName) && programFile.endsWith("%-INC")) {
var res = programFile.split("-");
if (res.length != 3) {break;}
var percComplete = Number(res[1].slice(0, -1));
if (isNaN(percComplete) || percComplete < 0 || percComplete >= 100) {break;}
this.timeWorked = percComplete / 100 * this.timeNeededToCompleteWork;
Player.getHomeComputer().programs.splice(i, 1);
this.timeWorkedCreateProgram = percComplete / 100 * this.timeNeededToCompleteWork;
this.getHomeComputer().programs.splice(i, 1);
}
}
@@ -1157,17 +1190,24 @@ PlayerObject.prototype.startCreateProgramWork = function(programName, time, reqL
}
PlayerObject.prototype.createProgramWork = function(numCycles) {
this.timeWorked += Engine._idleSpeed * numCycles;
//Higher hacking skill will allow you to create programs faster
var reqLvl = this.createProgramReqLvl;
var skillMult = (this.hacking_skill / reqLvl); //This should always be greater than 1;
skillMult = 1 + ((skillMult - 1) / 5); //The divider constant can be adjusted as necessary
//Skill multiplier directly applied to "time worked"
this.timeWorked += (Engine._idleSpeed * numCycles);
this.timeWorkedCreateProgram += (Engine._idleSpeed * numCycles * skillMult);
var programName = this.createProgramName;
if (this.timeWorked >= this.timeNeededToCompleteWork) {
if (this.timeWorkedCreateProgram >= this.timeNeededToCompleteWork) {
this.finishCreateProgramWork(false);
}
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are currently working on coding " + programName + ".<br><br> " +
"You have been working for " + convertTimeMsToTimeElapsedString(this.timeWorked) + "<br><br>" +
"The program is " + (this.timeWorked / this.timeNeededToCompleteWork * 100).toFixed(2) + "% complete. <br>" +
"The program is " + (this.timeWorkedCreateProgram / this.timeNeededToCompleteWork * 100).toFixed(2) + "% complete. <br>" +
"If you cancel, your work will be saved and you can come back to complete the program later.";
}
@@ -1177,17 +1217,19 @@ PlayerObject.prototype.finishCreateProgramWork = function(cancelled, sing=false)
dialogBoxCreate("You've finished creating " + programName + "!<br>" +
"The new program can be found on your home computer.");
Player.getHomeComputer().programs.push(programName);
this.getHomeComputer().programs.push(programName);
} else {
var perc = Math.floor(this.timeWorked / this.timeNeededToCompleteWork * 100).toString();
var perc = Math.floor(this.timeWorkedCreateProgram / this.timeNeededToCompleteWork * 100).toString();
var incompleteName = programName + "-" + perc + "%-INC";
Player.getHomeComputer().programs.push(incompleteName);
this.getHomeComputer().programs.push(incompleteName);
}
this.gainIntelligenceExp(this.createProgramReqLvl / CONSTANTS.IntelligenceProgramBaseExpGain);
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
Player.isWorking = false;
this.isWorking = false;
Engine.loadTerminalContent();
}
@@ -1255,7 +1297,7 @@ PlayerObject.prototype.startClass = function(costMult, expMult, className) {
agiExp = baseGymExp * expMult / gameCPS;
break;
default:
throw new Error("ERR: Invalid/unregocnized class name");
throw new Error("ERR: Invalid/unrecognized class name");
return;
}
@@ -1386,16 +1428,16 @@ PlayerObject.prototype.startCrime = function(hackExp, strExp, defExp, dexExp, ag
PlayerObject.prototype.commitCrime = function (numCycles) {
this.timeWorked += Engine._idleSpeed * numCycles;
if (this.timeWorked >= this.timeNeededToCompleteWork) {Player.finishCrime(false); return;}
if (this.timeWorked >= this.timeNeededToCompleteWork) {this.finishCrime(false); return;}
var percent = Math.round(Player.timeWorked / Player.timeNeededToCompleteWork * 100);
var percent = Math.round(this.timeWorked / this.timeNeededToCompleteWork * 100);
var numBars = Math.round(percent / 5);
if (numBars < 0) {numBars = 0;}
if (numBars > 20) {numBars = 20;}
var progressBar = "[" + Array(numBars+1).join("|") + Array(20 - numBars + 1).join(" ") + "]";
var txt = document.getElementById("work-in-progress-text");
txt.innerHTML = "You are attempting to " + Player.crimeType + ".<br>" +
txt.innerHTML = "You are attempting to " + this.crimeType + ".<br>" +
"Time remaining: " + convertTimeMsToTimeElapsedString(this.timeNeededToCompleteWork - this.timeWorked) + "<br>" +
progressBar.replace( / /g, "&nbsp;" );
}
@@ -1431,6 +1473,7 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
break;
case CONSTANTS.CrimeGrandTheftAuto:
this.karma -= 5;
this.gainIntelligenceExp(CONSTANTS.IntelligenceCrimeBaseExpGain);
break;
case CONSTANTS.CrimeKidnap:
this.karma -= 6;
@@ -1438,9 +1481,11 @@ PlayerObject.prototype.finishCrime = function(cancelled) {
case CONSTANTS.CrimeAssassination:
++this.numPeopleKilled;
this.karma -= 10;
this.gainIntelligenceExp(CONSTANTS.IntelligenceCrimeBaseExpGain);
break;
case CONSTANTS.CrimeHeist:
this.karma -= 15;
this.gainIntelligenceExp(5 * CONSTANTS.IntelligenceCrimeBaseExpGain);
break;
default:
console.log(this.crimeType);
@@ -1531,7 +1576,7 @@ PlayerObject.prototype.hospitalize = function() {
dialogBoxCreate("You were in critical condition! You were taken to the hospital where " +
"luckily they were able to save your life. You were charged $" +
formatNumber(this.max_hp * CONSTANTS.HospitalCostPerHp, 2));
Player.loseMoney(this.max_hp * CONSTANTS.HospitalCostPerHp);
this.loseMoney(this.max_hp * CONSTANTS.HospitalCostPerHp);
this.hp = this.max_hp;
}
@@ -1615,7 +1660,12 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
this.companyName = company.companyName;
this.companyPosition = pos;
Player.firstJobRecvd = true;
if (this.firstJobRecvd === false) {
this.firstJobRecvd = true;
document.getElementById("job-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
if (leaveCompany) {
if (sing) {return true;}
@@ -1719,7 +1769,12 @@ PlayerObject.prototype.applyForAgentJob = function(sing=false) {
PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.Employee)) {
Player.firstJobRecvd = true;
if (this.firstJobRecvd === false) {
this.firstJobRecvd = true;
document.getElementById("job-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.Employee;
if (sing) {return true;}
@@ -1734,7 +1789,12 @@ PlayerObject.prototype.applyForEmployeeJob = function(sing=false) {
PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.PartTimeEmployee)) {
Player.firstJobRecvd = true;
if (this.firstJobRecvd === false) {
this.firstJobRecvd = true;
document.getElementById("job-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.PartTimeEmployee;
if (sing) {return true;}
@@ -1749,7 +1809,12 @@ PlayerObject.prototype.applyForPartTimeEmployeeJob = function(sing=false) {
PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.Waiter)) {
Player.firstJobRecvd = true;
if (this.firstJobRecvd === false) {
this.firstJobRecvd = true;
document.getElementById("job-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.Waiter;
if (sing) {return true;}
@@ -1764,7 +1829,12 @@ PlayerObject.prototype.applyForWaiterJob = function(sing=false) {
PlayerObject.prototype.applyForPartTimeWaiterJob = function(sing=false) {
var company = Companies[this.location]; //Company being applied to
if (this.isQualified(company, CompanyPositions.PartTimeWaiter)) {
Player.firstJobRecvd = true;
if (this.firstJobRecvd === false) {
this.firstJobRecvd = true;
document.getElementById("job-tab").style.display = "list-item";
document.getElementById("world-menu-header").click();
document.getElementById("world-menu-header").click();
}
this.companyName = company.companyName;
this.companyPosition = CompanyPositions.PartTimeWaiter;
if (sing) {return true;}
@@ -2113,10 +2183,10 @@ PlayerObject.prototype.checkForFactionInvitations = function() {
var totalHacknetRam = 0;
var totalHacknetCores = 0;
var totalHacknetLevels = 0;
for (var i = 0; i < Player.hacknetNodes.length; ++i) {
totalHacknetLevels += Player.hacknetNodes[i].level;
totalHacknetRam += Player.hacknetNodes[i].ram;
totalHacknetCores += Player.hacknetNodes[i].cores;
for (var i = 0; i < this.hacknetNodes.length; ++i) {
totalHacknetLevels += this.hacknetNodes[i].level;
totalHacknetRam += this.hacknetNodes[i].ram;
totalHacknetCores += this.hacknetNodes[i].cores;
}
if (!netburnersFac.isBanned && !netburnersFac.isMember && !netburnersFac.alreadyInvited &&
this.hacking_skill >= 80 && totalHacknetRam >= 8 &&
+9
View File
@@ -9,6 +9,7 @@ import {Factions, Faction, initFactions,
joinFaction} from "./Faction.js";
import {Locations} from "./Location.js";
import {initMessages, Messages, Message} from "./Message.js";
import {initSingularitySFFlags} from "./NetscriptFunctions.js";
import {WorkerScript, workerScripts,
prestigeWorkerScripts} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
@@ -117,6 +118,7 @@ function prestigeAugmentation() {
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
Terminal.resetTerminalInput();
Engine.loadTerminalContent();
//Red Pill
@@ -215,7 +217,14 @@ function prestigeSourceFile() {
var mainMenu = document.getElementById("mainmenu-container");
mainMenu.style.visibility = "visible";
Terminal.resetTerminalInput();
Engine.loadTerminalContent();
//Reinitialize flags in case you just finished BN-4
initSingularitySFFlags();
//Gain int exp
Player.gainIntelligenceExp(5);
}
export {prestigeAugmentation, prestigeSourceFile};
+4 -1
View File
@@ -123,6 +123,9 @@ function giveSourceFile(bitNodeNumber) {
} else {
var playerSrcFile = new PlayerOwnedSourceFile(bitNodeNumber, 1);
Player.sourceFiles.push(playerSrcFile);
if (bitNodeNumber === 5) { //Artificial Intelligence
Player.intelligence = 1;
}
dialogBoxCreate("You received a Source-File for destroying a Bit Node!<br><br>" +
sourceFile.name + "<br><br>" + sourceFile.info);
}
@@ -206,7 +209,7 @@ function loadBitVerse(destroyedBitNodeNum) {
var elemId = "bitnode-" + i.toString();
var elem = clearEventListeners(elemId);
if (elem == null) {return;}
if (i === 1 || i === 2 || i === 4 || i === 11) {
if (i === 1 || i === 2 || i === 4 || i === 5 || i === 11) {
elem.addEventListener("click", function() {
var bitNodeKey = "BitNode" + i;
var bitNode = BitNodes[bitNodeKey];
+11 -2
View File
@@ -73,7 +73,16 @@ BitburnerSaveObject.prototype.saveGame = function() {
this.AllGangsSave = JSON.stringify(AllGangs);
}
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
window.localStorage.setItem("bitburnerSave", saveString);
try {
window.localStorage.setItem("bitburnerSave", saveString);
} catch(e) {
if (e.code == 22) {
dialogBoxCreate("Failed to save game because the size of the save file " +
"is too large. Consider killing several of your scripts to " +
"fix this, or increasing the size of your browsers localStorage");
}
}
console.log("Game saved!");
Engine.createStatusText("Game saved!");
@@ -466,7 +475,7 @@ BitburnerSaveObject.prototype.exportGame = function() {
this.VersionSave = JSON.stringify(CONSTANTS.Version);
var saveString = btoa(unescape(encodeURIComponent(JSON.stringify(this))));
var filename = "bitburnerSave.json";
var file = new Blob([saveString], {type: 'text/plain'});
if (window.navigator.msSaveOrOpenBlob) {// IE10+
window.navigator.msSaveOrOpenBlob(file, filename);
+90 -49
View File
@@ -1,6 +1,18 @@
var ace = require('brace');
require('brace/mode/javascript');
require('brace/mode/netscript');
require('brace/theme/chaos');
require('brace/theme/chrome');
require('brace/theme/monokai');
require('brace/theme/solarized_dark');
require('brace/theme/solarized_light');
require('brace/theme/terminal');
require('brace/theme/twilight');
require('brace/theme/xcode');
require("brace/keybinding/vim");
require("brace/keybinding/emacs");
import {CONSTANTS} from "./Constants.js";
import {Engine} from "./engine.js";
@@ -18,6 +30,12 @@ import {compareArrays} from "../utils/HelperFunctions.j
import {formatNumber, numOccurrences,
numNetscriptOperators} from "../utils/StringHelperFunctions.js";
var keybindings = {
ace: null,
vim: "ace/keyboard/vim",
emacs: "ace/keyboard/emacs",
};
function scriptEditorInit() {
//Initialize save and close button
var closeButton = document.getElementById("script-editor-save-and-close-button");
@@ -27,26 +45,59 @@ function scriptEditorInit() {
return false;
});
//Allow tabs (four spaces) in all textareas
var textareas = document.getElementsByTagName('textarea');
var count = textareas.length;
for(var i=0;i<count;i++){
textareas[i].onkeydown = function(e){
if(e.keyCode==9 || e.which==9){
e.preventDefault();
var start = this.selectionStart;
var end = this.selectionEnd;
//Initialize ACE Script editor
var editor = ace.edit('javascript-editor');
editor.getSession().setMode('ace/mode/netscript');
editor.setTheme('ace/theme/monokai');
document.getElementById('javascript-editor').style.fontSize='16px';
editor.setOption("showPrintMargin", false);
//Set textarea value to: text before caret + four spaces + text after caret
let spaces = " ";
this.value = this.value.substring(0, start) + spaces + this.value.substring(end);
/* Script editor options */
//Theme
var themeDropdown = document.getElementById("script-editor-option-theme");
themeDropdown.selectedIndex = 2;
themeDropdown.onchange = function() {
var val = themeDropdown.value;
var themePath = "ace/theme/" + val.toLowerCase();
editor.setTheme(themePath);
};
//Put caret at after the four spaces
this.selectionStart = this.selectionEnd = start + spaces.length;
}
}
}
};
//Keybinding
var keybindingDropdown = document.getElementById("script-editor-option-keybinding");
keybindingDropdown.onchange = function() {
var val = keybindingDropdown.value;
editor.setKeyboardHandler(keybindings[val.toLowerCase()]);
};
//Highlight Active line
var highlightActiveChkBox = document.getElementById("script-editor-option-highlightactiveline");
highlightActiveChkBox.onchange = function() {
editor.setHighlightActiveLine(highlightActiveChkBox.checked);
};
//Show Invisibles
var showInvisiblesChkBox = document.getElementById("script-editor-option-showinvisibles");
showInvisiblesChkBox.onchange = function() {
editor.setShowInvisibles(showInvisiblesChkBox.checked);
};
//Use Soft Tab
var softTabChkBox = document.getElementById("script-editor-option-usesofttab");
softTabChkBox.onchange = function() {
editor.getSession().setUseSoftTabs(softTabChkBox.checked);
};
//Configure some of the VIM keybindings
ace.config.loadModule('ace/keyboard/vim', function(module) {
var VimApi = module.CodeMirror.Vim;
VimApi.defineEx('write', 'w', function(cm, input) {
saveAndCloseScriptEditor();
});
VimApi.defineEx('quit', 'q', function(cm, input) {
Engine.loadTerminalContent();
});
});
}
document.addEventListener("DOMContentLoaded", scriptEditorInit, false);
//Updates line number and RAM usage in script
@@ -163,6 +214,7 @@ Script.prototype.updateRamUsage = function() {
}
function calculateRamUsage(codeCopy) {
codeCopy = codeCopy.replace(/\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm, '$1'); //Delete comments
codeCopy = codeCopy.replace(/\s/g,''); //Remove all whitespace
var baseRam = 1.4;
var whileCount = numOccurrences(codeCopy, "while(");
@@ -183,8 +235,12 @@ function calculateRamUsage(codeCopy) {
var killCount = numOccurrences(codeCopy, "kill(") + numOccurrences(codeCopy, "killall(");
var scpCount = numOccurrences(codeCopy, "scp(");
var hasRootAccessCount = numOccurrences(codeCopy, "hasRootAccess(");
var getHostnameCount = numOccurrences(codeCopy, "getHostname(");
var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel(");
var getHostnameCount = numOccurrences(codeCopy, "getHostname(") +
numOccurrences(codeCopy, "getIp(");
var getHackingLevelCount = numOccurrences(codeCopy, "getHackingLevel(") +
numOccurrences(codeCopy, "getIntelligence(");
var getMultipliersCount = numOccurrences(codeCopy, "getHackingMultipliers(") +
numOccurrences(codeCopy, "getBitNodeMultipliers(");
var getServerCount = numOccurrences(codeCopy, "getServerMoneyAvailable(") +
numOccurrences(codeCopy, "getServerMaxMoney(") +
numOccurrences(codeCopy, "getServerSecurityLevel(") +
@@ -192,10 +248,10 @@ function calculateRamUsage(codeCopy) {
numOccurrences(codeCopy, "getServerGrowth(") +
numOccurrences(codeCopy, "getServerRequiredHackingLevel(") +
numOccurrences(codeCopy, "getServerNumPortsRequired(") +
numOccurrences(codeCopy, "getServerRam(");
numOccurrences(codeCopy, "getServerRam(") +
numOccurrences(codeCopy, "serverExists(");
var fileExistsCount = numOccurrences(codeCopy, "fileExists(");
var isRunningCount = numOccurrences(codeCopy, "isRunning(");
var numOperators = numNetscriptOperators(codeCopy);
var purchaseHacknetCount = numOccurrences(codeCopy, "purchaseHacknetNode(");
var hacknetnodesArrayCount = numOccurrences(codeCopy, "hacknetnodes[");
var hnUpgLevelCount = numOccurrences(codeCopy, ".upgradeLevel(");
@@ -212,7 +268,9 @@ function calculateRamUsage(codeCopy) {
var scriptReadCount = numOccurrences(codeCopy, "read(");
var arbScriptCount = numOccurrences(codeCopy, "scriptRunning(") +
numOccurrences(codeCopy, "scriptKill(");
var getScriptCount = numOccurrences(codeCopy, "getScriptRam(");
var getScriptCount = numOccurrences(codeCopy, "getScriptRam(") +
numOccurrences(codeCopy, "getScriptIncome(") +
numOccurrences(codeCopy, "getScriptExpGain(");
var getHackTimeCount = numOccurrences(codeCopy, "getHackTime(") +
numOccurrences(codeCopy, "getGrowTime(") +
numOccurrences(codeCopy, "getWeakenTime(");
@@ -262,10 +320,10 @@ function calculateRamUsage(codeCopy) {
(hasRootAccessCount * CONSTANTS.ScriptHasRootAccessRamCost) +
(getHostnameCount * CONSTANTS.ScriptGetHostnameRamCost) +
(getHackingLevelCount * CONSTANTS.ScriptGetHackingLevelRamCost) +
(getMultipliersCount * CONSTANTS.ScriptGetMultipliersRamCost) +
(getServerCount * CONSTANTS.ScriptGetServerCost) +
(fileExistsCount * CONSTANTS.ScriptFileExistsRamCost) +
(isRunningCount * CONSTANTS.ScriptIsRunningRamCost) +
(numOperators * CONSTANTS.ScriptOperatorRamCost) +
(purchaseHacknetCount * CONSTANTS.ScriptPurchaseHacknetRamCost) +
(hacknetnodesArrayCount * CONSTANTS.ScriptHacknetNodesRamCost) +
(hnUpgLevelCount * CONSTANTS.ScriptHNUpgLevelRamCost) +
@@ -444,19 +502,7 @@ function RunningScript(script, args) {
this.threads = 1;
//[MoneyStolen, NumTimesHacked, NumTimesGrown, NumTimesWeaken]
this.dataMap = new AllServersMap([0, 0, 0, 0]);
}
RunningScript.prototype.reset = function() {
this.scriptRef.updateRamUsage();
this.offlineRunningTime = 0.01; //Seconds
this.offlineMoneyMade = 0;
this.offlineExpGained = 0;
this.onlineRunningTime = 0.01; //Seconds
this.onlineMoneyMade = 0;
this.onlineExpGained = 0;
this.logs = [];
this.dataMap = new AllServersMap([0, 0, 0, 0], true);
}
RunningScript.prototype.log = function(txt) {
@@ -483,7 +529,7 @@ RunningScript.prototype.clearLog = function() {
RunningScript.prototype.recordHack = function(serverIp, moneyGained, n=1) {
if (this.dataMap == null) {
//[MoneyStolen, NumTimesHacked, NumTimesGrown, NumTimesWeaken]
this.dataMap = new AllServersMap([0, 0, 0, 0]);
this.dataMap = new AllServersMap([0, 0, 0, 0], true);
}
this.dataMap[serverIp][0] += moneyGained;
this.dataMap[serverIp][1] += n;
@@ -493,7 +539,7 @@ RunningScript.prototype.recordHack = function(serverIp, moneyGained, n=1) {
RunningScript.prototype.recordGrow = function(serverIp, n=1) {
if (this.dataMap == null) {
//[MoneyStolen, NumTimesHacked, NumTimesGrown, NumTimesWeaken]
this.dataMap = new AllServersMap([0, 0, 0, 0]);
this.dataMap = new AllServersMap([0, 0, 0, 0], true);
}
this.dataMap[serverIp][2] += n;
}
@@ -502,7 +548,7 @@ RunningScript.prototype.recordGrow = function(serverIp, n=1) {
RunningScript.prototype.recordWeaken = function(serverIp, n=1) {
if (this.dataMap == null) {
//[MoneyStolen, NumTimesHacked, NumTimesGrown, NumTimesWeaken]
this.dataMap = new AllServersMap([0, 0, 0, 0]);
this.dataMap = new AllServersMap([0, 0, 0, 0], true);
}
this.dataMap[serverIp][3] += n;
}
@@ -520,9 +566,12 @@ Reviver.constructors.RunningScript = RunningScript;
//Creates an object that creates a map/dictionary with the IP of each existing server as
//a key. Initializes every key with a specified value that can either by a number or an array
function AllServersMap(arr=false) {
function AllServersMap(arr=false, filterOwned=false) {
for (var ip in AllServers) {
if (AllServers.hasOwnProperty(ip)) {
if (filterOwned && (AllServers[ip].purchasedByPlayer || AllServers[ip].hostname === "home")) {
continue;
}
if (arr) {
this[ip] = [0, 0, 0, 0];
} else {
@@ -532,14 +581,6 @@ function AllServersMap(arr=false) {
}
}
AllServersMap.prototype.reset = function() {
for (var ip in this) {
if (this.hasOwnProperty(ip)) {
this[ip] = 0;
}
}
}
AllServersMap.prototype.printConsole = function() {
for (var ip in this) {
if (this.hasOwnProperty(ip)) {
+32 -29
View File
@@ -32,7 +32,7 @@ function Server(ip=createRandomIp(), hostname="", organizationName="",
//RAM, CPU speed and Scripts
this.maxRam = maxRam; //GB
this.ramUsed = 0;
this.cpuSpeed = 1; //MHz
this.cpuCores = 1; //Max of 8, affects hacking times and Hacking MIssion starting Cores
this.scripts = [];
this.runningScripts = []; //Stores RunningScript objects
@@ -78,8 +78,8 @@ Server.prototype.setHackingParameters = function(requiredHackingSkill, moneyAvai
this.moneyAvailable = moneyAvailable * BitNodeMultipliers.ServerStartingMoney;
}
this.moneyMax = 25 * this.moneyAvailable * BitNodeMultipliers.ServerMaxMoney;
this.hackDifficulty = hackDifficulty;
this.baseDifficulty = hackDifficulty;
this.hackDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
this.baseDifficulty = hackDifficulty * BitNodeMultipliers.ServerStartingSecurity;
this.minDifficulty = Math.max(1, Math.round(hackDifficulty / 3));
this.serverGrowth = serverGrowth;
}
@@ -118,7 +118,9 @@ Server.prototype.getScript = function(scriptName) {
//Strengthens a server's security level (difficulty) by the specified amount
Server.prototype.fortify = function(amt) {
this.hackDifficulty += amt;
if (this.hackDifficulty > 99) {this.hackDifficulty = 99;}
//Place some arbitrarily limit that realistically should never happen unless someone is
//screwing around with the game
if (this.hackDifficulty > 1000000) {this.hackDifficulty = 1000000;}
}
Server.prototype.weaken = function(amt) {
@@ -155,26 +157,26 @@ function initForeignServers() {
BachmanAndAssociatesServer.setPortProperties(5);
AddToAllServers(BachmanAndAssociatesServer);
var BladeIndustriesServer = new Server(createRandomIp(), "blade", "Blade Industries", false, false, false, 0);
var BladeIndustriesServer = new Server(createRandomIp(), "blade", "Blade Industries", false, false, false, 2);
BladeIndustriesServer.setHackingParameters(getRandomInt(1000, 1100), getRandomInt(12000000000, 20000000000), getRandomInt(90, 95), getRandomInt(60, 75));
BladeIndustriesServer.setPortProperties(5);
BladeIndustriesServer.messages.push("beyond-man.lit");
AddToAllServers(BladeIndustriesServer);
var NWOServer = new Server(createRandomIp(), "nwo", "New World Order", false, false, false, 0);
var NWOServer = new Server(createRandomIp(), "nwo", "New World Order", false, false, false, 2);
NWOServer.setHackingParameters(getRandomInt(1000, 1200), getRandomInt(25000000000, 35000000000), 99, getRandomInt(75, 85));
NWOServer.setPortProperties(5);
NWOServer.messages.push("the-hidden-world.lit");
AddToAllServers(NWOServer);
var ClarkeIncorporatedServer = new Server(createRandomIp(), "clarkeinc", "Clarke Incorporated", false, false, false, 0);
var ClarkeIncorporatedServer = new Server(createRandomIp(), "clarkeinc", "Clarke Incorporated", false, false, false, 2);
ClarkeIncorporatedServer.setHackingParameters(getRandomInt(1000, 1200), getRandomInt(15000000000, 25000000000), getRandomInt(50, 60), getRandomInt(50, 70));
ClarkeIncorporatedServer.setPortProperties(5);
ClarkeIncorporatedServer.messages.push("beyond-man.lit");
ClarkeIncorporatedServer.messages.push("cost-of-immortality.lit");
AddToAllServers(ClarkeIncorporatedServer);
var OmniTekIncorporatedServer = new Server(createRandomIp(), "omnitek", "OmniTek Incorporated", false, false, false, 0);
var OmniTekIncorporatedServer = new Server(createRandomIp(), "omnitek", "OmniTek Incorporated", false, false, false, 2);
OmniTekIncorporatedServer.setHackingParameters(getRandomInt(900, 1100), getRandomInt(15000000000, 20000000000), getRandomInt(90, 99), getRandomInt(95, 99));
OmniTekIncorporatedServer.setPortProperties(5);
OmniTekIncorporatedServer.messages.push("coded-intelligence.lit");
@@ -218,7 +220,7 @@ function initForeignServers() {
InfoCommServer.setPortProperties(5);
AddToAllServers(InfoCommServer);
var HeliosLabsServer = new Server(createRandomIp(), "helios", "Helios Labs", false, false, false, 0);
var HeliosLabsServer = new Server(createRandomIp(), "helios", "Helios Labs", false, false, false, 2);
HeliosLabsServer.setHackingParameters(getRandomInt(800, 900), getRandomInt(550000000, 750000000), getRandomInt(85, 95), getRandomInt(70, 80));
HeliosLabsServer.setPortProperties(5);
HeliosLabsServer.messages.push("beyond-man.lit");
@@ -252,7 +254,7 @@ function initForeignServers() {
MicrodyneTechnologiesServer.messages.push("synthetic-muscles.lit");
AddToAllServers(MicrodyneTechnologiesServer);
var TaiYangDigitalServer = new Server(createRandomIp(), "taiyang-digital", "Taiyang Digital", false, false, false, 0);
var TaiYangDigitalServer = new Server(createRandomIp(), "taiyang-digital", "Taiyang Digital", false, false, false, 2);
TaiYangDigitalServer.setHackingParameters(getRandomInt(850, 950), getRandomInt(800000000, 900000000), getRandomInt(70, 80), getRandomInt(70, 80));
TaiYangDigitalServer.setPortProperties(5);
TaiYangDigitalServer.messages.push("A-Green-Tomorrow.lit");
@@ -265,7 +267,7 @@ function initForeignServers() {
AddToAllServers(GalacticCyberSystemsServer);
//Defense Companies ("Large" Companies)
var AeroCorpServer = new Server(createRandomIp(), "aerocorp", "AeroCorp", false, false, false, 0);
var AeroCorpServer = new Server(createRandomIp(), "aerocorp", "AeroCorp", false, false, false, 2);
AeroCorpServer.setHackingParameters(getRandomInt(850, 925), getRandomInt(1000000000, 1200000000), getRandomInt(80, 90), getRandomInt(55, 65));
AeroCorpServer.setPortProperties(5);
AeroCorpServer.messages.push("man-and-machine.lit");
@@ -276,7 +278,7 @@ function initForeignServers() {
OmniaCybersystemsServer.setPortProperties(5);
AddToAllServers(OmniaCybersystemsServer);
var ZBDefenseServer = new Server(createRandomIp(), "zb-def", "ZB Defense Industries", false, false, false, 0);
var ZBDefenseServer = new Server(createRandomIp(), "zb-def", "ZB Defense Industries", false, false, false, 2);
ZBDefenseServer.setHackingParameters(getRandomInt(775, 825), getRandomInt(900000000, 1100000000), getRandomInt(55, 65), getRandomInt(65, 75));
ZBDefenseServer.setPortProperties(4);
ZBDefenseServer.messages.push("synthetic-muscles.lit");
@@ -287,7 +289,7 @@ function initForeignServers() {
AppliedEnergeticsServer.setPortProperties(4);
AddToAllServers(AppliedEnergeticsServer);
var SolarisSpaceSystemsServer = new Server(createRandomIp(), "solaris", "Solaris Space Systems", false, false, false, 0);
var SolarisSpaceSystemsServer = new Server(createRandomIp(), "solaris", "Solaris Space Systems", false, false, false, 2);
SolarisSpaceSystemsServer.setHackingParameters(getRandomInt(750, 850), getRandomInt(700000000, 900000000), getRandomInt(70, 80), getRandomInt(70, 80));
SolarisSpaceSystemsServer.setPortProperties(5);
SolarisSpaceSystemsServer.messages.push("A-Green-Tomorrow.lit");
@@ -332,7 +334,7 @@ function initForeignServers() {
RhoConstructionServer.setPortProperties(3);
AddToAllServers(RhoConstructionServer);
var AlphaEnterprisesServer = new Server(createRandomIp(), "alpha-ent", "Alpha Enterprises", false, false, false, 0);
var AlphaEnterprisesServer = new Server(createRandomIp(), "alpha-ent", "Alpha Enterprises", false, false, false, 2);
AlphaEnterprisesServer.setHackingParameters(getRandomInt(500, 600), getRandomInt(600000000, 750000000), getRandomInt(50, 70), getRandomInt(50, 60));
AlphaEnterprisesServer.setPortProperties(4);
AlphaEnterprisesServer.messages.push("sector-12-crime.lit");
@@ -369,7 +371,7 @@ function initForeignServers() {
SysCoreSecuritiesServer.setPortProperties(4);
AddToAllServers(SysCoreSecuritiesServer);
var CatalystVenturesServer = new Server(createRandomIp(), "catalyst", "Catalyst Ventures", false, false, false, 0);
var CatalystVenturesServer = new Server(createRandomIp(), "catalyst", "Catalyst Ventures", false, false, false, 2);
CatalystVenturesServer.setHackingParameters(getRandomInt(400, 450), getRandomInt(300000000, 550000000), getRandomInt(60, 70), getRandomInt(25, 55));
CatalystVenturesServer.setPortProperties(3);
CatalystVenturesServer.messages.push("tensions-in-tech-race.lit");
@@ -386,7 +388,7 @@ function initForeignServers() {
CompuTekServer.messages.push("man-and-machine.lit");
AddToAllServers(CompuTekServer);
var NetLinkTechnologiesServer = new Server(createRandomIp(), "netlink", "NetLink Technologies", false, false, false, 0);
var NetLinkTechnologiesServer = new Server(createRandomIp(), "netlink", "NetLink Technologies", false, false, false, 2);
NetLinkTechnologiesServer.setHackingParameters(getRandomInt(375, 425), 275000000, getRandomInt(60, 80), getRandomInt(45, 75));
NetLinkTechnologiesServer.setPortProperties(3);
NetLinkTechnologiesServer.messages.push("simulated-reality.lit");
@@ -414,7 +416,7 @@ function initForeignServers() {
JoesGunsServer.setPortProperties(0);
AddToAllServers(JoesGunsServer);
var Zer0NightclubServer = new Server(createRandomIp(), "zer0", "ZER0 Nightclub", false, false, false, 4);
var Zer0NightclubServer = new Server(createRandomIp(), "zer0", "ZER0 Nightclub", false, false, false, 16);
Zer0NightclubServer.setHackingParameters(75, 7500000, 25, 40);
Zer0NightclubServer.setPortProperties(1);
AddToAllServers(Zer0NightclubServer);
@@ -424,13 +426,13 @@ function initForeignServers() {
NectarNightclubServer.setPortProperties(0);
AddToAllServers(NectarNightclubServer);
var NeoNightclubServer = new Server(createRandomIp(), "neo-net", "Neo Nightclub Network", false, false, false, 4);
var NeoNightclubServer = new Server(createRandomIp(), "neo-net", "Neo Nightclub Network", false, false, false, 16);
NeoNightclubServer.setHackingParameters(50, 5000000, 25, 25);
NeoNightclubServer.setPortProperties(1);
NeoNightclubServer.messages.push("the-hidden-world.lit");
AddToAllServers(NeoNightclubServer);
var SilverHelixServer = new Server(createRandomIp(), "silver-helix", "Silver Helix", false, false, false, 2);
var SilverHelixServer = new Server(createRandomIp(), "silver-helix", "Silver Helix", false, false, false, 32);
SilverHelixServer.setHackingParameters(150, 45000000, 30, 30);
SilverHelixServer.setPortProperties(2);
SilverHelixServer.messages.push("new-triads.lit");
@@ -447,17 +449,17 @@ function initForeignServers() {
HaraKiriSushiBarServer.setPortProperties(0);
AddToAllServers(HaraKiriSushiBarServer);
var PhantasyServer = new Server(createRandomIp(), "phantasy", "Phantasy Club", false, false, false, 0);
var PhantasyServer = new Server(createRandomIp(), "phantasy", "Phantasy Club", false, false, false, 16);
PhantasyServer.setHackingParameters(100, 24000000, 20, 35);
PhantasyServer.setPortProperties(2);
AddToAllServers(PhantasyServer);
var MaxHardwareServer = new Server(createRandomIp(), "max-hardware", "Max Hardware Store", false, false, false, 4);
var MaxHardwareServer = new Server(createRandomIp(), "max-hardware", "Max Hardware Store", false, false, false, 16);
MaxHardwareServer.setHackingParameters(80, 10000000, 15, 30);
MaxHardwareServer.setPortProperties(1);
AddToAllServers(MaxHardwareServer);
var OmegaSoftwareServer = new Server(createRandomIp(), "omega-net", "Omega Software", false, false, false, 8);
var OmegaSoftwareServer = new Server(createRandomIp(), "omega-net", "Omega Software", false, false, false, 16);
OmegaSoftwareServer.setHackingParameters(getRandomInt(180, 220), getRandomInt(60000000, 70000000), getRandomInt(25, 35), getRandomInt(30, 40));
OmegaSoftwareServer.setPortProperties(2);
OmegaSoftwareServer.messages.push("the-new-god.lit");
@@ -469,7 +471,7 @@ function initForeignServers() {
CrushFitnessGymServer.setPortProperties(2);
AddToAllServers(CrushFitnessGymServer);
var IronGymServer = new Server(createRandomIp(), "iron-gym", "Iron Gym Network", false, false, false, 4);
var IronGymServer = new Server(createRandomIp(), "iron-gym", "Iron Gym Network", false, false, false, 16);
IronGymServer.setHackingParameters(100, 20000000, 30, 20);
IronGymServer.setPortProperties(1);
AddToAllServers(IronGymServer);
@@ -490,7 +492,7 @@ function initForeignServers() {
AddToAllServers(SnapFitnessGymServer);
//Faction servers, cannot hack money from these
var BitRunnersServer = new Server(createRandomIp(), "run4theh111z", "The Runners", false, false, false, 0);
var BitRunnersServer = new Server(createRandomIp(), "run4theh111z", "The Runners", false, false, false, 2);
BitRunnersServer.setHackingParameters(getRandomInt(505, 550), 0, 0, 0);
BitRunnersServer.setPortProperties(4);
BitRunnersServer.messages.push("simulated-reality.lit");
@@ -498,14 +500,14 @@ function initForeignServers() {
AddToAllServers(BitRunnersServer);
SpecialServerIps.addIp(SpecialServerNames.BitRunnersServer, BitRunnersServer.ip);
var TheBlackHandServer = new Server(createRandomIp(), "I.I.I.I", "I.I.I.I", false, false, false, 0);
var TheBlackHandServer = new Server(createRandomIp(), "I.I.I.I", "I.I.I.I", false, false, false, 2);
TheBlackHandServer.setHackingParameters(getRandomInt(340, 365), 0, 0, 0);
TheBlackHandServer.setPortProperties(3);
TheBlackHandServer.messages.push("democracy-is-dead.lit");
AddToAllServers(TheBlackHandServer);
SpecialServerIps.addIp(SpecialServerNames.TheBlackHandServer, TheBlackHandServer.ip);
var NiteSecServer = new Server(createRandomIp(), "avmnite-02h", "NiteSec", false, false, false, 0);
var NiteSecServer = new Server(createRandomIp(), "avmnite-02h", "NiteSec", false, false, false, 2);
NiteSecServer.setHackingParameters(getRandomInt(202, 220), 0, 0, 0);
NiteSecServer.setPortProperties(2);
NiteSecServer.messages.push("democracy-is-dead.lit");
@@ -518,14 +520,14 @@ function initForeignServers() {
AddToAllServers(DarkArmyServer);
SpecialServerIps.addIp(SpecialServerNames.TheDarkArmyServer, DarkArmyServer.ip);
var CyberSecServer = new Server(createRandomIp(), "CSEC", "CyberSec", false, false, false, 0);
var CyberSecServer = new Server(createRandomIp(), "CSEC", "CyberSec", false, false, false, 2);
CyberSecServer.setHackingParameters(getRandomInt(51, 60), 0, 0, 0);
CyberSecServer.setPortProperties(1);
CyberSecServer.messages.push("democracy-is-dead.lit");
AddToAllServers(CyberSecServer);
SpecialServerIps.addIp(SpecialServerNames.CyberSecServer, CyberSecServer.ip);
var DaedalusServer = new Server(createRandomIp(), "The-Cave", "Helios", false, false, false, 0);
var DaedalusServer = new Server(createRandomIp(), "The-Cave", "Helios", false, false, false, 2);
DaedalusServer.setHackingParameters(925, 0, 0, 0);
DaedalusServer.setPortProperties(5);
DaedalusServer.messages.push("alpha-omega.lit");
@@ -669,13 +671,14 @@ function processSingleServerGrowth(server, numCycles) {
serverGrowth = 1;
}
var oldMoneyAvailable = server.moneyAvailable;
server.moneyAvailable *= serverGrowth;
if (server.moneyMax && isNaN(server.moneyAvailable)) {
server.moneyAvailable = server.moneyMax;
}
if (server.moneyMax && server.moneyAvailable > server.moneyMax) {
server.moneyAvailable = server.moneyMax;
return 1;
return server.moneyAvailable / oldMoneyAvailable;
}
//Growing increases server security twice as much as hacking
+3 -1
View File
@@ -1,9 +1,11 @@
import {CONSTANTS} from "./Constants.js";
import {Player} from "./Player.js";
import {AllServers} from "./Server.js";
import {Server, AllServers, AddToAllServers} from "./Server.js";
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {createRandomIp} from "../utils/IPAddress.js";
import {yesNoTxtInpBoxGetInput} from "../utils/YesNoBox.js";
/* Functions to handle any server-related purchasing:
* Purchasing new servers
* Purchasing more RAM for home computer
+2 -2
View File
@@ -1,6 +1,6 @@
/* Settings.js */
let Settings = {
CodeInstructionRunTime: 100,
CodeInstructionRunTime: 50,
MaxLogCapacity: 50,
MaxPortCapacity: 50,
SuppressMessages: false,
@@ -12,7 +12,7 @@ function loadSettings(saveString) {
}
function initSettings() {
Settings.CodeInstructionRunTime = 100;
Settings.CodeInstructionRunTime = 50;
Settings.MaxLogCapacity = 50;
Settings.MaxPortCapacity = 50;
Settings.SuppressMessages = false;
+77 -18
View File
@@ -13,6 +13,9 @@ import {iTutorialNextStep, iTutorialSteps,
currITutorialStep} from "./InteractiveTutorial.js";
import {showLiterature} from "./Literature.js";
import {showMessage, Message} from "./Message.js";
import {scriptCalculateHackingTime,
scriptCalculateGrowTime,
scriptCalculateWeakenTime} from "./NetscriptEvaluator.js";
import {killWorkerScript, addWorkerScript} from "./NetscriptWorker.js";
import {Player} from "./Player.js";
import {hackWorldDaemon} from "./RedPill.js";
@@ -24,18 +27,18 @@ import {SpecialServerIps,
SpecialServerNames} from "./SpecialServerIps.js";
import {containsAllStrings, longestCommonStart,
formatNumber} from "../utils/StringHelperFunctions.js";
formatNumber, isString} from "../utils/StringHelperFunctions.js";
import {addOffset, printArray} from "../utils/HelperFunctions.js";
import {logBoxCreate} from "../utils/LogBox.js";
/* Write text to terminal */
//If replace is true then spaces are replaced with "&nbsp;"
function post(input, replace=true) {
if (replace) {
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input.replace( / /g, "&nbsp;" ) + '</td></tr>');
} else {
$("#terminal-input").before('<tr class="posted"><td class="terminal-line" style="color: var(--my-font-color); background-color: var(--my-background-color);">' + input + '</td></tr>');
}
updateTerminalScroll();
}
@@ -72,10 +75,10 @@ $(document).keydown(function(event) {
event.preventDefault(); //Prevent newline from being entered in Script Editor
var command = $('input[class=terminal-input]').val();
if (command.length > 0) {
post("> " + command);
post("[" + Player.getCurrentServer().hostname + " ~]> " + command);
Terminal.resetTerminalInput(); //Clear input first
Terminal.executeCommand(command);
$('input[class=terminal-input]').val("");
}
}
@@ -211,13 +214,13 @@ function tabCompletion(command, arg, allPossibilities, index=0) {
//that we are attempting to autocomplete
if (arg == "") {
for (var i = allPossibilities.length-1; i >= 0; --i) {
if (!allPossibilities[i].startsWith(command)) {
if (!allPossibilities[i].toLowerCase().startsWith(command.toLowerCase())) {
allPossibilities.splice(i, 1);
}
}
} else {
for (var i = allPossibilities.length-1; i >= 0; --i) {
if (!allPossibilities[i].startsWith(arg)) {
if (!allPossibilities[i].toLowerCase().startsWith(arg.toLowerCase())) {
allPossibilities.splice(i, 1);
}
}
@@ -337,7 +340,7 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
}
if (input.startsWith("kill ") || input.startsWith("nano ") ||
input.startsWith("tail ") || input.startsWith("rm ") ||
input.startsWith("tail ") ||
input.startsWith("mem ") || input.startsWith("check ")) {
//All Scripts
for (var i = 0; i < currServ.scripts.length; ++i) {
@@ -346,6 +349,22 @@ function determineAllPossibilitiesForTabCompletion(input, index=0) {
return allPos;
}
if (input.startsWith("rm ")) {
for (var i = 0; i < currServ.scripts.length; ++i) {
allPos.push(currServ.scripts[i].filename);
}
for (var i = 0; i < currServ.programs.length; ++i) {
allPos.push(currServ.programs[i]);
}
for (var i = 0; i < currServ.messages.length; ++i) {
if (!(currServ.messages[i] instanceof Message) && isString(currServ.messages[i]) &&
currServ.messages[i].endsWith(".lit")) {
allPos.push(currServ.messages[i]);
}
}
return allPos;
}
if (input.startsWith("run ")) {
//All programs and scripts
for (var i = 0; i < currServ.scripts.length; ++i) {
@@ -390,6 +409,17 @@ let Terminal = {
}
},
resetTerminalInput: function() {
document.getElementById("terminal-input-td").innerHTML =
"<div id='terminal-input-header'>[" + Player.getCurrentServer().hostname + " ~]" + "$ </div>" +
'<input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
var hdr = document.getElementById("terminal-input-header");
hdr.style.display = "inline";
var lineWidth = document.getElementById("terminal-input-td").offsetWidth;
var width = lineWidth - hdr.offsetWidth - 10;
document.getElementById("terminal-input-text-box").style.width = width + "px";
},
//Complete the hack/analyze command
finishHack: function(cancelled = false) {
if (cancelled == false) {
@@ -414,13 +444,12 @@ let Terminal = {
var moneyGained = Player.calculatePercentMoneyHacked();
moneyGained = Math.floor(server.moneyAvailable * moneyGained);
//Safety check
if (moneyGained <= 0) {moneyGained = 0;}
if (moneyGained <= 0) {moneyGained = 0;} //Safety check
server.moneyAvailable -= moneyGained;
Player.gainMoney(moneyGained);
Player.gainHackingExp(expGainedOnSuccess)
Player.gainIntelligenceExp(expGainedOnSuccess / CONSTANTS.IntelligenceTerminalHackBaseExpGain);
server.fortify(CONSTANTS.ServerFortifyAmount);
@@ -435,7 +464,8 @@ let Terminal = {
//Rename the progress bar so that the next hacks dont trigger it. Re-enable terminal
$("#hack-progress-bar").attr('id', "old-hack-progress-bar");
$("#hack-progress").attr('id', "old-hack-progress");
document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
Terminal.resetTerminalInput();
//document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
$('input[class=terminal-input]').prop('disabled', false);
Terminal.hackFlag = false;
@@ -490,7 +520,8 @@ let Terminal = {
//Rename the progress bar so that the next hacks dont trigger it. Re-enable terminal
$("#hack-progress-bar").attr('id', "old-hack-progress-bar");
$("#hack-progress").attr('id', "old-hack-progress");
document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
Terminal.resetTerminalInput();
//document.getElementById("terminal-input-td").innerHTML = '$ <input type="text" id="terminal-input-text-box" class="terminal-input" tabindex="1"/>';
$('input[class=terminal-input]').prop('disabled', false);
},
@@ -587,6 +618,7 @@ let Terminal = {
Player.analyze();
//Disable terminal
//Terminal.resetTerminalInput();
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
$('input[class=terminal-input]').prop('disabled', true);
iTutorialNextStep();
@@ -610,6 +642,7 @@ let Terminal = {
Player.hack();
//Disable terminal
//Terminal.resetTerminalInput();
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
$('input[class=terminal-input]').prop('disabled', true);
iTutorialNextStep();
@@ -690,6 +723,7 @@ let Terminal = {
Player.analyze();
//Disable terminal
//Terminal.resetTerminalInput();
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
$('input[class=terminal-input]').prop('disabled', true);
break;
@@ -793,6 +827,7 @@ let Terminal = {
Player.hack();
//Disable terminal
//Terminal.resetTerminalInput();
document.getElementById("terminal-input-td").innerHTML = '<input type="text" class="terminal-input"/>';
$('input[class=terminal-input]').prop('disabled', true);
}
@@ -821,6 +856,7 @@ let Terminal = {
Player.currentServer = Player.getHomeComputer().ip;
Player.getCurrentServer().isConnectedTo = true;
post("Connected to home");
Terminal.resetTerminalInput();
break;
case "hostname":
if (commandArray.length != 1) {
@@ -961,6 +997,15 @@ let Terminal = {
}
}
//Check literature files
for (var i = 0; i < s.messages.length; ++i) {
var f = s.messages[i];
if (!(f instanceof Message) && isString(f) && f === delTarget) {
s.messages.splice(i, 1);
return;
}
}
post("No such file exists");
break;
case "run":
@@ -986,7 +1031,17 @@ let Terminal = {
if (commandArray.length == 1) {
Terminal.executeScanAnalyzeCommand(1);
} else if (commandArray.length == 2) {
var depth = Number(commandArray[1]);
var all = false;
if (commandArray[1].endsWith("-a")) {
all = true;
commandArray[1] = commandArray[1].replace("-a", "");
}
var depth;
if (commandArray[1].length === 0) {
depth = 1;
} else {
depth = Number(commandArray[1]);
}
if (isNaN(depth) || depth < 0) {
post("Incorrect usage of scan-analyze command. depth argument must be positive numeric");
return;
@@ -1002,7 +1057,7 @@ let Terminal = {
post("You cannot scan-analyze with that high of a depth. Maximum depth is 10");
return;
}
Terminal.executeScanAnalyzeCommand(depth);
Terminal.executeScanAnalyzeCommand(depth, all);
} else {
post("Incorrect usage of scan-analyze command. usage: scan-analyze [depth]");
}
@@ -1033,7 +1088,6 @@ let Terminal = {
//Scp for lit files
if (scriptname.endsWith(".lit")) {
var found = false;
var curr
for (var i = 0; i < currServ.messages.length; ++i) {
if (!(currServ.messages[i] instanceof Message) && currServ.messages[i] == scriptname) {
found = true;
@@ -1227,6 +1281,7 @@ let Terminal = {
if (Player.getCurrentServer().hostname == "darkweb") {
checkIfConnectedToDarkweb(); //Posts a 'help' message if connecting to dark web
}
Terminal.resetTerminalInput();
},
executeListCommand: function(commandArray) {
@@ -1330,12 +1385,13 @@ let Terminal = {
}
},
executeScanAnalyzeCommand: function(depth=1) {
executeScanAnalyzeCommand: function(depth=1, all=false) {
//We'll use the AllServersMap as a visited() array
//TODO Using array as stack for now, can make more efficient
post("~~~~~~~~~~ Beginning scan-analyze ~~~~~~~~~~");
post(" ");
var visited = new AllServersMap();
var stack = [];
var depthQueue = [0];
var currServ = Player.getCurrentServer();
@@ -1343,8 +1399,10 @@ let Terminal = {
while(stack.length != 0) {
var s = stack.pop();
var d = depthQueue.pop();
if (visited[s.ip] || d > depth) {
continue;
if (!all && s.purchasedByPlayer && s.hostname != "home") {
continue; //Purchased server
} else if (visited[s.ip] || d > depth) {
continue; //Already visited or out-of-depth
} else {
visited[s.ip] = 1;
}
@@ -1375,6 +1433,7 @@ let Terminal = {
(function() {
var hostname = links[i].innerHTML.toString();
links[i].onclick = function() {
if (Terminal.analyzeFlag || Terminal.hackFlag) {return;}
Terminal.connectToServer(hostname);
}
}());//Immediate invocation
+144 -242
View File
@@ -1,9 +1,3 @@
var ace = require('brace');
require('brace/mode/javascript');
require('brace/theme/monokai');
require('brace/theme/terminal');
require('brace/theme/twilight');
import {dialogBoxCreate} from "../utils/DialogBox.js";
import {gameOptionsBoxOpen, gameOptionsBoxClose}from "../utils/GameOptions.js";
import {clearEventListeners} from "../utils/HelperFunctions.js";
@@ -441,16 +435,30 @@ let Engine = {
displayCharacterOverviewInfo: function() {
if (Player.hp == null) {Player.hp = Player.max_hp;}
document.getElementById("character-overview-text").innerHTML =
("Hp: " + Player.hp + " / " + Player.max_hp + "<br>" +
"Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + "<br>" +
"Hack: " + (Player.hacking_skill).toLocaleString() + "<br>" +
"Str: " + (Player.strength).toLocaleString() + "<br>" +
"Def: " + (Player.defense).toLocaleString() + "<br>" +
"Dex: " + (Player.dexterity).toLocaleString() + "<br>" +
"Agi: " + (Player.agility).toLocaleString() + "<br>" +
"Cha: " + (Player.charisma).toLocaleString()
).replace( / /g, "&nbsp;" );
if (Player.intelligence >= 1) {
document.getElementById("character-overview-text").innerHTML =
("Hp: " + Player.hp + " / " + Player.max_hp + "<br>" +
"Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + "<br>" +
"Hack: " + (Player.hacking_skill).toLocaleString() + "<br>" +
"Str: " + (Player.strength).toLocaleString() + "<br>" +
"Def: " + (Player.defense).toLocaleString() + "<br>" +
"Dex: " + (Player.dexterity).toLocaleString() + "<br>" +
"Agi: " + (Player.agility).toLocaleString() + "<br>" +
"Cha: " + (Player.charisma).toLocaleString() + "<br>" +
"Int: " + (Player.intelligence).toLocaleString()
).replace( / /g, "&nbsp;" );
} else {
document.getElementById("character-overview-text").innerHTML =
("Hp: " + Player.hp + " / " + Player.max_hp + "<br>" +
"Money: " + numeral(Player.money.toNumber()).format('($0.000a)') + "<br>" +
"Hack: " + (Player.hacking_skill).toLocaleString() + "<br>" +
"Str: " + (Player.strength).toLocaleString() + "<br>" +
"Def: " + (Player.defense).toLocaleString() + "<br>" +
"Dex: " + (Player.dexterity).toLocaleString() + "<br>" +
"Agi: " + (Player.agility).toLocaleString() + "<br>" +
"Cha: " + (Player.charisma).toLocaleString()
).replace( / /g, "&nbsp;" );
}
},
/* Display character info */
@@ -915,7 +923,13 @@ let Engine = {
if (Engine.Counters.checkFactionInvitations <= 0) {
var invitedFactions = Player.checkForFactionInvitations();
if (invitedFactions.length > 0) {
Player.firstFacInvRecvd = true;
if (Player.firstFacInvRecvd === false) {
Player.firstFacInvRecvd = true;
document.getElementById("factions-tab").style.display = "list-item";
document.getElementById("character-menu-header").click();
document.getElementById("character-menu-header").click();
}
var randFaction = invitedFactions[Math.floor(Math.random() * invitedFactions.length)];
inviteToFaction(randFaction);
}
@@ -930,7 +944,11 @@ let Engine = {
if (Engine.Counters.messages <= 0) {
checkForMessagesToSend();
Engine.Counters.messages = 150;
if (Augmentations[AugmentationNames.TheRedPill].owned) {
Engine.Counters.messages = 600; //2 minutes for Red pill message
} else {
Engine.Counters.messages = 150;
}
}
if (Engine.Counters.stockTick <= 0) {
@@ -1018,14 +1036,54 @@ let Engine = {
document.getElementById("entire-game-container").style.visibility = "visible";
},
load: function() {
//Load script editor
var editor = ace.edit('javascript-editor');
editor.getSession().setMode('ace/mode/javascript');
editor.setTheme('ace/theme/monokai');
document.getElementById('javascript-editor').style.fontSize='16px';
editor.setOption("showPrintMargin", false);
//Used when initializing a game
//elems should be an array of all DOM elements under the header
closeMainMenuHeader: function(elems) {
for (var i = 0; i < elems.length; ++i) {
elems[i].style.maxHeight = null;
elems[i].style.opacity = 0;
elems[i].style.pointerEvents = "none";
}
},
//Used when initializing the game
//elems should be an array of all DOM elements under the header
openMainMenuHeader: function(elems) {
for (var i = 0; i < elems.length; ++i) {
elems[i].style.maxHeight = elems[i].scrollHeight + "px";
elems[i].style.display = "block";
}
},
//Used in game when clicking on a main menu header (NOT FOR INITIALIZATION)
//open is a boolean specifying whether its being opened or closed
//elems is an array of DOM elements for main menu tabs (li)
//links is an array of DOM elements for main menu links (a)
toggleMainMenuHeader: function(open, elems, links) {
for (var i = 0; i < elems.length; ++i) {
if (open) {
elems[i].style.opacity = 1;
elems[i].style.maxHeight = elems[i].scrollHeight + "px";
} else {
elems[i].style.opacity = 0;
elems[i].style.maxHeight = null;
}
}
for (var i = 0; i < links.length; ++i) {
if (open) {
links[i].style.opacity = 1;
links[i].style.maxHeight = links[i].scrollHeight + "px";
links[i].style.pointerEvents = "auto";
} else {
links[i].style.opacity = 0;
links[i].style.maxHeight = null;
links[i].style.pointerEvents = "none";
}
}
},
load: function() {
//Initialize main menu accordion panels to all start as "open"
var terminal = document.getElementById("terminal-tab");
var createScript = document.getElementById("create-script-tab");
@@ -1090,7 +1148,7 @@ let Engine = {
processPassiveFactionRepGain(numCyclesOffline);
//Gang progress for BitNode 2
if (Player.bitNodeN != null && Player.bitNodeN == 2 && Player.inGang()) {
if (Player.bitNodeN != null && Player.bitNodeN === 2 && Player.inGang()) {
Player.gang.process(numCyclesOffline);
}
@@ -1108,45 +1166,20 @@ let Engine = {
formatNumber(offlineProductionFromScripts, 2) + " and your Hacknet Nodes generated $" +
formatNumber(offlineProductionFromHacknetNodes, 2));
//Close main menu accordions for loaded game
terminal.style.maxHeight = null;
terminal.style.opacity = 0;
terminal.style.pointerEvents = "none";
createScript.style.maxHeight = null;
createScript.style.opacity = 0;
createScript.style.pointerEvents = "none";
activeScripts.style.maxHeight = null;
activeScripts.style.opacity = 0;
activeScripts.style.pointerEvents = "none";
createProgram.style.maxHeight = null;
createProgram.style.opacity = 0;
createProgram.style.pointerEvents = "none";
stats.style.maxHeight = null;
stats.style.opacity = 0;
stats.style.pointerEvents = "none";
factions.style.maxHeight = null;
factions.style.opacity = 0;
factions.style.pointerEvents = "none";
augmentations.style.maxHeight = null;
augmentations.style.opacity = 0;
augmentations.style.pointerEvents = "none";
hacknetnodes.style.maxHeight = null;
hacknetnodes.style.opacity = 0;
hacknetnodes.style.pointerEvents = "none";
city.style.maxHeight = null;
city.style.opacity = 0;
city.style.pointerEvents = "none";
travel.style.maxHeight = null;
travel.style.opacity = 0;
travel.style.pointerEvents = "none";
job.style.maxHeight = null;
job.style.opacity = 0;
job.style.pointerEvents = "none";
tutorial.style.maxHeight = null;
tutorial.style.opacity = 0;
tutorial.style.pointerEvents = "none";
options.style.maxHeight = null;
options.style.opacity = 0;
options.style.pointerEvents = "none";
var visibleMenuTabs = [terminal, createScript, activeScripts, stats,
hacknetnodes, city, tutorial, options];
if (Player.firstFacInvRecvd) {visibleMenuTabs.push(factions);}
else {factions.style.display = "none";}
if (Player.firstAugPurchased) {visibleMenuTabs.push(augmentations);}
else {augmentations.style.display = "none";}
if (Player.firstJobRecvd) {visibleMenuTabs.push(job);}
else {job.style.display = "none";}
if (Player.firstTimeTraveled) {visibleMenuTabs.push(travel);}
else {travel.style.display = "none";}
if (Player.firstProgramAvailable) {visibleMenuTabs.push(createProgram);}
else {createProgram.style.display = "none";}
Engine.closeMainMenuHeader(visibleMenuTabs);
} else {
//No save found, start new game
console.log("Initializing new game");
@@ -1177,32 +1210,19 @@ let Engine = {
worldHdr.classList.toggle("opened");
var helpHdr = document.getElementById("help-menu-header");
helpHdr.classList.toggle("opened");
terminal.style.maxHeight = terminal.scrollHeight + "px";
terminal.style.display = "block";
createScript.style.maxHeight = createScript.scrollHeight + "px";
createScript.style.display = "block";
activeScripts.style.maxHeight = activeScripts.scrollHeight + "px";
activeScripts.style.display = "block";
createProgram.style.maxHeight = createProgram.scrollHeight + "px";
createProgram.style.display = "block";
stats.style.maxHeight = stats.scrollHeight + "px";
stats.style.display = "block";
factions.style.maxHeight = factions.scrollHeight + "px";
factions.style.display = "block";
augmentations.style.maxHeight = augmentations.scrollHeight + "px";
augmentations.style.display = "block";
hacknetnodes.style.maxHeight = hacknetnodes.scrollHeight + "px";
hacknetnodes.style.display = "block";
city.style.maxHeight = city.scrollHeight + "px";
city.style.display = "block";
travel.style.maxHeight = travel.scrollHeight + "px";
travel.style.display = "block";
job.style.maxHeight = job.scrollHeight + "px";
job.style.display = "block";
tutorial.style.maxHeight = tutorial.scrollHeight + "px";
tutorial.style.display = "block";
options.style.maxHeight = options.scrollHeight + "px";
options.style.display = "block";
//Hide tabs that wont be revealed until later
factions.style.display = "none";
augmentations.style.display = "none";
job.style.display = "none";
travel.style.display = "none";
createProgram.style.display = "none";
Engine.openMainMenuHeader(
[terminal, createScript, activeScripts, stats,
hacknetnodes, city,
tutorial, options]
);
//Start interactive tutorial
iTutorialStart();
@@ -1210,6 +1230,7 @@ let Engine = {
}
//Initialize labels on game settings
setSettingsLabels();
Terminal.resetTerminalInput();
},
setDisplayElements: function() {
@@ -1350,13 +1371,9 @@ let Engine = {
//Main menu accordions
var hackingHdr = document.getElementById("hacking-menu-header");
//hackingHdr.classList.toggle("opened");
var characterHdr = document.getElementById("character-menu-header");
//characterHdr.classList.toggle("opened");
var worldHdr = document.getElementById("world-menu-header");
//worldHdr.classList.toggle("opened");
var helpHdr = document.getElementById("help-menu-header");
//helpHdr.classList.toggle("opened");
hackingHdr.onclick = function() {
var terminal = document.getElementById("terminal-tab");
@@ -1370,55 +1387,18 @@ let Engine = {
var createProgramNot = document.getElementById("create-program-notification");
this.classList.toggle("opened");
if (terminal.style.maxHeight) {
terminal.style.opacity = 0;
terminal.style.maxHeight = null;
terminalLink.style.opacity = 0;
terminalLink.style.maxHeight = null;
terminalLink.style.pointerEvents = "none";
createScript.style.opacity = 0;
createScript.style.maxHeight = null;
createScriptLink.style.opacity = 0;
createScriptLink.style.maxHeight = null;
createScriptLink.style.pointerEvents = "none";
activeScripts.style.opacity = 0;
activeScripts.style.maxHeight = null;
activeScriptsLink.style.opacity = 0;
activeScriptsLink.style.maxHeight = null;
activeScriptsLink.style.pointerEvents = "none";
createProgram.style.opacity = 0;
createProgram.style.maxHeight = null;
createProgramLink.style.opacity = 0;
createProgramLink.style.maxHeight = null;
createProgramLink.style.pointerEvents = "none";
Engine.toggleMainMenuHeader(false,
[terminal, createScript, activeScripts, createProgram],
[terminalLink, createScriptLink, activeScriptsLink, createProgramLink]
);
createProgramNot.style.display = "none";
} else {
terminal.style.maxHeight = terminal.scrollHeight + "px";
terminal.style.opacity = 1;
terminalLink.style.maxHeight = terminalLink.scrollHeight + "px";
terminalLink.style.opacity = 1;
terminalLink.style.pointerEvents = "auto";
Engine.toggleMainMenuHeader(true,
[terminal, createScript, activeScripts, createProgram],
[terminalLink, createScriptLink, activeScriptsLink, createProgramLink]
);
createScript.style.maxHeight = createScript.scrollHeight + "px";
createScript.style.opacity = 1;
createScriptLink.style.maxHeight = createScriptLink.scrollHeight + "px";
createScriptLink.style.opacity = 1;
createScriptLink.style.pointerEvents = "auto";
activeScripts.style.maxHeight = activeScripts.scrollHeight + "px";
activeScripts.style.opacity = 1;
activeScriptsLink.style.maxHeight = activeScriptsLink.scrollHeight + "px";
activeScriptsLink.style.opacity = 1;
activeScriptsLink.style.pointerEvents = "auto";
createProgram.style.maxHeight = createProgram.scrollHeight + "px";
createProgram.style.opacity = 1;
createProgramLink.style.maxHeight = createProgramLink.scrollHeight + "px";
createProgramLink.style.opacity = 1;
createProgramLink.style.pointerEvents = "auto";
createProgramNot.style.display = "block"
}
}
@@ -1434,53 +1414,15 @@ let Engine = {
var hacknetnodesLink = document.getElementById("hacknet-nodes-menu-link");
this.classList.toggle("opened");
if (stats.style.maxHeight) {
stats.style.opacity = 0;
stats.style.maxHeight = null;
statsLink.style.opacity = 0;
statsLink.style.maxHeight = null;
statsLink.style.pointerEvents = "none";
factions.style.opacity = 0;
factions.style.maxHeight = null;
factionsLink.style.opacity = 0;
factionsLink.style.maxHeight = null;
factionsLink.style.pointerEvents = "none";
augmentations.style.opacity = 0;
augmentations.style.maxHeight = null;
augmentationsLink.style.opacity = 0;
augmentationsLink.style.maxHeight = null;
augmentationsLink.style.pointerEvents = "none";
hacknetnodes.style.opacity = 0;
hacknetnodes.style.maxHeight = null;
hacknetnodesLink.style.opacity = 0;
hacknetnodesLink.style.maxHeight = null;
hacknetnodesLink.style.pointerEvents = "none";
Engine.toggleMainMenuHeader(false,
[stats, factions, augmentations, hacknetnodes],
[statsLink, factionsLink, augmentationsLink, hacknetnodesLink]
);
} else {
stats.style.maxHeight = stats.scrollHeight + "px";
stats.style.opacity = 1;
statsLink.style.maxHeight = statsLink.scrollHeight + "px";
statsLink.style.opacity = 1;
statsLink.style.pointerEvents = "auto";
factions.style.maxHeight = factions.scrollHeight + "px";
factions.style.opacity = 1;
factionsLink.style.maxHeight = factionsLink.scrollHeight + "px";
factionsLink.style.opacity = 1;
factionsLink.style.pointerEvents = "auto";
augmentations.style.maxHeight = augmentations.scrollHeight + "px";
augmentations.style.opacity = 1;
augmentationsLink.style.maxHeight = augmentationsLink.scrollHeight + "px";
augmentationsLink.style.opacity = 1;
augmentationsLink.style.pointerEvents = "auto";
hacknetnodes.style.maxHeight = hacknetnodes.scrollHeight + "px";
hacknetnodes.style.opacity = 1;
hacknetnodesLink.style.maxHeight = hacknetnodesLink.scrollHeight + "px";
hacknetnodesLink.style.opacity = 1;
hacknetnodesLink.style.pointerEvents = "auto";
Engine.toggleMainMenuHeader(true,
[stats, factions, augmentations, hacknetnodes],
[statsLink, factionsLink, augmentationsLink, hacknetnodesLink]
);
}
}
@@ -1493,41 +1435,15 @@ let Engine = {
var jobLink = document.getElementById("job-menu-link");
this.classList.toggle("opened");
if (city.style.maxHeight) {
city.style.opacity = 0;
city.style.maxHeight = null;
cityLink.style.opacity = 0;
cityLink.style.maxHeight = null;
cityLink.style.pointerEvents = "none";
travel.style.opacity = 0;
travel.style.maxHeight = null;
travelLink.style.opacity = 0;
travelLink.style.maxHeight = null;
travelLink.style.pointerEvents = "none";
job.style.opacity = 0;
job.style.maxHeight = null;
jobLink.style.opacity = 0;
jobLink.style.maxHeight = null;
jobLink.style.pointerEvents = "none";
Engine.toggleMainMenuHeader(false,
[city, travel, job],
[cityLink, travelLink, jobLink]
);
} else {
city.style.maxHeight = city.scrollHeight + "px";
city.style.opacity = 1;
cityLink.style.maxHeight = cityLink.scrollHeight + "px";
cityLink.style.opacity = 1;
cityLink.style.pointerEvents = "auto";
travel.style.maxHeight = travel.scrollHeight + "px";
travel.style.opacity = 1;
travelLink.style.maxHeight = travelLink.scrollHeight + "px";
travelLink.style.opacity = 1;
travelLink.style.pointerEvents = "auto";
job.style.maxHeight = job.scrollHeight + "px";
job.style.opacity = 1;
jobLink.style.maxHeight = jobLink.scrollHeight + "px";
jobLink.style.opacity = 1;
jobLink.style.pointerEvents = "auto";
Engine.toggleMainMenuHeader(true,
[city, travel, job],
[cityLink, travelLink, jobLink]
);
}
}
@@ -1538,29 +1454,15 @@ let Engine = {
var optionsLink = document.getElementById("options-menu-link");
this.classList.toggle("opened");
if (tutorial.style.maxHeight) {
tutorial.style.opacity = 0;
tutorial.style.maxHeight = null;
tutorialLink.style.opacity = 0;
tutorialLink.style.maxHeight = null;
tutorialLink.style.pointerEvents = "none";
options.style.opacity = 0;
options.style.maxHeight = null;
optionsLink.style.opacity = 0;
optionsLink.style.maxHeight = null;
optionsLink.style.pointerEvents = "none";
Engine.toggleMainMenuHeader(false,
[tutorial, options],
[tutorialLink, optionsLink]
);
} else {
tutorial.style.maxHeight = tutorial.scrollHeight + "px";
tutorial.style.opacity = 1;
tutorialLink.style.maxHeight = tutorialLink.scrollHeight + "px";
tutorialLink.style.opacity = 1;
tutorialLink.style.pointerEvents = "auto";
options.style.maxHeight = options.scrollHeight + "px";
options.style.opacity = 1;
optionsLink.style.maxHeight = optionsLink.scrollHeight + "px";
optionsLink.style.opacity = 1;
optionsLink.style.pointerEvents = "auto";
Engine.toggleMainMenuHeader(true,
[tutorial, options],
[tutorialLink, optionsLink]
);
}
}