v0.28.6 changes

This commit is contained in:
danielyxie 2017-09-15 09:06:59 -05:00
parent c0369bc937
commit e3991b8795
17 changed files with 983 additions and 566 deletions

995
dist/bundle.js vendored

File diff suppressed because it is too large Load Diff

@ -53,7 +53,20 @@ 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>" +
"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. This source file 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

@ -1,5 +1,5 @@
let CONSTANTS = {
Version: "0.28.5",
Version: "0.28.6",
//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
@ -112,6 +112,13 @@ 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.0001,
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
//Gang constants
GangRespectToReputationRatio: 2, //Respect is divided by this to get rep gain
MaximumGangMembers: 20,
@ -231,7 +238,8 @@ 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 " +
"Each server has a security level, typically between 1 and 100. It is possible for a server to have a security " +
"level 100 or higher, in which case hacking a server will become impossible. A higher number means " +
"the server has stronger security. 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 " +
@ -482,6 +490,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> " +
@ -547,6 +557,17 @@ let CONSTANTS = {
"The second argument must be a string with the hostname/IP of the target server. If the first argument is specified " +
"then the second argument must be specified as well. Any additional arguments passed to the function will specify " +
"the arguments passed into the target script.<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 " +
@ -875,41 +896,17 @@ let CONSTANTS = {
"World Stock Exchange account and TIX API Access<br>",
LatestUpdate:
"v0.28.5<br>" +
"-The fl1ght.exe program that is received from jump3r is now sent very early on in the game, rather " +
"than at hacking level 1000<br>" +
"-Hostname is now displayed in Terminal<br>" +
"-Syntax highlighting now works for all Netscript functions<br>" +
"-Export should now work on Edge/IE<br><br>" +
"v0.28.4<br>" +
"-Added getScriptIncome() Netscript function<br>" +
"-Added Javascript's Math module to Netscript. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math<br>" +
"-Added several member variables for the Hacknet Node API that allow you to access info about their income<br>" +
"-All valid Netscript functions are now syntax highlighted as keywords in the editor. This means they will a different " +
"color than invalid netscript functions. The color will depend on your theme. " +
"Note that right now, this only applies for normal Netscript functions, not " +
"functions in the TIX API, Hacknet Node API, or Singularity Functions.<br><br>" +
"-Comments and operators no longer count towards RAM usage in scripts.<br>" +
"-Variety of bug fixes and updates to informational text in the game<br><br>" +
"v0.28.3<br>" +
"-Added ls() Netscript function<br>" +
"-Increased company wages by about ~10% across the board<br>" +
"-The scp() Netsction function and Terminal command now works for .lit files<br>" +
"-Increased the amount of RAM on many lower level servers (up to level 200 hacking level required).<br><br>" +
"v0.28.2<br>" +
"-Added a few script editor configuration options. Includes key bindings, themes, etc.<br>" +
"-Certain menu options will now be hidden until their relevant gameplay is unlocked. This " +
"really only affects new players<br>" +
"-Most unrecognized or un-implemented syntax errors in a script will now include line number in error message<br>" +
"-Various bug fixes<br><br>" +
"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.28.6<br>" +
"-Time required to create programs now scales better with hacking level, and should generally be much faster<br>" +
"-Added serverExists(hostname/ip) and getScriptExpGain(scriptname, ip, args...) Netscript functions<br>" +
"-Short circuiting && and || logical operators should now work<br>" +
"-Assigning to multidimensional arrays should now work<br>" +
"-Scripts will no longer wait for hack/grow/weaken functions to finish if they are killed. They will die immediately<br>" +
"-The script loop that checks whether any scripts need to be started/stopped now runs every 6 seconds rather than 10 " +
"(resulting in less delays when stopping/starting scripts)<br>" +
"-Fixed several bugs/exploits<br>" +
"-Added some description for BitNode-5 (not implemented yet, should be soon though)<br>",
}
export {CONSTANTS};

@ -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);
}

@ -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);
}
}

@ -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};

@ -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) {

@ -252,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){
@ -307,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);
@ -341,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) {
@ -360,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"));
@ -380,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 {
@ -406,11 +462,12 @@ 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);
});
@ -567,9 +624,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();
};
});
}
@ -577,6 +638,7 @@ function makeRuntimeRejectMsg(workerScript, msg) {
return "|"+workerScript.serverIp+"|"+workerScript.name+"|" + msg;
}
/*
function apply_op(op, a, b) {
function num(x) {
if (typeof x != "number")
@ -605,6 +667,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) {
@ -671,7 +734,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;}
@ -682,7 +745,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;
}
@ -708,7 +771,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;
}
@ -716,7 +779,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;
}

@ -37,9 +37,10 @@ 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 singularitySFLvl = 1;
@ -101,7 +102,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();
@ -146,7 +147,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);
});
},
@ -171,7 +172,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);
@ -207,10 +208,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);
@ -232,6 +232,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() {
@ -678,6 +686,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])");
@ -1038,6 +1049,32 @@ function NetscriptFunctions(workerScript) {
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) {

@ -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
@ -148,7 +149,7 @@ function runScriptsLoop() {
}
}
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;
}
}

@ -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";
@ -146,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;
@ -196,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;
@ -395,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);
@ -442,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;}
@ -457,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;
}
@ -578,7 +578,18 @@ PlayerObject.prototype.gainIntelligenceExp = function(exp) {
if (isNaN(exp)) {
console.log("ERROR: NaN passed into Player.gainIntelligenceExp()"); return;
}
//TODO
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 *******/
@ -602,6 +613,7 @@ PlayerObject.prototype.resetWorkStatus = function() {
this.workMoneyGained = 0;
this.timeWorked = 0;
this.timeWorkedCreateProgram = 0;
this.currentWorkFactionName = "";
this.currentWorkFactionDescription = "";
@ -658,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 " +
@ -734,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>" +
@ -851,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 " +
@ -894,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 " +
@ -936,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";
@ -984,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();
@ -1103,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;}
@ -1124,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;
}
@ -1136,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);
}
}
@ -1168,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.";
}
@ -1188,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();
}
@ -1397,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;" );
}
@ -1442,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;
@ -1449,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);
@ -1542,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;
}
@ -1626,8 +1660,8 @@ PlayerObject.prototype.applyForJob = function(entryPosType, sing=false) {
this.companyName = company.companyName;
this.companyPosition = pos;
if (Player.firstJobRecvd === false) {
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();
@ -1735,8 +1769,8 @@ 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)) {
if (Player.firstJobRecvd === false) {
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();
@ -1755,8 +1789,8 @@ 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)) {
if (Player.firstJobRecvd === false) {
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();
@ -1775,8 +1809,8 @@ 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)) {
if (Player.firstJobRecvd === false) {
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();
@ -1795,8 +1829,8 @@ 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)) {
if (Player.firstJobRecvd === false) {
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();
@ -2149,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 &&

@ -218,6 +218,9 @@ function prestigeSourceFile() {
mainMenu.style.visibility = "visible";
Terminal.resetTerminalInput();
Engine.loadTerminalContent();
//Gain int exp
Player.gainIntelligenceExp(5);
}
export {prestigeAugmentation, prestigeSourceFile};

@ -232,7 +232,8 @@ 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 purchaseHacknetCount = numOccurrences(codeCopy, "purchaseHacknetNode(");
@ -251,7 +252,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(");

@ -669,13 +669,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

@ -29,13 +29,13 @@ 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();
}
@ -441,13 +441,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);
@ -1418,6 +1417,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

@ -47,7 +47,7 @@ function infiltrationBoxCreate(inst) {
formatNumber(inst.chaExpGained, 3) + " cha exp<br>");
return;
}
var facValue = totalValue * Player.faction_rep_mult * 1.2
var facValue = totalValue * Player.faction_rep_mult * 1.25
var moneyValue = totalValue * CONSTANTS.InfiltrationMoneyValue;
infiltrationSetText("You can sell the classified documents and secrets " +
"you stole from " + inst.companyName + " for $" +

@ -129,6 +129,16 @@ function numNetscriptOperators(string) {
return total;
}
//Checks if a string contains HTML elements
function isHTML(str) {
var a = document.createElement('div');
a.innerHTML = str;
for (var c = a.childNodes, i = c.length; i--; ) {
if (c[i].nodeType == 1) return true;
}
return false;
}
export {getIndicesOf, convertTimeMsToTimeElapsedString, longestCommonStart,
isString, isPositiveNumber, containsAllStrings, formatNumber,
numOccurrences, numNetscriptOperators};
numOccurrences, numNetscriptOperators, isHTML};